bbarchivist.scripts.lazyloader   A
last analyzed

Complexity

Total Complexity 32

Size/Duplication

Total Lines 348
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 215
dl 0
loc 348
rs 9.84
c 0
b 0
f 0
wmc 32

9 Functions

Rating   Name   Duplication   Size   Complexity  
A questionnaire() 0 11 1
B grab_args() 0 88 2
A questionnaire_loader() 0 9 2
A questionnaire_devices() 0 14 3
A questionnaire_radiocheck() 0 16 3
A questionnaire_check() 0 18 3
A execute_args() 0 13 2
A questionnaire_getversions() 0 11 3
D lazyloader_main() 0 124 13
1
#!/usr/bin/env python3
2
"""Create one autoloader for personal use."""
3
4
import os  # path work
5
import subprocess  # autoloader running
6
import sys  # load arguments
7
8
import requests  # session
9
from bbarchivist import argutils  # arguments
10
from bbarchivist import barutils  # file operations
11
from bbarchivist import bbconstants  # constants/versions
12
from bbarchivist import decorators  # timer
13
from bbarchivist import loadergen  # cap wrapper
14
from bbarchivist import networkutils  # download/lookup
15
from bbarchivist import scriptutils  # script stuff
16
from bbarchivist import utilities  # input validation
17
18
__author__ = "Thurask"
19
__license__ = "WTFPL v2"
20
__copyright__ = "2015-2019 Thurask"
21
22
23
@decorators.timer
24
def grab_args():
25
    """
26
    Parse arguments from argparse/questionnaire.
27
28
    Invoke :func:`lazyloader.lazyloader_main` with arguments.
29
    """
30
    if len(sys.argv) > 1:
31
        argflags = ("folder", "osr")
32
        parser = argutils.default_parser("bb-lazyloader", "Create one autoloader", argflags)
33
        devgroup = parser.add_argument_group("devices", "Device to load (one required)")
34
        compgroup = devgroup.add_mutually_exclusive_group()
35
        compgroup.add_argument(
36
            "--stl100-1",
37
            dest="device",
38
            help="STL100-1",
39
            action="store_const",
40
            const=0)
41
        compgroup.add_argument(
42
            "--stl100-x",
43
            dest="device",
44
            help="STL100-2/3, P'9982",
45
            action="store_const",
46
            const=1)
47
        compgroup.add_argument(
48
            "--stl100-4",
49
            dest="device",
50
            help="STL100-4",
51
            action="store_const",
52
            const=2)
53
        compgroup.add_argument(
54
            "--q10",
55
            dest="device",
56
            help="Q10, Q5, P'9983",
57
            action="store_const",
58
            const=3)
59
        compgroup.add_argument(
60
            "--z30",
61
            dest="device",
62
            help="Z30, Classic, Leap",
63
            action="store_const",
64
            const=4)
65
        compgroup.add_argument(
66
            "--z3",
67
            dest="device",
68
            help="Z3",
69
            action="store_const",
70
            const=5)
71
        compgroup.add_argument(
72
            "--passport",
73
            dest="device",
74
            help="Passport",
75
            action="store_const",
76
            const=6)
77
        parser.add_argument(
78
            "--run-loader",
79
            dest="autoloader",
80
            help="Run autoloader after creation",
81
            action="store_true",
82
            default=False)
83
        parser.add_argument(
84
            "-n",
85
            "--no-download",
86
            dest="download",
87
            help="Don't download files",
88
            action="store_false",
89
            default=True)
90
        parser.add_argument(
91
            "-r",
92
            "--radiosw",
93
            dest="altsw",
94
            metavar="SW",
95
            help="Radio software version; use without software to guess",
96
            nargs="?",
97
            const="checkme",
98
            default=None)
99
        parser.add_argument(
100
            "-c",
101
            "--core",
102
            dest="core",
103
            help="Make core/radio loader",
104
            default=False,
105
            action="store_true")
106
        parser.set_defaults(device=None)
107
        args = parser.parse_args(sys.argv[1:])
108
        execute_args(args)
109
    else:
110
        questionnaire()
111
112
113
def execute_args(args):
114
    """
115
    Get args and decide what to do with them.
116
117
    :param args: Arguments.
118
    :type args: argparse.Namespace
119
    """
120
    args.folder = scriptutils.generate_workfolder(args.folder)
121
    if not utilities.is_windows():
122
        args.autoloader = False
