Passed
Push — master ( 274f62...7831d2 )
by John
06:44
created

bbarchivist.loadergentcl.generate_tclloader_img()   B

Complexity

Conditions 4

Size

Total Lines 23
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 11
CRAP Score 4

Importance

Changes 0
Metric Value
cc 4
eloc 11
nop 3
dl 0
loc 23
ccs 11
cts 11
cp 1
crap 4
rs 8.7972
c 0
b 0
f 0
1
#!/usr/bin/env python3
2 5
"""This module is used for creation of TCL autoloaders."""
3
4 5
import os  # path work
5 5
import shutil  # file copying
6
7 5
from bbarchivist import bbconstants  # versions/constants
8
9 5
__author__ = "Thurask"
10 5
__license__ = "WTFPL v2"
11 5
__copyright__ = "2018 Thurask"
12
13
14 5
def point_point_copy(inpath, outpath, filename):
15
    """
16
    Copy a file from one absolute path to another.
17
18
    :param inpath: Input path.
19
    :type inpath: str
20
21
    :param outpath: Output path.
22
    :type outpath: str
23
24
    :param filename: Filename.
25
    :type filename: str
26
    """
27 5
    shutil.copy(os.path.join(inpath, filename), os.path.join(outpath, filename))
28
29
30 5
def point_point_bulk(inpath, outpath, files):
31
    """
32
    Copy a list of files from one absolute path to another.
33
34
    :param inpath: Input path.
35
    :type inpath: str
36
37
    :param outpath: Output path.
38
    :type outpath: str
39
40
    :param files: List of filenames.
41
    :type files: list(str)
42
    """
43 5
    for file in files:
44 5
        point_point_copy(inpath, outpath, file)
45
46
47 5
def generate_tclloader_script(dirname, batchfile, shfile, wipe=True):
48
    """
49
    Copy script files from site-packages to loader directory.
50
51
    :param dirname: Name for final directory and loader.
52
    :type dirname: str
53
54
    :param batchfile: Path to flashall.bat.
55
    :type batchfile: str
56
57
    :param shfile: Path to flashall.sh.
58
    :type shfile: str
59
60
    :param wipe: If the final loader wipes userdata. Default is True.
61
    :type wipe: bool
62
    """
63 5
    shutil.copy(batchfile, os.path.join(dirname, "flashall.bat"))
64 5
    shutil.copy(shfile, os.path.join(dirname, "flashall.sh"))
65 5
    if not wipe:
66 5
        tclloader_nowipe(os.path.join(dirname, "flashall.bat"))
67 5
        tclloader_nowipe(os.path.join(dirname, "flashall.sh"))
68
69
70 5
def tclloader_nowipe(infile):
71
    """
72
    Modify a script file to strike references to wiping the phone.
73
74
    :param infile: Path to script file to modify.
75
    :type infile: str
76
    """
77 5
    filterout = ("oem securewipe", "flash userdata")
78 5
    with open(infile, "r+", newline="") as afile:
79 5
        content = afile.read()
80 5
        afile.seek(0)
81 5
        for line in content.split("\n"):
82 5
            if not any(part in line for part in filterout):
83 5
                afile.write(line + "\n")
84 5
        afile.truncate()
85
86
87 5
def generate_google_host(hostin, hostout):
88
    """
89
    Generate host directory from Google platform tools, i.e. fastboot.
90
91
    :param hostin: Directory containing files to copy.
92
    :type hostin: str
93
94
    :param hostout: Directory that files are to be copied to.
95
    :type hostout: str
96
    """
97 5
    platforms = ["linux", "windows", "darwin"]
98 5
    inouts = {os.path.join(hostin, plat, "platform-tools"): os.path.join(hostout, "{0}-x86".format(plat), "bin") for plat in platforms}
99 5
    for infile, outfile in inouts.items():
100 5
        shutil.copytree(infile, outfile)
101
102
103 5
def generate_tclloader_host(hostin, hostout):
104
    """
105
    Generate host directory from autoloader template, i.e. fastboot.
106
107
    :param hostin: Directory containing files to copy.
108
    :type hostin: str
109
110
    :param hostout: Directory that files are to be copied to.
111
    :type hostout: str
112
    """
