Passed
Push — master ( 58a270...86e01c )
by John
01:35
created

tcllib.tclcheck.TclCheckMixin.do_check()   D

Complexity

Conditions 8

Size

Total Lines 35
Code Lines 33

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 8
eloc 33
nop 5
dl 0
loc 35
rs 4
c 0
b 0
f 0
1
#!/usr/bin/env python3
2
# -*- coding: utf-8 -*-
3
4
# pylint: disable=C0111,C0326,C0103
5
6
"""Tools to interface with TCL's update request API."""
7
8
import time
9
from collections import OrderedDict
10
11
import requests
12
from defusedxml import ElementTree
13
14
15
class TclCheckMixin:
0 ignored issues
show
Unused Code introduced by
The variable __class__ seems to be unused.
Loading history...
16
    """A mixin component for TCL's update request API."""
17
    def prep_check(self, device=None, https=True):
18
        """Prepare URL and parameters for update request."""
19
        protocol = "https://" if https else "http://"
20
        url = protocol + self.g2master + "/check.php"
21
        params = OrderedDict()
22
        if device:
23
            # Need to support both ways for now
24
            params["id"] = device.imei
25
            params["curef"] = device.curef
26
            params["fv"] = device.fwver
27
            params["mode"] = device.mode
28
            params["type"] = device.type
29
            params["cltp"] = device.cltp
30
            params["cktp"] = device.cktp
31
            params["rtd"] = device.rtd
32
            params["chnl"] = device.chnl
33
            #params["osvs"] = device.osvs
34
            #params["ckot"] = device.ckot
35
        else:
36
            params["id"] = self.serid
37
            params["curef"] = self.curef
38
            params["fv"] = self.fv
39
            params["mode"] = self.mode.value
40
            params["type"] = self.ftype
41
            params["cltp"] = self.cltp.value
42
            params["cktp"] = self.cktp.value
43
            params["rtd"] = self.rtd.value
44
            params["chnl"] = self.chnl.value
45
            #params["osvs"] = self.osvs
46
            #params["ckot"] = self.ckot.value
47
        return url, params
48
49
    def do_check(self, device=None, https=True, timeout=10, max_tries=5):
50
        """Perform update request with given parameters."""
51
        url, params = self.prep_check(device, https)
52
        last_response = None
53
        for _ in range(0, max_tries):
54
            try:
55
                reqtime_start = time.perf_counter()
56
                req = self.sess.get(url, params=params, timeout=timeout)
57
                reqtime = time.perf_counter() - reqtime_start
58
                reqtime_avg = self.check_time_avg()
59
                self.check_time_add(reqtime)
60
                last_response = req
61
                if req.status_code == 200:
62
                    self.master_server_vote_on_time(reqtime, reqtime_avg)
63
                    req.encoding = "utf-8"    # Force encoding as server doesn't give one
64
                    self.write_dump(req.text)
65
                    return req.text
66
                elif req.status_code == 204:
67
                    self.master_server_vote_on_time(reqtime, reqtime_avg)
68
                    raise requests.exceptions.HTTPError("No update available.", response=req)
69
                elif req.status_code == 404:
70
                    self.master_server_vote_on_time(reqtime, reqtime_avg)
71
                    raise requests.exceptions.HTTPError("No data for requested CUREF/FV combination.", response=req)
72
                elif req.status_code not in [500, 502, 503]:
73
                    self.master_server_downvote()
74
                    req.raise_for_status()
75
                    raise requests.exceptions.HTTPError("HTTP {}.".format(req.status_code), response=req)
76
            except requests.exceptions.Timeout:
77
                pass
78
            # Something went wrong, try a different server
79
            self.master_server_downvote()
80
            self.g2master = self.get_master_server()
81
            protocol = "https://" if https else "http://"
82
            url = protocol + self.g2master + "/check.php"
83
        raise requests.exceptions.RetryError("Max tries ({}) reached.".format(max_tries), response=last_response)
84
85
    @staticmethod
86
    def parse_check(xmlstr):
87
        """Parse output of ``do_check``."""
88
        root = ElementTree.fromstring(xmlstr)
89
        curef = root.find("CUREF").text
90
        fvver = root.find("VERSION").find("FV").text
91
        tvver = root.find("VERSION").find("TV").text
92
        fw_id = root.find("FIRMWARE").find("FW_ID").text
93
        fileinfo = root.find("FIRMWARE").find("FILESET").find("FILE")
94
        fileid = fileinfo.find("FILE_ID").text
95
        filename = fileinfo.find("FILENAME").text
96
        filesize = fileinfo.find("SIZE").text
97
        filehash = fileinfo.find("CHECKSUM").text
98
        return curef, fvver, tvver, fw_id, fileid, filename, filesize, filehash
99