Hanno Böck commited on 2022-07-15 12:43:59
Zeige 6 geänderte Dateien mit 174 Einfügungen und 134 Löschungen.
... | ... |
@@ -58,40 +58,48 @@ def checkoldsafe(old_safe, find_version): |
58 | 58 |
return False |
59 | 59 |
|
60 | 60 |
|
61 |
-def vulnprint(appname, version, safeversion, vuln, vfilename, subdir, |
|
62 |
- xml): |
|
63 |
- appdir = '/'.join(os.path.abspath(vfilename).split('/')[:-1 - subdir]) |
|
61 |
+def vulnprint(appname, version, safeversion, vuln, vfilename, subdir, xml): |
|
62 |
+ appdir = "/".join(os.path.abspath(vfilename).split("/")[: -1 - subdir]) |
|
64 | 63 |
if not xml: |
65 | 64 |
print(f"{appname} {version} ({safeversion}) {vuln} {appdir}") |
66 | 65 |
else: |
67 |
- state = 'vulnerable' |
|
68 |
- if safeversion == 'ok': |
|
69 |
- state = 'ok' |
|
66 |
+ state = "vulnerable" |
|
67 |
+ if safeversion == "ok": |
|
68 |
+ state = "ok" |
|
70 | 69 |
print(f' <app state="{state}">') |
71 |
- print(f' <appname>{escape(appname)}</appname>') |
|
72 |
- print(f' <version>{escape(version)}</version>') |
|
73 |
- print(f' <directory>{escape(appdir)}</directory>') |
|
74 |
- if state == 'vulnerable': |
|
75 |
- print(f' <safeversion>{escape(safeversion)}</safeversion>') |
|
76 |
- print(f' <vulninfo>{escape(vuln)}</vulninfo>') |
|
77 |
- print(' </app>') |
|
70 |
+ print(f" <appname>{escape(appname)}</appname>") |
|
71 |
+ print(f" <version>{escape(version)}</version>") |
|
72 |
+ print(f" <directory>{escape(appdir)}</directory>") |
|
73 |
+ if state == "vulnerable": |
|
74 |
+ print(f" <safeversion>{escape(safeversion)}</safeversion>") |
|
75 |
+ print(f" <vulninfo>{escape(vuln)}</vulninfo>") |
|
76 |
+ print(" </app>") |
|
78 | 77 |
|
79 | 78 |
|
80 | 79 |
# Command-line options |
81 | 80 |
parser = argparse.ArgumentParser() |
82 |
-parser.add_argument("dirs", nargs="*", |
|
83 |
- help="Directories to scan") |
|
84 |
-parser.add_argument("-a", "--all", action="store_true", |
|
85 |
- help="Show all webapps found, not just vulnerable") |
|
86 |
-parser.add_argument("-x", "--xml", action="store_true", |
|
87 |
- help="Output results as XML") |
|
88 |
-parser.add_argument("-3", "--thirdparty", action="store_true", |
|
89 |
- help="Scan for third-party components like jquery") |
|
81 |
+parser.add_argument("dirs", nargs="*", help="Directories to scan") |
|
82 |
+parser.add_argument( |
|
83 |
+ "-a", |
|
84 |
+ "--all", |
|
85 |
+ action="store_true", |
|
86 |
+ help="Show all webapps found, not just vulnerable", |
|
87 |
+) |
|
88 |
+parser.add_argument("-x", "--xml", action="store_true", help="Output results as XML") |
|
89 |
+parser.add_argument( |
|
90 |
+ "-3", |
|
91 |
+ "--thirdparty", |
|
92 |
+ action="store_true", |
|
93 |
+ help="Scan for third-party components like jquery", |
|
94 |
+) |
|
90 | 95 |
opts = parser.parse_args() |
91 | 96 |
|
92 | 97 |
jdir = False |
93 |
-for p in [os.path.dirname(sys.argv[0]) + '/freewvsdb', '/var/lib/freewvs', |
|
94 |
- str(pathlib.Path.home()) + "/.cache/freewvs/"]: |
|
98 |
+for p in [ |
|
99 |
+ os.path.dirname(sys.argv[0]) + "/freewvsdb", |
|
100 |
+ "/var/lib/freewvs", |
|
101 |
+ str(pathlib.Path.home()) + "/.cache/freewvs/", |
|
102 |
+]: |
|
95 | 103 |
if os.path.isdir(p): |
96 | 104 |
jdir = p |
97 | 105 |
break |
... | ... |
@@ -100,20 +108,20 @@ if not jdir: |
100 | 108 |
sys.exit(1) |
101 | 109 |
|
102 | 110 |
jconfig = [] |
103 |
-for cfile in glob.glob(jdir + '/*.json'): |
|
111 |
+for cfile in glob.glob(jdir + "/*.json"): |
|
104 | 112 |
with open(cfile, encoding="ascii") as json_file: |
105 | 113 |
data = json.load(json_file) |
106 | 114 |
jconfig += data |
107 | 115 |
|
108 | 116 |
scanfiles = set() |
109 | 117 |
for app in jconfig: |
110 |
- for det in app['detection']: |
|
111 |
- scanfiles.add(det['file']) |
|
118 |
+ for det in app["detection"]: |
|
119 |
+ scanfiles.add(det["file"]) |
|
112 | 120 |
|
113 | 121 |
|
114 | 122 |
if opts.xml: |
115 | 123 |
print('<?xml version="1.0" ?>') |
116 |
- print('<freewvs>') |
|
124 |
+ print("<freewvs>") |
|
117 | 125 |
|
118 | 126 |
# start the search |
119 | 127 |
|
... | ... |
@@ -125,61 +133,78 @@ for fdir in opts.dirs: |
125 | 133 |
del dirs[:] |
126 | 134 |
for filename in scanfiles.intersection(files): |
127 | 135 |
for item in jconfig: |
128 |
- if not opts.thirdparty and 'thirdparty' in item: |
|
136 |
+ if not opts.thirdparty and "thirdparty" in item: |
|
129 | 137 |
continue |
130 |
- for det in item['detection']: |
|
131 |
- if filename == det['file']: |
|
138 |
+ for det in item["detection"]: |
|
139 |
+ if filename == det["file"]: |
|
132 | 140 |
mfile = os.path.join(root, filename) |
133 | 141 |
try: |
134 |
- file = open(mfile, encoding='ascii', |
|
135 |
- errors='replace') |
|
142 |
+ file = open(mfile, encoding="ascii", errors="replace") |
|
136 | 143 |
except OSError: |
137 | 144 |
continue |
138 | 145 |
filestr = file.read(200000) |
139 | 146 |
file.close() |
140 | 147 |
|
141 |
- if (('extra_match' in det |
|
142 |
- and det['extra_match'] not in filestr) |
|
143 |
- or ('extra_nomatch' in det |
|
144 |
- and det['extra_nomatch'] in filestr)): |
|
148 |
+ if ( |
|
149 |
+ "extra_match" in det and det["extra_match"] not in filestr |
|
150 |
+ ) or ( |
|
151 |
+ "extra_nomatch" in det and det["extra_nomatch"] in filestr |
|
152 |
+ ): |
|
145 | 153 |
continue |
146 | 154 |
|
147 |
- if ('path_match' in det |
|
148 |
- and (not root.endswith(det['path_match']))): |
|
155 |
+ if "path_match" in det and ( |
|
156 |
+ not root.endswith(det["path_match"]) |
|
157 |
+ ): |
|
149 | 158 |
continue |
150 | 159 |
|
151 |
- findversion = re.search(re.escape(det['variable']) |
|
152 |
- + r"[^0-9\n\r]*[.]*" |
|
160 |
+ findversion = re.search( |
|
161 |
+ re.escape(det["variable"]) + r"[^0-9\n\r]*[.]*" |
|
153 | 162 |
"([0-9.]*[0-9])[^0-9.]", |
154 |
- filestr) |
|
163 |
+ filestr, |
|
164 |
+ ) |
|
155 | 165 |
if not findversion: |
156 | 166 |
continue |
157 | 167 |
findversion = findversion.group(1) |
158 | 168 |
|
159 | 169 |
# Very ugly phpbb workaround |
160 |
- if 'add_minor' in det: |
|
161 |
- findversion = findversion.split('.') |
|
162 |
- findversion[-1] = str(int(findversion[-1]) |
|
163 |
- + int(det['add_minor'])) |
|
164 |
- findversion = '.'.join(findversion) |
|
165 |
- |
|
166 |
- if (not versioncompare(item['safe'], findversion) |
|
167 |
- or ('old_safe' in item |
|
168 |
- and checkoldsafe(item['old_safe'], |
|
169 |
- findversion))): |
|
170 |
+ if "add_minor" in det: |
|
171 |
+ findversion = findversion.split(".") |
|
172 |
+ findversion[-1] = str( |
|
173 |
+ int(findversion[-1]) + int(det["add_minor"]) |
|
174 |
+ ) |
|
175 |
+ findversion = ".".join(findversion) |
|
176 |
+ |
|
177 |
+ if not versioncompare(item["safe"], findversion) or ( |
|
178 |
+ "old_safe" in item |
|
179 |
+ and checkoldsafe(item["old_safe"], findversion) |
|
180 |
+ ): |
|
170 | 181 |
if opts.all: |
171 |
- vulnprint(item['name'], findversion, "ok", "", |
|
172 |
- mfile, det['subdir'], opts.xml) |
|
182 |
+ vulnprint( |
|
183 |
+ item["name"], |
|
184 |
+ findversion, |
|
185 |
+ "ok", |
|
186 |
+ "", |
|
187 |
+ mfile, |
|
188 |
+ det["subdir"], |
|
189 |
+ opts.xml, |
|
190 |
+ ) |
|
173 | 191 |
continue |
174 | 192 |
|
175 |
- safev = item['safe'] |
|
176 |
- if 'old_safe' in item: |
|
177 |
- for ver in item['old_safe'].split(','): |
|
193 |
+ safev = item["safe"] |
|
194 |
+ if "old_safe" in item: |
|
195 |
+ for ver in item["old_safe"].split(","): |
|
178 | 196 |
if versioncompare(ver, findversion): |
179 | 197 |
safev = ver |
180 | 198 |
|
181 |
- vulnprint(item['name'], findversion, safev, |
|
182 |
- item['vuln'], mfile, det['subdir'], opts.xml) |
|
199 |
+ vulnprint( |
|
200 |
+ item["name"], |
|
201 |
+ findversion, |
|
202 |
+ safev, |
|
203 |
+ item["vuln"], |
|
204 |
+ mfile, |
|
205 |
+ det["subdir"], |
|
206 |
+ opts.xml, |
|
207 |
+ ) |
|
183 | 208 |
|
184 | 209 |
if opts.xml: |
185 |
- print('</freewvs>') |
|
210 |
+ print("</freewvs>") |
... | ... |
@@ -4,34 +4,36 @@ import os |
4 | 4 |
import setuptools |
5 | 5 |
import setuptools.command.install |
6 | 6 |
|
7 |
-f = open(os.path.join(os.path.abspath(os.path.dirname(__file__)), 'README.md'), |
|
8 |
- encoding="ascii") |
|
7 |
+f = open( |
|
8 |
+ os.path.join(os.path.abspath(os.path.dirname(__file__)), "README.md"), |
|
9 |
+ encoding="ascii", |
|
10 |
+) |
|
9 | 11 |
readme = f.read() |
10 | 12 |
f.close() |
11 | 13 |
|
12 | 14 |
setuptools.setup( |
13 |
- name='freewvs', |
|
15 |
+ name="freewvs", |
|
14 | 16 |
version="0.1.2", |
15 | 17 |
description="A free web vulnerability scanner", |
16 | 18 |
long_description=readme, |
17 |
- long_description_content_type='text/markdown', |
|
18 |
- url='https://freewvs.schokokeks.org/', |
|
19 |
+ long_description_content_type="text/markdown", |
|
20 |
+ url="https://freewvs.schokokeks.org/", |
|
19 | 21 |
packages=[], |
20 |
- scripts=['freewvs', 'update-freewvsdb'], |
|
21 |
- python_requires='>=3', |
|
22 |
+ scripts=["freewvs", "update-freewvsdb"], |
|
23 |
+ python_requires=">=3", |
|
22 | 24 |
license="CC0", |
23 |
- keywords=['security', 'vulnerability', 'web'], |
|
25 |
+ keywords=["security", "vulnerability", "web"], |
|
24 | 26 |
classifiers=[ |
25 |
- 'Development Status :: 4 - Beta', |
|
26 |
- 'Intended Audience :: System Administrators', |
|
27 |
- 'License :: CC0 1.0 Universal (CC0 1.0) Public Domain Dedication', |
|
28 |
- 'Natural Language :: English', |
|
29 |
- 'Programming Language :: Python :: 3', |
|
30 |
- 'Programming Language :: Python :: 3 :: Only', |
|
31 |
- 'Programming Language :: Python :: 3.7', |
|
32 |
- 'Programming Language :: Python :: 3.8', |
|
33 |
- 'Programming Language :: Python :: 3.9', |
|
34 |
- 'Programming Language :: Python :: 3.10', |
|
35 |
- 'Programming Language :: Python :: 3.11', |
|
36 |
- ] |
|
27 |
+ "Development Status :: 4 - Beta", |
|
28 |
+ "Intended Audience :: System Administrators", |
|
29 |
+ "License :: CC0 1.0 Universal (CC0 1.0) Public Domain Dedication", |
|
30 |
+ "Natural Language :: English", |
|
31 |
+ "Programming Language :: Python :: 3", |
|
32 |
+ "Programming Language :: Python :: 3 :: Only", |
|
33 |
+ "Programming Language :: Python :: 3.7", |
|
34 |
+ "Programming Language :: Python :: 3.8", |
|
35 |
+ "Programming Language :: Python :: 3.9", |
|
36 |
+ "Programming Language :: Python :: 3.10", |
|
37 |
+ "Programming Language :: Python :: 3.11", |
|
38 |
+ ], |
|
37 | 39 |
) |
... | ... |
@@ -6,21 +6,22 @@ import glob |
6 | 6 |
class TestCodingstyle(unittest.TestCase): |
7 | 7 |
@staticmethod |
8 | 8 |
def test_codingstyle(): |
9 |
- pyfiles = ["freewvs", "update-freewvsdb", |
|
10 |
- "setup.py"] + glob.glob("tests/*.py") |
|
11 |
- subprocess.run(["pycodestyle", "--ignore=W503", "--max-line-length=88"] |
|
12 |
- + pyfiles, check=True) |
|
9 |
+ pyfiles = ["freewvs", "update-freewvsdb", "setup.py"] + glob.glob("tests/*.py") |
|
10 |
+ subprocess.run( |
|
11 |
+ ["pycodestyle", "--ignore=W503", "--max-line-length=88"] + pyfiles, |
|
12 |
+ check=True, |
|
13 |
+ ) |
|
13 | 14 |
subprocess.run(["pyflakes"] + pyfiles, check=True) |
14 | 15 |
|
15 |
- pylint_disable = "missing-docstring,invalid-name,duplicate-code," \ |
|
16 |
+ pylint_disable = ( |
|
17 |
+ "missing-docstring,invalid-name,duplicate-code," |
|
16 | 18 |
+ "too-many-arguments,consider-using-with" |
17 |
- subprocess.run(["pylint", f"--disable={pylint_disable}"] |
|
18 |
- + pyfiles, check=True) |
|
19 |
+ ) |
|
20 |
+ subprocess.run(["pylint", f"--disable={pylint_disable}"] + pyfiles, check=True) |
|
19 | 21 |
|
20 | 22 |
subprocess.run(["flake8", "--select=DUO"] + pyfiles, check=True) |
21 |
- subprocess.run(["pyupgrade", "--py311-plus"] |
|
22 |
- + pyfiles, check=True) |
|
23 |
+ subprocess.run(["pyupgrade", "--py311-plus"] + pyfiles, check=True) |
|
23 | 24 |
|
24 | 25 |
|
25 |
-if __name__ == '__main__': |
|
26 |
+if __name__ == "__main__": |
|
26 | 27 |
unittest.main() |
... | ... |
@@ -11,44 +11,46 @@ TESTDATA_REPO = "https://github.com/schokokeksorg/freewvs-testdata" |
11 | 11 |
|
12 | 12 |
|
13 | 13 |
class TestFreewvsData(unittest.TestCase): |
14 |
- @unittest.skipUnless(os.environ.get("RUN_ONLINETESTS"), |
|
15 |
- "Not running online tests") |
|
14 |
+ @unittest.skipUnless(os.environ.get("RUN_ONLINETESTS"), "Not running online tests") |
|
16 | 15 |
def test_freewvs_testdata(self): |
17 | 16 |
tmp = tempfile.mkdtemp(prefix="testdata") |
18 | 17 |
if os.environ.get("TESTDATA_REPOSITORY"): |
19 |
- os.symlink(os.environ.get("TESTDATA_REPOSITORY"), |
|
20 |
- tmp + "/testdata") |
|
18 |
+ os.symlink(os.environ.get("TESTDATA_REPOSITORY"), tmp + "/testdata") |
|
21 | 19 |
else: |
22 |
- subprocess.run(["git", "clone", "--depth=1", |
|
23 |
- TESTDATA_REPO, |
|
24 |
- tmp + "/testdata"], |
|
25 |
- check=True) |
|
20 |
+ subprocess.run( |
|
21 |
+ ["git", "clone", "--depth=1", TESTDATA_REPO, tmp + "/testdata"], |
|
22 |
+ check=True, |
|
23 |
+ ) |
|
26 | 24 |
|
27 | 25 |
for tdir in glob.glob(tmp + "/testdata/webapps/*"): |
28 | 26 |
bdir = os.path.basename(tdir) |
29 | 27 |
for tarball in glob.glob(tdir + "/dist/*"): |
30 | 28 |
tname = os.path.basename(tarball) |
31 |
- shutil.unpack_archive(tarball, |
|
32 |
- f"{tmp}/{bdir}/{tname}-src") |
|
33 |
- fwrun = subprocess.run(["./freewvs", "-a", tmp + "/" + bdir], |
|
34 |
- stdout=subprocess.PIPE, check=True) |
|
29 |
+ shutil.unpack_archive(tarball, f"{tmp}/{bdir}/{tname}-src") |
|
30 |
+ fwrun = subprocess.run( |
|
31 |
+ ["./freewvs", "-a", tmp + "/" + bdir], |
|
32 |
+ stdout=subprocess.PIPE, |
|
33 |
+ check=True, |
|
34 |
+ ) |
|
35 | 35 |
fwdata = re.sub(tmp, "[dir]", fwrun.stdout.decode("utf-8")) |
36 |
- fwclean = re.sub(r' \(.* ', " ", fwdata) |
|
36 |
+ fwclean = re.sub(r" \(.* ", " ", fwdata) |
|
37 | 37 |
f = open(tdir + "/refdata-a.txt", encoding="ascii") |
38 | 38 |
refdata = f.read() |
39 | 39 |
f.close() |
40 |
- refclean = re.sub(r' \(.* ', " ", refdata) |
|
40 |
+ refclean = re.sub(r" \(.* ", " ", refdata) |
|
41 | 41 |
fwclean = sorted(fwclean.split("\n")) |
42 | 42 |
refclean = sorted(refclean.split("\n")) |
43 | 43 |
if refclean != fwclean: |
44 | 44 |
print("\n".join(difflib.ndiff(refclean, fwclean))) |
45 |
- self.assertEqual(refclean, fwclean, |
|
46 |
- msg=f"Output in {bdir} does not match") |
|
45 |
+ self.assertEqual(refclean, fwclean, msg=f"Output in {bdir} does not match") |
|
47 | 46 |
|
48 | 47 |
# misc tests, for read errors, garbage data etc. |
49 |
- subprocess.run(["./freewvs", "-a", tmp + "/testdata/misc/"], |
|
50 |
- stdout=subprocess.PIPE, check=True) |
|
48 |
+ subprocess.run( |
|
49 |
+ ["./freewvs", "-a", tmp + "/testdata/misc/"], |
|
50 |
+ stdout=subprocess.PIPE, |
|
51 |
+ check=True, |
|
52 |
+ ) |
|
51 | 53 |
|
52 | 54 |
|
53 |
-if __name__ == '__main__': |
|
55 |
+if __name__ == "__main__": |
|
54 | 56 |
unittest.main() |
... | ... |
@@ -13,9 +13,9 @@ def versioncompare(safe_version, find_version): |
13 | 13 |
|
14 | 14 |
|
15 | 15 |
class TestJsonLint(unittest.TestCase): |
16 |
- |
|
17 |
- @unittest.skipIf(sys.version_info < (3, 6, 0), |
|
18 |
- "json.dumps force-sorts on python 3.5") |
|
16 |
+ @unittest.skipIf( |
|
17 |
+ sys.version_info < (3, 6, 0), "json.dumps force-sorts on python 3.5" |
|
18 |
+ ) |
|
19 | 19 |
def test_json_lint(self): |
20 | 20 |
valid = True |
21 | 21 |
for f in glob.glob("freewvsdb/*.json"): |
... | ... |
@@ -32,48 +32,58 @@ class TestJsonLint(unittest.TestCase): |
32 | 32 |
|
33 | 33 |
def test_json_values(self): |
34 | 34 |
jconfig = [] |
35 |
- for cfile in glob.glob('freewvsdb/*.json'): |
|
35 |
+ for cfile in glob.glob("freewvsdb/*.json"): |
|
36 | 36 |
with open(cfile, encoding="ascii") as json_file: |
37 | 37 |
jconfig += json.load(json_file) |
38 | 38 |
|
39 |
- mkeys = {'name', 'url', 'safe', 'vuln', 'detection'} |
|
39 |
+ mkeys = {"name", "url", "safe", "vuln", "detection"} |
|
40 | 40 |
for item in jconfig: |
41 | 41 |
|
42 | 42 |
# check for all mandatory keys |
43 |
- self.assertEqual(mkeys.intersection(item.keys()), mkeys, |
|
44 |
- msg=f"Missing key in {item['name']}") |
|
43 |
+ self.assertEqual( |
|
44 |
+ mkeys.intersection(item.keys()), |
|
45 |
+ mkeys, |
|
46 |
+ msg=f"Missing key in {item['name']}", |
|
47 |
+ ) |
|
45 | 48 |
|
46 | 49 |
# check we have at least one detection |
47 |
- self.assertTrue(len(item['detection']) >= 1, |
|
48 |
- msg=f"No detection in {item['name']}") |
|
50 |
+ self.assertTrue( |
|
51 |
+ len(item["detection"]) >= 1, msg=f"No detection in {item['name']}" |
|
52 |
+ ) |
|
49 | 53 |
|
50 | 54 |
# vuln needs to be CVE or HTTPS URL |
51 |
- self.assertTrue(re.match("^CVE-[0-9]*-[0-9]*$", item['vuln']) |
|
52 |
- or item['vuln'].startswith("https://"), |
|
53 |
- msg=f"{item['name']}: Invalid vuln {item['vuln']}") |
|
55 |
+ self.assertTrue( |
|
56 |
+ re.match("^CVE-[0-9]*-[0-9]*$", item["vuln"]) |
|
57 |
+ or item["vuln"].startswith("https://"), |
|
58 |
+ msg=f"{item['name']}: Invalid vuln {item['vuln']}", |
|
59 |
+ ) |
|
54 | 60 |
|
55 | 61 |
# make sure old_safe is properly sorted |
56 |
- if 'old_safe' in item: |
|
57 |
- old_safe = item['old_safe'].split(',') |
|
62 |
+ if "old_safe" in item: |
|
63 |
+ old_safe = item["old_safe"].split(",") |
|
58 | 64 |
for i in range(1, len(old_safe)): |
59 |
- self.assertTrue(versioncompare(old_safe[i - 1], |
|
60 |
- old_safe[i]), |
|
65 |
+ self.assertTrue( |
|
66 |
+ versioncompare(old_safe[i - 1], old_safe[i]), |
|
61 | 67 |
msg=f"{item['name']}: Invalid old_safe" |
62 |
- " ordering {item['old_safe']}") |
|
68 |
+ " ordering {item['old_safe']}", |
|
69 |
+ ) |
|
63 | 70 |
|
64 | 71 |
# make sure latest is not outdated |
65 |
- if 'latest' in item and item['safe'] != "": |
|
66 |
- self.assertTrue(not versioncompare(item['safe'], |
|
67 |
- item['latest']), |
|
72 |
+ if "latest" in item and item["safe"] != "": |
|
73 |
+ self.assertTrue( |
|
74 |
+ not versioncompare(item["safe"], item["latest"]), |
|
68 | 75 |
msg=f"{item['name']}: Safe version " |
69 | 76 |
"{item['safe']} newer than latest" |
70 |
- " {item['latest']}") |
|
77 |
+ " {item['latest']}", |
|
78 |
+ ) |
|
71 | 79 |
|
72 | 80 |
# subdir needs to be integer |
73 |
- for det in item['detection']: |
|
74 |
- self.assertTrue(isinstance(det['subdir'], int), |
|
75 |
- msg=f"{item['name']}: subdir not int") |
|
81 |
+ for det in item["detection"]: |
|
82 |
+ self.assertTrue( |
|
83 |
+ isinstance(det["subdir"], int), |
|
84 |
+ msg=f"{item['name']}: subdir not int", |
|
85 |
+ ) |
|
76 | 86 |
|
77 | 87 |
|
78 |
-if __name__ == '__main__': |
|
88 |
+if __name__ == "__main__": |
|
79 | 89 |
unittest.main() |
... | ... |
@@ -9,7 +9,7 @@ import tarfile |
9 | 9 |
|
10 | 10 |
|
11 | 11 |
DBURL = "https://freewvsdb.schokokeks.org/" |
12 |
-dbpaths = ['/var/lib/freewvs/', str(pathlib.Path.home()) + "/.cache/freewvs/"] |
|
12 |
+dbpaths = ["/var/lib/freewvs/", str(pathlib.Path.home()) + "/.cache/freewvs/"] |
|
13 | 13 |
|
14 | 14 |
target = False |
15 | 15 |
for dbpath in dbpaths: |
16 | 16 |