113 5
    os.makedirs(os.path.join(hostout, "darwin-x86", "bin"))
114 5
    os.makedirs(os.path.join(hostout, "linux-x86", "bin"))
115 5
    os.makedirs(os.path.join(hostout, "windows-x86", "bin"))
116 5
    macfile = os.path.join("darwin-x86", "bin", "fastboot")
117 5
    linfile = os.path.join("linux-x86", "bin", "fastboot")
118 5
    winx = ["AdbWinApi.dll", "AdbWinUsbApi.dll", "fastboot.exe"]
119 5
    winfiles = [os.path.join("windows-x86", "bin", x) for x in winx]
120 5
    winfiles.extend([linfile, macfile])
121 5
    point_point_bulk(hostin, hostout, winfiles)
122
123
124 5
def generate_tclloader_sig(sigin, sigout):
125
    """
126
    Generate common signature files.
127
128
    :param sigin: Directory containing files to copy.
129
    :type sigin: str
130
131
    :param sigout: Directory that files are to be copied to.
132
    :type sigout: str
133
    """
134 5
    for entry in ["boot", "recovery"]:
135 5
        shutil.copy(os.path.join(sigin, "{0}.img.production.sig".format(entry)), os.path.join(sigout, "{0}.img.sig".format(entry)))
136
137
138 5
def generate_tclloader_csig(sigin, sigout, carrier):
139
    """
140
    Generate carrier variant signature files.
141
142
    :param sigin: Directory containing files to copy.
143
    :type sigin: str
144
145
    :param sigout: Directory that files are to be copied to.
146
    :type sigout: str
147
148
    :param carrier: Carrier to check: att, sprint, china, vzw
149
    :type carrier: str
150
    """
151 5
    for entry in ["boot", "recovery"]:
152 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)))
153
154
155 5
def generate_tclloader_carriers(sigin, sigout):
156
    """
157
    Collect carrier variant signature files.
158
159
    :param sigin: Directory containing files to copy.
160
    :type sigin: str
161
162
    :param sigout: Directory that files are to be copied to.
163
    :type sigout: str
164
    """
165 5
    prods = set(x.split("-")[-1].split(".")[0] for x in os.listdir(sigin) if "production-" in x) - {"boot", "recovery"}
166 5
    if prods:
167 5
        generate_tclloader_carriter(sigin, sigout, prods)
168
169
170 5
def generate_tclloader_carriter(sigin, sigout, prods):
171
    """
172
    Iterate carrier variant signature files.
173
174
    :param sigin: Directory containing files to copy.
175
    :type sigin: str
176
177
    :param sigout: Directory that files are to be copied to.
178
    :type sigout: str
179
180
    :param prods: Set of carriers.
181
    :type prods: set(str)
182
    """
183 5
    for carr in prods:
184 5
        generate_tclloader_csig(sigin, sigout, carr)
185
186
187 5
def generate_tclloader_mbn(mdnin, mdnout):
188
    """
189
    Generate mbn files.
190
191
    :param mdnin: Directory containing files to copy.
192
    :type mdnin: str
193
194
    :param mdnout: Directory that files are to be copied to.
195
    :type mdnout: str
196
    """
197 5
    files = ["devcfg.mbn", "devcfg_cn.mbn", "rpm.mbn", "tz.mbn"]
198 5
    point_point_bulk(mdnin, mdnout, files)
199
200
201 5
def generate_tclloader_omniset(omnin, omnilist, prefix, suffix, filt):
202
    """
203
    Generic function to generate sets.
204
205
    :param omnin: Directory containing files to copy.
206
    :type omnin: str
207
208
    :param omnilist: List of variants.
209
    :type omnilist: list(str)
210
211
    :param prefix: Prefix, before items in list.
212
    :type prefix: str
213
214
    :param suffix: Suffix, after items in list.
215
    :type suffix: str
216
217
    :param filt: Filter, required to pick file out of directory listing.
218
    :type filt: str
219
    """
