imdiff 0.2.6__tar.gz → 0.2.7__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.
- {imdiff-0.2.6 → imdiff-0.2.7}/PKG-INFO +1 -1
- {imdiff-0.2.6 → imdiff-0.2.7}/imdiff/gui/file_list_frame.py +31 -6
- {imdiff-0.2.6 → imdiff-0.2.7}/imdiff/image_comparator.py +32 -29
- {imdiff-0.2.6 → imdiff-0.2.7}/imdiff/version.py +1 -1
- {imdiff-0.2.6 → imdiff-0.2.7}/imdiff.egg-info/PKG-INFO +1 -1
- {imdiff-0.2.6 → imdiff-0.2.7}/LICENSE +0 -0
- {imdiff-0.2.6 → imdiff-0.2.7}/README.md +0 -0
- {imdiff-0.2.6 → imdiff-0.2.7}/imdiff/__init__.py +0 -0
- {imdiff-0.2.6 → imdiff-0.2.7}/imdiff/__main__.py +0 -0
- {imdiff-0.2.6 → imdiff-0.2.7}/imdiff/cli/__init__.py +0 -0
- {imdiff-0.2.6 → imdiff-0.2.7}/imdiff/cli/dir_diff.py +0 -0
- {imdiff-0.2.6 → imdiff-0.2.7}/imdiff/cli/image_diff.py +0 -0
- {imdiff-0.2.6 → imdiff-0.2.7}/imdiff/cli/main.py +0 -0
- {imdiff-0.2.6 → imdiff-0.2.7}/imdiff/gui/__init__.py +0 -0
- {imdiff-0.2.6 → imdiff-0.2.7}/imdiff/gui/dir_diff_main_window.py +0 -0
- {imdiff-0.2.6 → imdiff-0.2.7}/imdiff/gui/image_canvas.py +0 -0
- {imdiff-0.2.6 → imdiff-0.2.7}/imdiff/gui/image_diff_main_window.py +0 -0
- {imdiff-0.2.6 → imdiff-0.2.7}/imdiff/gui/image_frame.py +0 -0
- {imdiff-0.2.6 → imdiff-0.2.7}/imdiff/gui/image_scaling.py +0 -0
- {imdiff-0.2.6 → imdiff-0.2.7}/imdiff/gui/status_bar.py +0 -0
- {imdiff-0.2.6 → imdiff-0.2.7}/imdiff/gui/transient_menu.py +0 -0
- {imdiff-0.2.6 → imdiff-0.2.7}/imdiff/gui/zoom_menu.py +0 -0
- {imdiff-0.2.6 → imdiff-0.2.7}/imdiff/list_files.py +0 -0
- {imdiff-0.2.6 → imdiff-0.2.7}/imdiff/util.py +0 -0
- {imdiff-0.2.6 → imdiff-0.2.7}/imdiff.egg-info/SOURCES.txt +0 -0
- {imdiff-0.2.6 → imdiff-0.2.7}/imdiff.egg-info/dependency_links.txt +0 -0
- {imdiff-0.2.6 → imdiff-0.2.7}/imdiff.egg-info/entry_points.txt +0 -0
- {imdiff-0.2.6 → imdiff-0.2.7}/imdiff.egg-info/requires.txt +0 -0
- {imdiff-0.2.6 → imdiff-0.2.7}/imdiff.egg-info/top_level.txt +0 -0
- {imdiff-0.2.6 → imdiff-0.2.7}/pyproject.toml +0 -0
- {imdiff-0.2.6 → imdiff-0.2.7}/setup.cfg +0 -0
|
@@ -64,6 +64,7 @@ class FileListFrame(ttk.Frame):
|
|
|
64
64
|
self.file_queue = IterableQueue()
|
|
65
65
|
self.file_processing_queue = IterableQueue()
|
|
66
66
|
self.file_properties_queue = IterableQueue()
|
|
67
|
+
self.text_file_queue = IterableQueue()
|
|
67
68
|
self.leftdir = None
|
|
68
69
|
self.rightdir = None
|
|
69
70
|
self.progress_var = tk.IntVar()
|
|
@@ -191,6 +192,7 @@ class FileListFrame(ttk.Frame):
|
|
|
191
192
|
self.file_queue.status = IterableQueue.Status.Inactive
|
|
192
193
|
self.file_processing_queue.status = IterableQueue.Status.Inactive
|
|
193
194
|
self.file_properties_queue.status = IterableQueue.Status.Inactive
|
|
195
|
+
self.text_file_queue.status = IterableQueue.Status.Inactive
|
|
194
196
|
if executor := self.executor:
|
|
195
197
|
executor.shutdown(wait=False, cancel_futures=True)
|
|
196
198
|
|
|
@@ -203,17 +205,18 @@ class FileListFrame(ttk.Frame):
|
|
|
203
205
|
@separate_thread
|
|
204
206
|
def queue_files(self):
|
|
205
207
|
assert self.file_queue.status == IterableQueue.Status.Filling
|
|
208
|
+
assert self.text_file_queue.status == IterableQueue.Status.Filling
|
|
206
209
|
if self.leftdir and self.rightdir:
|
|
207
210
|
for file_path, left, right in list_files(self.leftdir, self.rightdir):
|
|
208
211
|
if is_image(left) or is_image(right):
|
|
209
212
|
file_cmp = ImageComparator(left, right)
|
|
210
213
|
self.files[file_path] = file_cmp
|
|
211
214
|
self.file_queue.put(file_path)
|
|
212
|
-
elif self.
|
|
215
|
+
elif self.text_file_queue.status == IterableQueue.Status.Filling:
|
|
213
216
|
if left.is_file() and right.is_file():
|
|
214
|
-
|
|
215
|
-
self.button_text_diff.configure(bootstyle=ttk.DANGER)
|
|
217
|
+
self.text_file_queue.put(file_path)
|
|
216
218
|
self.file_queue.status = IterableQueue.Status.Complete
|
|
219
|
+
self.text_file_queue.status = IterableQueue.Status.Complete
|
|
217
220
|
|
|
218
221
|
def append_file_entry(self, file_path):
|
|
219
222
|
self.file_entries.append(file_path)
|
|
@@ -228,6 +231,7 @@ class FileListFrame(ttk.Frame):
|
|
|
228
231
|
assert self.file_processing_queue.status == IterableQueue.Status.Filling
|
|
229
232
|
for file_path in self.file_queue:
|
|
230
233
|
self.append_file_entry(file_path)
|
|
234
|
+
for file_path in self.file_entries:
|
|
231
235
|
self.file_processing_queue.put(file_path)
|
|
232
236
|
self.file_processing_queue.status = IterableQueue.Status.Complete
|
|
233
237
|
self.file_treeview.heading('#0', command=lambda: self.sort_filepaths(0, True))
|
|
@@ -244,6 +248,12 @@ class FileListFrame(ttk.Frame):
|
|
|
244
248
|
}
|
|
245
249
|
|
|
246
250
|
comparator = self.files[file_path]
|
|
251
|
+
|
|
252
|
+
proc = multiprocessing.Process(target=comparator.calculate_diff_info)
|
|
253
|
+
proc.start()
|
|
254
|
+
while proc.is_alive():
|
|
255
|
+
self.update()
|
|
256
|
+
time.sleep(0.1)
|
|
247
257
|
diff_info = comparator.diff_info
|
|
248
258
|
|
|
249
259
|
if diff_info == 'failed-to-load':
|
|
@@ -262,22 +272,35 @@ class FileListFrame(ttk.Frame):
|
|
|
262
272
|
|
|
263
273
|
@separate_thread
|
|
264
274
|
def process_files(self):
|
|
275
|
+
while self.file_processing_queue.status == IterableQueue.Status.Filling:
|
|
276
|
+
self.update()
|
|
277
|
+
assert self.file_processing_queue.status == IterableQueue.Status.Complete
|
|
265
278
|
assert self.file_properties_queue.status == IterableQueue.Status.Filling
|
|
266
|
-
with concurrent.futures.ThreadPoolExecutor(
|
|
267
|
-
max_workers=multiprocessing.cpu_count()
|
|
268
|
-
) as executor:
|
|
279
|
+
with concurrent.futures.ThreadPoolExecutor() as executor:
|
|
269
280
|
self.executor = executor
|
|
270
281
|
try:
|
|
271
282
|
jobs = []
|
|
272
283
|
for file_path in self.file_processing_queue:
|
|
273
284
|
jobs.append(executor.submit(self.get_diff_info, file_path))
|
|
274
285
|
for job in concurrent.futures.as_completed(jobs):
|
|
286
|
+
self.update()
|
|
275
287
|
file_path, category, diff_info = job.result()
|
|
276
288
|
self.file_properties_queue.put((file_path, category, diff_info))
|
|
277
289
|
self.file_properties_queue.status = IterableQueue.Status.Complete
|
|
278
290
|
finally:
|
|
279
291
|
self.executor = None
|
|
280
292
|
|
|
293
|
+
@separate_thread
|
|
294
|
+
def process_text_files(self):
|
|
295
|
+
assert self.text_file_queue.status == IterableQueue.Status.Filling
|
|
296
|
+
for file_path in self.text_file_queue:
|
|
297
|
+
left = self.leftdir / file_path
|
|
298
|
+
right = self.rightdir / file_path
|
|
299
|
+
if not filecmp.cmp(left, right):
|
|
300
|
+
self.button_text_diff.configure(bootstyle=ttk.DANGER)
|
|
301
|
+
self.text_file_queue.status = IterableQueue.Status.Complete
|
|
302
|
+
break
|
|
303
|
+
|
|
281
304
|
def show_progress_bar(self, initial_value=0):
|
|
282
305
|
self.progress_var.set(initial_value)
|
|
283
306
|
self.progress_bar.grid(column=0, row=2, columnspan=2, sticky='sew')
|
|
@@ -310,12 +333,14 @@ class FileListFrame(ttk.Frame):
|
|
|
310
333
|
self.num_files_loaded = 0
|
|
311
334
|
self.show_progress_bar(0)
|
|
312
335
|
self.file_queue.status = IterableQueue.Status.Filling
|
|
336
|
+
self.text_file_queue.status = IterableQueue.Status.Filling
|
|
313
337
|
self.queue_files()
|
|
314
338
|
self.file_processing_queue.status = IterableQueue.Status.Filling
|
|
315
339
|
self.append_files_to_list()
|
|
316
340
|
self.file_properties_queue.status = IterableQueue.Status.Filling
|
|
317
341
|
self.process_files()
|
|
318
342
|
self.update_properties()
|
|
343
|
+
self.process_text_files()
|
|
319
344
|
|
|
320
345
|
def select_next(self):
|
|
321
346
|
select_next = None
|
|
@@ -96,38 +96,41 @@ class ImageComparator:
|
|
|
96
96
|
self._diff = Image.fromarray(data)
|
|
97
97
|
return self._diff
|
|
98
98
|
|
|
99
|
+
def calculate_diff_info(self):
|
|
100
|
+
if self.left_file and self.left_file.is_file():
|
|
101
|
+
if self.right_file and self.right_file.is_file():
|
|
102
|
+
if file_compare(self.left_file, self.right_file):
|
|
103
|
+
self._diff_info = 'identical'
|
|
104
|
+
else:
|
|
105
|
+
try:
|
|
106
|
+
left_size = Size((self.left.width, self.left.height))
|
|
107
|
+
right_size = Size((self.right.width, self.right.height))
|
|
108
|
+
if left_size != right_size:
|
|
109
|
+
self._diff_info = 'different-size'
|
|
110
|
+
else:
|
|
111
|
+
left_data = np.array(self.left)
|
|
112
|
+
right_data = np.array(self.right)
|
|
113
|
+
errors = left_data.astype(int) - right_data
|
|
114
|
+
normalized_rmse = (
|
|
115
|
+
np.sqrt(np.mean(np.square(errors))) / 0xFF
|
|
116
|
+
)
|
|
117
|
+
self._diff_info = normalized_rmse
|
|
118
|
+
except:
|
|
119
|
+
self._diff_info = 'failed-to-load'
|
|
120
|
+
else:
|
|
121
|
+
self._diff_info = 'missing'
|
|
122
|
+
elif self.right_file and self.right_file.is_file():
|
|
123
|
+
if self.right:
|
|
124
|
+
self._diff_info = 'new'
|
|
125
|
+
else:
|
|
126
|
+
self._diff_info = 'failed-to-load'
|
|
127
|
+
else:
|
|
128
|
+
self._diff_info = 'not-found'
|
|
129
|
+
|
|
99
130
|
@property
|
|
100
131
|
def diff_info(self):
|
|
101
132
|
if self._diff_info is None:
|
|
102
|
-
|
|
103
|
-
if self.right_file and self.right_file.is_file():
|
|
104
|
-
if file_compare(self.left_file, self.right_file):
|
|
105
|
-
self._diff_info = 'identical'
|
|
106
|
-
else:
|
|
107
|
-
try:
|
|
108
|
-
left_size = Size((self.left.width, self.left.height))
|
|
109
|
-
right_size = Size((self.right.width, self.right.height))
|
|
110
|
-
if left_size != right_size:
|
|
111
|
-
self._diff_info = 'different-size'
|
|
112
|
-
else:
|
|
113
|
-
left_data = np.array(self.left)
|
|
114
|
-
right_data = np.array(self.right)
|
|
115
|
-
errors = left_data.astype(int) - right_data
|
|
116
|
-
normalized_rmse = (
|
|
117
|
-
np.sqrt(np.mean(np.square(errors))) / 0xFF
|
|
118
|
-
)
|
|
119
|
-
self._diff_info = normalized_rmse
|
|
120
|
-
except:
|
|
121
|
-
self._diff_info = 'failed-to-load'
|
|
122
|
-
else:
|
|
123
|
-
self._diff_info = 'missing'
|
|
124
|
-
elif self.right_file and self.right_file.is_file():
|
|
125
|
-
if self.right:
|
|
126
|
-
self._diff_info = 'new'
|
|
127
|
-
else:
|
|
128
|
-
self._diff_info = 'failed-to-load'
|
|
129
|
-
else:
|
|
130
|
-
self._diff_info = 'not-found'
|
|
133
|
+
self.calculate_diff_info()
|
|
131
134
|
return self._diff_info
|
|
132
135
|
|
|
133
136
|
@property
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
__version__ = '0.2.
|
|
1
|
+
__version__ = '0.2.7'
|
|
2
2
|
version_info = __version__.split('.')
|
|
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
|
|
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
|