Source code for bbarchivist.scripts.lazyloader

#!/usr/bin/env python3
"""Create one autoloader for personal use."""

import os  # path work
import subprocess  # autoloader running
import sys  # load arguments

import requests  # session
from bbarchivist import argutils  # arguments
from bbarchivist import barutils  # file operations
from bbarchivist import bbconstants  # constants/versions
from bbarchivist import decorators  # timer
from bbarchivist import loadergen  # cap wrapper
from bbarchivist import networkutils  # download/lookup
from bbarchivist import scriptutils  # script stuff
from bbarchivist import utilities  # input validation

__author__ = "Thurask"
__license__ = "WTFPL v2"
__copyright__ = "2015-2018 Thurask"


@decorators.timer
def grab_args():
    """
    Parse arguments from argparse/questionnaire.

    Invoke :func:`lazyloader.lazyloader_main` with arguments.
    """
    if len(sys.argv) > 1:
        argflags = ("folder", "osr")
        parser = argutils.default_parser("bb-lazyloader", "Create one autoloader", argflags)
        devgroup = parser.add_argument_group("devices", "Device to load (one required)")
        compgroup = devgroup.add_mutually_exclusive_group()
        compgroup.add_argument(
            "--stl100-1",
            dest="device",
            help="STL100-1",
            action="store_const",
            const=0)
        compgroup.add_argument(
            "--stl100-x",
            dest="device",
            help="STL100-2/3, P'9982",
            action="store_const",
            const=1)
        compgroup.add_argument(
            "--stl100-4",
            dest="device",
            help="STL100-4",
            action="store_const",
            const=2)
        compgroup.add_argument(
            "--q10",
            dest="device",
            help="Q10, Q5, P'9983",
            action="store_const",
            const=3)
        compgroup.add_argument(
            "--z30",
            dest="device",
            help="Z30, Classic, Leap",
            action="store_const",
            const=4)
        compgroup.add_argument(
            "--z3",
            dest="device",
            help="Z3",
            action="store_const",
            const=5)
        compgroup.add_argument(
            "--passport",
            dest="device",
            help="Passport",
            action="store_const",
            const=6)
        parser.add_argument(
            "--run-loader",
            dest="autoloader",
            help="Run autoloader after creation",
            action="store_true",
            default=False)
        parser.add_argument(
            "-n",
            "--no-download",
            dest="download",
            help="Don't download files",
            action="store_false",
            default=True)
        parser.add_argument(
            "-r",
            "--radiosw",
            dest="altsw",
            metavar="SW",
            help="Radio software version; use without software to guess",
            nargs="?",
            const="checkme",
            default=None)
        parser.add_argument(
            "-c",
            "--core",
            dest="core",
            help="Make core/radio loader",
            default=False,
            action="store_true")
        parser.set_defaults(device=None)
        args = parser.parse_args(sys.argv[1:])
        execute_args(args)
    else:
        questionnaire()


