Passed
Push — master ( ba99c1...808282 )
by Markus
01:38
created

tcllib.tclcheck   A

Complexity

Total Complexity 11

Size/Duplication

Total Lines 95
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 74
dl 0
loc 95
rs 10
c 0
b 0
f 0
wmc 11

2 Methods

Rating   Name   Duplication   Size   Complexity  
A TclCheckMixin.parse_check() 0 14 1
D TclCheckMixin.do_check() 0 63 10
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 do_check(self, device=None, https=True, timeout=10, max_tries=5):
18
        """Perform update request with given parameters."""
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
48
        last_response = None
49
        for _ in range(0, max_tries):
50
            try:
51
                reqtime_start = time.perf_counter()
52
                req = self.sess.get(url, params=params, timeout=timeout)
53
                reqtime = time.perf_counter() - reqtime_start
54
                reqtime_avg = self.check_time_avg()
55
                self.check_time_add(reqtime)
56
                last_response = req
57
                if req.status_code == 200:
58
                    self.master_server_vote_on_time(reqtime, reqtime_avg)
59
                    req.encoding = "utf-8"    # Force encoding as server doesn't give one
60
                    self.write_dump(req.text)
61
                    return req.text
62
                elif req.status_code == 204:
63
                    self.master_server_vote_on_time(reqtime, reqtime_avg)
64
                    raise requests.exceptions.HTTPError("No update available.", response=req)
65
                elif req.status_code == 404:
66
                    self.master_server_vote_on_time(reqtime, reqtime_avg)
67
                    raise requests.exceptions.HTTPError("No data for requested CUREF/FV combination.", response=req)
68
                elif req.status_code not in [500, 502, 503]:
69
                    self.master_server_downvote()
70
                    req.raise_for_status()
71
                    raise requests.exceptions.HTTPError("HTTP {}.".format(req.status_code), response=req)
72
            except requests.exceptions.Timeout:
73
                pass
74
            # Something went wrong, try a different server
75
            self.master_server_downvote()
76
            self.g2master = self.get_master_server()
77
            protocol = "https://" if https else "http://"
78
            url = protocol + self.g2master + "/check.php"
79
        raise requests.exceptions.RetryError("Max tries ({}) reached.".format(max_tries), response=last_response)
80
81
    @staticmethod
82
    def parse_check(xmlstr):
83
        """Parse output of ``do_check``."""
84
        root = ElementTree.fromstring(xmlstr)
85
        curef = root.find("CUREF").text
86
        fvver = root.find("VERSION").find("FV").text
87
        tvver = root.find("VERSION").find("TV").text
88
        fw_id = root.find("FIRMWARE").find("FW_ID").text
89
        fileinfo = root.find("FIRMWARE").find("FILESET").find("FILE")
90
        fileid = fileinfo.find("FILE_ID").text
91
        filename = fileinfo.find("FILENAME").text
92
        filesize = fileinfo.find("SIZE").text
93
        filehash = fileinfo.find("CHECKSUM").text
94
        return curef, fvver, tvver, fw_id, fileid, filename, filesize, filehash
95