|
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
|
|
|
|
|
7
|
5 |
|
from bbarchivist import exceptions # exception handling |
|
8
|
5 |
|
from bbarchivist import jsonutils # json |
|
9
|
5 |
|
from bbarchivist import pseudocap # implement cap |
|
10
|
5 |
|
from bbarchivist import utilities # directory handler |
|
11
|
|
|
|
|
12
|
5 |
|
__author__ = "Thurask" |
|
13
|
5 |
|
__license__ = "WTFPL v2" |
|
14
|
5 |
|
__copyright__ = "2015-2018 Thurask" |
|
15
|
|
|
|
|
16
|
|
|
|
|
17
|
5 |
|
def read_files(localdir, core=False): |
|
18
|
|
|
""" |
|
19
|
|
|
Read list of signed files, return name assignments. |
|
20
|
|
|
|
|
21
|
|
|
:param localdir: Directory to use. |
|
22
|
|
|
:type localdir: str |
|
23
|
|
|
|
|
24
|
|
|
:param core: If we're using a core OS image. Default is false. |
|
25
|
|
|
:type core: bool |
|
26
|
|
|
""" |
|
27
|
5 |
|
oslist = read_os_files(localdir, core) |
|
28
|
|
|
# [8960, 8x30, 8974, ti] |
|
29
|
5 |
|
radlist = read_radio_files(localdir) |
|
30
|
|
|
# [ti, z10, z10_vzw, q10, z30, z3, 8974] |
|
31
|
5 |
|
pairdict = {} |
|
32
|
5 |
|
mapping = {0:3, 1:0, 2:0, 3:0, 4:0, 5:1, 6:2} |
|
33
|
5 |
|
for idx, rad in enumerate(radlist): |
|
34
|
5 |
|
pairdict[rad] = oslist[mapping[idx]] |
|
35
|
5 |
|
filtdict = {k: v for k, v in pairdict.items() if k} # pop None |
|
36
|
5 |
|
return filtdict |
|
37
|
|
|
|
|
38
|
|
|
|
|
39
|
5 |
|
def find_signed_file(match, localdir, title, silent=False): |
|
40
|
|
|
""" |
|
41
|
|
|
Use pattern matching to find a signed file in a directory. |
|
42
|
|
|
|
|
43
|
|
|
:param match: Match pattern to use. |
|
44
|
|
|
:type match: str |
|
45
|
|
|
|
|
46
|
|
|
:param localdir: Directory to use. |
|
47
|
|
|
:type localdir: str |
|
48
|
|
|
|
|
49
|
|
|
:param title: File type, in case it isn't found. |
|
50
|
|
|
:type title: str |
|
51
|
|
|
|
|
52
|
|
|
:param silent: Don't print that a file wasn't found. Default is False. |
|
53
|
|
|
:type silent: bool |
|
54
|
|
|
""" |
|
55
|
5 |
|
try: |
|
56
|
5 |
|
signedfile = glob.glob(os.path.join(localdir, match))[0] |
|
57
|
5 |
|
except IndexError: |
|
58
|
5 |
|
signedfile = None |
|
59
|
5 |
|
if not silent: |
|
60
|
5 |
|
print("No {0} found".format(title)) |
|
61
|
5 |
|
return signedfile |
|
62
|
|
|
|
|
63
|
|
|
|
|
64
|
5 |
|
def generate_os_fixes(core=False): |
|
65
|
|
|
""" |
|
66
|
|
|
Generate name regexes for OS signed files. |
|
67
|
|
|
|
|
68
|
|
|
:param core: If we're using a core OS image. Default is false. |
|
69
|
|
|
:type core: bool |
|
70
|
|
|
""" |
|
71
|
5 |
|
if core: |
|
72
|
5 |
|
fix8960 = "*qc8960.*_sfi.BB*.signed" |
|
73
|
5 |
|
fixomap_new = "*winchester.*_sfi.BB*.signed" |
|
74
|
5 |
|
fixomap_old = "*os.factory_sfi.BB*.signed" |
|
75
|
5 |
|
fix8930 = "*qc8x30.BB*.signed" |
|
76
|
5 |
|
fix8974_new = "*qc8974.BB*.signed" |
|
77
|
5 |
|
fix8974_old = "*qc8974.*_sfi.BB*.signed" |
|
78
|
|
|
else: |
|
79
|
5 |
|
fix8960 = "*qc8960.*_sfi.desktop.BB*.signed" |
|
80
|
5 |
|
fixomap_new = "*winchester.*_sfi.desktop.BB*.signed" |
|
81
|
5 |
|
fixomap_old = "*os.factory_sfi.desktop.BB*.signed" |
|
82
|
5 |
|
fix8930 = "*qc8x30.desktop.BB*.signed" |
|
83
|
5 |
|
fix8974_new = "*qc8974.desktop.BB*.signed" |
|
84
|
5 |
|
fix8974_old = "*qc8974.*_sfi.desktop.BB*.signed" |
|
85
|
5 |
|
return fix8960, fixomap_new, fixomap_old, fix8930, fix8974_new, fix8974_old |
|
86
|
|
|
|
|
87
|
|
|
|
|
88
|
5 |
|
def read_os_files(localdir, core=False): |
|
89
|
|
|
""" |
|
90
|
|
|
Read list of OS signed files, return name assignments. |
|
91
|
|
|
|
|
92
|
|
|
:param localdir: Directory to use. |
|
93
|
|
|
:type localdir: str |
|
94
|
|
|
|
|
95
|
|
|
:param core: If we're using a core OS image. Default is false. |
|
96
|
|
|
:type core: bool |
|
97
|
|
|
""" |
|
98
|
5 |
|
fix8960, fixomap_new, fixomap_old, fix8930, fix8974_new, fix8974_old = generate_os_fixes(core) |
|
99
|
|
|
# 8960 |
|
100
|
5 |
|
os_8960 = find_signed_file(fix8960, localdir, "8960 OS") |
|
101
|
|
|
# 8x30 (10.3.1 MR+) |
|
102
|
5 |
|
os_8x30 = find_signed_file(fix8930, localdir, "8x30 OS", True) |
|
103
|
5 |
|
if os_8x30 is None: |
|
104
|
5 |
|
os_8x30 = find_signed_file(fix8960, localdir, "8x30 OS") |
|
105
|
|
|
# 8974 |
|
106
|
5 |
|
os_8974 = find_signed_file(fix8974_new, localdir, "8974 OS", True) |
|
107
|
5 |
|
if os_8974 is None: |
|
108
|
5 |
|
os_8974 = find_signed_file(fix8974_old, localdir, "8974 OS") |
|
109
|
|
|
# OMAP |
|
110
|
5 |
|
os_ti = find_signed_file(fixomap_new, localdir, "OMAP OS", True) |
|
111
|
5 |
|
if os_ti is None: |
|
112
|
5 |
|
os_ti = find_signed_file(fixomap_old, localdir, "OMAP OS") |
|
113
|
5 |
|
return [os_8960, os_8x30, os_8974, os_ti] |
|
114
|
|
|
|
|
115
|
|
|
|
|
116
|
5 |
|
def read_radio_files(localdir): |
|
117
|
|
|
""" |
|
118
|
|
|
Read list of radio signed files, return name assignments. |
|
119
|
|
|
|
|
120
|
|
|
:param localdir: Directory to use. |
|
121
|
|
|
:type localdir: str |
|
122
|
|
|
""" |
|
123
|
|
|
# STL100-1 |
|
124
|
5 |
|
radio_ti = find_signed_file("*radio.m5730*.signed", localdir, "OMAP radio") |
|
125
|
|
|
# STL100-X |
|
126
|
5 |
|
radio_z10 = find_signed_file("*radio.qc8960.BB*.signed", localdir, "8960 radio") |
|
127
|
|
|
# STL100-4 |
|
128
|
5 |
|
radio_z10_vzw = find_signed_file("*radio.qc8960*omadm*.signed", localdir, "VZW 8960 radio") |
|
129
|
|
|
# Q10/Q5 |
|
130
|
5 |
|
radio_q10 = find_signed_file("*radio.qc8960*wtr.*signed", localdir, "Q10/Q5 radio") |
|
131
|
|
|
# Z30/Classic |
|
132
|
5 |
|
radio_z30 = find_signed_file("*radio.qc8960*wtr5*.signed", localdir, "Z30/Classic radio") |
|
133
|
|
|
# Z3 |
|
134
|
5 |
|
radio_z3 = find_signed_file("*radio.qc8930*wtr5*.signed", localdir, "Z3 radio") |
|
135
|
|
|
# Passport |
|
136
|
5 |
|
radio_8974 = find_signed_file("*radio.qc8974*wtr2*.signed", localdir, "Passport radio") |
|
137
|
5 |
|
return [radio_ti, radio_z10, radio_z10_vzw, radio_q10, radio_z30, radio_z3, radio_8974] |
|
138
|
|
|
|
|
139
|
|
|
|
|
140
|
5 |
|
def zeropad(splitver, idx, padlen): |
|
141
|
|
|
""" |
|
142
|
|
|
Zero-pad an element of an OS/radio version to a certain length. |
|
143
|
|
|
|
|
144
|
|
|
:param splitver: OS/radio version, but split into quarters. |
|
145
|
|
|
:type splitver: list(str) |
|
146
|
|
|
|
|
147
|
|
|
:param idx: Index of splitver which must be checked. |
|
148
|
|
|
:type idx: int |
|
149
|
|
|
|
|
150
|
|
|
:param padlen: Length to pad to. |
|
151
|
|
|
:type padlen: int |
|
152
|
|
|
""" |
|
153
|
5 |
|
if len(splitver[idx]) < padlen: |
|
154
|
5 |
|
splitver[idx] = splitver[idx].rjust(padlen, "0") |
|
155
|
5 |
|
return splitver |
|
156
|
|
|
|
|
157
|
|
|
|
|
158
|
5 |
|
def versionpad(splitver): |
|
159
|
|
|
""" |
|
160
|
|
|
Properly pad an OS/radio version. |
|
161
|
|
|
|
|
162
|
|
|
:param splitver: OS/radio version, but split into quarters. |
|
163
|
|
|
:type splitver: list(str) |
|
164
|
|
|
""" |
|
165
|
5 |
|
splitver = zeropad(splitver, 2, 2) |
|
166
|
5 |
|
splitver = zeropad(splitver, 3, 4) |
|
167
|
5 |
|
return splitver |
|
168
|
|
|
|
|
169
|
|
|
|
|
170
|
5 |
|
def pretty_formatter(osversion, radioversion): |
|
171
|
|
|
""" |
|
172
|
|
|
Format OS/radio versions to cope with systems with poor sorting. |
|
173
|
|
|
|
|
174
|
|
|
:param osversion: OS version, 10.x.y.zzzz. |
|
175
|
|
|
:type osversion: str |
|
176
|
|
|
|
|
177
|
|
|
:param radioversion: Radio version, 10.x.y.zzzz. |
|
178
|
|
|
:type radioversion: str |
|
179
|
|
|
""" |
|
180
|
|
|
# 10.x.y.zzz becomes 10.x.0y.0zzz |
|
181
|
5 |
|
splitos = osversion.split(".") |
|
182
|
5 |
|
splitos = versionpad(splitos) |
|
183
|
5 |
|
the_os = ".".join(splitos) |
|
184
|
5 |
|
splitrad = radioversion.split(".") |
|
185
|
5 |
|
splitrad = versionpad(splitrad) |
|
186
|
5 |
|
the_radio = ".".join(splitrad) |
|
187
|
5 |
|
return the_os, the_radio |
|
188
|
|
|
|
|
189
|
|
|
|
|
190
|
5 |
|
def format_suffix(altradio=None, radioversion=None, core=False): |
|
191
|
|
|
""" |
|
192
|
|
|
Formulate suffix for hybrid autoloaders. |
|
193
|
|
|
|
|
194
|
|
|
:param altradio: If a hybrid autoloader is being made. |
|
195
|
|
|
:type altradio: bool |
|
196
|
|
|
|
|
197
|
|
|
:param radioversion: The hybrid radio version, if applicable. |
|
198
|
|
|
:type radioversion: str |
|
199
|
|
|
|
|
200
|
|
|
:param core: If we're using a core OS image. Default is false. |
|
201
|
|
|
:type core: bool |
|
202
|
|
|
""" |
|
203
|
5 |
|
suffix = "_R{0}".format(radioversion) if altradio and radioversion else "" |
|
204
|
5 |
|
if core: |
|
205
|
5 |
|
suffix += "_CORE" |
|
206
|
5 |
|
return suffix |
|
207
|
|
|
|
|
208
|
|
|
|
|
209
|
5 |
|
def generate_loaders(osversion, radioversion, radios=True, localdir=None, altradio=False, core=False): |
|
210
|
|
|
""" |
|
211
|
|
|
Create and label autoloaders for :mod:`bbarchivist.scripts.archivist`. |
|
212
|
|
|
|
|
213
|
|
|
:param osversion: OS version, 10.x.y.zzzz. |
|
214
|
|
|
:type osversion: str |
|
215
|
|
|
|
|
216
|
|
|
:param radioversion: Radio version, 10.x.y.zzzz. |
|
217
|
|
|
:type radioversion: str |
|
218
|
|
|
|
|
219
|
|
|
:param radios: Whether to make radios or not. True by default. |
|
220
|
|
|
:type radios: bool |
|
221
|
|
|
|
|
222
|
|
|
:param localdir: Working path. Default is local dir. |
|
223
|
|
|
:type localdir: str |
|
224
|
|
|
|
|
225
|
|
|
:param altradio: If we're using an alternate radio. Default is false. |
|
226
|
|
|
:type altradio: bool |
|
227
|
|
|
|
|
228
|
|
|
:param core: If we're using a core OS image. Default is false. |
|
229
|
|
|
:type core: bool |
|
230
|
|
|
""" |
|
231
|
|
|
# default parsing |
|
232
|
5 |
|
localdir = utilities.dirhandler(localdir, os.getcwd()) |
|
233
|
5 |
|
print("GETTING FILENAMES...") |
|
234
|
5 |
|
filedict = read_files(localdir, core) |
|
235
|
5 |
|
osversion, radioversion = pretty_formatter(osversion, radioversion) |
|
236
|
5 |
|
suffix = format_suffix(altradio, radioversion, core) |
|
237
|
|
|
# Generate loaders |
|
238
|
5 |
|
print("CREATING LOADERS...") |
|
239
|
5 |
|
filtrad = [rad for rad in filedict.keys() if rad] # pop None |
|
240
|
5 |
|
generate_individual_loaders(filtrad, osversion, radioversion, suffix, filedict, radios, localdir) |
|
241
|
|
|
|
|
242
|
|
|
|
|
243
|
5 |
|
def generate_individual_loaders(filtrad, osversion, radioversion, suffix, filedict, radios, localdir): |
|
244
|
|
|
""" |
|
245
|
|
|
Generate individual loaders when generating several at once. |
|
246
|
|
|
|
|
247
|
|
|
:param filtrad: List of radio files, if they exist. |
|
248
|
|
|
:type filtrad: list(str) |
|
249
|
|
|
|
|
250
|
|
|
:param osversion: OS version, 10.x.y.zzzz. |
|
251
|
|
|
:type osversion: str |
|
252
|
|
|
|
|
253
|
|
|
:param radioversion: Radio version, 10.x.y.zzzz. |
|
254
|
|
|
:type radioversion: str |
|
255
|
|
|
|
|
256
|
|
|
:param suffix: Alternate radio, or blank. |
|
257
|
|
|
:type suffix: str |
|
258
|
|
|
|
|
259
|
|
|
:param filedict: Dictionary of radio:OS pairs. |
|
260
|
|
|
:type filedict: dict(str: str) |
|
261
|
|
|
|
|
262
|
|
|
:param radios: Whether to make radios or not. True by default. |
|
263
|
|
|
:type radios: bool |
|
264
|
|
|
|
|
265
|
|
|
:param localdir: Working path. Default is local dir. |
|
266
|
|
|
:type localdir: str |
|
267
|
|
|
""" |
|
268
|
5 |
|
for radval in filtrad: |
|
269
|
5 |
|
device = generate_device(radval) |
|
270
|
5 |
|
osname = generate_filename(device, osversion, suffix) |
|
271
|
5 |
|
osfile = filedict[radval] |
|
272
|
5 |
|
if osfile is not None: |
|
273
|
5 |
|
wrap_pseudocap(osname, localdir, osfile, radval) |
|
274
|
5 |
|
if radios: |
|
275
|
5 |
|
radname = generate_filename(device, radioversion, "") |
|
276
|
5 |
|
wrap_pseudocap(radname, localdir, radval) |
|
277
|
|
|
|
|
278
|
|
|
|
|
279
|
|
|
|
|
280
|
5 |
|
def wrap_pseudocap(filename, folder, first, second=None): |
|
281
|
|
|
""" |
|
282
|
|
|
A filtered, excepting wrapper for pseudocap. |
|
283
|
|
|
|
|
284
|
|
|
:param filename: The title of the new loader. |
|
285
|
|
|
:type filename: str |
|
286
|
|
|
|
|
287
|
|
|
:param folder: The folder to create the loader in. |
|
288
|
|
|
:type folder: str |
|
289
|
|
|
|
|
290
|
|
|
:param first: The first signed file, required. |
|
291
|
|
|
:type first: str |
|
292
|
|
|
|
|
293
|
|
|
:param second: The second signed file, optional. |
|
294
|
|
|
:type second: str |
|
295
|
|
|
""" |
|
296
|
5 |
|
if first is None: |
|
297
|
5 |
|
print("No OS!") |
|
298
|
5 |
|
raise SystemError |
|
299
|
5 |
|
try: |
|
300
|
5 |
|
pseudocap.make_autoloader(filename, [first, second], folder=folder) |
|
301
|
5 |
|
except (OSError, IndexError, SystemError) as exc: |
|
302
|
5 |
|
msg = "Could not create {0}".format(filename) |
|
303
|
5 |
|
exceptions.handle_exception(exc, msg, None) |
|
304
|
|
|
|
|
305
|
|
|
|
|
306
|
5 |
|
def generate_skeletons(): |
|
307
|
|
|
""" |
|
308
|
|
|
Read JSON to get a dict of all filename components. |
|
309
|
|
|
""" |
|
310
|
5 |
|
namelist = {0: None, 1: None, 2: None, 3: None, 4: None, 5: None, 6: None} |
|
311
|
5 |
|
data = jsonutils.load_json('integermap') |
|
312
|
5 |
|
for key in data: |
|
313
|
5 |
|
if key['id'] in namelist: |
|
314
|
5 |
|
namelist[key['id']] = (key['parts']) |
|
315
|
5 |
|
namelist[key['id']].append(".exe") |
|
316
|
5 |
|
return namelist |
|
317
|
|
|
|
|
318
|
|
|
|
|
319
|
5 |
|
def generate_device(radio): |
|
320
|
|
|
""" |
|
321
|
|
|
Read JSON to get the device integer ID from device radio. |
|
322
|
|
|
|
|
323
|
|
|
:param radio: The radio filename to look up. |
|
324
|
|
|
:type radio: str |
|
325
|
|
|
""" |
|
326
|
5 |
|
data = jsonutils.load_json('integermap') |
|
327
|
5 |
|
for key in data: |
|
328
|
5 |
|
if key['radtype'] in radio: |
|
329
|
5 |
|
idx = int(key['id']) |
|
330
|
5 |
|
break |
|
331
|
5 |
|
return idx |
|
332
|
|
|
|
|
333
|
|
|
|
|
334
|
5 |
|
def generate_filename(device, version, suffix=None): |
|
335
|
|
|
""" |
|
336
|
|
|
Use skeleton dict to create loader filenames. |
|
337
|
|
|
|
|
338
|
|
|
:param device: Device to use. |
|
339
|
|
|
:type device: int |
|
340
|
|
|
|
|
341
|
|
|
:param version: OS or radio version. |
|
342
|
|
|
:type version: str |
|
343
|
|
|
|
|
344
|
|
|
:param suffix: Alternate radio, or blank. |
|
345
|
|
|
:type suffix: str |
|
346
|
|
|
""" |
|
347
|
5 |
|
thed = generate_skeletons() |
|
348
|
5 |
|
if device < 0: |
|
349
|
5 |
|
return None |
|
350
|
5 |
|
dev = thed[device] |
|
351
|
5 |
|
if suffix is None: |
|
352
|
5 |
|
suffix = "" |
|
353
|
5 |
|
return "{0}{1}{2}{3}{4}".format(dev[0], version, suffix, dev[1], dev[2]) |
|
354
|
|
|
|
|
355
|
|
|
|
|
356
|
5 |
|
def generate_lazy_loader(osversion, device, localdir=None, altradio=None, core=False): |
|
357
|
|
|
""" |
|
358
|
|
|
Create and label autoloaders for :mod:`bbarchivist.scripts.lazyloader`. |
|
359
|
|
|
:func:`generate_loaders`, but for making one OS/radio loader. |
|
360
|
|
|
|
|
361
|
|
|
:param osversion: OS version, 10.x.y.zzzz. |
|
362
|
|
|
:type osversion: str |
|
363
|
|
|
|
|
364
|
|
|
:param device: Selected device, from |
|
365
|
|
|
:type device: int |
|
366
|
|
|
|
|
367
|
|
|
:param localdir: Working path. Default is local dir. |
|
368
|
|
|
:type localdir: str |
|
369
|
|
|
|
|
370
|
|
|
:param altradio: The alternate radio in use, if there is one. |
|
371
|
|
|
:type altradio: str |
|
372
|
|
|
|
|
373
|
|
|
:param core: If we're using a core OS image. Default is false. |
|
374
|
|
|
:type core: bool |
|
375
|
|
|
""" |
|
376
|
|
|
# default parsing |
|
377
|
5 |
|
localdir = utilities.dirhandler(localdir, os.getcwd()) |
|
378
|
5 |
|
print("CREATING LOADER...") |
|
379
|
5 |
|
suffix = format_suffix(bool(altradio), altradio, core) |
|
380
|
5 |
|
osfile = None |
|
381
|
5 |
|
absoglob = "{0}{1}".format(localdir, os.sep) |
|
382
|
5 |
|
try: |
|
383
|
5 |
|
osfile = str(glob.glob("{0}*_sfi*.signed".format(absoglob))[0]) |
|
384
|
5 |
|
except IndexError: |
|
385
|
5 |
|
print("No OS found") |
|
386
|
|
|
else: |
|
387
|
5 |
|
generate_lazy_set(osversion, device, osfile, suffix, absoglob, localdir) |
|
388
|
|
|
|
|
389
|
|
|
|
|
390
|
5 |
|
def generate_lazy_set(osversion, device, osfile, suffix, absoglob, localdir=None): |
|
391
|
|
|
""" |
|
392
|
|
|
Get radio file and then generate autoloader. |
|
393
|
|
|
|
|
394
|
|
|
:param osversion: OS version, 10.x.y.zzzz. |
|
395
|
|
|
:type osversion: str |
|
396
|
|
|
|
|
397
|
|
|
:param device: Selected device, from |
|
398
|
|
|
:type device: int |
|
399
|
|
|
|
|
400
|
|
|
:param osfile: OS signed filename. |
|
401
|
|
|
:type osfile: str |
|
402
|
|
|
|
|
403
|
|
|
:param suffix: Loader name suffix. |
|
404
|
|
|
:type suffix: str |
|
405
|
|
|
|
|
406
|
|
|
:param absoglob: Local path + path separator. |
|
407
|
|
|
:type absoglob: str |
|
408
|
|
|
|
|
409
|
|
|
:param localdir: Working path. Default is local dir. |
|
410
|
|
|
:type localdir: str |
|
411
|
|
|
""" |
|
412
|
5 |
|
radiofile = None |
|
413
|
5 |
|
try: |
|
414
|
5 |
|
sset = set(glob.glob("{0}*.signed".format(absoglob))) |
|
415
|
5 |
|
rset = sset - set(glob.glob("{0}*_sfi*.signed".format(absoglob))) |
|
416
|
5 |
|
radiofile = str(list(rset)[0]) |
|
417
|
5 |
|
except IndexError: |
|
418
|
5 |
|
print("No radio found") |
|
419
|
|
|
else: |
|
420
|
5 |
|
loadername = generate_lazy_filename(osversion, suffix, device) |
|
421
|
5 |
|
wrap_pseudocap(loadername, localdir, osfile, radiofile) |
|
422
|
|
|
|
|
423
|
|
|
|
|
424
|
5 |
|
def generate_lazy_filename(osversion, suffix, device): |
|
425
|
|
|
""" |
|
426
|
|
|
Read JSON to formulate a single filename. |
|
427
|
|
|
|
|
428
|
|
|
:param osversion: OS version. |
|
429
|
|
|
:type osversion: str |
|
430
|
|
|
|
|
431
|
|
|
:param suffix: Alternate radio, or just blank. |
|
432
|
|
|
:type suffix: str |
|
433
|
|
|
|
|
434
|
|
|
:param device: Device to use. |
|
435
|
|
|
:type device: int |
|
436
|
|
|
""" |
|
437
|
5 |
|
data = jsonutils.load_json('integermap') |
|
438
|
5 |
|
for key in data: |
|
439
|
5 |
|
if key['id'] == device: |
|
440
|
5 |
|
fname = key['parts'] |
|
441
|
5 |
|
break |
|
442
|
|
|
return "{0}{1}{2}{3}.exe".format(fname[0], osversion, suffix, fname[1]) |
|
443
|
|
|
|