Passed
Push — master ( 457845...1fdd25 )
by John
03:36
created

bbarchivist.loadergen   F

Complexity

Total Complexity 105

Size/Duplication

Total Lines 839
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
eloc 296
dl 0
loc 839
ccs 293
cts 293
cp 1
rs 1.263
c 0
b 0
f 0
wmc 105

39 Functions

Rating   Name   Duplication   Size   Complexity  
B generate_lazy_set() 0 32 3
A versionpad() 0 10 1
A point_point_copy() 0 14 1
A format_suffix() 0 17 3
A point_point_bulk() 0 15 2
A generate_tclloader_radfilt() 0 14 4
A generate_tclloader_oemfilt() 0 14 4
A generate_tclloader_radset() 0 12 1
A generate_tclloader_carriers() 0 13 4
B generate_individual_loaders() 0 34 4
A generate_tclloader_oemset() 0 12 1
A generate_tclloader_mbn() 0 12 1
B generate_loaders() 0 32 3
A generate_tclloader_host() 0 19 2
A read_files() 0 20 4
A generate_tclloader_csig() 0 15 2
B wrap_pseudocap() 0 24 3
A generate_tclloader_sig() 0 12 2
A pretty_formatter() 0 18 1
A generate_device() 0 13 3
B generate_tclloader_omniset() 0 22 4
A read_radio_files() 0 22 1
A generate_tclloader_script() 0 21 2
B read_os_files() 0 26 4
A generate_os_fixes() 0 22 2
A find_signed_file() 0 23 3
A generate_google_host() 0 14 3
A zeropad() 0 16 2
A generate_skeletons() 0 11 3
A generate_tclloader_carriter() 0 15 2
B tclloader_nowipe() 0 15 5
A generate_lazy_filename() 0 19 3
A generate_filename() 0 20 3
B generate_lazy_loader() 0 34 3
A generate_tclloader_looseends() 0 16 4
A looseends_krypton() 0 16 1
B generate_tclloader() 0 39 3
B generate_tclloader_img() 0 23 4
A generate_tclloader_deps() 0 17 4

How to fix   Complexity   

Complexity

Complex classes like bbarchivist.loadergen 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 5
"""This module is used for creation of autoloaders."""
3
4 5
import glob  # filename matching
5 5
import os  # path work
6 5
import shutil  # file copying
7
8 5
from bbarchivist import bbconstants  # versions/constants
9 5
from bbarchivist import exceptions  # exception handling
10 5
from bbarchivist import jsonutils  # json
11 5
from bbarchivist import pseudocap  # implement cap
12 5
from bbarchivist import utilities  # directory handler
13
14 5
__author__ = "Thurask"
15 5
__license__ = "WTFPL v2"
16 5
__copyright__ = "2015-2018 Thurask"
17
18
19 5
def read_files(localdir, core=False):
20
    """
21
    Read list of signed files, return name assignments.
22
23
    :param localdir: Directory to use.
24
    :type localdir: str
25
26
    :param core: If we're using a core OS image. Default is false.
27
    :type core: bool
28
    """
29 5
    oslist = read_os_files(localdir, core)
30
    # [8960, 8x30, 8974, ti]
31 5
    radlist = read_radio_files(localdir)
32
    # [ti, z10, z10_vzw, q10, z30, z3, 8974]
33 5
    pairdict = {}
34 5
    mapping = {0:3, 1:0, 2:0, 3:0, 4:0, 5:1, 6:2}
35 5
    for idx, rad in enumerate(radlist):
36 5
        pairdict[rad] = oslist[mapping[idx]]
37 5
    filtdict = {k: v for k, v in pairdict.items() if k}  # pop None
38 5
    return filtdict
39
40
41 5
def find_signed_file(match, localdir, title, silent=False):
42
    """
43
    Use pattern matching to find a signed file in a directory.
44
45
    :param match: Match pattern to use.
46
    :type match: str
47
48
    :param localdir: Directory to use.
49
    :type localdir: str
50
51
    :param title: File type, in case it isn't found.
52
    :type title: str
53
54
    :param silent: Don't print that a file wasn't found. Default is False.
55
    :type silent: bool
56
    """
57 5
    try:
58 5
        signedfile = glob.glob(os.path.join(localdir, match))[0]
59 5
    except IndexError:
60 5
        signedfile = None
61 5
        if not silent:
62 5
            print("No {0} found".format(title))
