Completed
Push — master ( 35a5b7...cfb57c )
by John
03:59
created

forced_args()   A

Complexity

Conditions 3

Size

Total Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

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