carrierchecker_export()   A
last analyzed

Complexity

Conditions 2

Size

Total Lines 38
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 5
nop 10
dl 0
loc 38
rs 10
c 0
b 0
f 0

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
#!/usr/bin/env python3
2
"""Checks a carrier for an OS version, can download."""
3
4
import os  # file/path operations
5
import sys  # load arguments
6
import webbrowser  # code list
7
8
import requests  # session
9
from bbarchivist import argutils  # arguments
10
from bbarchivist import bbconstants  # versions/constants
11
from bbarchivist import decorators  # enter to exit
12
from bbarchivist import jsonutils  # json
13
from bbarchivist import networkutils  # check function
14
from bbarchivist import scriptutils  # default parser
15
from bbarchivist import utilities  # input validation
16
17
__author__ = "Thurask"
18
__license__ = "WTFPL v2"
19
__copyright__ = "2015-2019 Thurask"
20
21
22
def grab_args():
23
    """
24
    Parse arguments from argparse/questionnaire.
25
26
    Invoke :func:`carrierchecker.carrierchecker_main` with those arguments.
27
    """
28
    if len(sys.argv) > 1:
29
        parser = argutils.default_parser("bb-cchecker", "Carrier info checking")
30
        parser.add_argument(
31
            "mcc",
32
            help="1-3 digit country code",
33
            type=argutils.valid_carrier,
34
            nargs="?",
35
            default=None)
36
        parser.add_argument(
37
            "mnc",
38
            help="1-3 digit carrier code",
39
            type=argutils.valid_carrier,
40
            nargs="?",
41
            default=None)
42
        parser.add_argument(
43
            "device",
44
            help="'STL100-1', 'SQW100-3', etc.",
45
            nargs="?",
46
            default=None)
47
        parser.add_argument(
48
            "-c", "--codes",
49
            dest="codes",
50
            help="Open browser for MCC/MNC list",
51
            action="store_true",
52
            default=False)
53
        parser.add_argument(
54
            "-a", "--available-bundles",
55
            dest="bundles",
56
            help="Check available bundles",
57
            action="store_true",
58
            default=False)
59
        parser.add_argument(
60
            "-d", "--download",
61
            dest="download",
62
            help="Download files after checking",
63
            action="store_true",
64
            default=False)
65
        parser.add_argument(
66
            "-e", "--export",
67
            dest="export",
68
            help="Export links to files",
69
            action="store_true",
70
            default=False)
71
        parser.add_argument(
72
            "-r", "--repair",
73
            dest="upgrade",
74
            help="Debrick instead of upgrade bars",
75
            action="store_false",
76
            default=True)
77
        parser.add_argument(
78
            "-f", "--folder",
79
            dest="folder",
80
            help="Working folder",
81
            default=None,
82
            metavar="DIR")
83
        parser.add_argument(
84
            "-b", "--blitz",
85
            dest="blitz",
86
            help="Create blitz package",
87
            action="store_true",
88
            default=False)
89
        parser.add_argument(
90
            "--selective",
91
            dest="selective",
92
            help="Skip Nuance/retaildemo",
93
            action="store_true",
94
            default=False)
95
        fgroup = parser.add_mutually_exclusive_group()
96
        fgroup.add_argument(
97
            "-s", "--software-release",
98
            dest="forcedsw",
99
            help="Force SW release (check bundles first!)",
100
            default=None,
101
            metavar="SWRELEASE")
102
        fgroup.add_argument(
103
            "-o", "--os",
104
            dest="forcedos",
105
            help="Force OS (check bundles first!)",
106
            default=None,
107
            metavar="OS")
108
        parser.set_defaults()
109
        args = parser.parse_args(sys.argv[1:])
110
        if args.codes:
111
            webbrowser.open("https://en.wikipedia.org/wiki/Mobile_country_code")
112
        else:
113
            execute_args(args)
114
    else:
115
        questionnaire()
116
    decorators.enter_to_exit(True)
117
118
119
def forced_avail(args):
120
    """
121
    Determine the forced argument after availability checking.
122
123
    :param args: Arguments.
124
    :type args: argparse.Namespace
125
    """
126
    avail = networkutils.sr_lookup(args.forcedos, bbconstants.SERVERS['p'])
127
    forced = avail if avail != "SR not in system" else None
