Passed
Push — master ( 0262c6...733284 )
by Markus
01:42
created

tcllib.devlist.DevListMixin.get_devicelist()   F

Complexity

Conditions 10

Size

Total Lines 28
Code Lines 22

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 10
eloc 22
nop 2
dl 0
loc 28
rs 3.1304
c 0
b 0
f 0

How to fix   Complexity   

Complexity

Complex classes like tcllib.devlist.DevListMixin.get_devicelist() often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

1
#!/usr/bin/env python3
2
# -*- coding: utf-8 -*-
3
4
# pylint: disable=C0111,C0326,C0103
5
6
"""Tools to manage saved device databases."""
7
8
import json
9
import os
10
import time
11
12
import requests
13
14
from . import ansi
15
16
17
DEVICELIST_URL = "https://tclota.birth-online.de/json_lastupdates.php"
18
DEVICELIST_FILE = "prds.json"
19
DEVICELIST_CACHE_SECONDS = 86400
20
21
22
def get_devicelist(force=False, output_diff=True):
23
    """Return device list from saved database."""
24
    need_download = True
25
26
    old_prds = None
27
    try:
28
        filestat = os.stat(DEVICELIST_FILE)
29
        filemtime = filestat.st_mtime
30
        if filemtime > time.time() - DEVICELIST_CACHE_SECONDS:
31
            need_download = False
32
        with open(DEVICELIST_FILE, "rt") as dlfile:
33
            old_prds = json.load(dlfile)
34
    except FileNotFoundError:
35
        pass
36
37
    if need_download or force:
38
        prds_json = requests.get(DEVICELIST_URL).text
39
        with open(DEVICELIST_FILE, "wt") as dlfile:
40
            dlfile.write(prds_json)
41
42
    with open(DEVICELIST_FILE, "rt") as dlfile:
43
        prds = json.load(dlfile)
44
45
    if old_prds and output_diff:
46
        print_prd_diff(old_prds, prds)
47
48
    return prds
49
50
def print_prd_diff(old_prds, new_prds):
51
    """Print changes between old and new databases."""
52
    added_prds = [prd for prd in new_prds if prd not in old_prds]
53
    removed_prds = [prd for prd in old_prds if prd not in new_prds]
54
    for prd in removed_prds:
55
        print("> Removed device {} (was at {} / OTA: {}).".format(ansi.RED + prd + ansi.RESET, old_prds[prd]["last_full"], old_prds[prd]["last_ota"]))
1 ignored issue
show
Coding Style introduced by
This line is too long as per the coding-style (150/100).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
56
    for prd in added_prds:
57
        print("> New device {} ({} / OTA: {}).".format(ansi.GREEN + prd + ansi.RESET, new_prds[prd]["last_full"], new_prds[prd]["last_ota"]))
1 ignored issue
show
Coding Style introduced by
This line is too long as per the coding-style (141/100).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
58
    for prd, pdata in new_prds.items():
59
        if prd in added_prds:
60
            continue
61
        odata = old_prds[prd]
62
        if pdata["last_full"] != odata["last_full"] and pdata["last_ota"] != odata["last_ota"]:
63
            print("> {}: {} ⇨ {} (OTA: {} ⇨ {})".format(
64
                prd,
65
                ansi.CYAN_DARK + str(odata["last_full"]) + ansi.RESET,
66
                ansi.CYAN + str(pdata["last_full"]) + ansi.RESET,
67
                ansi.YELLOW_DARK + str(odata["last_ota"]) + ansi.RESET,
68
                ansi.YELLOW + str(pdata["last_ota"]) + ansi.RESET
69
            ))
70
        elif pdata["last_full"] != odata["last_full"]:
71
            print("> {}: {} ⇨ {} (FULL)".format(prd, ansi.CYAN_DARK + str(odata["last_full"]) + ansi.RESET, ansi.CYAN + str(pdata["last_full"]) + ansi.RESET))
1 ignored issue
show
Coding Style introduced by
This line is too long as per the coding-style (158/100).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
72
        elif pdata["last_ota"] != odata["last_ota"]:
73
            print("> {}: {} ⇨ {} (OTA)".format(prd, ansi.YELLOW_DARK + str(odata["last_ota"]) + ansi.RESET, ansi.YELLOW + str(pdata["last_ota"]) + ansi.RESET))
1 ignored issue
show
Coding Style introduced by
This line is too long as per the coding-style (159/100).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
74