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
|
|
|
|