Completed
Push — master ( 1db2c1...2d4f92 )
by John
01:14
created

archivist_integritysigned()   A

Complexity

Conditions 2

Size

Total Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

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