diff --git a/ordigi/cli.py b/ordigi/cli.py index 7d1f53a..0189336 100755 --- a/ordigi/cli.py +++ b/ordigi/cli.py @@ -178,6 +178,7 @@ def _check(**kwargs): if log_level < 30: summary.print() if summary.errors: + LOG.error('Db data is not accurate run `ordigi update --checksum`') sys.exit(1) else: LOG.error('Db data is not accurate run `ordigi update`') @@ -578,6 +579,13 @@ def _sort(**kwargs): @cli.command('update') @add_options(_logger_options) +@click.option( + '--checksum', + '-c', + default=False, + is_flag=True, + help='Update checksum, assuming file are changed by the user', +) @click.argument('path', required=True, nargs=1, type=click.Path()) def _update(**kwargs): """ @@ -589,7 +597,7 @@ def _update(**kwargs): collection = Collection(root) loc = _cli_get_location(collection) - summary = collection.update(loc) + summary = collection.update(loc, kwargs['checksum']) if log_level < 30: summary.print() diff --git a/ordigi/collection.py b/ordigi/collection.py index 0a0ecd5..a852e92 100644 --- a/ordigi/collection.py +++ b/ordigi/collection.py @@ -835,7 +835,9 @@ class Collection(SortMedias): file_paths = list(self.get_collection_files()) db_rows = [row['FilePath'] for row in self.db.sqlite.get_rows('metadata')] for file_path in file_paths: + # Assuming file_path are inside collection root dir relpath = os.path.relpath(file_path, self.root) + # If file not in database if relpath not in db_rows: self.log.error('Db data is not accurate') diff --git a/ordigi/media.py b/ordigi/media.py index b0538e8..363f553 100644 --- a/ordigi/media.py +++ b/ordigi/media.py @@ -527,7 +527,7 @@ class Media(ReadExif): return db.get_metadata(relpath, 'LocationId') - def _check_file(self, db, root): + def _check_file(self, db, root, check=True): """Check if file_path is a subpath of root""" if str(self.file_path).startswith(str(root)): @@ -535,14 +535,13 @@ class Media(ReadExif): db_checksum = db.get_checksum(relpath) file_checksum = self.metadata['checksum'] # Check if checksum match - if db_checksum and db_checksum != file_checksum: - self.log.error(f'{self.file_path} checksum has changed') - self.log.error('(modified or corrupted file).') + if check and db_checksum and db_checksum != file_checksum: + self.log.error(f'{self.file_path} checksum has changed, modified or corrupted file.') self.log.error( f'file_checksum={file_checksum},\ndb_checksum={db_checksum}' ) self.log.info( - 'Use --reset-cache, check database integrity or try to restore the file' + 'Use ordigi update --checksum or --reset-cache, check database integrity or try to restore the file' ) # We d'ont want to silently ignore or correct this without # resetting the cache as is could be due to file corruption @@ -605,7 +604,7 @@ class Media(ReadExif): if not album or album == '': self.metadata['album'] = folder - def get_metadata(self, root, loc=None, db=None, cache=False): + def get_metadata(self, root, loc=None, db=None, cache=False, check=True): """ Get a dictionary of metadata from exif. All keys will be present and have a value of None if not obtained. @@ -615,8 +614,9 @@ class Media(ReadExif): db_checksum = False location_id = None - if cache and db: - relpath, db_checksum = self._check_file(db, root) + if cache and db and str(self.file_path).startswith(str(root)): + relpath = os.path.relpath(self.file_path, root) + db_checksum = db.get_checksum(relpath) if db_checksum: location_id = self._set_metadata_from_db(db, relpath) self.set_location_from_db(location_id, db) @@ -702,17 +702,17 @@ class Medias: return media - def get_media_data(self, file_path, src_dir, loc=None): + def get_media_data(self, file_path, src_dir, loc=None, check=True): media = self.get_media(file_path, src_dir) media.get_metadata( - self.root, loc, self.db.sqlite, self.exif_opt['cache'] + self.root, loc, self.db.sqlite, self.exif_opt['cache'], check ) return media - def get_metadata(self, src_path, src_dir, loc=None): + def get_metadata(self, src_path, src_dir, loc=None, check=True): """Get metadata""" - return self.get_media_data(src_path, src_dir, loc).metadata + return self.get_media_data(src_path, src_dir, loc, check).metadata def get_paths(self, src_dirs, imp=False): """Get paths""" diff --git a/tests/test_cli.py b/tests/test_cli.py index 952af28..9414ba7 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -154,6 +154,7 @@ class TestOrdigi: shutil.copyfile(file_path, dest_path) for opt, arg in self.logger_options: self.assert_cli(cli._update, [opt, arg, str(self.src_path)]) + self.assert_cli(cli._update, ['--checksum', str(self.src_path)]) def assert_check(self): for opt, arg in self.logger_options: @@ -187,7 +188,6 @@ class TestOrdigi: def test_init_update_check_clean(self): self.assert_init() self.assert_update() - self.assert_check() self.assert_clean() def test_import(self, tmp_path): @@ -239,6 +239,9 @@ class TestOrdigi: self.assert_cli(cli._compare, paths) self.assert_options(cli._compare, bool_options, arg_options, paths) + def test_check(self): + self.assert_check() + def test_needsfiles(tmpdir): assert tmpdir diff --git a/tests/test_collection.py b/tests/test_collection.py index 22b3a93..4d7d94c 100644 --- a/tests/test_collection.py +++ b/tests/test_collection.py @@ -169,7 +169,7 @@ class TestCollection: path_format = 'test_exif//<%Y>-.%l' summary = collection.sort_files([tmp_path], loc) - self.assert_sort(summary, 23) + self.assert_sort(summary, 26) shutil.copytree(tmp_path / 'test_exif', tmp_path / 'test_exif_copy') collection.summary = Summary(tmp_path)