[docs]def execute_args(args): """ Get args and decide what to do with them. :param args: Arguments. :type args: argparse.Namespace """ args.folder = scriptutils.generate_workfolder(args.folder) if not utilities.is_windows(): args.autoloader = False argutils.arg_verify_none(args.os, "No OS specified!") argutils.arg_verify_none(args.device, "No device specified!") lazyloader_main(args.device, args.os, args.radio, args.swrelease, args.folder, args.autoloader, args.download, args.altsw, args.core)
[docs]def questionnaire_getversions(): """ Get OS, radio, and software versions. """ while True: osversion = input("OS VERSION (REQUIRED): ") if osversion: break radioversion = input("RADIO VERSION (PRESS ENTER TO GUESS): ") softwareversion = input("OS SOFTWARE RELEASE (PRESS ENTER TO GUESS): ") return osversion, radioversion, softwareversion
[docs]def questionnaire_check(softwareversion, radioversion): """ Check software and radio versions. :param softwareversion: Software version, 10.x.y.zzzz. :type softwareversion: str :param radioversion: Radio version, 10.x.y.zzzz. :type radioversion: str """ if not softwareversion: softwareversion = None if not radioversion: radioversion = None altsw = None else: radioversion, altsw = questionnaire_radiocheck(radioversion) return softwareversion, radioversion, altsw
[docs]def questionnaire_radiocheck(radioversion, altsw=None): """ Get radio information in working order. :param radioversion: Radio version, 10.x.y.zzzz. :type radioversion: str :param altsw: Radio software release, if not the same as OS. :type altsw: str """ altcheck = utilities.i2b("USING ALTERNATE RADIO (Y/N)?: ") if altcheck: altsw = input("RADIO SOFTWARE RELEASE (PRESS ENTER TO GUESS): ") if not altsw: altsw = "checkme" return radioversion, altsw
[docs]def questionnaire_devices(): """ Ask about which device this script is to be run for. """ print("DEVICES:") devlist = ["0=STL100-1", "1=STL100-2/3/P9982", "2=STL100-4", "3=Q10/Q5/P9983", "4=Z30/CLASSIC/LEAP", "5=Z3", "6=PASSPORT"] utilities.lprint(devlist) while True: device = int(input("SELECTED DEVICE: ")) if not 0 <= device <= len(devlist) - 1: continue else: break return device
[docs]def questionnaire_loader(): """ Ask about whether to run an autoloader. """ if utilities.is_windows(): autoloader = utilities.i2b("RUN AUTOLOADER - WILL WIPE YOUR DEVICE! (Y/N)?: ") else: autoloader = False return autoloader
[docs]def questionnaire(): """ Questions to ask if no arguments given. """ localdir = os.getcwd() osver, radiover, swver = questionnaire_getversions() swver, radiover, altsw = questionnaire_check(swver, radiover) device = questionnaire_devices() autoloader = questionnaire_loader() print(" ") lazyloader_main(device, osver, radiover, swver, localdir, autoloader, True, altsw, False)
[docs]def lazyloader_main(device, osversion, radioversion=None, softwareversion=None, localdir=None, autoloader=False, download=True, altsw=None, core=False): """ Wrap the tools necessary to make one autoloader. :param device: Device family to create loader for. :type device: int :param osversion: OS version, 10.x.y.zzzz. :type osversion: str :param radioversion: Radio version, 10.x.y.zzzz. :type radioversion: str :param softwareversion: Software version, 10.x.y.zzzz. :type softwareversion: str :param localdir: Working path. Default is local dir. :type localdir: str :param autoloader: Whether to run loader. Default is false. Windows-only. :type autoloader: bool :param download: Whether to download files. Default is true. :type download: bool :param altsw: Radio software release, if not the same as OS. :type altsw: str :param core: Whether to create a core/radio loader. Default is false. :type core: bool """ radioversion = scriptutils.return_radio_version(osversion, radioversion) softwareversion, swc = scriptutils.return_sw_checked(softwareversion, osversion) if altsw == "checkme": altsw, altchecked = scriptutils.return_radio_sw_checked(altsw, radioversion) argutils.standard_preamble("lazyloader", osversion, softwareversion, radioversion, altsw) print("DEVICE: {0}".format(bbconstants.DEVICES[device])) # Make dirs bd_o, bd_r, ld_o, ld_r, zd_o, zd_r = barutils.make_dirs(localdir, osversion, radioversion) osurl = radiourl = None # Create download URLs baseurl = utilities.create_base_url(softwareversion) if altsw: alturl = utilities.create_base_url(altsw) osurl, radiourl = utilities.generate_lazy_urls(softwareversion, osversion, radioversion, device) if altsw: radiourl = radiourl.replace(baseurl, alturl) if core: osurl = osurl.replace(".desktop", "") #Terminate if device is STL100-1 and OS >= 10.3.3 splitos = [int(i) for i in osversion.split(".")] if device == 0 and utilities.newer_103(splitos, 3): print("STL100-1 UNSUPPORTED IN 10.3.3+!") print("\nEXITING...") raise SystemExit if download: # Check availability of software releases scriptutils.check_sw(baseurl, softwareversion, swc) if altsw: scriptutils.check_radio_sw(alturl, altsw, altchecked) # Check availability of OS, radio scriptutils.check_os_single(osurl, osversion, device) radiourl, radioversion = scriptutils.check_radio_single(radiourl, radioversion) dllist = [osurl, radiourl] # Check cached osfile = os.path.join(localdir, bd_o, os.path.basename(osurl)) radfile = os.path.join(localdir, bd_r, os.path.basename(radiourl)) if download: # Download files print("DOWNLOADING...") sess = requests.Session() networkutils.download_bootstrap(dllist, outdir=localdir, workers=2, session=sess) elif all(os.path.exists(x) for x in [osfile, radfile]): # Already downloaded in previous session print("USING CACHED OS/RADIO...") barutils.replace_bar_pair(localdir, osfile, radfile) # Test bar files scriptutils.test_bar_files(localdir, dllist) # Extract bar files print("EXTRACTING...") barutils.extract_bars(localdir) # Test signed files scriptutils.test_signed_files(localdir) # Move bar files print("MOVING BAR FILES...") barutils.move_bars(localdir, bd_o, bd_r) # Generate loader altradio = radioversion if altsw else None loadergen.generate_lazy_loader(osversion, device, os.path.abspath(localdir), altradio, core) # Test loader suffix = loadergen.format_suffix(bool(altradio), altradio, core) loadername = loadergen.generate_filename(device, osversion, suffix) loaderpath = os.path.join(localdir, loadername) scriptutils.test_single_loader(loaderpath) # Remove signed files print("REMOVING SIGNED FILES...") barutils.remove_signed_files(localdir) # Move loaders print("MOVING LOADERS...") barutils.move_loaders(localdir, ld_o, ld_r, zd_o, zd_r) loadername = os.path.join(ld_o, loadername) # Delete empty folders print("REMOVING EMPTY FOLDERS...") barutils.remove_empty_folders(localdir) if autoloader: subprocess.call(loadername) print("\nFINISHED!!!")
if __name__ == "__main__": grab_args() decorators.enter_to_exit(True)