bbarchivist.scripts.archivist.grab_args()   C
last analyzed

Complexity

Conditions 6

Size

Total Lines 132
Code Lines 124

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 6
eloc 124
nop 0
dl 0
loc 132
rs 6.0666
c 0
b 0
f 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
#!/usr/bin/env python3
2
"""Download bar files, create autoloaders."""
3
4
import os  # filesystem read
5
import sys  # load arguments
6
7
import requests  # session
8
from bbarchivist import archiveutils  # archive work
9
from bbarchivist import argutils  # arguments
10
from bbarchivist import barutils  # file/folder work
11
from bbarchivist import decorators  # timer
12
from bbarchivist import hashutils  # hashes, GPG
13
from bbarchivist import loadergen  # cap, in Python
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:`archivist.archivist_main` with those arguments.
29
    """
30
    if len(sys.argv) > 1:
31
        parser = argutils.default_parser("bb-archivist", "Create autoloaders", ("folder", "osr"))
32
        negategroup = parser.add_argument_group(
33
            "negators",
34
            "Disable program functionality")
35
        negategroup.add_argument(
36
            "-no",
37
            "--no-download",
38
            dest="download",
39
            help="Don't download files",
40
            action="store_false",
41
            default=True)
42
        negategroup.add_argument(
43
            "-ni",
44
            "--no-integrity",
45
            dest="integrity",
46
            help="Don't test bar files after download",
47
            action="store_false",
48
            default=True)
49
        negategroup.add_argument(
50
            "-nx",
51
            "--no-extract",
52
            dest="extract",
53
            help="Don't extract bar files",
54
            action="store_false",
55
            default=True)
56
        negategroup.add_argument(
57
            "-nr",
58
            "--no-radios",
59
            dest="radloaders",
60
            help="Don't make radio autoloaders",
61
            action="store_false",
62
            default=True)
63
        negategroup.add_argument(
64
            "-ns",
65
            "--no-rmsigned",
66
            dest="signed",
67
            help="Don't remove signed files",
68
            action="store_false",
69
            default=True)
70
        negategroup.add_argument(
71
            "-nc",
72
            "--no-compress",
73
            dest="compress",
74
            help="Don't compress loaders",
75
            action="store_false",
76
            default=True)
77
        negategroup.add_argument(
78
            "-nd",
79
            "--no-delete",
80
            dest="delete",
81
            help="Don't delete uncompressed loaders",
82
            action="store_false",
83
            default=True)
84
        negategroup.add_argument(
85
            "-nv",
86
            "--no-verify",
87
            dest="verify",
88
            help="Don't verify created loaders",
89
            action="store_false",
90
            default=True)
91
        if not getattr(sys, 'frozen', False):
92
            parser.add_argument(
93
                "-g",
94
                "--gpg",
95
                dest="gpg",
96
                help="Enable GPG signing. Set up GnuPG.",
97
                action="store_true",
98
                default=False)
99
        parser.add_argument(
100
            "-r",
101
            "--radiosw",
102
            dest="altsw",
103
            metavar="SW",
104
            help="Radio software version; use without software to guess",
105
            nargs="?",
106
            const="checkme",
107
            default=None)
108
        if not getattr(sys, 'frozen', False):
109
            parser.add_argument(
110
                "-m",
111
                "--method",
112
                dest="method",
113
                metavar="METHOD",
114
                help="Compression method",
115
                nargs="?",
116
                type=argutils.valid_method,
117
                default=None)
118
        parser.add_argument(
119
            "-c",
120
            "--core",
121
            dest="core",
122
            help="Make core/radio loaders",
123
            default=False,
124
            action="store_true")
125
        parser.add_argument(
126
            "-o",
127
            "--old-style",
128
            dest="oldstyle",
129
            help="Make old-style checksum files",
130
            default=False,
131
            action="store_true")
132
        parser.set_defaults(compmethod="7z")
133
        args = parser.parse_args(sys.argv[1:])
134
        args.folder = scriptutils.generate_workfolder(args.folder)
135
        if getattr(sys, 'frozen', False):
136
            args.gpg = False
137
            hashdict = hashutils.verifier_config_loader(os.getcwd())
138
            args.method = "7z"
139
        else:
140
            hashdict = hashutils.verifier_config_loader()
141
        hashutils.verifier_config_writer(hashdict)
142
        if args.method is None:
143
            compmethod = archiveutils.compress_config_loader()
144
            archiveutils.compress_config_writer(compmethod)
145
        else:
146
            compmethod = args.method
147
        archivist_main(args.os, args.radio, args.swrelease,
148
                       os.path.abspath(args.folder), args.radloaders,
149
                       args.compress, args.delete, args.verify,
150
                       hashdict, args.download,
151
                       args.extract, args.signed, compmethod, args.gpg,
152
                       args.integrity, args.altsw, args.core, args.oldstyle)
153
    else:
154
        questionnaire()
155
156
157
def questionnaire():
158
    """
