htmlcmp 1.0.7__tar.gz → 1.0.9__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.7 → htmlcmp-1.0.9}/PKG-INFO +1 -1
- {htmlcmp-1.0.7 → htmlcmp-1.0.9}/pyproject.toml +1 -1
- {htmlcmp-1.0.7 → htmlcmp-1.0.9}/src/htmlcmp/compare_output.py +29 -43
- {htmlcmp-1.0.7 → htmlcmp-1.0.9}/src/htmlcmp/compare_output_server.py +33 -43
- {htmlcmp-1.0.7 → htmlcmp-1.0.9}/src/htmlcmp/html_render_diff.py +2 -2
- {htmlcmp-1.0.7 → htmlcmp-1.0.9}/src/htmlcmp.egg-info/PKG-INFO +1 -1
- {htmlcmp-1.0.7 → htmlcmp-1.0.9}/README.md +0 -0
- {htmlcmp-1.0.7 → htmlcmp-1.0.9}/setup.cfg +0 -0
- {htmlcmp-1.0.7 → htmlcmp-1.0.9}/src/htmlcmp/__init__.py +0 -0
- {htmlcmp-1.0.7 → htmlcmp-1.0.9}/src/htmlcmp/common.py +0 -0
- {htmlcmp-1.0.7 → htmlcmp-1.0.9}/src/htmlcmp/tidy_output.py +0 -0
- {htmlcmp-1.0.7 → htmlcmp-1.0.9}/src/htmlcmp.egg-info/SOURCES.txt +0 -0
- {htmlcmp-1.0.7 → htmlcmp-1.0.9}/src/htmlcmp.egg-info/dependency_links.txt +0 -0
- {htmlcmp-1.0.7 → htmlcmp-1.0.9}/src/htmlcmp.egg-info/entry_points.txt +0 -0
- {htmlcmp-1.0.7 → htmlcmp-1.0.9}/src/htmlcmp.egg-info/requires.txt +0 -0
- {htmlcmp-1.0.7 → htmlcmp-1.0.9}/src/htmlcmp.egg-info/top_level.txt +0 -0
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
#!/usr/bin/env python3
|
|
2
2
|
# -*- coding: utf-8 -*-
|
|
3
3
|
|
|
4
|
-
import os
|
|
5
4
|
import sys
|
|
6
5
|
import argparse
|
|
7
6
|
import json
|
|
8
7
|
import threading
|
|
9
8
|
import filecmp
|
|
9
|
+
from pathlib import Path
|
|
10
10
|
from concurrent.futures import ThreadPoolExecutor
|
|
11
11
|
|
|
12
12
|
from htmlcmp.html_render_diff import get_browser, html_render_diff
|
|
@@ -34,10 +34,10 @@ def compare_html(a, b, browser=None, diff_output=None):
|
|
|
34
34
|
diff, (image_a, image_b) = html_render_diff(a, b, browser=browser)
|
|
35
35
|
result = True if diff.getbbox() is None else False
|
|
36
36
|
if diff_output is not None and not result:
|
|
37
|
-
|
|
38
|
-
image_a.save(
|
|
39
|
-
image_b.save(
|
|
40
|
-
diff.save(
|
|
37
|
+
diff_output.mkdir(parents=True, exist_ok=True)
|
|
38
|
+
image_a.save(diff_output / "a.png")
|
|
39
|
+
image_b.save(diff_output / "b.png")
|
|
40
|
+
diff.save(diff_output / "diff.png")
|
|
41
41
|
return result
|
|
42
42
|
|
|
43
43
|
|
|
@@ -68,24 +68,14 @@ def submit_compare_dirs(a, b, executor, diff_output=None, **kwargs):
|
|
|
68
68
|
"right_dirs_missing": [],
|
|
69
69
|
}
|
|
70
70
|
|
|
71
|
-
left = sorted(
|
|
72
|
-
right = sorted(
|
|
71
|
+
left = sorted(p.name for p in a.iterdir())
|
|
72
|
+
right = sorted(p.name for p in b.iterdir())
|
|
73
73
|
|
|
74
74
|
left_files = sorted(
|
|
75
|
-
[
|
|
76
|
-
name
|
|
77
|
-
for name in left
|
|
78
|
-
if os.path.isfile(os.path.join(a, name))
|
|
79
|
-
and comparable_file(os.path.join(a, name))
|
|
80
|
-
]
|
|
75
|
+
[name for name in left if (a / name).is_file() and comparable_file(a / name)]
|
|
81
76
|
)
|
|
82
77
|
right_files = sorted(
|
|
83
|
-
[
|
|
84
|
-
name
|
|
85
|
-
for name in right
|
|
86
|
-
if os.path.isfile(os.path.join(b, name))
|
|
87
|
-
and comparable_file(os.path.join(b, name))
|
|
88
|
-
]
|
|
78
|
+
[name for name in right if (b / name).is_file() and comparable_file(b / name)]
|
|
89
79
|
)
|
|
90
80
|
common_files = [name for name in left_files if name in right_files]
|
|
91
81
|
|
|
@@ -96,11 +86,9 @@ def submit_compare_dirs(a, b, executor, diff_output=None, **kwargs):
|
|
|
96
86
|
for name in common_files:
|
|
97
87
|
future = executor.submit(
|
|
98
88
|
compare,
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
diff_output=(
|
|
102
|
-
None if diff_output is None else os.path.join(diff_output, name)
|
|
103
|
-
),
|
|
89
|
+
a / name,
|
|
90
|
+
b / name,
|
|
91
|
+
diff_output=(None if diff_output is None else diff_output / name),
|
|
104
92
|
)
|
|
105
93
|
results["common_files"].append((name, future))
|
|
106
94
|
|
|
@@ -111,20 +99,16 @@ def submit_compare_dirs(a, b, executor, diff_output=None, **kwargs):
|
|
|
111
99
|
name for name in left_files if name not in right_files
|
|
112
100
|
]
|
|
113
101
|
|
|
114
|
-
left_dirs = sorted([name for name in left if
|
|
115
|
-
right_dirs = sorted(
|
|
116
|
-
[name for name in right if os.path.isdir(os.path.join(b, name))]
|
|
117
|
-
)
|
|
102
|
+
left_dirs = sorted([name for name in left if (a / name).is_dir()])
|
|
103
|
+
right_dirs = sorted([name for name in right if (b / name).is_dir()])
|
|
118
104
|
common_dirs = [path for path in left_dirs if path in right_dirs]
|
|
119
105
|
|
|
120
106
|
for name in common_dirs:
|
|
121
107
|
sub_results = submit_compare_dirs(
|
|
122
|
-
|
|
123
|
-
|
|
108
|
+
a / name,
|
|
109
|
+
b / name,
|
|
124
110
|
executor=executor,
|
|
125
|
-
diff_output=(
|
|
126
|
-
None if diff_output is None else os.path.join(diff_output, name)
|
|
127
|
-
),
|
|
111
|
+
diff_output=(None if diff_output is None else diff_output / name),
|
|
128
112
|
**kwargs,
|
|
129
113
|
)
|
|
130
114
|
results["common_dirs"].append((name, sub_results))
|
|
@@ -158,7 +142,7 @@ def print_results(results, a, b, level=0, prefix=""):
|
|
|
158
142
|
f"{prefix_file}{bcolors.FAIL}missing files left: {left_files_missing} ✘{bcolors.ENDC}"
|
|
159
143
|
)
|
|
160
144
|
result["left_files_missing"].extend(
|
|
161
|
-
[
|
|
145
|
+
[a / name for name in results["left_files_missing"]]
|
|
162
146
|
)
|
|
163
147
|
right_files_missing = " ".join(results["right_files_missing"])
|
|
164
148
|
if right_files_missing:
|
|
@@ -166,7 +150,7 @@ def print_results(results, a, b, level=0, prefix=""):
|
|
|
166
150
|
f"{prefix_file}{bcolors.FAIL}missing files right: {right_files_missing} ✘{bcolors.ENDC}"
|
|
167
151
|
)
|
|
168
152
|
result["right_files_missing"].extend(
|
|
169
|
-
[
|
|
153
|
+
[a / name for name in results["right_files_missing"]]
|
|
170
154
|
)
|
|
171
155
|
|
|
172
156
|
for name, future in results["common_files"]:
|
|
@@ -175,7 +159,7 @@ def print_results(results, a, b, level=0, prefix=""):
|
|
|
175
159
|
print(f"{prefix_file}{bcolors.OKGREEN}{name} ✓{bcolors.ENDC}")
|
|
176
160
|
else:
|
|
177
161
|
print(f"{prefix_file}{bcolors.FAIL}{name} ✘{bcolors.ENDC}")
|
|
178
|
-
result["files_different"].append(
|
|
162
|
+
result["files_different"].append(a / name)
|
|
179
163
|
|
|
180
164
|
left_dirs_missing = " ".join(results["left_dirs_missing"])
|
|
181
165
|
if left_dirs_missing:
|
|
@@ -183,7 +167,7 @@ def print_results(results, a, b, level=0, prefix=""):
|
|
|
183
167
|
f"{prefix_file}{bcolors.FAIL}missing dirs left: {left_dirs_missing} ✘{bcolors.ENDC}"
|
|
184
168
|
)
|
|
185
169
|
result["left_dirs_missing"].extend(
|
|
186
|
-
[
|
|
170
|
+
[a / name for name in results["left_dirs_missing"]]
|
|
187
171
|
)
|
|
188
172
|
right_dirs_missing = " ".join(results["right_dirs_missing"])
|
|
189
173
|
if right_dirs_missing:
|
|
@@ -191,15 +175,15 @@ def print_results(results, a, b, level=0, prefix=""):
|
|
|
191
175
|
f"{prefix_file}{bcolors.FAIL}missing dirs right: {right_dirs_missing} ✘{bcolors.ENDC}"
|
|
192
176
|
)
|
|
193
177
|
result["right_dirs_missing"].extend(
|
|
194
|
-
[
|
|
178
|
+
[a / name for name in results["right_dirs_missing"]]
|
|
195
179
|
)
|
|
196
180
|
|
|
197
181
|
for name, sub_results in results["common_dirs"]:
|
|
198
182
|
print(prefix + "├── " + name)
|
|
199
183
|
sub_result = print_results(
|
|
200
184
|
sub_results,
|
|
201
|
-
|
|
202
|
-
|
|
185
|
+
a / name,
|
|
186
|
+
b / name,
|
|
203
187
|
level=level + 1,
|
|
204
188
|
prefix=prefix + "│ ",
|
|
205
189
|
)
|
|
@@ -214,12 +198,14 @@ def print_results(results, a, b, level=0, prefix=""):
|
|
|
214
198
|
|
|
215
199
|
def main():
|
|
216
200
|
parser = argparse.ArgumentParser()
|
|
217
|
-
parser.add_argument("a")
|
|
218
|
-
parser.add_argument("b")
|
|
201
|
+
parser.add_argument("a", type=Path, help="Path to the first directory")
|
|
202
|
+
parser.add_argument("b", type=Path, help="Path to the second directory")
|
|
219
203
|
parser.add_argument(
|
|
220
204
|
"--driver", choices=["chrome", "firefox", "phantomjs"], default="firefox"
|
|
221
205
|
)
|
|
222
|
-
parser.add_argument(
|
|
206
|
+
parser.add_argument(
|
|
207
|
+
"--diff-output", type=Path, help="Output directory for diff images"
|
|
208
|
+
)
|
|
223
209
|
parser.add_argument("--max-workers", type=int, default=1)
|
|
224
210
|
args = parser.parse_args()
|
|
225
211
|
|
|
@@ -1,18 +1,20 @@
|
|
|
1
1
|
#!/usr/bin/env python3
|
|
2
2
|
# -*- coding: utf-8 -*-
|
|
3
3
|
|
|
4
|
-
import os
|
|
5
4
|
import sys
|
|
6
5
|
import argparse
|
|
7
6
|
import threading
|
|
8
7
|
import io
|
|
8
|
+
from pathlib import Path
|
|
9
9
|
from concurrent.futures import ThreadPoolExecutor
|
|
10
|
-
|
|
10
|
+
|
|
11
11
|
from compare_output import comparable_file, compare_files
|
|
12
12
|
from flask import Flask, send_from_directory, send_file
|
|
13
13
|
import watchdog.observers
|
|
14
14
|
import watchdog.events
|
|
15
15
|
|
|
16
|
+
from html_render_diff import get_browser, html_render_diff
|
|
17
|
+
|
|
16
18
|
|
|
17
19
|
class Config:
|
|
18
20
|
path_a = None
|
|
@@ -34,10 +36,8 @@ class Observer:
|
|
|
34
36
|
if event.event_type in ["opened"]:
|
|
35
37
|
return
|
|
36
38
|
|
|
37
|
-
if
|
|
38
|
-
Config.comparator.submit(
|
|
39
|
-
os.path.relpath(event.src_path, self._path)
|
|
40
|
-
)
|
|
39
|
+
if event.src_path.is_file():
|
|
40
|
+
Config.comparator.submit(event.src_path.relative_to(self._path))
|
|
41
41
|
|
|
42
42
|
self._observer = watchdog.observers.Observer()
|
|
43
43
|
self._observer.schedule(Handler(Config.path_a), Config.path_a, recursive=True)
|
|
@@ -47,20 +47,18 @@ class Observer:
|
|
|
47
47
|
self._observer.start()
|
|
48
48
|
|
|
49
49
|
def init_compare(a, b):
|
|
50
|
-
common_path =
|
|
50
|
+
common_path = a / Config.path_a
|
|
51
51
|
|
|
52
|
-
left = sorted(
|
|
53
|
-
right = sorted(
|
|
52
|
+
left = sorted(p.name for p in a.iterdir())
|
|
53
|
+
right = sorted(p.name for p in b.iterdir())
|
|
54
54
|
|
|
55
55
|
common = [name for name in left if name in right]
|
|
56
56
|
|
|
57
57
|
for name in common:
|
|
58
|
-
if
|
|
59
|
-
|
|
60
|
-
):
|
|
61
|
-
|
|
62
|
-
elif os.path.isdir(os.path.join(a, name)):
|
|
63
|
-
init_compare(os.path.join(a, name), os.path.join(b, name))
|
|
58
|
+
if (a / name).is_file() and comparable_file(a / name):
|
|
59
|
+
Config.comparator.submit(common_path / name)
|
|
60
|
+
elif (a / name).is_dir():
|
|
61
|
+
init_compare(a / name, b / name)
|
|
64
62
|
|
|
65
63
|
init_compare(Config.path_a, Config.path_b)
|
|
66
64
|
|
|
@@ -100,8 +98,8 @@ class Comparator:
|
|
|
100
98
|
def compare(self, path):
|
|
101
99
|
browser = getattr(Config.thread_local, "browser", None)
|
|
102
100
|
result = compare_files(
|
|
103
|
-
|
|
104
|
-
|
|
101
|
+
Config.path_a / path,
|
|
102
|
+
Config.path_b / path,
|
|
105
103
|
browser=browser,
|
|
106
104
|
)
|
|
107
105
|
self._result[path] = "same" if result else "different"
|
|
@@ -139,34 +137,28 @@ app = Flask("compare")
|
|
|
139
137
|
@app.route("/")
|
|
140
138
|
def root():
|
|
141
139
|
def print_tree(a, b):
|
|
142
|
-
common_path =
|
|
140
|
+
common_path = a / Config.path_a
|
|
143
141
|
|
|
144
|
-
left = sorted(
|
|
145
|
-
right = sorted(
|
|
142
|
+
left = sorted(p.name for p in a.iterdir())
|
|
143
|
+
right = sorted(p.name for p in b.iterdir())
|
|
146
144
|
|
|
147
145
|
left_files = sorted(
|
|
148
146
|
[
|
|
149
147
|
name
|
|
150
148
|
for name in left
|
|
151
|
-
if
|
|
152
|
-
and comparable_file(os.path.join(a, name))
|
|
149
|
+
if (a / name).is_file() and comparable_file(a / name)
|
|
153
150
|
]
|
|
154
151
|
)
|
|
155
152
|
right_files = sorted(
|
|
156
153
|
[
|
|
157
154
|
name
|
|
158
155
|
for name in right
|
|
159
|
-
if
|
|
160
|
-
and comparable_file(os.path.join(b, name))
|
|
156
|
+
if (b / name).is_file() and comparable_file(b / name)
|
|
161
157
|
]
|
|
162
158
|
)
|
|
163
159
|
|
|
164
|
-
left_dirs = sorted(
|
|
165
|
-
|
|
166
|
-
)
|
|
167
|
-
right_dirs = sorted(
|
|
168
|
-
[name for name in right if os.path.isdir(os.path.join(b, name))]
|
|
169
|
-
)
|
|
160
|
+
left_dirs = sorted([name for name in left if (a / name).is_dir()])
|
|
161
|
+
right_dirs = sorted([name for name in right if (b / name).is_dir()])
|
|
170
162
|
|
|
171
163
|
common_files = [name for name in left_files if name in right_files]
|
|
172
164
|
common_dirs = [name for name in left_dirs if name in right_dirs]
|
|
@@ -196,17 +188,15 @@ def root():
|
|
|
196
188
|
|
|
197
189
|
for name in common_files:
|
|
198
190
|
if Config.comparator is None:
|
|
199
|
-
result += f'<li><a href="/compare/{
|
|
191
|
+
result += f'<li><a href="/compare/{common_path / name}">{name}</a></li>'
|
|
200
192
|
else:
|
|
201
|
-
symbol = Config.comparator.result_symbol(
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
css = Config.comparator.result_css(os.path.join(common_path, name))
|
|
205
|
-
result += f'<li style="{css}"><a style="{css}" href="/compare/{os.path.join(common_path, name)}">{name}</a> {symbol}</li>'
|
|
193
|
+
symbol = Config.comparator.result_symbol(common_path / name)
|
|
194
|
+
css = Config.comparator.result_css(common_path / name)
|
|
195
|
+
result += f'<li style="{css}"><a style="{css}" href="/compare/{common_path / name}">{name}</a> {symbol}</li>'
|
|
206
196
|
|
|
207
197
|
for name in common_dirs:
|
|
208
198
|
result += f"<li>{name}"
|
|
209
|
-
result += print_tree(
|
|
199
|
+
result += print_tree(a / name, b / name)
|
|
210
200
|
result += "</li>"
|
|
211
201
|
|
|
212
202
|
result += "</ul>"
|
|
@@ -229,7 +219,7 @@ html,body {{height:100%;margin:0;}}
|
|
|
229
219
|
</head>
|
|
230
220
|
<body style="display:flex;flex-flow:row;">
|
|
231
221
|
<div style="display:flex;flex:1;flex-flow:column;margin:5px;">
|
|
232
|
-
<a href="/file/a/{path}">{
|
|
222
|
+
<a href="/file/a/{path}">{Config.path_a /path}</a>
|
|
233
223
|
<iframe id="a" src="/file/a/{path}" title="a" frameborder="0" align="left" style="flex:1;"></iframe>
|
|
234
224
|
</div>
|
|
235
225
|
<div style="display:flex;flex:0 0 50px;flex-flow:column;">
|
|
@@ -237,7 +227,7 @@ html,body {{height:100%;margin:0;}}
|
|
|
237
227
|
<img src="/image_diff/{path}" width="50" height="0" style="flex:1;">
|
|
238
228
|
</div>
|
|
239
229
|
<div style="display:flex;flex:1;flex-flow:column;margin:5px;">
|
|
240
|
-
<a href="/file/b/{path}">{
|
|
230
|
+
<a href="/file/b/{path}">{Config.path_b / path}</a>
|
|
241
231
|
<iframe id="b" src="/file/b/{path}" title="b" frameborder="0" align="right" style="flex:1;"></iframe>
|
|
242
232
|
</div>
|
|
243
233
|
<script>
|
|
@@ -258,8 +248,8 @@ iframe_b.contentWindow.addEventListener('scroll', function(event) {{
|
|
|
258
248
|
@app.route("/image_diff/<path:path>")
|
|
259
249
|
def image_diff(path):
|
|
260
250
|
diff, _ = html_render_diff(
|
|
261
|
-
|
|
262
|
-
|
|
251
|
+
Config.path_a / path,
|
|
252
|
+
Config.path_b / path,
|
|
263
253
|
Config.browser,
|
|
264
254
|
)
|
|
265
255
|
tmp = io.BytesIO()
|
|
@@ -276,8 +266,8 @@ def file(variant, path):
|
|
|
276
266
|
|
|
277
267
|
def main():
|
|
278
268
|
parser = argparse.ArgumentParser()
|
|
279
|
-
parser.add_argument("a")
|
|
280
|
-
parser.add_argument("b")
|
|
269
|
+
parser.add_argument("a", type=Path, help="Path to the first directory")
|
|
270
|
+
parser.add_argument("b", type=Path, help="Path to the second directory")
|
|
281
271
|
parser.add_argument(
|
|
282
272
|
"--driver", choices=["chrome", "firefox", "phantomjs"], default="firefox"
|
|
283
273
|
)
|
|
@@ -76,8 +76,8 @@ def html_render_diff(a, b, browser):
|
|
|
76
76
|
|
|
77
77
|
def main():
|
|
78
78
|
parser = argparse.ArgumentParser()
|
|
79
|
-
parser.add_argument("a", type=Path)
|
|
80
|
-
parser.add_argument("b", type=Path)
|
|
79
|
+
parser.add_argument("a", type=Path, help="Path to the first HTML file")
|
|
80
|
+
parser.add_argument("b", type=Path, help="Path to the second HTML file")
|
|
81
81
|
parser.add_argument(
|
|
82
82
|
"--driver", choices=["chrome", "firefox", "phantomjs"], default="firefox"
|
|
83
83
|
)
|
|
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
|