1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
|
import argparse
import os
import re
import uuid
import zipfile
def pattern_to_regexp(p):
return re.compile(
'^'
+ re.escape(p)
.replace(r'\*\*\/', '[_DIR_]')
.replace(r'\*', '[_FILE_]')
.replace('[_DIR_]', '(.*/)?')
.replace('[_FILE_]', '([^/]*)')
+ '$'
)
def is_deathman(positive_filter, negative_filter, candidate):
remove = positive_filter
for pf in positive_filter:
if pf.match(candidate):
remove = False
break
if not negative_filter or remove:
return remove
for nf in negative_filter:
if nf.match(candidate):
remove = True
break
return remove
def just_do_it():
parser = argparse.ArgumentParser()
parser.add_argument('--positive', action='append', default=[])
parser.add_argument('--negative', action='append', default=[])
parser.add_argument('--file', action='store', required=True)
args = parser.parse_args()
if not args.positive and not args.negative:
return
pos = [pattern_to_regexp(i) for i in args.positive]
neg = [pattern_to_regexp(i) for i in args.negative]
temp_dirname = None
for _ in range(10):
candidate = '__unpacked_{}__'.format(uuid.uuid4())
if not os.path.exists(candidate):
temp_dirname = candidate
os.makedirs(temp_dirname)
if not temp_dirname:
raise Exception("Can't generate name for temp dir")
with zipfile.ZipFile(args.file, 'r') as zip_ref:
zip_ref.extractall(temp_dirname)
for root, _, files in os.walk(temp_dirname):
for f in files:
candidate = os.path.join(root, f).replace('\\', '/')
if is_deathman(pos, neg, os.path.relpath(candidate, temp_dirname)):
os.remove(candidate)
with zipfile.ZipFile(args.file, 'w') as zip_ref:
for root, _, files in os.walk(temp_dirname):
for f in files:
realname = os.path.join(root, f)
zip_ref.write(realname, os.path.sep.join(os.path.normpath(realname).split(os.path.sep, 2)[1:]))
if __name__ == '__main__':
just_do_it()
|