Completed
Push — master ( d75233...e013eb )
by John
02:04
created

get_sevenzip()   A

Complexity

Conditions 2

Size

Total Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 2
c 2
b 0
f 0
dl 0
loc 12
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
    if architecture()[0] == "64bit":
37
        indirx = "{0}-64".format(indir)
38
    else:
39
        indirx = indir
40
    if not exists(indirx):
41
        makedirs(indirx)
42
    return indirx
43
44
45
def generate_specs():
46
    """
47
    Generate pyinstaller spec files.
48
    """
49
    scripts = ["archivist", "autolookup", "barlinker", "carrierchecker", "certchecker", "devloader", "downloader", "droidlookup", "droidscraper", "escreens", "kernchecker", "lazyloader", "linkgen", "metachecker", "swlookup", "tclloader", "tclscan", "tcldelta"]
50
    here = getcwd().replace("\\", "\\\\")
51
    for script in scripts:
52
        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)
53
        with open("{0}.spec".format(script), "w") as afile:
54
            afile.write(template)
55
56
57
def clean_specs():
58
    """
59
    Remove pyinstaller spec files.
60
    """
61
    specs = [x for x in listdir() if x.endswith(".spec")]
62
    for spec in specs:
63
        remove(spec)
64
65
66
def get_sevenzip():
67
    """
68
    Get 7-Zip.
69
    """
70
    szver = "1700"
71
    szurl = "http://www.7-zip.org/a/7z{0}-extra.7z".format(szver)
72
    psz = prep_seven_zip()
73
    if psz:
74
        get_sevenzip_write(szurl)
75
    else:
76
        print("GO TO {0} AND DO IT MANUALLY".format(szurl))
77
        raise SystemError
78
79
80
def get_sevenzip_write(szurl):
81
    """
82
    Download 7-Zip file.
83
84
    :param szurl: Link to 7z download.
85
    :type szurl: str
86
    """
87
    szexe = get_seven_zip()
88
    szfile = basename(szurl)
89
    with open(szfile, "wb") as afile:
90
        req = get(szurl, stream=True)
91
        for chunk in req.iter_content(chunk_size=1024):
92
            afile.write(chunk)
93
    cmd = "{0} x {1} -o7z".format(szexe, szfile)
94
    with open(devnull, "wb") as dnull:
95
        call(cmd, stdout=dnull, stderr=STDOUT, shell=True)
96
    remove(basename(szurl))
97
98
99
def call_specs():
100
    """
101
    Call pyinstaller to make specs.
102
    """
103
    specs = [x for x in listdir() if x.endswith(".spec")]
104
    for spec in specs:  # use UPX 3.93 or up
105
        cmd = "pyinstaller --onefile --workpath {2} --distpath {1} {0}".format(spec, bitsdir("pyinst-dist"), bitsdir("pyinst-build"))
106
        call(cmd, shell=True)
107
108
109
def sz_wrapper(outdir):
110
    """
111
    Copy 7-Zip to outdir.
112
    """
113
    try:
114
        get_sevenzip()
115
    except SystemError:
116
        pass
117
    else:
118
        copy(join("7z", "7za.exe"), outdir)
119
        if architecture()[0] == "64bit":
120
            copy(join("7z", "x64", "7za.exe"), join(outdir, "7za64.exe"))
121
        rmtree("7z", ignore_errors=True)
122
123
124
def copy_json(outdir):
125
    """
126
    Copy JSON folder to outdir.
127
    """
128
    copytree(JSONDIR, join(outdir, "json"))
129
130
131
def main():
132
    """
133
    Create .exes with dynamic spec files.
134
    """
135
    write_versions()
136
    generate_specs()
137
    call_specs()
138
    outdir = bitsdir("pyinst-dist")
139
    copy("version.txt", outdir)
140
    copy("longversion.txt", outdir)
141
    copy(CAP.location, outdir)
142
    copy_json(outdir)
143
    copy(certs.where(), join(outdir, "cacerts.pem"))
144
    sz_wrapper(outdir)
145
    clean_versions()
146
    clean_specs()
147
148
149
if __name__ == "__main__":
150
    main()
151