Completed
Push — master ( 152b55...0bdad9 )
by John
01:22
created

archivist_main()   F

Complexity

Conditions 25

Size

Total Lines 179

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
cc 25
c 1
b 0
f 1
dl 0
loc 179
rs 2

How to fix   Long Method    Complexity   

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:

Complexity

Complex classes like archivist_main() often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

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
                       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
    if not radioversion:
163
        radioversion = None
164
    softwareversion = input("OS SOFTWARE RELEASE (PRESS ENTER TO GUESS): ")
165
    if not softwareversion:
166
        softwareversion = None
167
    altcheck = utilities.s2b(input("USING ALTERNATE RADIO (Y/N)?: "))
168
    if altcheck:
169
        altsw = input("RADIO SOFTWARE RELEASE (PRESS ENTER TO GUESS): ")
170
        if not altsw:
171
            altsw = "checkme"
172
    else:
173
        altsw = None
174
    radios = utilities.s2b(input("CREATE RADIO LOADERS (Y/N)?: "))
175
    compressed = utilities.s2b(input("COMPRESS LOADERS (Y/N)?: "))
176
    deleted = utilities.s2b(input("DELETE UNCOMPRESSED LOADERS (Y/N)?: ")) if compressed else False
177
    hashed = utilities.s2b(input("GENERATE HASHES (Y/N)?: "))
178
    if getattr(sys, 'frozen', False):
179
        hashdict = hashutils.verifier_config_loader(os.getcwd())
180
        compmethod = "7z"
181
    else:
182
        hashdict = hashutils.verifier_config_loader()
183
        hashutils.verifier_config_writer(hashdict)
184
        compmethod = archiveutils.compress_config_loader()
185
    print(" ")
186
    archivist_main(osversion, radioversion, softwareversion,
187
                   localdir, radios, compressed, deleted, hashed,
188
                   hashdict, download=True, extract=True, signed=True,
189
                   compmethod=compmethod, gpg=False, integrity=True,
190
                   altsw=None, core=False, oldstyle=False)
191
192
193
def archivist_main(osversion, radioversion=None, softwareversion=None,
194
                   localdir=None, radios=True, compressed=True, deleted=True,
195
                   hashed=True, hashdict=None, download=True,
196
                   extract=True, signed=True, compmethod="7z",
197
                   gpg=False, integrity=True, altsw=None,
198
                   core=False, oldstyle=False):
199
    """
200
    Wrap around multi-autoloader creation code.
201
    Some combination of creating, downloading, hashing,
202
    compressing and moving autoloaders.
203
204
    :param osversion: OS version, 10.x.y.zzzz. Required.
205
    :type osversion: str
206
207
    :param radioversion: Radio version, 10.x.y.zzzz. Can be guessed.
208
    :type radioversion: str
209
210
    :param softwareversion: Software release, 10.x.y.zzzz. Can be guessed.
211
    :type softwareversion: str
212
213
    :param localdir: Working directory. Local by default.
214
    :type localdir: str
215
216
    :param radios: Whether to create radio autoloaders. True by default.
217
    :type radios: bool
218
219
    :param compressed: Whether to compress files. True by default.
220
    :type compressed: bool
221
222
    :param deleted: Whether to delete uncompressed files. True by default.
223
    :type deleted: bool
224
225
    :param hashed: Whether to hash files. True by default.
226
    :type hashed: bool
227
228
    :param hashdict: Dictionary of hash rules, in ~\bbarchivist.ini.
229
    :type hashdict: dict({str: bool})
230
231
    :param download: Whether to download bar files. True by default.
232
    :type download: bool
233
234
    :param extract: Whether to extract bar files. True by default.
235
    :type extract: bool
236
237
    :param signed: Whether to delete signed files. True by default.
238
    :type signed: bool
239
240
    :param compmethod: Compression method. Default is "7z", fallback "zip".
241
    :type compmethod: str
242
243
    :param gpg: Whether to use GnuPG verification. False by default.
244
    :type gpg: bool
245
246
    :param integrity: Whether to test downloaded bar files. True by default.
247
    :type integrity: bool
248
249
    :param altsw: Radio software release, if not the same as OS.
250
    :type altsw: str
251
252
    :param core: Whether to create a core/radio loader. Default is false.
253
    :type core: bool
254
255
    :param oldstyle: Whether to make old-style checksum files. Default is false.
256
    :type oldstyle: bool
257
    """
258
    radioversion = scriptutils.return_radio_version(osversion, radioversion)
259
    softwareversion, swchecked = scriptutils.return_sw_checked(softwareversion, osversion)
260
    if altsw == "checkme":
261
        altsw, altchecked = scriptutils.return_radio_sw_checked(altsw, radioversion)