63 5
    return signedfile
64
65
66 5
def generate_os_fixes(core=False):
67
    """
68
    Generate name regexes for OS signed files.
69
70
    :param core: If we're using a core OS image. Default is false.
71
    :type core: bool
72
    """
73 5
    if core:
74 5
        fix8960 = "*qc8960.*_sfi.BB*.signed"
75 5
        fixomap_new = "*winchester.*_sfi.BB*.signed"
76 5
        fixomap_old = "*os.factory_sfi.BB*.signed"
77 5
        fix8930 = "*qc8x30.BB*.signed"
78 5
        fix8974_new = "*qc8974.BB*.signed"
79 5
        fix8974_old = "*qc8974.*_sfi.BB*.signed"
80
    else:
81 5
        fix8960 = "*qc8960.*_sfi.desktop.BB*.signed"
82 5
        fixomap_new = "*winchester.*_sfi.desktop.BB*.signed"
83 5
        fixomap_old = "*os.factory_sfi.desktop.BB*.signed"
84 5
        fix8930 = "*qc8x30.desktop.BB*.signed"
85 5
        fix8974_new = "*qc8974.desktop.BB*.signed"
86 5
        fix8974_old = "*qc8974.*_sfi.desktop.BB*.signed"
87 5
    return fix8960, fixomap_new, fixomap_old, fix8930, fix8974_new, fix8974_old
88
89
90 5
def read_os_files(localdir, core=False):
91
    """
92
    Read list of OS signed files, return name assignments.
93
94
    :param localdir: Directory to use.
95
    :type localdir: str
96
97
    :param core: If we're using a core OS image. Default is false.
98
    :type core: bool
99
    """
100 5
    fix8960, fixomap_new, fixomap_old, fix8930, fix8974_new, fix8974_old = generate_os_fixes(core)
101
    # 8960
102 5
    os_8960 = find_signed_file(fix8960, localdir, "8960 OS")
103
    # 8x30 (10.3.1 MR+)
104 5
    os_8x30 = find_signed_file(fix8930, localdir, "8x30 OS", True)
105 5
    if os_8x30 is None:
106 5
        os_8x30 = find_signed_file(fix8960, localdir, "8x30 OS")
107
    # 8974
108 5
    os_8974 = find_signed_file(fix8974_new, localdir, "8974 OS", True)
109 5
    if os_8974 is None:
110 5
        os_8974 = find_signed_file(fix8974_old, localdir, "8974 OS")
111
    # OMAP
112 5
    os_ti = find_signed_file(fixomap_new, localdir, "OMAP OS", True)
113 5
    if os_ti is None:
114 5
        os_ti = find_signed_file(fixomap_old, localdir, "OMAP OS")
115 5
    return [os_8960, os_8x30, os_8974, os_ti]
116
117
118 5
def read_radio_files(localdir):
119
    """
120
    Read list of radio signed files, return name assignments.
121
122
    :param localdir: Directory to use.
123
    :type localdir: str
124
    """
125
    # STL100-1
126 5
    radio_ti = find_signed_file("*radio.m5730*.signed", localdir, "OMAP radio")
127
    # STL100-X
128 5
    radio_z10 = find_signed_file("*radio.qc8960.BB*.signed", localdir, "8960 radio")
129
    # STL100-4
130 5
    radio_z10_vzw = find_signed_file("*radio.qc8960*omadm*.signed", localdir, "VZW 8960 radio")
131
    # Q10/Q5
132 5
    radio_q10 = find_signed_file("*radio.qc8960*wtr.*signed", localdir, "Q10/Q5 radio")
133
    # Z30/Classic
134 5
    radio_z30 = find_signed_file("*radio.qc8960*wtr5*.signed", localdir, "Z30/Classic radio")
135
    # Z3
136 5
    radio_z3 = find_signed_file("*radio.qc8930*wtr5*.signed", localdir, "Z3 radio")
137
    # Passport
138 5
    radio_8974 = find_signed_file("*radio.qc8974*wtr2*.signed", localdir, "Passport radio")
139 5
    return [radio_ti, radio_z10, radio_z10_vzw, radio_q10, radio_z30, radio_z3, radio_8974]
140
141
142 5
def zeropad(splitver, idx, padlen):
143
    """
144
    Zero-pad an element of an OS/radio version to a certain length.
145
146
    :param splitver: OS/radio version, but split into quarters.
147
    :type splitver: list(str)
148
149
    :param idx: Index of splitver which must be checked.
150
    :type idx: int
151
152
    :param padlen: Length to pad to.
153
    :type padlen: int
154
    """