128
    return forced
129
130
131
def forced_args(args):
132
    """
133
    Determine the forced argument.
134
135
    :param args: Arguments.
136
    :type args: argparse.Namespace
137
    """
138
    if utilities.one_and_none(args.forcedsw, args.forcedos):
139
        forced = forced_avail(args)
140
    elif utilities.one_and_none(args.forcedos, args.forcedsw):
141
        forced = args.forcedsw
142
    else:
143
        forced = None
144
    return forced
145
146
147
def execute_args(args):
148
    """
149
    Get args and decide what to do with them.
150
151
    :param args: Arguments.
152
    :type args: argparse.Namespace
153
    """
154
    args.folder = utilities.dirhandler(args.folder, os.getcwd())
155
    if args.blitz:
156
        args.download = True
157
        args.upgrade = True  # blitz takes precedence
158
    if args.bundles:
159
        args.download = False
160
        args.upgrade = False
161
        args.export = False
162
        args.blitz = False
163
    forced = forced_args(args)
164
    carrierchecker_main(args.mcc, args.mnc, args.device, args.download, args.upgrade, args.folder, args.export, args.blitz, args.bundles, forced, args.selective)
165
166
167
def questionnaire_3digit(message):
168
    """
169
    Get MCC/MNC from questionnaire.
170
    """
171
    while True:
172
        try:
173
            trip = int(input("{0}: ".format(message)))
174
        except ValueError:
175
            continue
176
        else:
177
            if trip == argutils.valid_carrier(trip):
178
                return trip
179
180
181
def questionnaire():
182
    """
183
    Questions to ask if no arguments given.
184
    """
185
    mcc = questionnaire_3digit("MCC")
186
    mnc = questionnaire_3digit("MNC")
187
    device = scriptutils.questionnaire_device()
188
    bundles = utilities.i2b("CHECK BUNDLES?: ")
189
    if bundles:
190
        download = False
191
        upgrade = False
192
        export = False
193
        blitz = False
194
    else:
195
        export = utilities.i2b("EXPORT TO FILE?: ")
196
        download = utilities.i2b("DOWNLOAD?: ")
197
        upgrade = False if not download else utilities.i2b("Y=UPGRADE BARS, N=DEBRICK BARS?: ")
198
        blitz = False if not download else (utilities.i2b("CREATE BLITZ?: ") if upgrade else False)
199
    directory = os.getcwd()
200
    print(" ")
201
    carrierchecker_main(mcc, mnc, device, download, upgrade, directory, export, blitz, bundles, None, False)
202
203
204
def carrierchecker_argfilter(mcc, mnc, device, directory):
205
    """
206
    Filter arguments.
207
208
    :param mcc: Country code.
209
    :type mcc: int
210
211
    :param mnc: Network code.
212
    :type mnc: int
213
214
    :param device: Device ID (XXX100-#)
215
    :type device: str
216
217
    :param directory: Where to store files. Default is local directory.
218
    :type directory: str
219
    """
220
    targdir = {"MCC": mcc, "MNC": mnc, "DEVICE": device}
221
    for key, value in targdir.items():
222
        if value is None:
223
            print("INVALID {0}!".format(key))
224
            raise SystemExit
225
    device = device.upper()
226
    directory = utilities.dirhandler(directory, os.getcwd())
227
    return device, directory
228
229
230
def carrierchecker_jsonprepare(mcc, mnc, device):
231
    """
232
    Prepare JSON data.
233
234
    :param mcc: Country code.
235
    :type mcc: int
236
237
    :param mnc: Network code.
238
    :type mnc: int
239
240
    :param device: Device ID (XXX100-#).
241
    :type device: str
242
    """
243
    data = jsonutils.load_json("devices")
244
    model, family, hwid = jsonutils.certchecker_prep(data, device)
245
    country, carrier = networkutils.carrier_checker(mcc, mnc)
246
    return model, family, hwid, country, carrier
247
248
249
def carrierchecker_bundles(mcc, mnc, hwid):
250
    """
251
    :param mcc: Country code.
252
    :type mcc: int
253
254
    :param mnc: Network code.
255
    :type mnc: int
256
257
    :param hwid: Device hardware ID.
258
    :type hwid: str
259
    """
