Completed
Push — master ( e013eb...d9a645 )
by John
02:55
created

sz_wrapper_writer()   A

Complexity

Conditions 2

Size

Total Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
c 1
b 0
f 0
dl 0
loc 11
rs 9.4285
1
#!/usr/bin/env python3
2
"""Generate .exe files with PyInstaller."""
3
4
from os import remove, listdir, devnull, getcwd, makedirs
5
from os.path import join, basename, exists
6
from platform import architecture
7
from shutil import copy, rmtree, copytree
8
from subprocess import call, STDOUT
9
from requests import certs, get
10
from bbarchivist.bbconstants import VERSION, LONGVERSION, CAP, JSONDIR, COMMITDATE
11
from bbarchivist.utilities import prep_seven_zip, get_seven_zip
12
13
14
def write_versions():
15
    """
16
    Write temporary version files.
17
    """
18
    with open("version.txt", "w") as afile:
19
        afile.write(VERSION)
20
    with open("longversion.txt", "w") as afile:
21
        afile.write("{0}\n{1}".format(LONGVERSION, COMMITDATE))
22
23
24
def clean_versions():
25
    """
26
    Remove temporary version files.
27
    """
28
    remove("version.txt")
29
    remove("longversion.txt")
30
31
32
def bitsdir(indir):
33
    """
34
    Create directories based on indir segregated on bit type.
35
36
    :param indir: Directory to modify.
37
    :type indir: str
38
    """
39
    if architecture()[0] == "64bit":
40
        indirx = "{0}-64".format(indir)
41
    else:
42
        indirx = indir
43
    if not exists(indirx):
44
        makedirs(indirx)
45
    return indirx
46
47
48
def generate_specs():
49
    """
50
    Generate pyinstaller spec files.
51
    """
52
    scripts = ["archivist", "autolookup", "barlinker", "carrierchecker", "certchecker", "devloader", "downloader", "droidlookup", "droidscraper", "escreens", "kernchecker", "lazyloader", "linkgen", "metachecker", "swlookup", "tclloader", "tclscan", "tcldelta"]
53
    here = getcwd().replace("\\", "\\\\")
54
    for script in scripts:
55
        template = "# -*- mode: python -*-\n\nblock_cipher = None\n\n\na = Analysis(['bbarchivist\\\\scripts\\\\{0}.py'],\n             pathex=['{1}'],\n             binaries=None,\n             datas=None,\n             hiddenimports=[],\n             hookspath=[],\n             runtime_hooks=[],\n             excludes=[],\n             win_no_prefer_redirects=False,\n             win_private_assemblies=False,\n             cipher=block_cipher)\npyz = PYZ(a.pure, a.zipped_data,\n             cipher=block_cipher)\nexe = EXE(pyz,\n          a.scripts,\n          a.binaries,\n          a.zipfiles,\n          a.datas,\n          name='{0}',\n          debug=False,\n          strip=False,\n          upx=False,\n          console=True )\n".format(script, here)
56
        with open("{0}.spec".format(script), "w") as afile:
57
            afile.write(template)
58
59
60
def clean_specs():
61
    """
62
    Remove pyinstaller spec files.
63
    """
64
    specs = [x for x in listdir() if x.endswith(".spec")]
65
    for spec in specs:
66
        remove(spec)
67
68
69
def get_sevenzip():
70
    """
71
    Get 7-Zip.
72
    """
73
    szver = "1700"
74
    szurl = "http://www.7-zip.org/a/7z{0}-extra.7z".format(szver)
75
    psz = prep_seven_zip()
76
    if psz:
77
        get_sevenzip_write(szurl)
78
    else:
79
        print("GO TO {0} AND DO IT MANUALLY".format(szurl))
80
        raise SystemError
81
82
83
def get_sevenzip_write(szurl):
84
    """
85
    Download 7-Zip file.
86
87
    :param szurl: Link to 7z download.
88
    :type szurl: str
89
    """
90
    szexe = get_seven_zip()
91
    szfile = basename(szurl)
92
    with open(szfile, "wb") as afile:
93
        req = get(szurl, stream=True)
94
        for chunk in req.iter_content(chunk_size=1024):
95
            afile.write(chunk)
96
    cmd = "{0} x {1} -o7z".format(szexe, szfile)
97
    with open(devnull, "wb") as dnull:
98
        call(cmd, stdout=dnull, stderr=STDOUT, shell=True)
99
    remove(basename(szurl))
100
101
102
def call_specs():
103
    """
104
    Call pyinstaller to make specs.
105
    """
106
    specs = [x for x in listdir() if x.endswith(".spec")]
107
    for spec in specs:  # use UPX 3.93 or up
108
        cmd = "pyinstaller --onefile --workpath {2} --distpath {1} {0}".format(spec, bitsdir("pyinst-dist"), bitsdir("pyinst-build"))
109
        call(cmd, shell=True)
110
111
112
def sz_wrapper(outdir):
113
    """
114
    Copy 7-Zip to outdir.
115
116
    :param outdir: Output directory.
117
    :type outdir: str
118
    """
119
    try:
120
        get_sevenzip()
121
    except SystemError:
122
        pass
123
    else:
124
        sz_wrapper_writer(outdir)
125
126
127
def sz_wrapper_writer(outdir):
128
    """
129
    Copy 7-Zip to outdir, the actual function.
130
131
    :param outdir: Output directory.
132
    :type outdir: str
133
    """
134
    copy(join("7z", "7za.exe"), outdir)
135
    if architecture()[0] == "64bit":
136
        copy(join("7z", "x64", "7za.exe"), join(outdir, "7za64.exe"))
137
    rmtree("7z", ignore_errors=True)
138
139
140
def copy_json(outdir):
141
    """
142
    Copy JSON folder to outdir.
143
144
    :param outdir: Output directory.
145
    :type outdir: str
146
    """
147
    copytree(JSONDIR, join(outdir, "json"))
148
149
150
def main():
151
    """
152
    Create .exes with dynamic spec files.
153
    """
154
    write_versions()
155
    generate_specs()
156
    call_specs()
157
    outdir = bitsdir("pyinst-dist")
158
    copy("version.txt", outdir)
159
    copy("longversion.txt", outdir)
160
    copy(CAP.location, outdir)
161
    copy_json(outdir)
162
    copy(certs.where(), join(outdir, "cacerts.pem"))
163
    sz_wrapper(outdir)
164
    clean_versions()
165
    clean_specs()
166
167
168
if __name__ == "__main__":
169
    main()
170