aboutsummaryrefslogtreecommitdiffstats
path: root/build/scripts/filter_zip.py
blob: 3ee15b07fba0854f24634dd7fff26765b726ced8 (plain) (blame)
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()