159
    Questions to ask if no arguments given.
160
    """
161
    localdir = os.getcwd()
162
    osversion = input("OS VERSION (REQUIRED): ")
163
    radioversion = input("RADIO VERSION (PRESS ENTER TO GUESS): ")
164
    radioversion = None if not radioversion else radioversion
165
    softwareversion = input("OS SOFTWARE RELEASE (PRESS ENTER TO GUESS): ")
166
    softwareversion = None if not softwareversion else softwareversion
167
    altcheck = utilities.i2b("USING ALTERNATE RADIO (Y/N)?: ")
168
    altsw = scriptutils.check_altsw(altcheck)
169
    radios = utilities.i2b("CREATE RADIO LOADERS (Y/N)?: ")
170
    compressed = utilities.i2b("COMPRESS LOADERS (Y/N)?: ")
171
    deleted = utilities.i2b("DELETE UNCOMPRESSED LOADERS (Y/N)?: ") if compressed else False
172
    hashed = utilities.i2b("GENERATE HASHES (Y/N)?: ")
173
    if getattr(sys, 'frozen', False):
174
        hashdict = hashutils.verifier_config_loader(os.getcwd())
175
        compmethod = "7z"
176
    else:
177
        hashdict = hashutils.verifier_config_loader()
178
        hashutils.verifier_config_writer(hashdict)
179
        compmethod = archiveutils.compress_config_loader()
180
    print(" ")
181
    archivist_main(osversion, radioversion, softwareversion,
182
                   localdir, radios, compressed, deleted, hashed,
183
                   hashdict, download=True, extract=True, signed=True,
184
                   compmethod=compmethod, gpg=False, integrity=True,
185
                   altsw=altsw, core=False, oldstyle=False)
186
187
188
def archivist_checksw(baseurl, softwareversion, swchecked):
189
    """
190
    Check availability of software releases.
191
192
    :param baseurl: Base URL for download links.
193
    :type baseurl: str
194
195
    :param softwareversion: Software release, 10.x.y.zzzz. Can be guessed.
196
    :type softwareversion: str
197
198
    :param swchecked: If we checked the sw release already.
199
    :type swchecked: bool
200
    """
201
    scriptutils.check_sw(baseurl, softwareversion, swchecked)
202
203
204
def archivist_download(download, osurls, radiourls, localdir, session, dirs):
205
    """
206
    Download function.
207
208
    :param download: Whether to download bar files. True by default.
209
    :type download: bool
210
211
    :param osurls: OS file list.
212
    :type osurls: list(str)
213
214
    :param radiourls: Radio file list.
215
    :type radiourls: list(str)
216
217
    :param localdir: Working directory. Local by default.
218
    :type localdir: str
219
220
    :param session: Requests session object, default is created on the fly.
221
    :type session: requests.Session()
222
223
    :param dirs: List of generated bar/loader/zip directories.
224
    :type dirs: list(str)