155 5
    if len(splitver[idx]) < padlen:
156 5
        splitver[idx] = splitver[idx].rjust(padlen, "0")
157 5
    return splitver
158
159
160 5
def versionpad(splitver):
161
    """
162
    Properly pad an OS/radio version.
163
164
    :param splitver: OS/radio version, but split into quarters.
165
    :type splitver: list(str)
166
    """
167 5
    splitver = zeropad(splitver, 2, 2)
168 5
    splitver = zeropad(splitver, 3, 4)
169 5
    return splitver
170
171
172 5
def pretty_formatter(osversion, radioversion):
173
    """
174
    Format OS/radio versions to cope with systems with poor sorting.
175
176
    :param osversion: OS version, 10.x.y.zzzz.
177
    :type osversion: str
178
179
    :param radioversion: Radio version, 10.x.y.zzzz.
180
    :type radioversion: str
181
    """
182
    # 10.x.y.zzz becomes 10.x.0y.0zzz
183 5
    splitos = osversion.split(".")
184 5
    splitos = versionpad(splitos)
185 5
    the_os = ".".join(splitos)
186 5
    splitrad = radioversion.split(".")
187 5
    splitrad = versionpad(splitrad)
188 5
    the_radio = ".".join(splitrad)
189 5
    return the_os, the_radio
190
191
192 5
def format_suffix(altradio=None, radioversion=None, core=False):
193
    """
194
    Formulate suffix for hybrid autoloaders.
195
196
    :param altradio: If a hybrid autoloader is being made.
197
    :type altradio: bool
198
199
    :param radioversion: The hybrid radio version, if applicable.
200
    :type radioversion: str
201
202
    :param core: If we're using a core OS image. Default is false.
203
    :type core: bool
204
    """
205 5
    suffix = "_R{0}".format(radioversion) if altradio and radioversion else ""
206 5
    if core:
207 5
        suffix += "_CORE"
208 5
    return suffix
209
210
211 5
def generate_loaders(osversion, radioversion, radios=True, localdir=None, altradio=False, core=False):
212
    """
213
    Create and label autoloaders for :mod:`bbarchivist.scripts.archivist`.
214
215
    :param osversion: OS version, 10.x.y.zzzz.
216
    :type osversion: str
217
218
    :param radioversion: Radio version, 10.x.y.zzzz.
219
    :type radioversion: str
220
221
    :param radios: Whether to make radios or not. True by default.
222
    :type radios: bool
223
224
    :param localdir: Working path. Default is local dir.
225
    :type localdir: str
226
227
    :param altradio: If we're using an alternate radio. Default is false.
228
    :type altradio: bool
229
230
    :param core: If we're using a core OS image. Default is false.
231
    :type core: bool
232
    """
233
    # default parsing
234 5
    localdir = utilities.dirhandler(localdir, os.getcwd())
235 5
    print("GETTING FILENAMES...")
236 5
    filedict = read_files(localdir, core)
237 5
    osversion, radioversion = pretty_formatter(osversion, radioversion)
238 5
    suffix = format_suffix(altradio, radioversion, core)
239
    # Generate loaders
240 5
    print("CREATING LOADERS...")
241 5
    filtrad = [rad for rad in filedict.keys() if rad]  # pop None
242 5
    generate_individual_loaders(filtrad, osversion, radioversion, suffix, filedict, radios, localdir)
243
244
245 5
def generate_individual_loaders(filtrad, osversion, radioversion, suffix, filedict, radios, localdir):
246
    """
247
    Generate individual loaders when generating several at once.
248
249
    :param filtrad: List of radio files, if they exist.
250
    :type filtrad: list(str)
251
252
    :param osversion: OS version, 10.x.y.zzzz.
253
    :type osversion: str
254
255
    :param radioversion: Radio version, 10.x.y.zzzz.
256
    :type radioversion: str
257
258
    :param suffix: Alternate radio, or blank.
259
    :type suffix: str
260
261
    :param filedict: Dictionary of radio:OS pairs.
262
    :type filedict: dict(str: str)
263
264
    :param radios: Whether to make radios or not. True by default.
265
    :type radios: bool
266
267
    :param localdir: Working path. Default is local dir.
268
    :type localdir: str
269
    """