123
    argutils.arg_verify_none(args.os, "No OS specified!")
124
    argutils.arg_verify_none(args.device, "No device specified!")
125
    lazyloader_main(args.device, args.os, args.radio, args.swrelease, args.folder, args.autoloader, args.download, args.altsw, args.core)
126
127
128
def questionnaire_getversions():
129
    """
130
    Get OS, radio, and software versions.
131
    """
132
    while True:
133
        osversion = input("OS VERSION (REQUIRED): ")
134
        if osversion:
135
            break
136
    radioversion = input("RADIO VERSION (PRESS ENTER TO GUESS): ")
137
    softwareversion = input("OS SOFTWARE RELEASE (PRESS ENTER TO GUESS): ")
138
    return osversion, radioversion, softwareversion
139
140
141
def questionnaire_check(softwareversion, radioversion):
142
    """
143
    Check software and radio versions.
144
145
    :param softwareversion: Software version, 10.x.y.zzzz.
146
    :type softwareversion: str
147
148
    :param radioversion: Radio version, 10.x.y.zzzz.
149
    :type radioversion: str
150
    """
151
    if not softwareversion:
152
        softwareversion = None
153
    if not radioversion:
154
        radioversion = None
155
        altsw = None
156
    else:
157
        radioversion, altsw = questionnaire_radiocheck(radioversion)
158
    return softwareversion, radioversion, altsw
159
160
161
def questionnaire_radiocheck(radioversion, altsw=None):
162
    """
163
    Get radio information in working order.
164
165
    :param radioversion: Radio version, 10.x.y.zzzz.
166
    :type radioversion: str
167
168
    :param altsw: Radio software release, if not the same as OS.
169
    :type altsw: str
170
    """
171
    altcheck = utilities.i2b("USING ALTERNATE RADIO (Y/N)?: ")
172
    if altcheck:
173
        altsw = input("RADIO SOFTWARE RELEASE (PRESS ENTER TO GUESS): ")
174
        if not altsw:
175
            altsw = "checkme"
176
    return radioversion, altsw
177
178
179
def questionnaire_devices():
180
    """
181
    Ask about which device this script is to be run for.
182
    """
183
    print("DEVICES:")
184
    devlist = ["0=STL100-1", "1=STL100-2/3/P9982", "2=STL100-4", "3=Q10/Q5/P9983", "4=Z30/CLASSIC/LEAP", "5=Z3", "6=PASSPORT"]
185
    utilities.lprint(devlist)
186
    while True:
187
        device = int(input("SELECTED DEVICE: "))
188
        if not 0 <= device <= len(devlist) - 1:
189
            continue
190
        else:
191
            break
192
    return device
193
194
195
def questionnaire_loader():
196
    """
197
    Ask about whether to run an autoloader.
198
    """
199
    if utilities.is_windows():
200
        autoloader = utilities.i2b("RUN AUTOLOADER - WILL WIPE YOUR DEVICE! (Y/N)?: ")
201
    else:
202
        autoloader = False
203
    return autoloader
204
205
206
def questionnaire():
207
    """
208
    Questions to ask if no arguments given.
209
    """
210
    localdir = os.getcwd()
211
    osver, radiover, swver = questionnaire_getversions()
212
    swver, radiover, altsw = questionnaire_check(swver, radiover)
213
    device = questionnaire_devices()
214
    autoloader = questionnaire_loader()
215
    print(" ")
216
    lazyloader_main(device, osver, radiover, swver, localdir, autoloader, True, altsw, False)
217
218
219
def lazyloader_main(device, osversion, radioversion=None, softwareversion=None, localdir=None, autoloader=False, download=True, altsw=None, core=False):
220
    """
221
    Wrap the tools necessary to make one autoloader.
222
223
    :param device: Device family to create loader for.
224
    :type device: int
225
226
    :param osversion: OS version, 10.x.y.zzzz.
227
    :type osversion: str
228
229
    :param radioversion: Radio version, 10.x.y.zzzz.
230
    :type radioversion: str
231
232
    :param softwareversion: Software version, 10.x.y.zzzz.
233
    :type softwareversion: str
234
235
    :param localdir: Working path. Default is local dir.
236
    :type localdir: str
237
238
    :param autoloader: Whether to run loader. Default is false. Windows-only.
239
    :type autoloader: bool
240
241
    :param download: Whether to download files. Default is true.
242
    :type download: bool
243
244
    :param altsw: Radio software release, if not the same as OS.
245
    :type altsw: str
246
247
    :param core: Whether to create a core/radio loader. Default is false.
248
    :type core: bool
249
    """