220 5
    omfiles = set(os.path.join(omnin, "{1}{0}{2}".format(omni, prefix, suffix)) for omni in omnilist)
221 5
    infiles = set(os.path.join(omnin, filex) for filex in os.listdir(omnin) if filt in filex)
222 5
    return omfiles, infiles
223
224
225 5
def generate_tclloader_oemset(oemin, oems):
226
    """
227
    Generate sets for OEM variants.
228
229
    :param oemin: Directory containing files to copy.
230
    :type oemin: str
231
232
    :param oems: List of OEM variants.
233
    :type oems: list(str)
234
    """
235 5
    ofiles, infiles = generate_tclloader_omniset(oemin, oems, "", ".img", "oem_")
236 5
    return ofiles, infiles
237
238
239 5
def generate_tclloader_oemfilt(oemin, oems):
240
    """
241
    Filter non-existent OEM variants.
242
243
    :param oemin: Directory containing files to copy.
244
    :type oemin: str
245
246
    :param oems: List of OEM variants.
247
    :type oems: list(str)
248
    """
249 5
    ofiles, infiles = generate_tclloader_oemset(oemin, oems)
250 5
    coll = [os.path.basename(oemf).replace(".img", "") for oemf in ofiles - infiles]
251 5
    oems = [oemp for oemp in oems if oemp not in coll]
252 5
    return oems
253
254
255 5
def generate_tclloader_radset(radin, rads):
256
    """
257
    Generate sets for radio variants.
258
259
    :param radin: Directory containing files to copy.
260
    :type radin: str
261
262
    :param rads: List of radio variants.
263
    :type rads: list(str)
264
    """
265 5
    rfiles, infiles = generate_tclloader_omniset(radin, rads, "NON-HLOS-", ".bin", "NON-HLOS-")
266 5
    return rfiles, infiles
267
268
269 5
def generate_tclloader_radfilt(radin, rads):
270
    """
271
    Filter non-existent radio variants.
272
273
    :param radin: Directory containing files to copy.
274
    :type radin: str
275
276
    :param rads: List of radio variants.
277
    :type rads: list(str)
278
    """
279 5
    rfiles, infiles = generate_tclloader_radset(radin, rads)
280 5
    coll = [os.path.basename(radf).replace(".bin", "").replace("NON-HLOS-", "") for radf in rfiles - infiles]
281 5
    rads = [radp for radp in rads if radp not in coll]
282 5
    return rads
283
284
285 5
def generate_tclloader_deps(platform):
286
    """
287
    Generate platform-specific file names.
288
289
    :param platform: Platform type (i.e. subdirectory of target/product).
290
    :type platform: str
291
    """
292 5
    if platform == "bbry_qc8953":  # KEYone
293 5
        oems = ["oem_att", "oem_china", "oem_common", "oem_sprint", "oem_vzw", "oem_indonesia", "oem_russia"]
294 5
        radios = ["china", "dschina", "emea", "global", "india", "japan", "usa"]
295 5
    elif platform == "bbry_qc8953krypton":  # Motion
296 5
        oems = ["oem_att", "oem_common", "oem_sprint", "oem_russia"]
297 5
        radios = ["americas", "cdma", "dscn", "dsglobal", "ssglobal"]
298 5
    elif platform == "bbry_sdm660":  # KEY2
299 5
        oems = ["oem_att", "oem_china", "oem_common", "oem_india", "oem_indonesia", "oem_sprint", "oem_russia"]
300 5
        radios = ["americas", "cn", "dsglobal", "dsjapan", "global", "japan"]
301 5
    return oems, radios
302
303
304 5
def generate_tclloader_looseends(imgout, platform):
305
    """
306
    Handle files that need to be handled.
307
308
    :param imgout: Directory that files are to be copied to.
309
    :type imgout: str
310
311
    :param platform: Platform type (i.e. subdirectory of target/product).
312
    :type platform: str
313
    """
314 5
    if platform == "bbry_qc8953":  # KEYone
315 5
        pass  # no special exceptions
316 5
    elif platform == "bbry_qc8953krypton":  # Motion
317 5
        looseends_krypton(imgout)
318 5
    elif platform == "bbry_sdm660":  # KEY2