260
    releases = networkutils.available_bundle_lookup(mcc, mnc, hwid)
261
    print("\nAVAILABLE BUNDLES:")
262
    utilities.lprint(releases)
263
264
265
def carrierchecker_selective(files, selective=False):
266
    """
267
    Filter useless bar files.
268
269
    :param files: List of files.
270
    :type files: list(str)
271
272
    :param selective: Whether or not to exclude Nuance/other dross. Default is false.
273
    :type selective: bool
274
    """
275
    if selective:
276
        craplist = jsonutils.load_json("apps_to_remove")
277
        files = scriptutils.clean_barlist(files, craplist)
278
    return files
279
280
281
def carrierchecker_export(mcc, mnc, files, hwid, osv, radv, swv, export=False, upgrade=False, forced=None):
282
    """
283
    Export files to file.
284
285
    :param mcc: Country code.
286
    :type mcc: int
287
288
    :param mnc: Network code.
289
    :type mnc: int
290
291
    :param files: List of files.
292
    :type files: list(str)
293
294
    :param hwid: Device hardware ID.
295
    :type hwid: str
296
297
    :param osv: OS version, 10.x.y.zzzz.
298
    :type osv: str
299
300
    :param radv: Radio version, 10.x.y.zzzz.
301
    :type radv: str
302
303
    :param swv: Software release, 10.x.y.zzzz.
304
    :type swv: str
305
306
    :param export: Whether or not to write URLs to a file. Default is false.
307
    :type export: bool
308
309
    :param upgrade: Whether or not to use upgrade files. Default is false.
310
    :type upgrade: bool
311
312
    :param forced: Force a software release. None to go for latest.
313
    :type forced: str
314
    """
315
    if export:
316
        print("\nEXPORTING...")
317
        npc = networkutils.return_npc(mcc, mnc)
318
        scriptutils.export_cchecker(files, npc, hwid, osv, radv, swv, upgrade, forced)
319
320
321
def carrierchecker_download_prep(files, directory, osv, radv, swv, family, blitz=False):
322
    """
323
    Prepare for downloading files.
324
325
    :param files: List of files.
326
    :type files: list(str)
327
328
    :param directory: Where to store files. Default is local directory.
329
    :type directory: str
330
331
    :param osv: OS version, 10.x.y.zzzz.
332
    :type osv: str
333
334
    :param radv: Radio version, 10.x.y.zzzz.
335
    :type radv: str
336
337
    :param swv: Software release, 10.x.y.zzzz.
338
    :type swv: str
339
340
    :param family: Device family.
341
    :type family: str
342
343
    :param blitz: Whether or not to create a blitz package. Default is false.
344
    :type blitz: bool
345
    """
346
    suffix = "-BLITZ" if blitz else "-{0}".format(family)
347
    bardir = os.path.join(directory, "{0}{1}".format(swv, suffix))
348
    if not os.path.exists(bardir):
349
        os.makedirs(bardir)
350
    if blitz:
351
        files = scriptutils.generate_blitz_links(files, osv, radv, swv)
352
    return bardir, files
353
354
355
def carrierchecker_download(files, directory, osv, radv, swv, family, download=False, blitz=False, session=None):
356
    """
357
    Download files, create blitz if specified.
358
359
    :param files: List of files.
360
    :type files: list(str)
361
362
    :param directory: Where to store files. Default is local directory.
363
    :type directory: str
364
365
    :param osv: OS version, 10.x.y.zzzz.
366
    :type osv: str
367
368
    :param radv: Radio version, 10.x.y.zzzz.
369
    :type radv: str
370
371
    :param swv: Software release, 10.x.y.zzzz.
372
    :type swv: str
373
374
    :param family: Device family.
375
    :type family: str
376
377
    :param download: Whether or not to download. Default is false.
378
    :type download: bool
379
380
    :param blitz: Whether or not to create a blitz package. Default is false.
381
    :type blitz: bool
382
383
    :param session: Requests session object, default is created on the fly.
384
    :type session: requests.Session()
385
    """
386
    if download:
387
        bardir, files = carrierchecker_download_prep(files, directory, osv, radv, swv, family, blitz)
388
        print("\nDOWNLOADING...")
389
        networkutils.download_bootstrap(files, outdir=bardir, session=session)