270 5
    for radval in filtrad:
271 5
        device = generate_device(radval)
272 5
        osname = generate_filename(device, osversion, suffix)
273 5
        osfile = filedict[radval]
274 5
        if osfile is not None:
275 5
            wrap_pseudocap(osname, localdir, osfile, radval)
276 5
        if radios:
277 5
            radname = generate_filename(device, radioversion, "")
278 5
            wrap_pseudocap(radname, localdir, radval)
279
280
281
282 5
def wrap_pseudocap(filename, folder, first, second=None):
283
    """
284
    A filtered, excepting wrapper for pseudocap.
285
286
    :param filename: The title of the new loader.
287
    :type filename: str
288
289
    :param folder: The folder to create the loader in.
290
    :type folder: str
291
292
    :param first: The first signed file, required.
293
    :type first: str
294
295
    :param second: The second signed file, optional.
296
    :type second: str
297
    """
298 5
    if first is None:
299 5
        print("No OS!")
300 5
        raise SystemError
301 5
    try:
302 5
        pseudocap.make_autoloader(filename, [first, second], folder=folder)
303 5
    except (OSError, IndexError, SystemError) as exc:
304 5
        msg = "Could not create {0}".format(filename)
305 5
        exceptions.handle_exception(exc, msg, None)
306
307
308 5
def generate_skeletons():
309
    """
310
    Read JSON to get a dict of all filename components.
311
    """
312 5
    namelist = {0: None, 1: None, 2: None, 3: None, 4: None, 5: None, 6: None}
313 5
    data = jsonutils.load_json('integermap')
314 5
    for key in data:
315 5
        if key['id'] in namelist:
316 5
            namelist[key['id']] = (key['parts'])
317 5
            namelist[key['id']].append(".exe")
318 5
    return namelist
319
320
321 5
def generate_device(radio):
322
    """
323
    Read JSON to get the device integer ID from device radio.
324
325
    :param radio: The radio filename to look up.
326
    :type radio: str
327
    """
328 5
    data = jsonutils.load_json('integermap')
329 5
    for key in data:
330 5
        if key['radtype'] in radio:
331 5
            idx = int(key['id'])
332 5
            break
333 5
    return idx
334
335
336 5
def generate_filename(device, version, suffix=None):
337
    """
338
    Use skeleton dict to create loader filenames.
339
340
    :param device: Device to use.
341
    :type device: int
342
343
    :param version: OS or radio version.
344
    :type version: str
345
346
    :param suffix: Alternate radio, or blank.
347
    :type suffix: str
348
    """
349 5
    thed = generate_skeletons()
350 5
    if device < 0:
351 5
        return None
352 5
    dev = thed[device]
353 5
    if suffix is None:
354 5
        suffix = ""
355 5
    return "{0}{1}{2}{3}{4}".format(dev[0], version, suffix, dev[1], dev[2])
356
357
358 5
def generate_lazy_loader(
359
        osversion, device,
360
        localdir=None, altradio=None, core=False):
361
    """
362
    Create and label autoloaders for :mod:`bbarchivist.scripts.lazyloader`.
363
    :func:`generate_loaders`, but for making one OS/radio loader.
364
365
    :param osversion: OS version, 10.x.y.zzzz.
366
    :type osversion: str
367
368
    :param device: Selected device, from
369
    :type device: int
370
371
    :param localdir: Working path. Default is local dir.
372
    :type localdir: str
373
374
    :param altradio: The alternate radio in use, if there is one.
375
    :type altradio: str
376
377
    :param core: If we're using a core OS image. Default is false.
378
    :type core: bool
379
    """
380
    # default parsing
381 5
    localdir = utilities.dirhandler(localdir, os.getcwd())
382 5
    print("CREATING LOADER...")
383 5
    suffix = format_suffix(bool(altradio), altradio, core)
384 5
    osfile = None
385 5
    absoglob = "{0}{1}".format(localdir, os.sep)
386 5
    try:
387 5
        osfile = str(glob.glob("{0}*_sfi*.signed".format(absoglob))[0])
388 5
    except IndexError:
389 5
        print("No OS found")
390
    else:
391 5
        generate_lazy_set(osversion, device, osfile, suffix, absoglob, localdir)
