From 0b7ae538612c9de5d20cd5e4a969789cffdcdf16 Mon Sep 17 00:00:00 2001 From: Markus Birth Date: Wed, 7 Feb 2018 01:49:44 +0100 Subject: [PATCH] Use new Device classes in ALL the features! --- tclcheck.py | 42 +++++++++++++++++++----------------------- tclcheck_allfull.py | 4 +--- tclcheck_allota.py | 4 +--- tclcheck_findprd.py | 15 +++++---------- tclcheck_findprd2.py | 15 +++++---------- tclcheck_findver.py | 10 +++++----- tclcheck_gapfill.py | 14 ++++++-------- tcldown.py | 38 ++++++++++++++++++-------------------- tcllib/__init__.py | 33 +++------------------------------ tcllib/tclcheck.py | 42 +++++++++++++++--------------------------- 10 files changed, 78 insertions(+), 139 deletions(-) diff --git a/tclcheck.py b/tclcheck.py index 8287499..88a273c 100755 --- a/tclcheck.py +++ b/tclcheck.py @@ -11,12 +11,11 @@ import sys import tcllib import tcllib.argparser +from tcllib.devices import Device from tcllib.xmltools import pretty_xml fc = tcllib.FotaCheck() -fc.serid = "3531510" -#fc.osvs = "7.1.1" dpdesc = """ Checks for the latest FULL updates for the specified PRD number or for an OTA from the @@ -32,48 +31,45 @@ dp.add_argument("--rawmode", help="override --mode with raw value (2=OTA, 4=FULL dp.add_argument("--rawcltp", help="override --type with raw value (10=MOBILE, 2010=DESKTOP)", metavar="CLTP") args = dp.parse_args(sys.argv[1:]) +dev = Device(args.prd[0], args.fvver) +dev.imei = "3531510" def sel_mode(txtmode, autoval, rawval): """Handle custom mode.""" if rawval: - enum = tcllib.default_enum("MODE", {"RAW": rawval}) - return enum.RAW + return rawval if txtmode == "auto": return autoval elif txtmode == "ota": - return fc.MODE.OTA - return fc.MODE.FULL - + return dev.MODE_STATES["OTA"] + return dev.MODE_STATES["FULL"] def sel_cltp(txtmode, autoval, rawval): """Handle custom CLTP.""" if rawval: - enum = tcllib.default_enum("CLTP", {"RAW": rawval}) - return enum.RAW + return rawval if txtmode == "auto": return autoval elif txtmode == "desktop": - return fc.CLTP.DESKTOP - return fc.CLTP.MOBILE - + return dev.CLTP_STATES["DESKTOP"] + return dev.CLTP_STATES["MOBILE"] if args.imei: print("Use specified IMEI: {}".format(args.imei)) - fc.serid = args.imei + dev.imei = args.imei -fc.curef = args.prd[0] -fc.fv = args.fvver if args.fvver == "AAA000": - fc.mode = sel_mode(args.mode, fc.MODE.FULL, args.rawmode) - fc.cltp = sel_cltp(args.type, fc.CLTP.DESKTOP, args.rawcltp) + dev.mode = sel_mode(args.mode, dev.MODE_STATES["FULL"], args.rawmode) + dev.cltp = sel_cltp(args.type, dev.CLTP_STATES["DESKTOP"], args.rawcltp) else: - fc.mode = sel_mode(args.mode, fc.MODE.OTA, args.rawmode) - fc.cltp = sel_cltp(args.type, fc.CLTP.MOBILE, args.rawcltp) + dev.mode = sel_mode(args.mode, dev.MODE_STATES["OTA"], args.rawmode) + dev.cltp = sel_cltp(args.type, dev.CLTP_STATES["MOBILE"], args.rawcltp) -print("Mode: {}".format(fc.mode.value)) -print("CLTP: {}".format(fc.cltp.value)) +print("Mode: {}".format(dev.mode)) +print("CLTP: {}".format(dev.cltp)) -check_xml = fc.do_check() +fc.reset_session(dev) +check_xml = fc.do_check(dev) print(pretty_xml(check_xml)) curef, fv, tv, fw_id, fileid, fn, fsize, fhash = fc.parse_check(check_xml) @@ -92,7 +88,7 @@ for s in slaves: for s in s3_slaves: print("http://{}{}".format(s, s3_fileurl)) -if fc.mode == fc.MODE.FULL: +if dev.mode == dev.MODE_STATES["FULL"]: header = fc.do_encrypt_header(random.choice(encslaves), fileurl) headname = "header_{}.bin".format(tv) headdir = "headers" diff --git a/tclcheck_allfull.py b/tclcheck_allfull.py index 10525ba..2286b39 100644 --- a/tclcheck_allfull.py +++ b/tclcheck_allfull.py @@ -16,9 +16,7 @@ from tcllib.devices import DesktopDevice dev = DesktopDevice() - fc = tcllib.FotaCheck() -fc.mode = fc.MODE.FULL # still needed to set User-Agent dpdesc = """ Checks for the latest FULL updates for all PRD numbers or only for @@ -40,8 +38,8 @@ for prd, variant in prds.items(): lastver = variant["last_full"] if prdcheck in prd: try: - fc.reset_session() dev.curef = prd + fc.reset_session(dev) check_xml = fc.do_check(dev, max_tries=20) curef, fv, tv, fw_id, fileid, fn, fsize, fhash = fc.parse_check(check_xml) txt_tv = tv diff --git a/tclcheck_allota.py b/tclcheck_allota.py index 0a9bd9f..a219fca 100644 --- a/tclcheck_allota.py +++ b/tclcheck_allota.py @@ -16,9 +16,7 @@ from tcllib.devices import MobileDevice dev = MobileDevice() - fc = tcllib.FotaCheck() -fc.mode = fc.MODE.OTA # still needed to set User-Agent dpdesc = """ Checks for the latest OTA updates for all PRD numbers or only for the PRD specified @@ -49,9 +47,9 @@ for prd, variant in prds.items(): lastver = args.forcever if prdcheck in prd: try: - fc.reset_session() dev.curef = prd dev.fwver = lastver + fc.reset_session(dev) check_xml = fc.do_check(dev, max_tries=20) curef, fv, tv, fw_id, fileid, fn, fsize, fhash = fc.parse_check(check_xml) versioninfo = ansi.YELLOW_DARK + fv + ansi.RESET + " ⇨ " + ansi.YELLOW + tv + ansi.RESET + " (FULL: {})".format(variant["last_full"]) diff --git a/tclcheck_findprd.py b/tclcheck_findprd.py index 628bf08..8e066f3 100755 --- a/tclcheck_findprd.py +++ b/tclcheck_findprd.py @@ -13,16 +13,11 @@ from requests.exceptions import RequestException, Timeout import tcllib import tcllib.argparser from tcllib import ansi, devlist +from tcllib.devices import DesktopDevice, MobileDevice +dev = DesktopDevice() fc = tcllib.FotaCheck() -fc.serid = "3531510" -fc.fv = "AAA000" -fc.mode = fc.MODE.FULL - -# CLTP = 10 (only show actual updates or HTTP 206) / 2010 (always show latest version for MODE.FULL) -#fc.cltp = fc.CLTP.MOBILE -fc.cltp = fc.CLTP.DESKTOP dpdesc = """ Finds new PRD numbers for all known variants, or specified variants with tocheck. Scan range @@ -74,9 +69,9 @@ for center in sorted(prddict.keys()): print("Checking {} ({}/{})".format(curef, done_count, total_count)) print(ansi.UP_DEL, end="") try: - fc.reset_session() - fc.curef = curef - check_xml = fc.do_check(https=False, max_tries=20) + dev.curef = curef + fc.reset_session(dev) + check_xml = fc.do_check(dev, https=False, max_tries=20) curef, fv, tv, fw_id, fileid, fn, fsize, fhash = fc.parse_check(check_xml) txt_tv = tv print("{}: {} {}".format(curef, txt_tv, fhash)) diff --git a/tclcheck_findprd2.py b/tclcheck_findprd2.py index e97f7ad..423110c 100644 --- a/tclcheck_findprd2.py +++ b/tclcheck_findprd2.py @@ -12,19 +12,14 @@ from requests.exceptions import RequestException, Timeout import tcllib import tcllib.argparser from tcllib import ansi, devlist +from tcllib.devices import DesktopDevice, MobileDevice # Variants to scan for SCAN_VARIANTS = ["001", "003", "009", "010", "700"] +dev = DesktopDevice() fc = tcllib.FotaCheck() -fc.serid = "3531510" -fc.fv = "AAA000" -fc.mode = fc.MODE.FULL - -# CLTP = 10 (only show actual updates or HTTP 206) / 2010 (always show latest version for MODE.FULL) -#fc.cltp = fc.CLTP.MOBILE -fc.cltp = fc.CLTP.DESKTOP dpdesc = """ Finds new PRD numbers for a range of variants. Scan range can be set by @@ -61,9 +56,9 @@ for center in to_scan: print("Checking {} ({}/{})".format(curef, done_count, total_count)) print(ansi.UP_DEL, end="") try: - fc.reset_session() - fc.curef = curef - check_xml = fc.do_check(https=False, max_tries=20) + dev.curef = curef + fc.reset_session(dev) + check_xml = fc.do_check(dev, https=False, max_tries=20) curef, fv, tv, fw_id, fileid, fn, fsize, fhash = fc.parse_check(check_xml) txt_tv = tv print("{}: {} {}".format(curef, txt_tv, fhash)) diff --git a/tclcheck_findver.py b/tclcheck_findver.py index 70941b6..301e66f 100755 --- a/tclcheck_findver.py +++ b/tclcheck_findver.py @@ -12,11 +12,11 @@ from requests.exceptions import RequestException, Timeout import tcllib import tcllib.argparser from tcllib import ansi +from tcllib.devices import DesktopDevice, MobileDevice +dev = MobileDevice() fc = tcllib.FotaCheck() -fc.serid = "3531510" -fc.mode = fc.MODE.OTA dpdesc = """ Finds all valid OTA updates for a given PRD. Scan range can be set by @@ -60,9 +60,9 @@ for fv in allvers: print("Checking {} ({}/{})".format(fv, done_count, total_count)) print(ansi.UP_DEL, end="") try: - fc.reset_session() - fc.fv = fv - check_xml = fc.do_check(https=False, max_tries=20) + dev.fwver = fv + fc.reset_session(dev) + check_xml = fc.do_check(dev, https=False, max_tries=20) curef, fv, tv, fw_id, fileid, fn, fsize, fhash = fc.parse_check(check_xml) txt_tv = tv print("{}: {} ⇨ {} {}".format(curef, fv, txt_tv, fhash)) diff --git a/tclcheck_gapfill.py b/tclcheck_gapfill.py index 56ddea9..b695c3c 100644 --- a/tclcheck_gapfill.py +++ b/tclcheck_gapfill.py @@ -11,17 +11,15 @@ import requests from requests.exceptions import RequestException import tcllib +from tcllib.devices import DesktopDevice, MobileDevice # 1. Fetch list of missing OTAs (e.g. from ancient versions to current) # 2. Query updates from FOTA servers (and store XML) # (3. Upload will be done manually with upload_logs.py) +dev = MobileDevice() fc = tcllib.FotaCheck() -fc.serid = "3531510" -#fc.osvs = "7.1.1" -fc.mode = fc.MODE.OTA -fc.cltp = fc.CLTP.MOBILE print("Loading list of missing OTAs.") versions_json = requests.get("https://tclota.birth-online.de/json_otaversions.php").text @@ -38,10 +36,10 @@ for prd, data in versions.items(): for ver in data["missing_froms"]: print(" {}".format(ver), end="", flush=True) try: - fc.reset_session() - fc.curef = prd - fc.fv = ver - check_xml = fc.do_check(max_tries=20) + dev.curef = prd + dev.fwver = ver + fc.reset_session(dev) + check_xml = fc.do_check(dev, max_tries=20) curef, fv, tv, fw_id, fileid, fn, fsize, fhash = fc.parse_check(check_xml) print("✔", end="", flush=True) except RequestException as e: diff --git a/tcldown.py b/tcldown.py index 37ab6d8..29a46cc 100644 --- a/tcldown.py +++ b/tcldown.py @@ -11,12 +11,12 @@ import sys import tcllib import tcllib.argparser +from tcllib.devices import DesktopDevice from tcllib.xmltools import pretty_xml fc = tcllib.FotaCheck() -fc.serid = "3531510" -#fc.osvs = "7.1.1" +dev = DesktopDevice() dpdesc = """ Downloads the given firmware file. @@ -36,41 +36,39 @@ args = dp.parse_args(sys.argv[1:]) def sel_mode(defaultmode, rawval): """Handle custom mode.""" if rawval: - enum = tcllib.default_enum("MODE", {"RAW": rawval}) - return enum.RAW + return rawval return defaultmode def sel_cltp(txtmode, rawval): """Handle custom CLTP.""" if rawval: - enum = tcllib.default_enum("CLTP", {"RAW": rawval}) - return enum.RAW + return rawval if txtmode == "mobile": - return fc.CLTP.MOBILE - return fc.CLTP.DESKTOP + return dev.CLTP_STATES["MOBILE"] + return dev.CLTP_STATES["DESKTOP"] if args.imei: print("Use specified IMEI: {}".format(args.imei)) - fc.serid = args.imei + dev.imei = args.imei -fc.curef = args.prd[0] +dev.curef = args.prd[0] if args.ota: - fc.fv = args.ota[0] - fc.mode = sel_mode(fc.MODE.OTA, args.rawmode) + dev.fwver = args.ota[0] + dev.mode = sel_mode(dev.MODE_STATES["OTA"], args.rawmode) else: - fc.fv = args.targetversion[0] - fc.mode = sel_mode(fc.MODE.FULL, args.rawmode) -fc.cltp = sel_cltp(args.type, args.rawcltp) + dev.fwver = args.targetversion[0] + dev.mode = sel_mode(dev.MODE_STATES["FULL"], args.rawmode) +dev.cltp = sel_cltp(args.type, args.rawcltp) -print("Mode: {}".format(fc.mode.value)) -print("CLTP: {}".format(fc.cltp.value)) +print("Mode: {}".format(dev.mode)) +print("CLTP: {}".format(dev.cltp)) -fv = fc.fv +fv = dev.fwver tv = args.targetversion[0] fw_id = args.fwid[0] -req_xml = fc.do_request(fc.curef, fv, tv, fw_id) +req_xml = fc.do_request(dev.curef, fv, tv, fw_id) print(pretty_xml(req_xml)) fileid, fileurl, slaves, encslaves, s3_fileurl, s3_slaves = fc.parse_request(req_xml) @@ -80,7 +78,7 @@ for s in slaves: for s in s3_slaves: print("http://{}{}".format(s, s3_fileurl)) -if fc.mode == fc.MODE.FULL: +if dev.mode == dev.MODE_STATES["FULL"]: header = fc.do_encrypt_header(random.choice(encslaves), fileurl) headname = "header_{}.bin".format(tv) headdir = "headers" diff --git a/tcllib/__init__.py b/tcllib/__init__.py index 60c6ccd..96f84b6 100644 --- a/tcllib/__init__.py +++ b/tcllib/__init__.py @@ -5,19 +5,12 @@ """Library for TCL API work and related functions.""" -import enum - import requests from . import (dumpmgr, servervote, tclcheck, tclchecksum, tclencheader, tclrequest) -def default_enum(enumname, vardict, qualroot="tcllib.FotaCheck"): - """Enum with defaults set.""" - return enum.IntEnum(enumname, vardict, module=__name__, qualname="{}.{}".format(qualroot, enumname)) - - class FotaCheck( tclcheck.TclCheckMixin, tclrequest.TclRequestMixin, @@ -28,35 +21,15 @@ class FotaCheck( ): """Main API handler class.""" - CKTP = default_enum("CKTP", ["AUTO", "MANUAL"]) - MODE = default_enum("MODE", {"OTA": 2, "FULL": 4}) - RTD = default_enum("RTD", ["UNROOTED", "ROOTED"]) - CHNL = default_enum("CHNL", ["3G", "WIFI"]) - CLTP = default_enum("CLTP", {"MOBILE": 10, "DESKTOP": 2010}) - CKOT = default_enum("CKOT", ["ALL", "AOTA_ONLY", "FOTA_ONLY"]) - def __init__(self): """Handle mixins and populate variables.""" super().__init__() - self.serid = "543212345000000" - self.curef = "PRD-63117-011" - self.fv = "AAM481" - self.osvs = "7.1.1" - self.mode = self.MODE.FULL - self.ftype = "Firmware" - self.cltp = self.CLTP.MOBILE - self.cktp = self.CKTP.MANUAL - self.ckot = self.CKOT.ALL - self.rtd = self.RTD.UNROOTED - self.chnl = self.CHNL.WIFI self.reset_session() - def reset_session(self): + def reset_session(self, device=None): """Reset everything to default.""" self.g2master = self.get_master_server() self.sess = requests.Session() - if self.mode == self.MODE.FULL: - self.sess.headers.update({"User-Agent": "com.tcl.fota/5.1.0.2.0029.0, Android"}) - else: - self.sess.headers.update({"User-Agent": "tcl"}) + if device: + self.sess.headers.update({"User-Agent": device.ua}) return self.sess diff --git a/tcllib/tclcheck.py b/tcllib/tclcheck.py index 68afdf6..32d483d 100644 --- a/tcllib/tclcheck.py +++ b/tcllib/tclcheck.py @@ -11,6 +11,8 @@ from collections import OrderedDict, defaultdict import requests from defusedxml import ElementTree +from .devices import Device + class TclCheckMixin: """A mixin component for TCL's update request API.""" @@ -21,38 +23,24 @@ class TclCheckMixin: url = protocol + self.g2master + "/check.php" return url - def prep_check(self, device=None, https=True): + def prep_check(self, device: Device, https=True): """Prepare URL and parameters for update request.""" url = self.prep_check_url(https) params = OrderedDict() - if device: - # Need to support both ways for now - params["id"] = device.imei - params["curef"] = device.curef - params["fv"] = device.fwver - params["mode"] = device.mode - params["type"] = device.type - params["cltp"] = device.cltp - params["cktp"] = device.cktp - params["rtd"] = device.rtd - params["chnl"] = device.chnl - #params["osvs"] = device.osvs - #params["ckot"] = device.ckot - else: - params["id"] = self.serid - params["curef"] = self.curef - params["fv"] = self.fv - params["mode"] = self.mode.value - params["type"] = self.ftype - params["cltp"] = self.cltp.value - params["cktp"] = self.cktp.value - params["rtd"] = self.rtd.value - params["chnl"] = self.chnl.value - #params["osvs"] = self.osvs - #params["ckot"] = self.ckot.value + params["id"] = device.imei + params["curef"] = device.curef + params["fv"] = device.fwver + params["mode"] = device.mode + params["type"] = device.type + params["cltp"] = device.cltp + params["cktp"] = device.cktp + params["rtd"] = device.rtd + params["chnl"] = device.chnl + #params["osvs"] = device.osvs + #params["ckot"] = device.ckot return url, params - def do_check(self, device=None, https=True, timeout=10, max_tries=5): + def do_check(self, device: Device, https=True, timeout=10, max_tries=5): """Perform update request with given parameters.""" url, params = self.prep_check(device, https) last_response = None