From e04ad3248a0129335f4b51d8aa3e75e73f8d7961 Mon Sep 17 00:00:00 2001 From: Cedric Leporcq Date: Mon, 1 Nov 2021 11:42:01 +0100 Subject: [PATCH] Refactoring summary --- ordigi/collection.py | 46 +++++++++-------- ordigi/summary.py | 105 +++++++++++++++++++++++++-------------- tests/test_collection.py | 17 ++++--- 3 files changed, 104 insertions(+), 64 deletions(-) diff --git a/ordigi/collection.py b/ordigi/collection.py index ca445df..20fa283 100644 --- a/ordigi/collection.py +++ b/ordigi/collection.py @@ -337,7 +337,7 @@ class Collection: row_data = self._format_row_data('metadata', metadata) self.db.add_row('metadata', row_data) - def _update_exif_data(self, dest_path, media): + def _update_exif_data(self, media): updated = False if self.album_from_folder: media.set_album_from_folder() @@ -374,7 +374,7 @@ class Collection: if fnmatch(file_path, exclude): if not self.dry_run: self.remove(file_path) - self.summary.append((file_path, 'remove_excluded')) + self.summary.append('remove', True, file_path) break return self.summary @@ -383,13 +383,13 @@ class Collection: checksum = media.metadata['checksum'] if not self._checkcomp(dest_path, checksum): self.logger.error(f'Files {src_path} and {dest_path} are not identical') - self.summary.append((src_path, False)) + self.summary.append('check', False, src_path, dest_path) return False # change media file_path to dest_path media.file_path = dest_path if not self.dry_run: - updated = self._update_exif_data(dest_path, media) + updated = self._update_exif_data(media) if updated: checksum = utils.checksum(dest_path) media.metadata['checksum'] = checksum @@ -420,7 +420,7 @@ class Collection: """Check file and record the file to db""" # Check if file remain the same if not self._check_file(src_path, dest_path, media): - self.summary.append((src_path, False)) + self.summary.append('check', False, src_path, dest_path) return False if not self.dry_run: @@ -678,7 +678,10 @@ class Collection: ) elif conflict == 1: # There is unresolved conflict - self.summary.append((src_path, False)) + if import_mode: + self.summary.append('import', False, src_path, dest_path) + else: + self.summary.append('sort', False, src_path, dest_path) elif conflict == 3: # Same file checksum if import_mode == 'move': @@ -809,7 +812,7 @@ class Collection: def init(self, loc, ignore_tags=set()): for media, file_path in self.get_medias(loc): self._add_db_data(media.metadata) - self.summary.append((file_path, 'update')) + self.summary.append('update', file_path) return self.summary @@ -853,7 +856,7 @@ class Collection: break # set row attribute to the file self._add_db_data(media.metadata) - self.summary.append((file_path, 'update')) + self.summary.append('update', file_path) # Finally delete invalid rows for row in invalid_db_rows: @@ -866,10 +869,10 @@ class Collection: checksum = utils.checksum(file_path) relpath = file_path.relative_to(self.root) if checksum == self.db.get_checksum(relpath): - self.summary.append((file_path, 'check')) + self.summary.append('check',True, file_path) else: self.logger.error('{file_path} is corrupted') - self.summary.append((file_path, False)) + self.summary.append('check', False, file_path) return self.summary @@ -898,7 +901,7 @@ class Collection: def remove_empty_folders(self, directory, remove_root=True): """Remove empty sub-folders in collection""" if not os.path.isdir(directory): - self.summary.append((directory, False)) + self.summary.append('remove', False, directory) return self.summary # remove empty subfolders @@ -915,7 +918,7 @@ class Collection: self.logger.info(f"Removing empty folder: {directory}") if not self.dry_run: os.rmdir(directory) - self.summary.append((directory, 'remove_empty_folders')) + self.summary.append('remove', True, directory) return self.summary @@ -924,8 +927,6 @@ class Collection: self._copy(src_path, dest_path) else: self._move(src_path, dest_path) - if import_mode: - update = False result = self._record_file( src_path, dest_path, media, import_mode=import_mode @@ -934,11 +935,14 @@ class Collection: if result: self.dest_list.append(dest_path) if import_mode: - self.summary.append((src_path, 'import')) + self.summary.append('import', True, src_path, dest_path) else: - self.summary.append((src_path, 'sort')) + self.summary.append('sort', True, src_path, dest_path) else: - self.summary.append((src_path, False)) + if import_mode: + self.summary.append('import', False, src_path, dest_path) + else: + self.summary.append('sort', False, src_path, dest_path) return self.summary @@ -973,7 +977,7 @@ class Collection: self._remove_empty_subdirs(subdirs, src_dirs) if not self._check_processed(): - self.summary.append((None, False)) + self.summary.append('check', False) return self.summary @@ -1023,7 +1027,7 @@ class Collection: self._sort_medias(files_data, remove_duplicates=remove_duplicates) if not self._check_processed(): - self.summary.append((None, False)) + self.summary.append('check', False) return self.summary @@ -1100,7 +1104,7 @@ class Collection: self.logger.error('Nb of row have changed unexpectedly') if not self._check_processed(): - self.summary.append((None, False)) + self.summary.append('check', False) return self.summary @@ -1166,6 +1170,6 @@ class Collection: # Update exif data media.set_key_values(key, value) - self.summary.append((file_path, 'update')) + self.summary.append('update', False, file_path) return self.summary diff --git a/ordigi/summary.py b/ordigi/summary.py index fe7e153..b40b224 100644 --- a/ordigi/summary.py +++ b/ordigi/summary.py @@ -1,64 +1,97 @@ +# import pandas as pd from tabulate import tabulate +class Tables: + """Create table and display result in Pandas DataFrame""" + + def __init__(self, actions): + self.actions = actions + + self.table = [] + + self.columns = ['action', 'file_path', 'dest_path'] + # self.df = self.dataframe() + + def append(self, action, file_path=None, dest_path=None): + row = (action, file_path, dest_path) + self.table.append(row) + + def sum(self, action=None): + if not action: + return len(self.table) + + count = 0 + for row in self.table: + if row[0] == action: + count += 1 + + return count + + # def dataframe(self): + # return pd.DataFrame(self.table, columns=self.columns) + + def tabulate(self): + errors_headers = self.columns + return tabulate(self.table, headers=errors_headers) class Summary: - def __init__(self, path): + """Result summary of ordigi program call""" + + def __init__(self, root): self.actions = ( 'check', 'import', - 'remove_empty_folders', - 'remove_excluded', + 'remove', 'sort', 'update', ) - self.path = path - self.result = {} - for action in self.actions: - self.result[action] = 0 + # Set labels + self.state = ['success', 'errors'] + self.root = root + self.success_table = Tables(self.actions) + self.errors_table = Tables(self.actions) self.errors = 0 - self.errors_items = [] - - def append(self, row): - file_path, action = row + def append(self, action, success, file_path=None, dest_path=None): if action: - for m in self.actions: - if action == m: - self.result[action] += 1 - else: - self.errors += 1 - if file_path: - self.errors_items.append(file_path) + if success: + self.success_table.append(action, file_path, dest_path) + else: + self.errors_table.append(action, file_path, dest_path) + + if not success: + self.errors +=1 def print(self): + """Print summary""" print() - for action in self.result: - nb = self.result[action] - if self.result[action] != 0: + for action in self.actions: + nb = self.success_table.sum(action) + if nb != 0: if action == 'check': - print(f"SUMMARY: {nb} files checked in {self.path}.") + print(f"SUMMARY: {nb} files checked in {self.root}.") elif action == 'import': - print(f"SUMMARY: {nb} files imported into {self.path}.") + print(f"SUMMARY: {nb} files imported into {self.root}.") elif action == 'sort': - print(f"SUMMARY: {nb} files sorted inside {self.path}.") + print(f"SUMMARY: {nb} files sorted inside {self.root}.") elif action == 'remove_excluded': - print(f"SUMMARY: {nb} files deleted in {self.path}.") + print(f"SUMMARY: {nb} files deleted in {self.root}.") elif action == 'remove_empty_folders': - print(f"SUMMARY: {nb} empty folders removed in {self.path}.") + print(f"SUMMARY: {nb} empty folders removed in {self.root}.") elif action == 'update': - print(f"SUMMARY: {nb} files updated in {self.path} database.") + print(f"SUMMARY: {nb} files updated in {self.root} database.") - if sum(self.result.values()) == 0 and not self.errors: - print(f"SUMMARY: no file imported, sorted or deleted from {self.path}.") + success = self.success_table.sum() + if not success and not self.errors: + print(f"SUMMARY: no action done in {self.root}.") - if self.errors > 0: + errors = self.errors_table.sum() + if errors: print() - errors_headers = [f"ERROR: {self.errors} errors reported in files:"] - errors_result = [] - for path in self.errors_items: - errors_result.append([path]) + print(f"ERROR: {errors} errors reported for files:") + print(self.success_table.tabulate()) - print(tabulate(errors_result, headers=errors_headers)) - print() + elif self.errors: + print(f"ERROR: {errors} errors reported.") diff --git a/tests/test_collection.py b/tests/test_collection.py index e5c1a0f..2a6795f 100644 --- a/tests/test_collection.py +++ b/tests/test_collection.py @@ -131,12 +131,12 @@ class TestCollection: def assert_import(self, summary, nb): # Summary is created and there is no errors assert summary.errors == 0 - assert summary.result['import'] == nb + assert summary.success_table.sum('import') == nb def assert_sort(self, summary, nb): # Summary is created and there is no errors assert summary.errors == 0 - assert summary.result['sort'] == nb + assert summary.success_table.sum('sort') == nb def test_sort_files(self, tmp_path): collection = Collection(tmp_path, album_from_folder=True, @@ -148,7 +148,8 @@ class TestCollection: self.assert_import(summary, 30) summary = collection.check_files() - assert summary.result['check'] == 30 + assert summary.success_table.sum('import') == 30 + assert summary.success_table.sum('update') == 0 assert not summary.errors # check if album value are set @@ -169,13 +170,14 @@ class TestCollection: shutil.copytree(tmp_path / 'test_exif', tmp_path / 'test_exif_copy') collection.summary = Summary(tmp_path) - assert sum(collection.summary.result.values()) == 0 + assert collection.summary.success_table.sum() == 0 summary = collection.update(loc) - assert summary.result['update'] == 2 + assert summary.success_table.sum('update') == 2 + assert summary.success_table.sum() == 2 assert not summary.errors collection.summary = Summary(tmp_path) summary = collection.update(loc) - assert not summary.result['update'] + assert summary.success_table.sum() == 0 assert not summary.errors # test with populated dest dir @@ -186,7 +188,8 @@ class TestCollection: # test summary update collection.summary = Summary(tmp_path) summary = collection.update(loc) - assert summary.result['update'] + assert summary.success_table.sum('sort') == 0 + assert summary.success_table.sum('update') assert not summary.errors def test_sort_files_invalid_db(self, tmp_path):