bbarchivist.scripts.autolookup   A
last analyzed

Complexity

Total Complexity 23

Size/Duplication

Total Lines 229
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 150
dl 0
loc 229
rs 10
c 0
b 0
f 0
wmc 23

5 Functions

Rating   Name   Duplication   Size   Complexity  
A questionnaire() 0 11 2
F autolookup_main() 0 87 14
B grab_args() 0 66 2
A execute_args() 0 13 3
A frozen_args() 0 21 2
1
#!/usr/bin/env python3
2
"""Get software release for one/many OS versions."""
3
4
import sys  # load arguments
5
6
import requests  # session
7
from bbarchivist import argutils  # arguments
8
from bbarchivist import decorators  # Ctrl+C wrapper
9
from bbarchivist import networkutils  # lookup
10
from bbarchivist import scriptutils  # default parser
11
from bbarchivist import smtputils  # email
12
from bbarchivist import utilities  # incrementer
13
14
__author__ = "Thurask"
15
__license__ = "WTFPL v2"
16
__copyright__ = "2015-2019 Thurask"
17
18
19
def grab_args():
20
    """
21
    Parse arguments from argparse/questionnaire.
22
23
    Invoke :func:`autolookup.autolookup_main` with those arguments.
24
    """
25
    if len(sys.argv) > 1:
26
        parser = argutils.default_parser("bb-autolookup", "Get software releases")
27
        parser.add_argument("os", help="OS version, 10.x.y.zzzz")
28
        parser.add_argument(
29
            "-l", "--loop",
30
            dest="recurse",
31
            help="Loop lookup, CTRL-C to quit",
32
            action="store_true",
33
            default=False)
34
        parser.add_argument(
35
            "-o", "--output",
36
            dest="log",
37
            help="Output to file",
38
            action="store_true",
39
            default=False)
40
        parser.add_argument(
41
            "-a", "--autogen",
42
            dest="autogen",
43
            help="Generate links for availables",
44
            action="store_true",
45
            default=False)
46
        parser.add_argument(
47
            "-q", "--quiet",
48
            dest="quiet",
49
            help="Only print if available (implies -p)",
50
            action="store_true",
51
            default=False)
52
        parser.add_argument(
53
            "-i", "--increment",
54
            dest="increment",
55
            help="Loop increment, default = 3",
56
            default=3,
57
            type=argutils.positive_integer,
58
            metavar="INT")
59
        parser = frozen_args(parser)
60
        parser.add_argument(
61
            "-c", "--ceiling",
62
            dest="ceiling",
63
            help="When to stop script, default = 9996",
64
            default=9996,
65
            type=int,
66
            choices=range(1, 9997),
67
            metavar="INT")
68
        parser.add_argument(
69
            "-p", "--prod-only",
70
            dest="production",
71
            help="Only check production server",
72
            action="store_true",
73
            default=False)
74
        parser.add_argument(
75
            "-n2", "--no-2",
76
            dest="no2",
77
            help="Skip checking Alpha/Beta 2 servers",
78
            action="store_true",
79
            default=False)
80
        args = parser.parse_args(sys.argv[1:])
81
        parser.set_defaults()
82
        execute_args(args)
83
    else:
84
        questionnaire()
85
86
87
def frozen_args(parser):
88
    """
89
    Add args to parser if not frozen.
90
91
    :param parser: Parser to modify.
92
    :type parser: argparse.ArgumentParser
93
    """
94
    if not getattr(sys, 'frozen', False):
95
        parser.add_argument(
96
            "-s", "--sql",
97
            dest="sql",
98
            help="Add valid links to database",
99
            action="store_true",
100
            default=False)
101
        parser.add_argument(
102
            "-e", "--email",
103
            dest="email",
104
            help="Email valid links to self",
105
            action="store_true",
106
            default=False)
107
    return parser
108
109
110
def execute_args(args):
111
    """
112
    Get args and decide what to do with them.
113
114
    :param args: Arguments.
115
    :type args: argparse.Namespace
116
    """
117
    if getattr(sys, 'frozen', False):
118
        args.sql = False
119
        args.email = False
120
    if args.quiet:
121
        args.production = True  # impossible otherwise
122
    autolookup_main(args.os, args.recurse, args.log, args.autogen, args.increment, args.sql, args.quiet, args.ceiling, args.email, args.production, args.no2)