390
        scriptutils.test_bar_files(bardir, files)
391
        if blitz:
392
            scriptutils.package_blitz(bardir, swv)
393
        print("\nFINISHED!!!")
394
395
396
def carrierchecker_nobundles(mcc, mnc, hwid, family, download=False, upgrade=True, directory=None, export=False, blitz=False, forced=None, selective=False):
397
    """
398
    Wrap around :mod:`bbarchivist.networkutils` carrier checking.
399
400
    :param mcc: Country code.
401
    :type mcc: int
402
403
    :param mnc: Network code.
404
    :type mnc: int
405
406
    :param hwid: Device hardware ID.
407
    :type hwid: str
408
409
    :param family: Device family.
410
    :type family: str
411
412
    :param download: Whether or not to download. Default is false.
413
    :type download: bool
414
415
    :param upgrade: Whether or not to use upgrade files. Default is false.
416
    :type upgrade: bool
417
418
    :param directory: Where to store files. Default is local directory.
419
    :type directory: str
420
421
    :param export: Whether or not to write URLs to a file. Default is false.
422
    :type export: bool
423
424
    :param blitz: Whether or not to create a blitz package. Default is false.
425
    :type blitz: bool
426
427
    :param forced: Force a software release. None to go for latest.
428
    :type forced: str
429
430
    :param selective: Whether or not to exclude Nuance/other dross. Default is false.
431
    :type selective: bool
432
    """
433
    npc = networkutils.return_npc(mcc, mnc)
434
    swv, osv, radv, files = networkutils.carrier_query(npc, hwid, upgrade, blitz, forced)
435
    print("SOFTWARE RELEASE: {0}".format(swv))
436
    print("OS VERSION: {0}".format(osv))
437
    print("RADIO VERSION: {0}".format(radv))
438
    files = carrierchecker_selective(files, selective)
439
    carrierchecker_export(mcc, mnc, files, hwid, osv, radv, swv, export, upgrade, forced)
440
    sess = requests.Session()
441
    carrierchecker_download(files, directory, osv, radv, swv, family, download, blitz, sess)
442
443
444
def carrierchecker_main(mcc, mnc, device, download=False, upgrade=True, directory=None, export=False, blitz=False, bundles=False, forced=None, selective=False):
445
    """
446
    Wrap around :mod:`bbarchivist.networkutils` carrier checking.
447
448
    :param mcc: Country code.
449
    :type mcc: int
450
451
    :param mnc: Network code.
452
    :type mnc: int
453
454
    :param device: Device ID (XXX100-#).
455
    :type device: str
456
457
    :param download: Whether or not to download. Default is false.
458
    :type download: bool
459
460
    :param upgrade: Whether or not to use upgrade files. Default is false.
461
    :type upgrade: bool
462
463
    :param directory: Where to store files. Default is local directory.
464
    :type directory: str
465
466
    :param export: Whether or not to write URLs to a file. Default is false.
467
    :type export: bool
468
469
    :param blitz: Whether or not to create a blitz package. Default is false.
470
    :type blitz: bool
471
472
    :param bundles: Whether or not to check software bundles. Default is false.
473
    :type bundles: bool
474
475
    :param forced: Force a software release. None to go for latest.
476
    :type forced: str
477
478
    :param selective: Whether or not to exclude Nuance/other dross. Default is false.
479
    :type selective: bool
480
    """
481
    device, directory = carrierchecker_argfilter(mcc, mnc, device, directory)
482
    model, family, hwid, country, carrier = carrierchecker_jsonprepare(mcc, mnc, device)
483
    argutils.slim_preamble("CARRIERCHECKER")
484
    print("COUNTRY: {0}".format(country.upper()))
485
    print("CARRIER: {0}".format(carrier.upper()))
486
    print("DEVICE: {0}".format(model.upper()))
487
    print("VARIANT: {0}".format(device.upper()))
488
    print("HARDWARE ID: {0}".format(hwid.upper()))
489
    print("\nCHECKING CARRIER...")
490
    if bundles:
491
        carrierchecker_bundles(mcc, mnc, hwid)
492
    else:
493
        carrierchecker_nobundles(mcc, mnc, hwid, family, download, upgrade, directory, export, blitz, forced, selective)
494
495
496
if __name__ == "__main__":
497
    grab_args()
498