262
    if localdir is None:
263
        localdir = os.getcwd()
264
    if hashed and hashdict is None:
265
        hashdict = hashutils.verifier_config_loader()
266
        hashutils.verifier_config_writer(hashdict)
267
    scriptutils.standard_preamble("archivist", osversion, softwareversion, radioversion, altsw)
268
269
    # Generate download URLs
270
    baseurl, alturl = scriptutils.get_baseurls(softwareversion, altsw)
271
    osurls, radiourls, cores = utilities.generate_urls(baseurl, osversion, radioversion, True)
272
    osurls = cores if core else osurls
273
    for idx, url in enumerate(osurls):
274
        if "qc8960.factory_sfi" in url:
275
            vzwurl = url
276
            vzwindex = idx
277
            break
278
    if not networkutils.availability(vzwurl):
279
        osurls[vzwindex] = osurls[vzwindex].replace("qc8960.factory_sfi", "qc8960.verizon_sfi")
280
    osurls = list(set(osurls))  # pop duplicates
281
    if altsw:
282
        radiourls2 = [x.replace(baseurl, alturl) for x in radiourls]
283
        radiourls = radiourls2
284
        del radiourls2
285
286
    # Check availability of software releases
287
    scriptutils.check_sw(baseurl, softwareversion, swchecked)
288
    if altsw:
289
        scriptutils.check_radio_sw(alturl, altsw, altchecked)
290
291
    # Check availability of OS, radio
292
    scriptutils.check_os_bulk(osurls)
293
    radiourls, radioversion = scriptutils.check_radio_bulk(radiourls, radioversion)
294
295
    # Get 7z executable
296
    compmethod, szexe = scriptutils.get_sz_executable(compmethod)
297
298
    # Make dirs: bd_o, bd_r, ld_o, ld_r, zd_o, zd_r
299
    dirs = barutils.make_dirs(localdir, osversion, radioversion)
300
301
    # Download files
302
    if download:
303
        print("BEGIN DOWNLOADING...")
304
        networkutils.download_bootstrap(radiourls + osurls, localdir, 3)
305
        print("ALL FILES DOWNLOADED")
306
307
    # Test bar files
308
    if integrity:
309
        urllist = osurls + radiourls
310
        scriptutils.test_bar_files(localdir, urllist)
311
312
    # Extract bar files
313
    if extract:
314
        print("EXTRACTING...")
315
        barutils.extract_bars(localdir)
316
317
    # Test signed files
318
    if integrity:
319
        scriptutils.test_signed_files(localdir)
320
321
    # Move bar files
322
    print("MOVING BAR FILES...")
323
    barutils.move_bars(localdir, dirs[0], dirs[1])
324
325
    # Create loaders
326
    print("GENERATING LOADERS...")
327
    altradio = altsw is not None
328
    loadergen.generate_loaders(osversion, radioversion, radios, localdir, altradio, core)
329
330
    # Test loader files
331
    if integrity:
332
        scriptutils.test_loader_files(localdir)
333
334
    # Remove .signed files
335
    if signed:
336
        print("REMOVING SIGNED FILES...")
337
        barutils.remove_signed_files(localdir)
338
339
    # If compression = true, compress
340
    if compressed:
341
        print("COMPRESSING...")
342
        archiveutils.compress(localdir, compmethod, szexe, True)
343
344
    if integrity and compressed:
345
        print("TESTING ARCHIVES...")
346
        archiveutils.verify(localdir, compmethod, szexe, True)
347
348
    # Move zipped/unzipped loaders
349
    print("MOVING LOADERS...")
350
    barutils.move_loaders(localdir, dirs[2], dirs[3], dirs[4], dirs[5])
351
352
    # Get hashes/signatures (if specified)
353
    if hashed:
354
        if oldstyle:
355
            scriptutils.bulk_hash(dirs, compressed, deleted, radios, hashdict)
356
        else:
357
            scriptutils.bulk_info(dirs, osversion, compressed, deleted, radios,
358
                                  radioversion, softwareversion)
359
    if gpg:
360
        scriptutils.bulk_verify(dirs, compressed, deleted, radios)
361
362
    # Remove uncompressed loaders (if specified)
363
    if deleted:
364
        print("DELETING UNCOMPRESSED LOADERS...")
365
        barutils.remove_unpacked_loaders(dirs[2], dirs[3], radios)
366
367
    # Delete empty folders
368
    print("REMOVING EMPTY FOLDERS...")
369
    barutils.remove_empty_folders(localdir)
370
371
    print("\nFINISHED!")
372
373
374
if __name__ == "__main__":
375
    grab_args()
376
    decorators.enter_to_exit(False)
377