123
124
125
def questionnaire():
126
    """
127
    Questions to ask if no arguments given.
128
    """
129
    osversion = input("OS VERSION: ")
130
    recurse = utilities.i2b("LOOP (Y/N)?: ")
131
    if recurse:
132
        print("Press Ctrl+C to stop loop")
133
    print(" ")
134
    autolookup_main(osversion, recurse, True, False, 3, False, False, 9996, False, False)
135
    decorators.enter_to_exit(True)
136
137
138
@decorators.wrap_keyboard_except
139
def autolookup_main(osversion, loop=False, log=False, autogen=False, inc=3, sql=False, quiet=False, ceiling=9996, mailer=False, prod=False, no2=False):
140
    """
141
    Lookup a software release from an OS. Can iterate.
142
143
    :param osversion: OS version, 10.x.y.zzzz.
144
    :type osversion: str
145
146
    :param loop: Whether or not to automatically lookup. Default is false.
147
    :type loop: bool
148
149
    :param log: Whether to log. Default is false.
150
    :type log: bool
151
152
    :param autogen: Whether to create text links. Default is false.
153
    :type autogen: bool
154
155
    :param inc: Lookup increment. Default is 3.
156
    :type inc: int
157
158
    :param sql: Whether to add valid lookups to a database. Default is false.
159
    :type sql: bool
160
161
    :param quiet: Whether to only output if release exists. Default is false.
162
    :type quiet: bool
163
164
    :param ceiling: When to stop loop. Default is 9996 (i.e. 10.x.y.9996).
165
    :type ceiling: int
166
167
    :param mailer: Whether to email new valid links. Default is false.
168
    :type mailer: bool
169
170
    :param prod: Whether to check only the production server. Default is false.
171
    :type prod: bool
172
173
    :param no2: Whether to skip Alpha2/Beta2 servers. Default is false.
174
    :type no2: bool
175
    """
176
    if mailer:
177
        sql = True
178
        smtpc = smtputils.smtp_config_loader()
179
        smtpc = smtputils.smtp_config_generator(smtpc)
180
        smtpc['homepath'] = None
181
        pword = smtpc['password']
182
        smtputils.smtp_config_writer(**smtpc)
183
    else:
184
        pword = None
185
    argutils.slim_preamble("AUTOLOOKUP")
186
    record = utilities.prep_logfile() if log else None
187
    sess = requests.Session()
188
    while True:
189
        if loop and int(osversion.split(".")[3]) > ceiling:
190
            raise KeyboardInterrupt
191
        print("NOW SCANNING: {0}".format(osversion), end="\r")
192
        if not prod:
193
            results = networkutils.sr_lookup_bootstrap(osversion, sess, no2)
194
        else:
195
            res = networkutils.sr_lookup(osversion, networkutils.SERVERS["p"], sess)
196
            results = {"p": res, "a1": None, "a2": None, "b1": None, "b2": None}
197
        if results is None:
198
            raise KeyboardInterrupt
199
        a1rel, a1av = networkutils.clean_availability(results, 'a1')
200
        if not no2:
201
            a2rel, a2av = networkutils.clean_availability(results, 'a2')
202
        else:
203
            a2rel = "SR not in system"
204
            a2av = "  "
205
        b1rel, b1av = networkutils.clean_availability(results, 'b1')
206
        b2rel, b2av = networkutils.clean_availability(results, 'b2')
207
        prel, pav, avail = scriptutils.prod_avail(results, mailer, osversion, pword)
208
        avpack = (a1av, a2av, b1av, b2av, pav)
209
        swrelease = scriptutils.clean_swrel(set([a1rel, a2rel, b1rel, b2rel, prel]))
210
        if swrelease != "":
211
            out = scriptutils.autolookup_output(osversion, swrelease, avail, avpack, sql)
212
            scriptutils.autolookup_printer(out, avail, log, quiet, record)
213
        if autogen and avail == "Available":
214
            rad = utilities.increment(osversion, 1)
215
            scriptutils.linkgen(osversion, rad, prel)
216
        if not loop:
217
            raise KeyboardInterrupt  # hack, but whatever
218
        else:
219
            if int(osversion.split(".")[3]) > ceiling:
220
                raise KeyboardInterrupt
221
            else:
222
                osversion = utilities.increment(osversion, inc)
223
                swrelease = ""
224
                continue
225
226
227
if __name__ == "__main__":
228
    grab_args()
229