summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjvoisin2018-04-29 22:55:26 +0200
committerjvoisin2018-04-29 22:59:23 +0200
commitd2b2a54a724db89447027e44ecb8f9bbed72cb83 (patch)
treeff68c16e9157c40d915b38769da5b31eac7080e2
parenta79c9410afbd81a7e2f40ea59cdcef2b36a4ad2f (diff)
MAT2's cli now uses meaningful return codes
- Simplify the multiprocessing by using a Pool - Use some functional (♥) constructions to exit with a return code - Add some tests to prove that we're doing things that are working correctly
-rwxr-xr-xmain.py42
-rw-r--r--tests/test_climat2.py16
2 files changed, 28 insertions, 30 deletions
diff --git a/main.py b/main.py
index 9e07e15..933059b 100755
--- a/main.py
+++ b/main.py
@@ -1,11 +1,12 @@
1#!/usr/bin/python3 1#!/usr/bin/python3
2 2
3import os 3import os
4from typing import Tuple
5import sys
6import itertools
4import mimetypes 7import mimetypes
5import argparse 8import argparse
6from threading import Thread
7import multiprocessing 9import multiprocessing
8from queue import Queue
9 10
10from src import parser_factory 11from src import parser_factory
11 12
@@ -52,14 +53,15 @@ def show_meta(filename:str):
52 print(" %s: harmful content" % k) 53 print(" %s: harmful content" % k)
53 54
54 55
55def clean_meta(filename:str, is_lightweigth:bool) -> bool: 56def clean_meta(params:Tuple[str, bool]) -> bool:
57 filename, is_lightweigth = params
56 if not __check_file(filename, os.R_OK|os.W_OK): 58 if not __check_file(filename, os.R_OK|os.W_OK):
57 return 59 return
58 60
59 p, mtype = parser_factory.get_parser(filename) 61 p, mtype = parser_factory.get_parser(filename)
60 if p is None: 62 if p is None:
61 print("[-] %s's format (%s) is not supported" % (filename, mtype)) 63 print("[-] %s's format (%s) is not supported" % (filename, mtype))
62 return 64 return False
63 if is_lightweigth: 65 if is_lightweigth:
64 return p.remove_all_lightweight() 66 return p.remove_all_lightweight()
65 return p.remove_all() 67 return p.remove_all()
@@ -82,15 +84,6 @@ def __get_files_recursively(files):
82 for _f in _files: 84 for _f in _files:
83 yield os.path.join(path, _f) 85 yield os.path.join(path, _f)
84 86
85def __do_clean_async(is_lightweigth, q):
86 while True:
87 f = q.get()
88 if f is None: # nothing more to process
89 return
90 clean_meta(f, is_lightweigth)
91 q.task_done()
92
93
94def main(): 87def main():
95 arg_parser = create_arg_parser() 88 arg_parser = create_arg_parser()
96 args = arg_parser.parse_args() 89 args = arg_parser.parse_args()
@@ -106,24 +99,13 @@ def main():
106 show_meta(f) 99 show_meta(f)
107 return 100 return
108 101
109 else: # Thread the cleaning 102 else:
103 p = multiprocessing.Pool()
110 mode = (args.lightweight is True) 104 mode = (args.lightweight is True)
111 q = Queue(maxsize=0) 105 l = zip(__get_files_recursively(args.files), itertools.repeat(mode))
112 threads = list()
113 for f in __get_files_recursively(args.files):
114 q.put(f)
115
116 for _ in range(multiprocessing.cpu_count()):
117 worker = Thread(target=__do_clean_async, args=(mode, q))
118 worker.start()
119 threads.append(worker)
120
121 for _ in range(multiprocessing.cpu_count()):
122 q.put(None) # stop the threads
123
124 for worker in threads:
125 worker.join()
126 106
107 ret = list(p.imap_unordered(clean_meta, list(l)))
108 return 0 if all(ret) else -1
127 109
128if __name__ == '__main__': 110if __name__ == '__main__':
129 main() 111 sys.exit(main())
diff --git a/tests/test_climat2.py b/tests/test_climat2.py
index 0536646..bc4a175 100644
--- a/tests/test_climat2.py
+++ b/tests/test_climat2.py
@@ -16,6 +16,22 @@ class TestHelp(unittest.TestCase):
16 self.assertIn(b'usage: main.py [-h] [-c] [-l] [-s] [-L] [files [files ...]]', stdout) 16 self.assertIn(b'usage: main.py [-h] [-c] [-l] [-s] [-L] [files [files ...]]', stdout)
17 17
18 18
19class TestReturnValue(unittest.TestCase):
20 def test_nonzero(self):
21 ret = subprocess.call(['./main.py', './main.py'], stdout=subprocess.DEVNULL)
22 self.assertEqual(255, ret)
23
24 ret = subprocess.call(['./main.py', '--whololo'], stderr=subprocess.DEVNULL)
25 self.assertEqual(2, ret)
26
27 def test_zero(self):
28 ret = subprocess.call(['./main.py'], stdout=subprocess.DEVNULL)
29 self.assertEqual(0, ret)
30
31 ret = subprocess.call(['./main.py', '--show', './main.py'], stdout=subprocess.DEVNULL)
32 self.assertEqual(0, ret)
33
34
19class TestCleanMeta(unittest.TestCase): 35class TestCleanMeta(unittest.TestCase):
20 def test_jpg(self): 36 def test_jpg(self):
21 shutil.copy('./tests/data/dirty.jpg', './tests/data/clean.jpg') 37 shutil.copy('./tests/data/dirty.jpg', './tests/data/clean.jpg')