htmlcmp 1.0.16__tar.gz → 1.0.18__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {htmlcmp-1.0.16 → htmlcmp-1.0.18}/PKG-INFO +1 -1
- {htmlcmp-1.0.16 → htmlcmp-1.0.18}/pyproject.toml +1 -1
- {htmlcmp-1.0.16 → htmlcmp-1.0.18}/src/htmlcmp/compare_output_server.py +34 -31
- {htmlcmp-1.0.16 → htmlcmp-1.0.18}/src/htmlcmp.egg-info/PKG-INFO +1 -1
- {htmlcmp-1.0.16 → htmlcmp-1.0.18}/README.md +0 -0
- {htmlcmp-1.0.16 → htmlcmp-1.0.18}/setup.cfg +0 -0
- {htmlcmp-1.0.16 → htmlcmp-1.0.18}/src/htmlcmp/__init__.py +0 -0
- {htmlcmp-1.0.16 → htmlcmp-1.0.18}/src/htmlcmp/common.py +0 -0
- {htmlcmp-1.0.16 → htmlcmp-1.0.18}/src/htmlcmp/compare_output.py +0 -0
- {htmlcmp-1.0.16 → htmlcmp-1.0.18}/src/htmlcmp/html_render_diff.py +0 -0
- {htmlcmp-1.0.16 → htmlcmp-1.0.18}/src/htmlcmp/tidy_output.py +0 -0
- {htmlcmp-1.0.16 → htmlcmp-1.0.18}/src/htmlcmp.egg-info/SOURCES.txt +0 -0
- {htmlcmp-1.0.16 → htmlcmp-1.0.18}/src/htmlcmp.egg-info/dependency_links.txt +0 -0
- {htmlcmp-1.0.16 → htmlcmp-1.0.18}/src/htmlcmp.egg-info/entry_points.txt +0 -0
- {htmlcmp-1.0.16 → htmlcmp-1.0.18}/src/htmlcmp.egg-info/requires.txt +0 -0
- {htmlcmp-1.0.16 → htmlcmp-1.0.18}/src/htmlcmp.egg-info/top_level.txt +0 -0
- {htmlcmp-1.0.16 → htmlcmp-1.0.18}/tests/test_html_render_diff.py +0 -0
|
@@ -17,6 +17,9 @@ from htmlcmp.compare_output import comparable_file, compare_files
|
|
|
17
17
|
from htmlcmp.html_render_diff import get_browser, html_render_diff
|
|
18
18
|
|
|
19
19
|
|
|
20
|
+
logger = logging.getLogger(__name__)
|
|
21
|
+
|
|
22
|
+
|
|
20
23
|
class Config:
|
|
21
24
|
path_a: Path = None
|
|
22
25
|
path_b: Path = None
|
|
@@ -37,31 +40,31 @@ class Observer:
|
|
|
37
40
|
event_type = event.event_type
|
|
38
41
|
src_path = Path(event.src_path)
|
|
39
42
|
|
|
40
|
-
|
|
43
|
+
logger.debug(f"Watchdog event: {event_type} {src_path}")
|
|
41
44
|
|
|
42
45
|
if event_type not in ["moved", "deleted", "created", "modified"]:
|
|
43
46
|
return
|
|
44
47
|
|
|
45
48
|
if src_path.is_file():
|
|
46
|
-
|
|
49
|
+
logger.debug(
|
|
47
50
|
f"Submit watchdog file change: {event_type} {src_path}"
|
|
48
51
|
)
|
|
49
52
|
Config.comparator.submit(src_path.relative_to(self._path))
|
|
50
53
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
+
logger.info("Create watchdog for paths:")
|
|
55
|
+
logger.info(f" A: {Config.path_a}")
|
|
56
|
+
logger.info(f" B: {Config.path_b}")
|
|
54
57
|
|
|
55
58
|
self._observer = watchdog.observers.Observer()
|
|
56
59
|
self._observer.schedule(Handler(Config.path_a), Config.path_a, recursive=True)
|
|
57
60
|
self._observer.schedule(Handler(Config.path_b), Config.path_b, recursive=True)
|
|
58
61
|
|
|
59
62
|
def start(self):
|
|
60
|
-
|
|
63
|
+
logger.info("Starting watchdog observer")
|
|
61
64
|
self._observer.start()
|
|
62
65
|
|
|
63
66
|
def init_compare(a: Path, b: Path):
|
|
64
|
-
|
|
67
|
+
logger.debug(f"Initial compare: {a} vs {b}")
|
|
65
68
|
|
|
66
69
|
if not isinstance(a, Path) or not isinstance(b, Path):
|
|
67
70
|
raise TypeError("Paths must be of type Path")
|
|
@@ -77,23 +80,23 @@ class Observer:
|
|
|
77
80
|
|
|
78
81
|
for name in common:
|
|
79
82
|
if (a / name).is_file() and comparable_file(a / name):
|
|
80
|
-
|
|
83
|
+
logger.debug(
|
|
81
84
|
f"Submit initial file comparison: {common_path / name}"
|
|
82
85
|
)
|
|
83
86
|
Config.comparator.submit(common_path / name)
|
|
84
87
|
elif (a / name).is_dir():
|
|
85
88
|
init_compare(a / name, b / name)
|
|
86
89
|
|
|
87
|
-
|
|
90
|
+
logger.info("Kick off initial comparison of all files")
|
|
88
91
|
init_compare(Config.path_a, Config.path_b)
|
|
89
|
-
|
|
92
|
+
logger.info("Initial comparison submitted")
|
|
90
93
|
|
|
91
94
|
def stop(self):
|
|
92
|
-
|
|
95
|
+
logger.info("Stopping watchdog observer")
|
|
93
96
|
self._observer.stop()
|
|
94
97
|
|
|
95
98
|
def join(self):
|
|
96
|
-
|
|
99
|
+
logger.info("Joining watchdog observer")
|
|
97
100
|
self._observer.join()
|
|
98
101
|
|
|
99
102
|
|
|
@@ -105,7 +108,7 @@ class Comparator:
|
|
|
105
108
|
browser = get_browser(driver=Config.driver)
|
|
106
109
|
Config.thread_local.browser = browser
|
|
107
110
|
|
|
108
|
-
|
|
111
|
+
logger.info(f"Creating comparator with {max_workers} workers")
|
|
109
112
|
|
|
110
113
|
self._executor = ThreadPoolExecutor(
|
|
111
114
|
max_workers=max_workers, initializer=initializer
|
|
@@ -114,7 +117,7 @@ class Comparator:
|
|
|
114
117
|
self._future = {}
|
|
115
118
|
|
|
116
119
|
def submit(self, path: Path):
|
|
117
|
-
|
|
120
|
+
logger.debug(f"Submitting comparison for path: {path}")
|
|
118
121
|
|
|
119
122
|
if not isinstance(path, Path):
|
|
120
123
|
raise TypeError("Path must be of type Path")
|
|
@@ -131,7 +134,7 @@ class Comparator:
|
|
|
131
134
|
self._future[path] = self._executor.submit(self.compare, path)
|
|
132
135
|
|
|
133
136
|
def compare(self, path: Path):
|
|
134
|
-
|
|
137
|
+
logger.debug(f"Comparing files for path: {path}")
|
|
135
138
|
|
|
136
139
|
if not isinstance(path, Path):
|
|
137
140
|
raise TypeError("Path must be of type Path")
|
|
@@ -148,7 +151,7 @@ class Comparator:
|
|
|
148
151
|
self._future.pop(path)
|
|
149
152
|
|
|
150
153
|
def result(self, path: Path):
|
|
151
|
-
|
|
154
|
+
logger.debug(f"Getting comparison result for path: {path}")
|
|
152
155
|
|
|
153
156
|
if not isinstance(path, Path):
|
|
154
157
|
raise TypeError("Path must be of type Path")
|
|
@@ -158,7 +161,7 @@ class Comparator:
|
|
|
158
161
|
return "unknown"
|
|
159
162
|
|
|
160
163
|
def result_symbol(self, path: Path):
|
|
161
|
-
|
|
164
|
+
logger.debug(f"Getting comparison result symbol for path: {path}")
|
|
162
165
|
|
|
163
166
|
if not isinstance(path, Path):
|
|
164
167
|
raise TypeError("Path must be of type Path")
|
|
@@ -173,7 +176,7 @@ class Comparator:
|
|
|
173
176
|
return "⛔"
|
|
174
177
|
|
|
175
178
|
def result_css(self, path: Path):
|
|
176
|
-
|
|
179
|
+
logger.debug(f"Getting comparison result CSS for path: {path}")
|
|
177
180
|
|
|
178
181
|
if not isinstance(path, Path):
|
|
179
182
|
raise TypeError("Path must be of type Path")
|
|
@@ -193,7 +196,7 @@ app = Flask("compare")
|
|
|
193
196
|
|
|
194
197
|
@app.route("/")
|
|
195
198
|
def root():
|
|
196
|
-
|
|
199
|
+
logger.debug("Generating root directory listing")
|
|
197
200
|
|
|
198
201
|
def print_tree(a: Path, b: Path):
|
|
199
202
|
if not isinstance(a, Path) or not isinstance(b, Path):
|
|
@@ -274,7 +277,7 @@ def root():
|
|
|
274
277
|
|
|
275
278
|
@app.route("/compare/<path:path>")
|
|
276
279
|
def compare(path: str):
|
|
277
|
-
|
|
280
|
+
logger.debug(f"Generating comparison page for path: {path}")
|
|
278
281
|
|
|
279
282
|
if not isinstance(path, str):
|
|
280
283
|
raise TypeError("Path must be a string")
|
|
@@ -316,7 +319,7 @@ iframe_b.contentWindow.addEventListener('scroll', function(event) {{
|
|
|
316
319
|
|
|
317
320
|
@app.route("/image_diff/<path:path>")
|
|
318
321
|
def image_diff(path: str):
|
|
319
|
-
|
|
322
|
+
logger.debug(f"Generating image diff for path: {path}")
|
|
320
323
|
|
|
321
324
|
if not isinstance(path, str):
|
|
322
325
|
raise TypeError("Path must be a string")
|
|
@@ -334,7 +337,7 @@ def image_diff(path: str):
|
|
|
334
337
|
|
|
335
338
|
@app.route("/file/<variant>/<path:path>")
|
|
336
339
|
def file(variant: str, path: str):
|
|
337
|
-
|
|
340
|
+
logger.debug(f"Serving file for variant: {variant}, path: {path}")
|
|
338
341
|
|
|
339
342
|
if not isinstance(variant, str) or not isinstance(path, str):
|
|
340
343
|
raise TypeError("Variant and path must be strings")
|
|
@@ -347,17 +350,13 @@ def file(variant: str, path: str):
|
|
|
347
350
|
|
|
348
351
|
def setup_logging(verbosity: int):
|
|
349
352
|
if verbosity >= 3:
|
|
350
|
-
level = logging.VERBOSE
|
|
351
|
-
elif verbosity == 2:
|
|
352
353
|
level = logging.DEBUG
|
|
353
|
-
elif verbosity ==
|
|
354
|
+
elif verbosity == 2:
|
|
354
355
|
level = logging.INFO
|
|
355
|
-
|
|
356
|
+
elif verbosity == 1:
|
|
356
357
|
level = logging.WARNING
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
logger.setLevel(level)
|
|
360
|
-
logger.handlers.clear()
|
|
358
|
+
else:
|
|
359
|
+
level = logging.ERROR
|
|
361
360
|
|
|
362
361
|
formatter = logging.Formatter(
|
|
363
362
|
fmt="%(asctime)s [%(levelname)s] %(name)s: %(message)s",
|
|
@@ -366,7 +365,11 @@ def setup_logging(verbosity: int):
|
|
|
366
365
|
|
|
367
366
|
console_handler = logging.StreamHandler(sys.stderr)
|
|
368
367
|
console_handler.setFormatter(formatter)
|
|
369
|
-
|
|
368
|
+
|
|
369
|
+
root_logger = logging.getLogger()
|
|
370
|
+
root_logger.setLevel(level)
|
|
371
|
+
root_logger.handlers.clear()
|
|
372
|
+
root_logger.addHandler(console_handler)
|
|
370
373
|
|
|
371
374
|
|
|
372
375
|
def main():
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|