225
    """
226
    osfiles = scriptutils.comp_joiner(localdir, dirs[0], osurls)
227
    radiofiles = scriptutils.comp_joiner(localdir, dirs[1], radiourls)
228
    if download:
229
        print("BEGIN DOWNLOADING...")
230
        networkutils.download_bootstrap(radiourls + osurls, localdir, 3, session)
231
        print("ALL FILES DOWNLOADED")
232
    elif all(os.path.exists(x) for x in osfiles+radiofiles):
233
        print("USING CACHED OS/RADIO FILES...")
234
        barutils.replace_bars_bulk(os.path.abspath(localdir), osfiles+radiofiles)
235
236
237
def archivist_integritybars(integrity, osurls, radiourls, localdir):
238
    """
239
    Check integrity of bar files, redownload if necessary.
240
241
    :param integrity: Whether to test downloaded files. True by default.
242
    :type integrity: bool
243
244
    :param osurls: OS file list.
245
    :type osurls: list(str)
246
247
    :param radiourls: Radio file list.
248
    :type radiourls: list(str)
249
    """
250
    if integrity:
251
        urllist = osurls + radiourls
252
        scriptutils.test_bar_files(localdir, urllist)
253
254
255
def archivist_extractbars(extract, localdir):
256
    """
257
    Extract signed files from bar files.
258
259
    :param extract: Whether to extract bar files. True by default.
260
    :type extract: bool
261
262
    :param localdir: Working directory. Local by default.
263
    :type localdir: str
264
    """
265
    if extract:
266
        print("EXTRACTING...")
267
        barutils.extract_bars(localdir)
268
269
270
def archivist_integritysigned(integrity, localdir):
271
    """
272
    Check integrity of signed files.
273
274
    :param integrity: Whether to test downloaded files. True by default.
275
    :type integrity: bool
276
277
    :param localdir: Working directory. Local by default.
278
    :type localdir: str
279
    """
280
    if integrity:
281
        scriptutils.test_signed_files(localdir)
282
283
284
def archivist_movebars(dirs, localdir):
285
    """
286
    Move bar files.
287
288
    :param dirs: List of OS/radio bar/loader/zipped folders.
289
    :type dirs: list(str)
290
291
    :param localdir: Working directory. Local by default.
292
    :type localdir: str
293
    """
294
    print("MOVING BAR FILES...")
295
    barutils.move_bars(localdir, dirs[0], dirs[1])
296
297
298
def archivist_generateloaders(osversion, radioversion, radios, localdir, altsw, core):
299
    """
300
    Generate loaders.
301
302
    :param osversion: OS version, 10.x.y.zzzz. Required.
303
    :type osversion: str
304
305
    :param radioversion: Radio version, 10.x.y.zzzz. Can be guessed.
306
    :type radioversion: str
307
308
    :param radios: Whether to create radio autoloaders. True by default.
309
    :type radios: bool
310
311
    :param localdir: Working directory. Local by default.
312
    :type localdir: str
313
314
    :param altsw: Radio software release, if not the same as OS.
315
    :type altsw: str
316
317
    :param core: Whether to create a core/radio loader. Default is false.
318
    :type core: bool
319
    """
320
    print("GENERATING LOADERS...")
321
    altradio = altsw is not None
322
    loadergen.generate_loaders(osversion, radioversion, radios, localdir, altradio, core)
323
324
325
def archivist_integrityloaders(integrity, localdir):
326
    """
327
    Check integrity of build loaders.
328
329
    :param integrity: Whether to test downloaded files. True by default.
330
    :type integrity: bool
331
332
    :param localdir: Working directory. Local by default.
333
    :type localdir: str
334
    """
335
    if integrity:
336
        scriptutils.test_loader_files(localdir)
337
338
339
def archivist_removesigned(signed, localdir):
340
    """
341
    Remove signed files.
342
343
    :param signed: Whether to delete signed files. True by default.
344
    :type signed: bool