250
    radioversion = scriptutils.return_radio_version(osversion, radioversion)
251
    softwareversion, swc = scriptutils.return_sw_checked(softwareversion, osversion)
252
    if altsw == "checkme":
253
        altsw, altchecked = scriptutils.return_radio_sw_checked(altsw, radioversion)
254
    argutils.standard_preamble("lazyloader", osversion, softwareversion, radioversion, altsw)
255
    print("DEVICE: {0}".format(bbconstants.DEVICES[device]))
256
257
    # Make dirs
258
    bd_o, bd_r, ld_o, ld_r, zd_o, zd_r = barutils.make_dirs(localdir, osversion, radioversion)
259
    osurl = radiourl = None
260
261
    # Create download URLs
262
    baseurl = utilities.create_base_url(softwareversion)
263
    if altsw:
264
        alturl = utilities.create_base_url(altsw)
265
    osurl, radiourl = utilities.generate_lazy_urls(softwareversion, osversion, radioversion, device)
266
    if altsw:
267
        radiourl = radiourl.replace(baseurl, alturl)
268
    if core:
269
        osurl = osurl.replace(".desktop", "")
270
271
    #Terminate if device is STL100-1 and OS >= 10.3.3
272
    splitos = [int(i) for i in osversion.split(".")]
273
    if device == 0 and utilities.newer_103(splitos, 3):
274
        print("STL100-1 UNSUPPORTED IN 10.3.3+!")
275
        print("\nEXITING...")
276
        raise SystemExit
277
278
    if download:
279
        # Check availability of software releases
280
        scriptutils.check_sw(baseurl, softwareversion, swc)
281
        if altsw:
282
            scriptutils.check_radio_sw(alturl, altsw, altchecked)
283
284
        # Check availability of OS, radio
285
        scriptutils.check_os_single(osurl, osversion, device)
286
        radiourl, radioversion = scriptutils.check_radio_single(radiourl, radioversion)
287
    dllist = [osurl, radiourl]
288
289
    # Check cached
290
    osfile = os.path.join(localdir, bd_o, os.path.basename(osurl))
291
    radfile = os.path.join(localdir, bd_r, os.path.basename(radiourl))
292
293
    if download:
294
        # Download files
295
        print("DOWNLOADING...")
296
        sess = requests.Session()
297
        networkutils.download_bootstrap(dllist, outdir=localdir, workers=2, session=sess)
298
    elif all(os.path.exists(x) for x in [osfile, radfile]):
299
        # Already downloaded in previous session
300
        print("USING CACHED OS/RADIO...")
301
        barutils.replace_bar_pair(localdir, osfile, radfile)
302
303
    # Test bar files
304
    scriptutils.test_bar_files(localdir, dllist)
305
306
    # Extract bar files
307
    print("EXTRACTING...")
308
    barutils.extract_bars(localdir)
309
310
    # Test signed files
311
    scriptutils.test_signed_files(localdir)
312
313
    # Move bar files
314
    print("MOVING BAR FILES...")
315
    barutils.move_bars(localdir, bd_o, bd_r)
316
317
    # Generate loader
318
    altradio = radioversion if altsw else None
319
    loadergen.generate_lazy_loader(osversion, device, os.path.abspath(localdir), altradio, core)
320
321
    # Test loader
322
    suffix = loadergen.format_suffix(bool(altradio), altradio, core)
323
    loadername = loadergen.generate_filename(device, osversion, suffix)
324
    loaderpath = os.path.join(localdir, loadername)
325
    scriptutils.test_single_loader(loaderpath)
326
327
    # Remove signed files
328
    print("REMOVING SIGNED FILES...")
329
    barutils.remove_signed_files(localdir)
330
331
    # Move loaders
332
    print("MOVING LOADERS...")
333
    barutils.move_loaders(localdir, ld_o, ld_r, zd_o, zd_r)
334
    loadername = os.path.join(ld_o, loadername)
335
336
    # Delete empty folders
337
    print("REMOVING EMPTY FOLDERS...")
338
    barutils.remove_empty_folders(localdir)
339
340
    if autoloader:
341
        subprocess.call(loadername)
342
    print("\nFINISHED!!!")
343
344
345
if __name__ == "__main__":
346
    grab_args()
347
    decorators.enter_to_exit(True)
348