392
393
394 5
def generate_lazy_set(osversion, device, osfile, suffix, absoglob, localdir=None):
395
    """
396
    Get radio file and then generate autoloader.
397
398
    :param osversion: OS version, 10.x.y.zzzz.
399
    :type osversion: str
400
401
    :param device: Selected device, from
402
    :type device: int
403
404
    :param osfile: OS signed filename.
405
    :type osfile: str
406
407
    :param suffix: Loader name suffix.
408
    :type suffix: str
409
410
    :param absoglob: Local path + path separator.
411
    :type absoglob: str
412
413
    :param localdir: Working path. Default is local dir.
414
    :type localdir: str
415
    """
416 5
    radiofile = None
417 5
    try:
418 5
        sset = set(glob.glob("{0}*.signed".format(absoglob)))
419 5
        rset = sset - set(glob.glob("{0}*_sfi*.signed".format(absoglob)))
420 5
        radiofile = str(list(rset)[0])
421 5
    except IndexError:
422 5
        print("No radio found")
423
    else:
424 5
        loadername = generate_lazy_filename(osversion, suffix, device)
425 5
        wrap_pseudocap(loadername, localdir, osfile, radiofile)
426
427
428 5
def generate_lazy_filename(osversion, suffix, device):
429
    """
430
    Read JSON to formulate a single filename.
431
432
    :param osversion: OS version.
433
    :type osversion: str
434
435
    :param suffix: Alternate radio, or just blank.
436
    :type suffix: str
437
438
    :param device: Device to use.
439
    :type device: int
440
    """
441 5
    data = jsonutils.load_json('integermap')
442 5
    for key in data:
443 5
        if key['id'] == device:
444 5
            fname = key['parts']
445 5
            break
446 5
    return "{0}{1}{2}{3}.exe".format(fname[0], osversion, suffix, fname[1])
447
448
449 5
def point_point_copy(inpath, outpath, filename):
450
    """
451
    Copy a file from one absolute path to another.
452
453
    :param inpath: Input path.
454
    :type inpath: str
455
456
    :param outpath: Output path.
457
    :type outpath: str
458
459
    :param filename: Filename.
460
    :type filename: str
461
    """
462 5
    shutil.copy(os.path.join(inpath, filename), os.path.join(outpath, filename))
463
464
465 5
def point_point_bulk(inpath, outpath, files):
466
    """
467
    Copy a list of files from one absolute path to another.
468
469
    :param inpath: Input path.
470
    :type inpath: str
471
472
    :param outpath: Output path.
473
    :type outpath: str
474
475
    :param files: List of filenames.
476
    :type files: list(str)
477
    """
478 5
    for file in files:
479 5
        point_point_copy(inpath, outpath, file)
480
481
482 5
def generate_tclloader_script(dirname, batchfile, shfile, wipe=True):
483
    """
484
    Copy script files from site-packages to loader directory.
485
486
    :param dirname: Name for final directory and loader.
487
    :type dirname: str
488
489
    :param batchfile: Path to flashall.bat.
490
    :type batchfile: str
491
492
    :param shfile: Path to flashall.sh.
493
    :type shfile: str
494
495
    :param wipe: If the final loader wipes userdata. Default is True.
496
    :type wipe: bool
497
    """
498 5
    shutil.copy(batchfile, os.path.join(dirname, "flashall.bat"))
499 5
    shutil.copy(shfile, os.path.join(dirname, "flashall.sh"))
500 5
    if not wipe:
501 5
        tclloader_nowipe(os.path.join(dirname, "flashall.bat"))
502 5
        tclloader_nowipe(os.path.join(dirname, "flashall.sh"))
503
504
505 5
def tclloader_nowipe(infile):
506
    """
507
    Modify a script file to strike references to wiping the phone.
508
509
    :param infile: Path to script file to modify.
510
    :type infile: str
511
    """
512 5
    filterout = ("oem securewipe", "flash userdata")
513 5
    with open(infile, "r+", newline="") as afile:
514 5
        content = afile.read()
515 5
        afile.seek(0)
516 5
        for line in content.split("\n"):
517 5
            if not any(part in line for part in filterout):
518 5
                afile.write(line + "\n")
519 5
        afile.truncate()
520
521
522 5
def generate_google_host(hostin, hostout):
523
    """
524
    Generate host directory from Google platform tools, i.e. fastboot.
525
526
    :param hostin: Directory containing files to copy.
527
    :type hostin: str
528
529
    :param hostout: Directory that files are to be copied to.
530
    :type hostout: str
531
    """
532 5
    platforms = ["linux", "windows", "darwin"]