345
346
    :param localdir: Working directory. Local by default.
347
    :type localdir: str
348
    """
349
    if signed:
350
        print("REMOVING SIGNED FILES...")
351
        barutils.remove_signed_files(localdir)
352
353
354
def archivist_compressor(compressed, integrity, localdir, compmethod, szexe):
355
    """
356
    Compress and optionally verify loaders.
357
358
    :param compressed: Whether to compress files. True by default.
359
    :type compressed: bool
360
361
    :param integrity: Whether to test downloaded files. True by default.
362
    :type integrity: bool
363
364
    :param localdir: Working directory. Local by default.
365
    :type localdir: str
366
367
    :param compmethod: Compression method. Default is "7z", fallback "zip".
368
    :type compmethod: str
369
370
    :param szexe: Path to 7z executable.
371
    :type szexe: str
372
    """
373
    if compressed:
374
        print("COMPRESSING...")
375
        archiveutils.compress(localdir, compmethod, szexe, True)
376
        if integrity:
377
            print("TESTING ARCHIVES...")
378
            archiveutils.verify(localdir, compmethod, szexe, True)
379
380
381
def archivist_moveloaders(dirs, localdir):
382
    """
383
    Move loaders.
384
385
    :param dirs: List of OS/radio bar/loader/zipped folders.
386
    :type dirs: list(str)
387
388
    :param localdir: Working directory. Local by default.
389
    :type localdir: str
390
    """
391
    print("MOVING LOADERS...")
392
    barutils.move_loaders(localdir, dirs[2], dirs[3], dirs[4], dirs[5])
393
394
395
def archivist_gethashes(dirs, hashed, compressed, deleted, radios, osversion, radioversion, softwareversion, oldstyle):
396
    """
397
    Make new-style info files.
398
399
    :param dirs: List of OS/radio bar/loader/zipped folders.
400
    :type dirs: list(str)
401
402
    :param hashed: Whether to hash files. True by default.
403
    :type hashed: bool
404
405
    :param compressed: Whether to compress files. True by default.
406
    :type compressed: bool
407
408
    :param deleted: Whether to delete uncompressed files. True by default.
409
    :type deleted: bool
410
411
    :param radios: Whether to create radio autoloaders. True by default.
412
    :type radios: bool
413
414
    :param osversion: OS version, 10.x.y.zzzz. Required.
415
    :type osversion: str
416
417
    :param radioversion: Radio version, 10.x.y.zzzz. Can be guessed.
418
    :type radioversion: str
419
420
    :param softwareversion: Software release, 10.x.y.zzzz. Can be guessed.
421
    :type softwareversion: str
422
423
    :param oldstyle: Whether to make old-style checksum files. Default is false.
424
    :type oldstyle: bool
425
    """
426
    if hashed and not oldstyle:
427
        scriptutils.bulk_info(dirs, osversion, compressed, deleted, radios, radioversion, softwareversion)
428
429
def archivist_getoldhashes(dirs, hashed, compressed, deleted, radios, hashdict, oldstyle):
430
    """
431
    Make old-style checksum files.
432
433
    :param dirs: List of OS/radio bar/loader/zipped folders.
434
    :type dirs: list(str)
435
436
    :param hashed: Whether to hash files. True by default.
437
    :type hashed: bool
438
439
    :param compressed: Whether to compress files. True by default.
440
    :type compressed: bool
441
442
    :param deleted: Whether to delete uncompressed files. True by default.
443
    :type deleted: bool
444
445
    :param radios: Whether to create radio autoloaders. True by default.
446
    :type radios: bool
447
448
    :param hashdict: Dictionary of hash rules, in ~\bbarchivist.ini.
449
    :type hashdict: dict({str: bool})
450
451
    :param oldstyle: Whether to make old-style checksum files. Default is false.
452
    :type oldstyle: bool