319 5
        pass  # TODO: KEY2 autoloader
0 ignored issues
show
Coding Style introduced by
TODO and FIXME comments should generally be avoided.
Loading history...
320
321
322 5
def looseends_krypton(imgout):
323
    """
324
    Handle files that need to be handled, for the Motion platform.
325
326
    :param imgout: Directory that files are to be copied to.
327
    :type imgout: str
328
    """
329 5
    oldglobal = os.path.join(imgout, "NON-HLOS-ssglobal.bin")
330 5
    newglobal = os.path.join(imgout, "NON-HLOS-global.bin")
331 5
    os.rename(oldglobal, newglobal)  # SS intl model has different name than modem
332 5
    oldamericas = os.path.join(imgout, "NON-HLOS-americas.bin")
333 5
    newamericas = os.path.join(imgout, "NON-HLOS-dsamericas.bin")
334 5
    shutil.copy(oldamericas, newamericas)  # DS/SS americas model use same modem
335
336
337 5
def generate_tclloader_img(imgin, imgout, platform):
338
    """
339
    Generate partition images and radios.
340
341
    :param imgin: Directory containing files to copy.
342
    :type imgin: str
343
344
    :param imgout: Directory that files are to be copied to.
345
    :type imgout: str
346
347
    :param platform: Platform type (i.e. subdirectory of target/product).
348
    :type platform: str
349
    """
350 5
    imgs = ["recovery", "system", "userdata", "cache", "boot"]
351 5
    point_point_bulk(imgin, imgout, ["{0}.img".format(img) for img in imgs])
352 5
    oems, radios = generate_tclloader_deps(platform)
353 5
    oems = generate_tclloader_oemfilt(imgin, oems)
354 5
    point_point_bulk(imgin, imgout, ["{0}.img".format(oem) for oem in oems])
355 5
    radios = generate_tclloader_radfilt(imgin, radios)
356 5
    point_point_bulk(imgin, imgout, ["NON-HLOS-{0}.bin".format(rad) for rad in radios])
357 5
    others = ["adspso.bin", "emmc_appsboot.mbn", "sbl1_signed.mbn"]
358 5
    point_point_bulk(imgin, imgout, others)
359 5
    generate_tclloader_looseends(imgout, platform)
360
361
362 5
def generate_tclloader(localdir, dirname, platform, localtools=False, wipe=True):
363
    """
364
    Generate Android loader from extracted template files.
365
366
    :param localdir: Directory containing extracted template files.
367
    :type localdir: str
368
369
    :param dirname: Name for final directory and loader.
370
    :type dirname: str
371
372
    :param platform: Platform type (i.e. subdirectory of target/product).
373
    :type platform: str
374
375
    :param localtools: If host files will be copied from a template rather than a download. Default is False.
376
    :type localtools: bool
377
378
    :param wipe: If the final loader wipes userdata. Default is True.
379
    :type wipe: bool
380
    """
381 5
    if not os.path.exists(dirname):
382 5
        os.makedirs(dirname)
383 5
    hostdir = os.path.join(dirname, "host")
384 5
    os.makedirs(hostdir)
385 5
    imgdir = os.path.join(dirname, "img")
386 5
    os.makedirs(imgdir)
387 5
    generate_tclloader_script(dirname, bbconstants.FLASHBAT.location, bbconstants.FLASHSH.location, wipe)
388 5
    if localtools:
389 5
        hdir = os.path.join(localdir, "host")
390 5
        generate_tclloader_host(hdir, hostdir)
391
    else:
392 5
        platdir = "plattools"
393 5
        generate_google_host(platdir, hostdir)
394 5
    pdir = os.path.join(localdir, "target", "product", platform)
395 5
    generate_tclloader_img(pdir, imgdir, platform)
396 5
    sdir = os.path.join(pdir, "sig")
397 5
    generate_tclloader_sig(sdir, imgdir)
398 5
    generate_tclloader_carriers(sdir, imgdir)
399 5
    qdir = os.path.join(pdir, "qcbc")
400
    generate_tclloader_mbn(qdir, imgdir)
401