533 5
    inouts = {os.path.join(hostin, plat, "platform-tools"): os.path.join(hostout, "{0}-x86".format(plat), "bin") for plat in platforms}
534 5
    for infile, outfile in inouts.items():
535 5
        shutil.copytree(infile, outfile)
536
537
538 5
def generate_tclloader_host(hostin, hostout):
539
    """
540
    Generate host directory from autoloader template, i.e. fastboot.
541
542
    :param hostin: Directory containing files to copy.
543
    :type hostin: str
544
545
    :param hostout: Directory that files are to be copied to.
546
    :type hostout: str
547
    """
548 5
    os.makedirs(os.path.join(hostout, "darwin-x86", "bin"))
549 5
    os.makedirs(os.path.join(hostout, "linux-x86", "bin"))
550 5
    os.makedirs(os.path.join(hostout, "windows-x86", "bin"))
551 5
    macfile = os.path.join("darwin-x86", "bin", "fastboot")
552 5
    linfile = os.path.join("linux-x86", "bin", "fastboot")
553 5
    winx = ["AdbWinApi.dll", "AdbWinUsbApi.dll", "fastboot.exe"]
554 5
    winfiles = [os.path.join("windows-x86", "bin", x) for x in winx]
555 5
    winfiles.extend([linfile, macfile])
556 5
    point_point_bulk(hostin, hostout, winfiles)
557
558
559 5
def generate_tclloader_sig(sigin, sigout):
560
    """
561
    Generate common signature files.
562
563
    :param sigin: Directory containing files to copy.
564
    :type sigin: str
565
566
    :param sigout: Directory that files are to be copied to.
567
    :type sigout: str
568
    """
569 5
    for entry in ["boot", "recovery"]:
570 5
        shutil.copy(os.path.join(sigin, "{0}.img.production.sig".format(entry)), os.path.join(sigout, "{0}.img.sig".format(entry)))
571
572
573 5
def generate_tclloader_csig(sigin, sigout, carrier):
574
    """
575
    Generate carrier variant signature files.
576
577
    :param sigin: Directory containing files to copy.
578
    :type sigin: str
579
580
    :param sigout: Directory that files are to be copied to.
581
    :type sigout: str
582
583
    :param carrier: Carrier to check: att, sprint, china, vzw
584
    :type carrier: str
585
    """
586 5
    for entry in ["boot", "recovery"]:
587 5
        shutil.copy(os.path.join(sigin, "{1}.img.production-{0}.sig".format(carrier, entry)), os.path.join(sigout, "{1}.img{0}.sig".format(carrier, entry)))
588
589
590 5
def generate_tclloader_carriers(sigin, sigout):
591
    """
592
    Collect carrier variant signature files.
593
594
    :param sigin: Directory containing files to copy.
595
    :type sigin: str
596
597
    :param sigout: Directory that files are to be copied to.
598
    :type sigout: str
599
    """
600 5
    prods = set(x.split("-")[-1].split(".")[0] for x in os.listdir(sigin) if "production-" in x) - {"boot", "recovery"}
601 5
    if prods:
602 5
        generate_tclloader_carriter(sigin, sigout, prods)
603
604
605 5
def generate_tclloader_carriter(sigin, sigout, prods):
606
    """
607
    Iterate carrier variant signature files.
608
609
    :param sigin: Directory containing files to copy.
610
    :type sigin: str
611
612
    :param sigout: Directory that files are to be copied to.
613
    :type sigout: str
614
615
    :param prods: Set of carriers.
616
    :type prods: set(str)
617
    """
618 5
    for carr in prods:
619 5
        generate_tclloader_csig(sigin, sigout, carr)
620
621
622 5
def generate_tclloader_mbn(mdnin, mdnout):
623
    """
624
    Generate mbn files.
625
626
    :param mdnin: Directory containing files to copy.
627
    :type mdnin: str
628
629
    :param mdnout: Directory that files are to be copied to.
630
    :type mdnout: str
631
    """
632 5
    files = ["devcfg.mbn", "devcfg_cn.mbn", "rpm.mbn", "tz.mbn"]
633 5
    point_point_bulk(mdnin, mdnout, files)
