bbarchivist.scripts.downloader.downloader_main()   C
last analyzed

Complexity

Conditions 11

Size

Total Lines 78
Code Lines 42

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 11
eloc 42
nop 8
dl 0
loc 78
rs 5.4
c 0
b 0
f 0

How to fix   Long Method    Complexity    Many Parameters   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

Complexity

Complex classes like bbarchivist.scripts.downloader.downloader_main() 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.

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
#!/usr/bin/env python3
2
"""Only download OS/radio bar files."""
3
4
import os  # filesystem read
5
import sys  # load arguments
6
7
import requests  # session
8
from bbarchivist import argutils  # arguments
9
from bbarchivist import decorators  # enter to exit
10
from bbarchivist import networkutils  # download/lookup
11
from bbarchivist import scriptutils  # script stuff
12
from bbarchivist import utilities  # input validation
13
14
__author__ = "Thurask"
15
__license__ = "WTFPL v2"
16
__copyright__ = "2015-2019 Thurask"
17
18
19
@decorators.timer
20
def grab_args():
21
    """
22
    Parse arguments from argparse/questionnaire.
23
24
    Invoke downloader from :func:`archivist.archivist_main` with arguments.
25
    """
26
    if len(sys.argv) > 1:
27
        parser = argutils.default_parser("bb-downloader", "Download bar files", ("folder", "osr"))
28
        parser.add_argument(
29
            "-a",
30
            "--altsw",
31
            dest="altsw",
32
            metavar="SW",
33
            help="Radio software version, if not same as OS",
34
            nargs="?",
35
            default=None)
36
        parser.add_argument(
37
            "-d",
38
            "--debricks",
39
            dest="debricks",
40
            help="Download debricks",
41
            default=False,
42
            action="store_true")
43
        parser.add_argument(
44
            "-c",
45
            "--cores",
46
            dest="cores",
47
            help="Download debricks",
48
            default=False,
49
            action="store_true")
50
        parser.add_argument(
51
            "-r",
52
            "--radios",
53
            dest="radios",
54
            help="Download radios",
55
            default=False,
56
            action="store_true")
57
        parser.set_defaults()
58
        args = parser.parse_args(sys.argv[1:])
59
        args.folder = utilities.dirhandler(args.folder, os.getcwd())
60
        downloader_main(args.os, args.radio, args.swrelease,
61
                        args.folder, args.debricks, args.radios,
62
                        args.cores, args.altsw)
63
    else:
64
        questionnaire()
65
66
67
def questionnaire():
68
    """
69
    Questions to ask if no arguments given.
70
    """
71
    localdir = os.getcwd()
72
    osversion = input("OS VERSION: ")
73
    radioversion = input("RADIO VERSION: ")
74
    softwareversion = input("SOFTWARE RELEASE: ")
75
    debricks = utilities.i2b("DOWNLOAD DEBRICKS? Y/N: ")
76
    radios = utilities.i2b("DOWNLOAD RADIOS? Y/N: ")
77
    if not radios:
78
        radios = False
79
    cores = utilities.i2b("DOWNLOAD CORES? Y/N: ")
80
    if not cores:
81
        cores = False
82
    altsw = None
83
    print(" ")
84
    downloader_main(osversion, radioversion, softwareversion,
85
                    localdir, debricks, radios, cores, altsw)
86
    decorators.enter_to_exit(True)
87
88
89
def downloader_main(osversion, radioversion=None, softwareversion=None,
90
                    localdir=None, debricks=True, radios=True, cores=False, altsw=None):
91
    """
92
    Archivist's download function, abstracted out.
93
94
    :param osversion: OS version, 10.x.y.zzzz.
95
    :type osversion: str
96
97
    :param radioversion: Radio version, 10.x.y.zzzz. Can be guessed.
98
    :type radioversion: str
99
100
    :param softwareversion: Software release, 10.x.y.zzzz. Can be guessed.
101
    :type softwareversion: str
102
103
    :param localdir: Working directory. Local by default.
104
    :type localdir: str
105
106
    :param debricks: Whether to download debrick OS files. True by default.
107
    :type debricks: bool
108
109
    :param radios: Whether to download radio files. True by default.
110
    :type radios: bool
111
112
    :param cores: Whether to download core OS files. False by default.
113
    :type cores: bool
114
115
    :param altsw: Radio software release, if not the same as OS.
116
    :type altsw: str
117
    """
118
    radioversion = scriptutils.return_radio_version(osversion, radioversion)
119
    softwareversion, swchecked = scriptutils.return_sw_checked(softwareversion, osversion)
120
    if altsw:
121
        altsw, altchecked = scriptutils.return_radio_sw_checked(altsw, radioversion)
122
    localdir = utilities.dirhandler(localdir, os.getcwd())
123
    argutils.standard_preamble("downloader", osversion, softwareversion, radioversion, altsw)
124
    if not any((debricks, radios, cores)):
125
        print("NO FILES SPECIFIED, DEFAULTING TO DEBRICKS + RADIOS")
126
        debricks = True
127
        radios = True
128
    baseurl, alturl = scriptutils.get_baseurls(softwareversion, altsw)
129
    osurls, corurls, radurls = utilities.bulk_urls(softwareversion, osversion, radioversion, cores, altsw)
130
131
    # Check availability of software releases
132
    scriptutils.check_sw(baseurl, softwareversion, swchecked)
133
    if altsw:
134
        scriptutils.check_radio_sw(alturl, altsw, altchecked)
135
136
    # Check availability of OS, radio
137
    if debricks:
138
        scriptutils.check_os_bulk(osurls)
139
        osurls = scriptutils.bulk_avail(osurls)
140
    if cores:
141
        scriptutils.check_os_bulk(corurls)
142
        corurls = scriptutils.bulk_avail(corurls)
143
    if radios:
144
        radurls, radioversion = scriptutils.check_radio_bulk(radurls, radioversion)
145
        radurls = scriptutils.bulk_avail(radurls)
146
147
    # Download files
148
    print("BEGIN DOWNLOADING...")
149
    urllist = []
150
    if debricks:
151
        urllist += osurls
152
    if radios:
153
        urllist += radurls
154
    if cores:
155
        urllist += corurls
156
    urllist = list(set(urllist))  # pop duplicates
157
    if urllist:
158
        sess = requests.Session()
159
        networkutils.download_bootstrap(urllist, localdir, workers=5, session=sess)
160
        print("ALL FILES DOWNLOADED")
161
    else:
162
        print("NO FILES TO DOWNLOAD!")
163
        raise SystemExit
164
165
    # Test bar files
166
    scriptutils.test_bar_files(localdir, urllist)
167
168
169
if __name__ == "__main__":
170
    grab_args()
171