mirror of
https://github.com/mbirth/tcl_ota_check.git
synced 2024-11-09 22:06:47 +00:00
do_check error handler refactor + pylint stuff
This commit is contained in:
parent
86e01c1e33
commit
dbaced1fe8
@ -11,6 +11,7 @@ import webbrowser
|
||||
|
||||
class DefaultParser(argparse.ArgumentParser):
|
||||
"""argparse parser with some defaults set."""
|
||||
|
||||
def __init__(self, appname, desc=None):
|
||||
"""Set default name, description, epilogue, arguments."""
|
||||
homeurl = "https://github.com/mbirth/tcl_ota_check"
|
||||
|
@ -17,6 +17,7 @@ def get_creds():
|
||||
params = {base64.b64decode(key): base64.b64decode(val) for key, val in creds.items()}
|
||||
return params
|
||||
|
||||
|
||||
def get_creds2():
|
||||
"""Return alternate authentication."""
|
||||
creds = {
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
"""Pseudo-devices for desktop/mobile requests"""
|
||||
|
||||
|
||||
class Device():
|
||||
"""Generic pseudo-device class."""
|
||||
CLTP_STATES = {
|
||||
@ -60,18 +61,24 @@ class Device():
|
||||
# Throws exception when invalid mode given:
|
||||
self.ckot = self.CKOT_STATES[new_ckot]
|
||||
|
||||
|
||||
class MobileDevice(Device):
|
||||
"""Generic mobile (i.e. OTA) device."""
|
||||
|
||||
def __init__(self, curef="PRD-63117-011", fwver="AAO472"):
|
||||
"""Populate variables."""
|
||||
super().__init__(curef, fwver)
|
||||
self.imei = "3531510"
|
||||
self.set_cltp("MOBILE")
|
||||
self.set_mode("OTA")
|
||||
self.ua = "com.tcl.fota/5.1.0.2.0029.0, Android"
|
||||
|
||||
|
||||
class DesktopDevice(Device):
|
||||
"""Generic desktop (i.e. full) device."""
|
||||
|
||||
def __init__(self, curef="PRD-63117-011", fwver="AAA000"):
|
||||
"""Populate variables."""
|
||||
super().__init__(curef, fwver)
|
||||
self.imei = "543212345000000"
|
||||
self.set_cltp("DESKTOP")
|
||||
|
@ -32,6 +32,7 @@ def load_local_devicelist():
|
||||
except FileNotFoundError:
|
||||
return None, True
|
||||
|
||||
|
||||
def get_devicelist(force=False, output_diff=True):
|
||||
"""Return device list from saved database."""
|
||||
old_prds, need_download = load_local_devicelist()
|
||||
@ -49,7 +50,9 @@ def get_devicelist(force=False, output_diff=True):
|
||||
|
||||
return prds
|
||||
|
||||
|
||||
def print_versions_diff(old_data, new_data):
|
||||
"""Print version changes between old and new databases."""
|
||||
prd = new_data["curef"]
|
||||
if new_data["last_full"] != old_data["last_full"] and new_data["last_ota"] != old_data["last_ota"]:
|
||||
print("> {}: {} ⇨ {} (OTA: {} ⇨ {})".format(
|
||||
@ -64,8 +67,9 @@ def print_versions_diff(old_data, new_data):
|
||||
elif new_data["last_ota"] != old_data["last_ota"]:
|
||||
print("> {}: {} ⇨ {} (OTA)".format(prd, ansi.YELLOW_DARK + str(old_data["last_ota"]) + ansi.RESET, ansi.YELLOW + str(new_data["last_ota"]) + ansi.RESET))
|
||||
|
||||
|
||||
def print_prd_diff(old_prds, new_prds):
|
||||
"""Print changes between old and new databases."""
|
||||
"""Print PRD changes between old and new databases."""
|
||||
added_prds = [prd for prd in new_prds if prd not in old_prds]
|
||||
removed_prds = [prd for prd in old_prds if prd not in new_prds]
|
||||
for prd in removed_prds:
|
||||
|
@ -17,6 +17,7 @@ from . import ansi
|
||||
|
||||
class DumpMgrMixin:
|
||||
"""A mixin component for XML dump management."""
|
||||
|
||||
def __init__(self):
|
||||
"""Populate dump file name."""
|
||||
self.last_dump_filename = None
|
||||
|
@ -10,6 +10,7 @@ import numpy
|
||||
|
||||
class ServerVoteMixin:
|
||||
"""A mixin component for server sorting."""
|
||||
|
||||
def __init__(self):
|
||||
"""Populate server list and weighting variables."""
|
||||
self.g2master = None
|
||||
|
@ -6,7 +6,7 @@
|
||||
"""Tools to interface with TCL's update request API."""
|
||||
|
||||
import time
|
||||
from collections import OrderedDict
|
||||
from collections import OrderedDict, defaultdict
|
||||
|
||||
import requests
|
||||
from defusedxml import ElementTree
|
||||
@ -14,10 +14,16 @@ from defusedxml import ElementTree
|
||||
|
||||
class TclCheckMixin:
|
||||
"""A mixin component for TCL's update request API."""
|
||||
def prep_check(self, device=None, https=True):
|
||||
"""Prepare URL and parameters for update request."""
|
||||
|
||||
def prep_check_url(self, https=True):
|
||||
"""Prepare URL for update request."""
|
||||
protocol = "https://" if https else "http://"
|
||||
url = protocol + self.g2master + "/check.php"
|
||||
return url
|
||||
|
||||
def prep_check(self, device=None, 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
|
||||
@ -63,25 +69,28 @@ class TclCheckMixin:
|
||||
req.encoding = "utf-8" # Force encoding as server doesn't give one
|
||||
self.write_dump(req.text)
|
||||
return req.text
|
||||
elif req.status_code == 204:
|
||||
self.master_server_vote_on_time(reqtime, reqtime_avg)
|
||||
raise requests.exceptions.HTTPError("No update available.", response=req)
|
||||
elif req.status_code == 404:
|
||||
self.master_server_vote_on_time(reqtime, reqtime_avg)
|
||||
raise requests.exceptions.HTTPError("No data for requested CUREF/FV combination.", response=req)
|
||||
elif req.status_code not in [500, 502, 503]:
|
||||
self.master_server_downvote()
|
||||
req.raise_for_status()
|
||||
raise requests.exceptions.HTTPError("HTTP {}.".format(req.status_code), response=req)
|
||||
self.do_check_errorhandle(req, reqtime, reqtime_avg)
|
||||
except requests.exceptions.Timeout:
|
||||
pass
|
||||
# Something went wrong, try a different server
|
||||
self.master_server_downvote()
|
||||
self.g2master = self.get_master_server()
|
||||
protocol = "https://" if https else "http://"
|
||||
url = protocol + self.g2master + "/check.php"
|
||||
url = self.prep_check_url(https)
|
||||
raise requests.exceptions.RetryError("Max tries ({}) reached.".format(max_tries), response=last_response)
|
||||
|
||||
def do_check_errorhandle(self, req, reqtime, reqtime_avg):
|
||||
"""Handle non-HTTP 200 results for ``do_check``."""
|
||||
errcodes = defaultdict(lambda: "HTTP {}.".format(req.status_code))
|
||||
errcodes[204] = "No update available."
|
||||
errcodes[404] = "No data for requested CUREF/FV combination."
|
||||
if req.status_code in [204, 404]:
|
||||
self.master_server_vote_on_time(reqtime, reqtime_avg)
|
||||
elif req.status_code not in [500, 502, 503]:
|
||||
self.master_server_downvote()
|
||||
req.raise_for_status()
|
||||
raise requests.exceptions.HTTPError(errcodes[req.status_code], response=req)
|
||||
|
||||
@staticmethod
|
||||
def parse_check(xmlstr):
|
||||
"""Parse output of ``do_check``."""
|
||||
|
@ -14,6 +14,7 @@ from . import credentials
|
||||
|
||||
class TclChecksumMixin:
|
||||
"""A mixin component for TCL's checksum API."""
|
||||
|
||||
def do_checksum(self, encslave, address, uri):
|
||||
"""Perform checksum request with given parameters."""
|
||||
url = "http://" + encslave + "/checksum.php"
|
||||
|
@ -10,6 +10,7 @@ from . import credentials
|
||||
|
||||
class TclEncHeaderMixin:
|
||||
"""A mixin component for TCL's encrypted header API.."""
|
||||
|
||||
def do_encrypt_header(self, encslave, address):
|
||||
"""Perform encrypted header request with given parameters."""
|
||||
params = credentials.get_creds2()
|
||||
|
@ -40,12 +40,14 @@ from defusedxml import ElementTree
|
||||
|
||||
VDKEY_B64Z = b"eJwdjwEOwDAIAr8kKFr//7HhmqXp8AIIDrYAgg8byiUXrwRJRXja+d6iNxu0AhUooDCN9rd6rDLxmGIakUVWo3IGCTRWqCAt6X4jGEIUAxgN0eYWnp+LkpHQAg/PsO90ELsy0Npm/n2HbtPndFgGEV31R9OmT4O4nrddjc3Qt6nWscx7e+WRHq5UnOudtjw5skuV09pFhvmqnOEIs4ljPeel1wfLYUF4\n"
|
||||
|
||||
|
||||
def get_salt():
|
||||
"""Generate cryptographic salt."""
|
||||
millis = floor(time.time() * 1000)
|
||||
tail = "{:06d}".format(random.randint(0, 999999))
|
||||
return "{}{}".format(str(millis), tail)
|
||||
|
||||
|
||||
def get_vk2(params_dict, cltp):
|
||||
"""Generate salted hash of API parameters."""
|
||||
params_dict["cltp"] = cltp
|
||||
@ -61,11 +63,12 @@ def get_vk2(params_dict, cltp):
|
||||
hexhash = engine.hexdigest()
|
||||
return hexhash
|
||||
|
||||
|
||||
class TclRequestMixin:
|
||||
"""A mixin component for TCL's download request API."""
|
||||
|
||||
def do_request(self, curef, fvver, tvver, fw_id):
|
||||
"""Perform download request with given parameters."""
|
||||
def prep_request(self, curef, fvver, tvver, fw_id):
|
||||
"""Prepare URL and device parameters for download request."""
|
||||
url = "https://" + self.g2master + "/download_request.php"
|
||||
params = OrderedDict()
|
||||
params["id"] = self.serid
|
||||
@ -83,7 +86,11 @@ class TclRequestMixin:
|
||||
if self.mode == self.MODE.FULL:
|
||||
params["foot"] = 1
|
||||
params["chnl"] = self.chnl.value
|
||||
return url, params
|
||||
|
||||
def do_request(self, curef, fvver, tvver, fw_id):
|
||||
"""Perform download request with given parameters."""
|
||||
url, params = self.prep_request(curef, fvver, tvver, fw_id)
|
||||
# print(repr(dict(params)))
|
||||
req = self.sess.post(url, data=params)
|
||||
if req.status_code == 200:
|
||||
|
Loading…
Reference in New Issue
Block a user