634
635
636 5
def generate_tclloader_omniset(omnin, omnilist, prefix, suffix, filt):
637
    """
638
    Generic function to generate sets.
639
640
    :param omnin: Directory containing files to copy.
641
    :type omnin: str
642
643
    :param omnilist: List of variants.
644
    :type omnilist: list(str)
645
646
    :param prefix: Prefix, before items in list.
647
    :type prefix: str
648
649
    :param suffix: Suffix, after items in list.
650
    :type suffix: str
651
652
    :param filt: Filter, required to pick file out of directory listing.
653
    :type filt: str
654
    """
655 5
    omfiles = set(os.path.join(omnin, "{1}{0}{2}".format(omni, prefix, suffix)) for omni in omnilist)
656 5
    infiles = set(os.path.join(omnin, filex) for filex in os.listdir(omnin) if filt in filex)
657 5
    return omfiles, infiles
658
659
660 5
def generate_tclloader_oemset(oemin, oems):
661
    """
662
    Generate sets for OEM variants.
663
664
    :param oemin: Directory containing files to copy.
665
    :type oemin: str
666
667
    :param oems: List of OEM variants.
668
    :type oems: list(str)
669
    """
670 5
    ofiles, infiles = generate_tclloader_omniset(oemin, oems, "", ".img", "oem_")
671 5
    return ofiles, infiles
672
673
674 5
def generate_tclloader_oemfilt(oemin, oems):
675
    """
676
    Filter non-existent OEM variants.
677
678
    :param oemin: Directory containing files to copy.
679
    :type oemin: str
680
681
    :param oems: List of OEM variants.
682
    :type oems: list(str)
683
    """
684 5
    ofiles, infiles = generate_tclloader_oemset(oemin, oems)
685 5
    coll = [os.path.basename(oemf).replace(".img", "") for oemf in ofiles - infiles]
686 5
    oems = [oemp for oemp in oems if oemp not in coll]
687 5
    return oems
688
689
690 5
def generate_tclloader_radset(radin, rads):
691
    """
692
    Generate sets for radio variants.
693
694
    :param radin: Directory containing files to copy.
695
    :type radin: str
696
697
    :param rads: List of radio variants.
698
    :type rads: list(str)
699
    """
700 5
    rfiles, infiles = generate_tclloader_omniset(radin, rads, "NON-HLOS-", ".bin", "NON-HLOS-")
701 5
    return rfiles, infiles
702
703
704 5
def generate_tclloader_radfilt(radin, rads):
705
    """
706
    Filter non-existent radio variants.
707
708
    :param radin: Directory containing files to copy.
709
    :type radin: str
710
711
    :param rads: List of radio variants.
712
    :type rads: list(str)
713
    """
714 5
    rfiles, infiles = generate_tclloader_radset(radin, rads)
715 5
    coll = [os.path.basename(radf).replace(".bin", "").replace("NON-HLOS-", "") for radf in rfiles - infiles]
716 5
    rads = [radp for radp in rads if radp not in coll]
717 5
    return rads
718
719
720 5
def generate_tclloader_deps(platform):
721
    """
722
    Generate platform-specific file names.
723
724
    :param platform: Platform type (i.e. subdirectory of target/product).
725
    :type platform: str
726
    """
727 5
    if platform == "bbry_qc8953":  # KEYone
728 5
        oems = ["oem_att", "oem_china", "oem_common", "oem_sprint", "oem_vzw", "oem_indonesia", "oem_russia"]
729 5
        radios = ["china", "dschina", "emea", "global", "india", "japan", "usa"]
730 5
    elif platform == "bbry_qc8953krypton":  # Motion
731 5
        oems = ["oem_att", "oem_common", "oem_sprint", "oem_russia"]
732 5
        radios = ["americas", "cdma", "dscn", "dsglobal", "ssglobal"]
733 5
    elif platform == "bbry_sdm660":  # KEY2
734 5
        oems = ["oem_att", "oem_china", "oem_common", "oem_india", "oem_indonesia", "oem_sprint", "oem_russia"]
735 5
        radios = ["americas", "cn", "dsglobal", "dsjapan", "global", "japan"]
736 5
    return oems, radios
737
738
739 5
def generate_tclloader_looseends(imgout, platform):
740
    """
741
    Handle files that need to be handled.
742
743
    :param imgout: Directory that files are to be copied to.
744
    :type imgout: str
745
746
    :param platform: Platform type (i.e. subdirectory of target/product).
747
    :type platform: str
748
    """
749 5
    if platform == "bbry_qc8953":  # KEYone
750 5
        pass  # no special exceptions
751 5
    elif platform == "bbry_qc8953krypton":  # Motion
