Refactoring summary
This commit is contained in:
parent
648930f139
commit
e04ad3248a
|
@ -337,7 +337,7 @@ class Collection:
|
||||||
row_data = self._format_row_data('metadata', metadata)
|
row_data = self._format_row_data('metadata', metadata)
|
||||||
self.db.add_row('metadata', row_data)
|
self.db.add_row('metadata', row_data)
|
||||||
|
|
||||||
def _update_exif_data(self, dest_path, media):
|
def _update_exif_data(self, media):
|
||||||
updated = False
|
updated = False
|
||||||
if self.album_from_folder:
|
if self.album_from_folder:
|
||||||
media.set_album_from_folder()
|
media.set_album_from_folder()
|
||||||
|
@ -374,7 +374,7 @@ class Collection:
|
||||||
if fnmatch(file_path, exclude):
|
if fnmatch(file_path, exclude):
|
||||||
if not self.dry_run:
|
if not self.dry_run:
|
||||||
self.remove(file_path)
|
self.remove(file_path)
|
||||||
self.summary.append((file_path, 'remove_excluded'))
|
self.summary.append('remove', True, file_path)
|
||||||
break
|
break
|
||||||
|
|
||||||
return self.summary
|
return self.summary
|
||||||
|
@ -383,13 +383,13 @@ class Collection:
|
||||||
checksum = media.metadata['checksum']
|
checksum = media.metadata['checksum']
|
||||||
if not self._checkcomp(dest_path, checksum):
|
if not self._checkcomp(dest_path, checksum):
|
||||||
self.logger.error(f'Files {src_path} and {dest_path} are not identical')
|
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
|
return False
|
||||||
|
|
||||||
# change media file_path to dest_path
|
# change media file_path to dest_path
|
||||||
media.file_path = dest_path
|
media.file_path = dest_path
|
||||||
if not self.dry_run:
|
if not self.dry_run:
|
||||||
updated = self._update_exif_data(dest_path, media)
|
updated = self._update_exif_data(media)
|
||||||
if updated:
|
if updated:
|
||||||
checksum = utils.checksum(dest_path)
|
checksum = utils.checksum(dest_path)
|
||||||
media.metadata['checksum'] = checksum
|
media.metadata['checksum'] = checksum
|
||||||
|
@ -420,7 +420,7 @@ class Collection:
|
||||||
"""Check file and record the file to db"""
|
"""Check file and record the file to db"""
|
||||||
# Check if file remain the same
|
# Check if file remain the same
|
||||||
if not self._check_file(src_path, dest_path, media):
|
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
|
return False
|
||||||
|
|
||||||
if not self.dry_run:
|
if not self.dry_run:
|
||||||
|
@ -678,7 +678,10 @@ class Collection:
|
||||||
)
|
)
|
||||||
elif conflict == 1:
|
elif conflict == 1:
|
||||||
# There is unresolved conflict
|
# 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:
|
elif conflict == 3:
|
||||||
# Same file checksum
|
# Same file checksum
|
||||||
if import_mode == 'move':
|
if import_mode == 'move':
|
||||||
|
@ -809,7 +812,7 @@ class Collection:
|
||||||
def init(self, loc, ignore_tags=set()):
|
def init(self, loc, ignore_tags=set()):
|
||||||
for media, file_path in self.get_medias(loc):
|
for media, file_path in self.get_medias(loc):
|
||||||
self._add_db_data(media.metadata)
|
self._add_db_data(media.metadata)
|
||||||
self.summary.append((file_path, 'update'))
|
self.summary.append('update', file_path)
|
||||||
|
|
||||||
return self.summary
|
return self.summary
|
||||||
|
|
||||||
|
@ -853,7 +856,7 @@ class Collection:
|
||||||
break
|
break
|
||||||
# set row attribute to the file
|
# set row attribute to the file
|
||||||
self._add_db_data(media.metadata)
|
self._add_db_data(media.metadata)
|
||||||
self.summary.append((file_path, 'update'))
|
self.summary.append('update', file_path)
|
||||||
|
|
||||||
# Finally delete invalid rows
|
# Finally delete invalid rows
|
||||||
for row in invalid_db_rows:
|
for row in invalid_db_rows:
|
||||||
|
@ -866,10 +869,10 @@ class Collection:
|
||||||
checksum = utils.checksum(file_path)
|
checksum = utils.checksum(file_path)
|
||||||
relpath = file_path.relative_to(self.root)
|
relpath = file_path.relative_to(self.root)
|
||||||
if checksum == self.db.get_checksum(relpath):
|
if checksum == self.db.get_checksum(relpath):
|
||||||
self.summary.append((file_path, 'check'))
|
self.summary.append('check',True, file_path)
|
||||||
else:
|
else:
|
||||||
self.logger.error('{file_path} is corrupted')
|
self.logger.error('{file_path} is corrupted')
|
||||||
self.summary.append((file_path, False))
|
self.summary.append('check', False, file_path)
|
||||||
|
|
||||||
return self.summary
|
return self.summary
|
||||||
|
|
||||||
|
@ -898,7 +901,7 @@ class Collection:
|
||||||
def remove_empty_folders(self, directory, remove_root=True):
|
def remove_empty_folders(self, directory, remove_root=True):
|
||||||
"""Remove empty sub-folders in collection"""
|
"""Remove empty sub-folders in collection"""
|
||||||
if not os.path.isdir(directory):
|
if not os.path.isdir(directory):
|
||||||
self.summary.append((directory, False))
|
self.summary.append('remove', False, directory)
|
||||||
return self.summary
|
return self.summary
|
||||||
|
|
||||||
# remove empty subfolders
|
# remove empty subfolders
|
||||||
|
@ -915,7 +918,7 @@ class Collection:
|
||||||
self.logger.info(f"Removing empty folder: {directory}")
|
self.logger.info(f"Removing empty folder: {directory}")
|
||||||
if not self.dry_run:
|
if not self.dry_run:
|
||||||
os.rmdir(directory)
|
os.rmdir(directory)
|
||||||
self.summary.append((directory, 'remove_empty_folders'))
|
self.summary.append('remove', True, directory)
|
||||||
|
|
||||||
return self.summary
|
return self.summary
|
||||||
|
|
||||||
|
@ -924,8 +927,6 @@ class Collection:
|
||||||
self._copy(src_path, dest_path)
|
self._copy(src_path, dest_path)
|
||||||
else:
|
else:
|
||||||
self._move(src_path, dest_path)
|
self._move(src_path, dest_path)
|
||||||
if import_mode:
|
|
||||||
update = False
|
|
||||||
|
|
||||||
result = self._record_file(
|
result = self._record_file(
|
||||||
src_path, dest_path, media, import_mode=import_mode
|
src_path, dest_path, media, import_mode=import_mode
|
||||||
|
@ -934,11 +935,14 @@ class Collection:
|
||||||
if result:
|
if result:
|
||||||
self.dest_list.append(dest_path)
|
self.dest_list.append(dest_path)
|
||||||
if import_mode:
|
if import_mode:
|
||||||
self.summary.append((src_path, 'import'))
|
self.summary.append('import', True, src_path, dest_path)
|
||||||
else:
|
else:
|
||||||
self.summary.append((src_path, 'sort'))
|
self.summary.append('sort', True, src_path, dest_path)
|
||||||
else:
|
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
|
return self.summary
|
||||||
|
|
||||||
|
@ -973,7 +977,7 @@ class Collection:
|
||||||
self._remove_empty_subdirs(subdirs, src_dirs)
|
self._remove_empty_subdirs(subdirs, src_dirs)
|
||||||
|
|
||||||
if not self._check_processed():
|
if not self._check_processed():
|
||||||
self.summary.append((None, False))
|
self.summary.append('check', False)
|
||||||
|
|
||||||
return self.summary
|
return self.summary
|
||||||
|
|
||||||
|
@ -1023,7 +1027,7 @@ class Collection:
|
||||||
self._sort_medias(files_data, remove_duplicates=remove_duplicates)
|
self._sort_medias(files_data, remove_duplicates=remove_duplicates)
|
||||||
|
|
||||||
if not self._check_processed():
|
if not self._check_processed():
|
||||||
self.summary.append((None, False))
|
self.summary.append('check', False)
|
||||||
|
|
||||||
return self.summary
|
return self.summary
|
||||||
|
|
||||||
|
@ -1100,7 +1104,7 @@ class Collection:
|
||||||
self.logger.error('Nb of row have changed unexpectedly')
|
self.logger.error('Nb of row have changed unexpectedly')
|
||||||
|
|
||||||
if not self._check_processed():
|
if not self._check_processed():
|
||||||
self.summary.append((None, False))
|
self.summary.append('check', False)
|
||||||
|
|
||||||
return self.summary
|
return self.summary
|
||||||
|
|
||||||
|
@ -1166,6 +1170,6 @@ class Collection:
|
||||||
# Update exif data
|
# Update exif data
|
||||||
media.set_key_values(key, value)
|
media.set_key_values(key, value)
|
||||||
|
|
||||||
self.summary.append((file_path, 'update'))
|
self.summary.append('update', False, file_path)
|
||||||
|
|
||||||
return self.summary
|
return self.summary
|
||||||
|
|
|
@ -1,64 +1,97 @@
|
||||||
|
# import pandas as pd
|
||||||
from tabulate import tabulate
|
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:
|
class Summary:
|
||||||
def __init__(self, path):
|
"""Result summary of ordigi program call"""
|
||||||
|
|
||||||
|
def __init__(self, root):
|
||||||
self.actions = (
|
self.actions = (
|
||||||
'check',
|
'check',
|
||||||
'import',
|
'import',
|
||||||
'remove_empty_folders',
|
'remove',
|
||||||
'remove_excluded',
|
|
||||||
'sort',
|
'sort',
|
||||||
'update',
|
'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 = 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:
|
if action:
|
||||||
for m in self.actions:
|
if success:
|
||||||
if action == m:
|
self.success_table.append(action, file_path, dest_path)
|
||||||
self.result[action] += 1
|
|
||||||
else:
|
else:
|
||||||
self.errors += 1
|
self.errors_table.append(action, file_path, dest_path)
|
||||||
if file_path:
|
|
||||||
self.errors_items.append(file_path)
|
if not success:
|
||||||
|
self.errors +=1
|
||||||
|
|
||||||
def print(self):
|
def print(self):
|
||||||
|
"""Print summary"""
|
||||||
|
|
||||||
print()
|
print()
|
||||||
for action in self.result:
|
for action in self.actions:
|
||||||
nb = self.result[action]
|
nb = self.success_table.sum(action)
|
||||||
if self.result[action] != 0:
|
if nb != 0:
|
||||||
if action == 'check':
|
if action == 'check':
|
||||||
print(f"SUMMARY: {nb} files checked in {self.path}.")
|
print(f"SUMMARY: {nb} files checked in {self.root}.")
|
||||||
elif action == 'import':
|
elif action == 'import':
|
||||||
print(f"SUMMARY: {nb} files imported into {self.path}.")
|
print(f"SUMMARY: {nb} files imported into {self.root}.")
|
||||||
elif action == 'sort':
|
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':
|
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':
|
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':
|
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:
|
success = self.success_table.sum()
|
||||||
print(f"SUMMARY: no file imported, sorted or deleted from {self.path}.")
|
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()
|
print()
|
||||||
errors_headers = [f"ERROR: {self.errors} errors reported in files:"]
|
print(f"ERROR: {errors} errors reported for files:")
|
||||||
errors_result = []
|
print(self.success_table.tabulate())
|
||||||
for path in self.errors_items:
|
|
||||||
errors_result.append([path])
|
|
||||||
|
|
||||||
print(tabulate(errors_result, headers=errors_headers))
|
elif self.errors:
|
||||||
print()
|
print(f"ERROR: {errors} errors reported.")
|
||||||
|
|
|
@ -131,12 +131,12 @@ class TestCollection:
|
||||||
def assert_import(self, summary, nb):
|
def assert_import(self, summary, nb):
|
||||||
# Summary is created and there is no errors
|
# Summary is created and there is no errors
|
||||||
assert summary.errors == 0
|
assert summary.errors == 0
|
||||||
assert summary.result['import'] == nb
|
assert summary.success_table.sum('import') == nb
|
||||||
|
|
||||||
def assert_sort(self, summary, nb):
|
def assert_sort(self, summary, nb):
|
||||||
# Summary is created and there is no errors
|
# Summary is created and there is no errors
|
||||||
assert summary.errors == 0
|
assert summary.errors == 0
|
||||||
assert summary.result['sort'] == nb
|
assert summary.success_table.sum('sort') == nb
|
||||||
|
|
||||||
def test_sort_files(self, tmp_path):
|
def test_sort_files(self, tmp_path):
|
||||||
collection = Collection(tmp_path, album_from_folder=True,
|
collection = Collection(tmp_path, album_from_folder=True,
|
||||||
|
@ -148,7 +148,8 @@ class TestCollection:
|
||||||
self.assert_import(summary, 30)
|
self.assert_import(summary, 30)
|
||||||
|
|
||||||
summary = collection.check_files()
|
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
|
assert not summary.errors
|
||||||
|
|
||||||
# check if album value are set
|
# check if album value are set
|
||||||
|
@ -169,13 +170,14 @@ class TestCollection:
|
||||||
|
|
||||||
shutil.copytree(tmp_path / 'test_exif', tmp_path / 'test_exif_copy')
|
shutil.copytree(tmp_path / 'test_exif', tmp_path / 'test_exif_copy')
|
||||||
collection.summary = Summary(tmp_path)
|
collection.summary = Summary(tmp_path)
|
||||||
assert sum(collection.summary.result.values()) == 0
|
assert collection.summary.success_table.sum() == 0
|
||||||
summary = collection.update(loc)
|
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
|
assert not summary.errors
|
||||||
collection.summary = Summary(tmp_path)
|
collection.summary = Summary(tmp_path)
|
||||||
summary = collection.update(loc)
|
summary = collection.update(loc)
|
||||||
assert not summary.result['update']
|
assert summary.success_table.sum() == 0
|
||||||
assert not summary.errors
|
assert not summary.errors
|
||||||
|
|
||||||
# test with populated dest dir
|
# test with populated dest dir
|
||||||
|
@ -186,7 +188,8 @@ class TestCollection:
|
||||||
# test summary update
|
# test summary update
|
||||||
collection.summary = Summary(tmp_path)
|
collection.summary = Summary(tmp_path)
|
||||||
summary = collection.update(loc)
|
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
|
assert not summary.errors
|
||||||
|
|
||||||
def test_sort_files_invalid_db(self, tmp_path):
|
def test_sort_files_invalid_db(self, tmp_path):
|
||||||
|
|
Loading…
Reference in New Issue