Completed
Push — master ( 344b16...b7946e )
by John
02:32 queued 01:09
created

droidlookup_main()   B

Complexity

Conditions 4

Size

Total Lines 29

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 4
c 1
b 0
f 0
dl 0
loc 29
rs 8.5806
1
#!/usr/bin/env python3
2
"""Check Android autoloader files."""
3
4
import sys  # load arguments
5
from bbarchivist import networkutils  # lookup
6
from bbarchivist import decorators  # Ctrl+C wrapping
7
from bbarchivist import utilities  # argument filters
8
from bbarchivist import scriptutils  # default parser
9
10
__author__ = "Thurask"
11
__license__ = "WTFPL v2"
12
__copyright__ = "Copyright 2015-2016 Thurask"
13
14
15
def grab_args():
16
    """
17
    Parse arguments from argparse/questionnaire.
18
19
    Invoke :func:`droidlookup.droidlookup_main` with those arguments."""
20
    if len(sys.argv) > 1:
21
        parser = scriptutils.default_parser("bb-droidlookup", "Get Android autoloaders")
22
        parser.add_argument(
23
            "device",
24
            help="Device to check",
25
            type=utilities.droidlookup_devicetype)
26
        parser.add_argument(
27
            "branch",
28
            help="OS branch, 3 letters")
29
        parser.add_argument(
30
            "floor",
31
            help="Start of search range",
32
            default=0,
33
            nargs="?",
34
            type=int,
35
            choices=range(0, 999),
36
            metavar="INT")
37
        parser.add_argument(
38
            "ceil",
39
            help="End of search range",
40
            default=999,
41
            nargs="?",
42
            type=int,
43
            choices=range(1, 1000),
44
            metavar="INT")
45
        parser.add_argument(
46
            "-t",
47
            "--type",
48
            help="Check SHA256/512 hashes instead",
49
            default=None,
50
            type=utilities.droidlookup_hashtype)
51
        parser.add_argument(
52
            "-s",
53
            "--single",
54
            dest="single",
55
            help="Only scan one version",
56
            action="store_true",
57
            default=False)
58
        args = parser.parse_args(sys.argv[1:])
59
        parser.set_defaults()
60
        if args.single:
61
            args.ceil = args.floor  # range(x, x+1) == x
62
        droidlookup_main(args.device, args.branch, args.floor, args.ceil, args.type)
63
    else:
64
        questionnaire()
65
66
67
def questionnaire():
68
    """
69
    Questions to ask if no arguments given.
70
    """
71
    print("DEVICES:")
72
    devlist = ["0=Priv",
73
               "1=DTEK50",]
74
    utilities.lprint(devlist)
75
    while True:
76
        devdex = int(input("SELECTED DEVICE: "))
77
        if not 0 <= devdex <= len(devlist) - 1:
78
            continue
79
        else:
80
            break
81
    device = devlist[devdex].split("=")[1]
82
    single = utilities.s2b(input("SINGLE OS (Y/N)?: "))
83
    if single:
84
        while True:
85
            scanos = input("OS (ex. AAD250): ")
86
            if len(scanos) != 6:
87
                print("OS MUST BE 3 LETTERS AND 3 NUMBERS, TRY AGAIN")
88
                continue
89
            branch = scanos[:3]
90
            if not branch.isalpha():
91
                print("OS MUST BE 3 LETTERS AND 3 NUMBERS, TRY AGAIN")
92
                continue
93
            floor = scanos[3:6]
94
            if not floor.isdigit():
95
                print("OS MUST BE 3 LETTERS AND 3 NUMBERS, TRY AGAIN")
96
                continue
97
            floor = int(floor)
98
            ceil = floor
99
            break
100
    else:
101
        while True:
102
            branch = input("BRANCH (ex. AAD): ")
103
            if len(branch) != 3 or not branch.isalpha():
104
                print("BRANCH MUST BE 3 LETTERS, TRY AGAIN")
105
                continue
106
            else:
107
                break
108
        while True:
109
            try:
110
                floor = int(input("INITIAL OS (0-998): "))
111
            except ValueError:
112
                continue
113
            else:
114
                if floor < 0:
115
                    print("INITIAL < 0, TRY AGAIN")
116
                    continue
117
                elif floor > 998:
118
                    print("INITIAL > 998, TRY AGAIN")
119
                    continue
120
                else:
121
                    break
122
        while True:
123
            try:
124
                ceil = int(input("FINAL OS (1-999): "))
125
            except ValueError:
126
                ceil = 999
127
            else:
128
                if ceil < floor:
129
                    print("FINAL < INITIAL, TRY AGAIN")
130
                    continue
131
                elif ceil > 999:
132
                    print("FINAL > 999, TRY AGAIN")
133
                    continue
134
                else:
135
                    break
136
    droidlookup_main(device, branch, floor, ceil)
137
    decorators.enter_to_exit(True)
138
139
140
@decorators.wrap_keyboard_except
141
def droidlookup_main(device, branch, floor=0, ceil=999, method=None):
142
    """
143
    Check the existence of Android factory images, in a range.
144
145
    :param device: Device to check.
146
    :type device: str
147
148
    :param branch: OS version, 3 letters.
149
    :type branch: str
150
151
    :param floor: Starting OS version, padded to 3 numbers. Default is 0.
152
    :type floor: int
153
154
    :param ceil: Ending OS version, padded to 3 numbers. Default is 999.
155
    :type ceil: int
156
157
    :param method: None for regular OS links, "hash256/512" for SHA256 or 512 hash.
158
    :type method: str
159
    """
160
    scriptutils.slim_preamble("DROIDLOOKUP")
161
    print("DEVICE: {0}".format(device.upper()))
162
    for ver in range(floor, ceil + 1):
163
        build = "{0}{1}".format(branch.upper(), str(ver).zfill(3))
164
        print("NOW SCANNING: {0}".format(build), end="\r")
165
        results = networkutils.droid_scanner(build, device, method)
166
        if results is not None:
167
            for result in results:
168
                print("{0} AVAILABLE! {1}\n".format(build, result), end="\r")
169
170
171
if __name__ == "__main__":
172
    grab_args()
173