752 5
        looseends_krypton(imgout, platform)
753 5
    elif platform == "bbry_sdm660":  # KEY2
754 5
        pass  # TODO: KEY2 autoloader
0 ignored issues
show
Coding Style introduced by
TODO and FIXME comments should generally be avoided.
Loading history...
755
756
757 5
def looseends_krypton(imgout, platform):
0 ignored issues
show
Unused Code introduced by
The argument platform seems to be unused.
Loading history...
758
    """
759
    Handle files that need to be handled, for the Motion platform.
760
761
    :param imgout: Directory that files are to be copied to.
762
    :type imgout: str
763
764
    :param platform: Platform type (i.e. subdirectory of target/product).
765
    :type platform: str
766
    """
767 5
    oldglobal = os.path.join(imgout, "NON-HLOS-ssglobal.bin")
768 5
    newglobal = os.path.join(imgout, "NON-HLOS-global.bin")
769 5
    os.rename(oldglobal, newglobal)  # SS intl model has different name than modem
770 5
    oldamericas = os.path.join(imgout, "NON-HLOS-americas.bin")
771 5
    newamericas = os.path.join(imgout, "NON-HLOS-dsamericas.bin")
772 5
    shutil.copy(oldamericas, newamericas)  # DS/SS americas model use same modem
773
774
775 5
def generate_tclloader_img(imgin, imgout, platform):
776
    """
777
    Generate partition images and radios.
778
779
    :param imgin: Directory containing files to copy.
780
    :type imgin: str
781
782
    :param imgout: Directory that files are to be copied to.
783
    :type imgout: str
784
785
    :param platform: Platform type (i.e. subdirectory of target/product).
786
    :type platform: str
787
    """
788 5
    imgs = ["recovery", "system", "userdata", "cache", "boot"]
789 5
    point_point_bulk(imgin, imgout, ["{0}.img".format(img) for img in imgs])
790 5
    oems, radios = generate_tclloader_deps(platform)
791 5
    oems = generate_tclloader_oemfilt(imgin, oems)
792 5
    point_point_bulk(imgin, imgout, ["{0}.img".format(oem) for oem in oems])
793 5
    radios = generate_tclloader_radfilt(imgin, radios)
794 5
    point_point_bulk(imgin, imgout, ["NON-HLOS-{0}.bin".format(rad) for rad in radios])
795 5
    others = ["adspso.bin", "emmc_appsboot.mbn", "sbl1_signed.mbn"]
796 5
    point_point_bulk(imgin, imgout, others)
797 5
    generate_tclloader_looseends(imgout, platform)
798
799
800 5
def generate_tclloader(localdir, dirname, platform, localtools=False, wipe=True):
801
    """
802
    Generate Android loader from extracted template files.
803
804
    :param localdir: Directory containing extracted template files.
805
    :type localdir: str
806
807
    :param dirname: Name for final directory and loader.
808
    :type dirname: str
809
810
    :param platform: Platform type (i.e. subdirectory of target/product).
811
    :type platform: str
812
813
    :param localtools: If host files will be copied from a template rather than a download. Default is False.
814
    :type localtools: bool
815
816
    :param wipe: If the final loader wipes userdata. Default is True.
817
    :type wipe: bool
818
    """
819 5
    if not os.path.exists(dirname):
820 5
        os.makedirs(dirname)
821 5
    hostdir = os.path.join(dirname, "host")
822 5
    os.makedirs(hostdir)
823 5
    imgdir = os.path.join(dirname, "img")
824 5
    os.makedirs(imgdir)
825 5
    generate_tclloader_script(dirname, bbconstants.FLASHBAT.location, bbconstants.FLASHSH.location, wipe)
826 5
    if localtools:
827 5
        hdir = os.path.join(localdir, "host")
828 5
        generate_tclloader_host(hdir, hostdir)
829
    else:
830 5
        platdir = "plattools"
831 5
        generate_google_host(platdir, hostdir)
832 5
    pdir = os.path.join(localdir, "target", "product", platform)
833 5
    generate_tclloader_img(pdir, imgdir, platform)
834 5
    sdir = os.path.join(pdir, "sig")
835 5
    generate_tclloader_sig(sdir, imgdir)
836 5
    generate_tclloader_carriers(sdir, imgdir)
837 5
    qdir = os.path.join(pdir, "qcbc")
838
    generate_tclloader_mbn(qdir, imgdir)
839