453
    """
454
    if hashed and oldstyle:
455
        scriptutils.bulk_hash(dirs, compressed, deleted, radios, hashdict)
456
457
458
def archivist_gpg(gpg, dirs, compressed, deleted, radios):
459
    """
460
    GPG-sign everything.
461
462
    :param gpg: Whether to use GnuPG verification. False by default.
463
    :type gpg: bool
464
465
    :param dirs: List of OS/radio bar/loader/zipped folders.
466
    :type dirs: list(str)
467
468
    :param compressed: Whether to compress files. True by default.
469
    :type compressed: bool
470
471
    :param deleted: Whether to delete uncompressed files. True by default.
472
    :type deleted: bool
473
474
    :param radios: Whether to create radio autoloaders. True by default.
475
    :type radios: bool
476
    """
477
    if gpg:
478
        scriptutils.bulk_verify(dirs, compressed, deleted, radios)
479
480
481
def archivist_deleteuncompressed(dirs, deleted, radios):
482
    """
483
    Delete uncompressed loaders.
484
485
    :param dirs: List of OS/radio bar/loader/zipped folders.
486
    :type dirs: list(str)
487
488
    :param deleted: Whether to delete uncompressed files. True by default.
489
    :type deleted: bool
490
491
    :param radios: Whether to create radio autoloaders. True by default.
492
    :type radios: bool
493
    """
494
    if deleted:
495
        print("DELETING UNCOMPRESSED LOADERS...")
496
        barutils.remove_unpacked_loaders(dirs[2], dirs[3], radios)
497
498
499
def archivist_removeemptyfolders(localdir):
500
    """
501
    Delete empty folders.
502
503
    :param localdir: Working directory. Local by default.
504
    :type localdir: str
505
    """
506
    print("REMOVING EMPTY FOLDERS...")
507
    barutils.remove_empty_folders(localdir)
508
509
510
def archivist_main(osversion, radioversion=None, softwareversion=None,
511
                   localdir=None, radios=True, compressed=True, deleted=True,
512
                   hashed=True, hashdict=None, download=True,
513
                   extract=True, signed=True, compmethod="7z",
514
                   gpg=False, integrity=True, altsw=None,
515
                   core=False, oldstyle=False):
516
    """
517
    Wrap around multi-autoloader creation code.
518
    Some combination of creating, downloading, hashing,
519
    compressing and moving autoloaders.
520
521
    :param osversion: OS version, 10.x.y.zzzz. Required.
522
    :type osversion: str
523
524
    :param radioversion: Radio version, 10.x.y.zzzz. Can be guessed.
525
    :type radioversion: str
526
527
    :param softwareversion: Software release, 10.x.y.zzzz. Can be guessed.
528
    :type softwareversion: str
529
530
    :param localdir: Working directory. Local by default.
531
    :type localdir: str
532
533
    :param radios: Whether to create radio autoloaders. True by default.
534
    :type radios: bool
535
536
    :param compressed: Whether to compress files. True by default.
537
    :type compressed: bool
538
539
    :param deleted: Whether to delete uncompressed files. True by default.
540
    :type deleted: bool
541
542
    :param hashed: Whether to hash files. True by default.
543
    :type hashed: bool
544
545
    :param hashdict: Dictionary of hash rules, in ~\bbarchivist.ini.
546
    :type hashdict: dict({str: bool})
547
548
    :param download: Whether to download bar files. True by default.
549
    :type download: bool
550
551
    :param extract: Whether to extract bar files. True by default.
552
    :type extract: bool
553
554
    :param signed: Whether to delete signed files. True by default.
555
    :type signed: bool
556
557
    :param compmethod: Compression method. Default is "7z", fallback "zip".
558
    :type compmethod: str
559
560
    :param gpg: Whether to use GnuPG verification. False by default.
561
    :type gpg: bool
562
563
    :param integrity: Whether to test downloaded files. True by default.
564
    :type integrity: bool
565
566
    :param altsw: Radio software release, if not the same as OS.
567
    :type altsw: str
568
569
    :param core: Whether to create a core/radio loader. Default is false.
570
    :type core: bool
571
572
    :param oldstyle: Whether to make old-style checksum files. Default is false.
573
    :type oldstyle: bool
574
    """
575
    if deleted and not compressed:
576
        deleted = False  # don't delete what we want to keep
577
    radioversion = scriptutils.return_radio_version(osversion, radioversion)
578
    softwareversion, swchecked = scriptutils.return_sw_checked(softwareversion, osversion)
579
    if altsw == "checkme":
580
        altsw, altchecked = scriptutils.return_radio_sw_checked(altsw, radioversion)
581
    localdir = utilities.dirhandler(localdir, os.getcwd())
582
    if hashed and hashdict is None:
583
        hashdict = hashutils.verifier_config_loader()
584
        hashutils.verifier_config_writer(hashdict)
585
    argutils.standard_preamble("archivist", osversion, softwareversion, radioversion, altsw)
586
    # Generate download URLs
587
    baseurl, alturl = scriptutils.get_baseurls(softwareversion, altsw)
588
    osurls, radiourls, cores = utilities.generate_urls(softwareversion, osversion, radioversion, True)
589
    osurls = cores if core else osurls
590
    for idx, url in enumerate(osurls):
591
        if "qc8960.factory_sfi" in url:
592
            vzwurl = url
593
            vzwindex = idx
594
            break
595
    if not networkutils.availability(vzwurl):
596
        osurls[vzwindex] = osurls[vzwindex].replace("qc8960.factory_sfi", "qc8960.verizon_sfi")
597
    osurls = list(set(osurls))  # pop duplicates
598
    if altsw:
599
        radiourls2 = [x.replace(baseurl, alturl) for x in radiourls]
600
        radiourls = radiourls2
601
        del radiourls2
602
    radiourls = list(set(radiourls))  # pop duplicates
603
    archivist_checksw(baseurl, softwareversion, swchecked)
604
    if altsw:
605
        scriptutils.check_radio_sw(alturl, altsw, altchecked)
606
    # Check availability of OS, radio
607
    scriptutils.check_os_bulk(osurls)
608
    radiourls, radioversion = scriptutils.check_radio_bulk(radiourls, radioversion)
609
    # Get 7z executable
610
    compmethod, szexe = scriptutils.get_sz_executable(compmethod)
611
    # Make dirs: bd_o, bd_r, ld_o, ld_r, zd_o, zd_r
612
    dirs = barutils.make_dirs(localdir, osversion, radioversion)
613
    osurls = scriptutils.bulk_avail(osurls)
614
    radiourls = scriptutils.bulk_avail(radiourls)
615
    sess = requests.Session()
616
    archivist_download(download, osurls, radiourls, localdir, sess, dirs)
617
    archivist_integritybars(integrity, osurls, radiourls, localdir)
618
    archivist_extractbars(extract, localdir)
619
    archivist_integritysigned(extract, localdir)
620
    archivist_movebars(dirs, localdir)
621
    archivist_generateloaders(osversion, radioversion, radios, localdir, altsw, core)
622
    archivist_integrityloaders(integrity, localdir)
623
    archivist_removesigned(signed, localdir)
624
    archivist_compressor(compressed, integrity, localdir, compmethod, szexe)
625
    archivist_moveloaders(dirs, localdir)
626
    archivist_gethashes(dirs, hashed, compressed, deleted, radios, osversion, radioversion, softwareversion, oldstyle)
627
    archivist_getoldhashes(dirs, hashed, compressed, deleted, radios, hashdict, oldstyle)
628
    archivist_gpg(gpg, dirs, compressed, deleted, radios)
629
    archivist_deleteuncompressed(dirs, deleted, radios)
630
    archivist_removeemptyfolders(localdir)
631
    print("\nFINISHED!")
632
633
634
if __name__ == "__main__":
635
    grab_args()
636
    decorators.enter_to_exit(False)
637