diff --git a/etiquette/constants.py b/etiquette/constants.py index c09cab0..d0fc1f1 100644 --- a/etiquette/constants.py +++ b/etiquette/constants.py @@ -41,7 +41,7 @@ ffmpeg = _load_ffmpeg() # Database ######################################################################################### -DATABASE_VERSION = 15 +DATABASE_VERSION = 16 DB_VERSION_PRAGMA = f''' PRAGMA user_version = {DATABASE_VERSION}; ''' @@ -91,8 +91,9 @@ CREATE TABLE IF NOT EXISTS photos( id TEXT PRIMARY KEY NOT NULL, filepath TEXT COLLATE NOCASE, dev_ino TEXT, + basename TEXT COLLATE NOCASE, override_filename TEXT COLLATE NOCASE, - extension TEXT, + extension TEXT COLLATE NOCASE, width INT, height INT, ratio REAL, @@ -195,6 +196,7 @@ SQL_INDEX = sqlhelpers.reverse_table_column_map(SQL_COLUMNS) ALLOWED_ORDERBY_COLUMNS = { 'area', + 'basename', 'bitrate', 'bytes', 'created', diff --git a/etiquette/objects.py b/etiquette/objects.py index 1fdd9a5..303df69 100644 --- a/etiquette/objects.py +++ b/etiquette/objects.py @@ -1097,6 +1097,7 @@ class Photo(ObjectBase): data = { 'id': self.id, 'filepath': new_filepath.absolute_path, + 'basename': new_filepath.basename, } self.photodb.sql_update(table='photos', pairs=data, where_key='id') self.real_path = new_filepath @@ -1180,9 +1181,11 @@ class Photo(ObjectBase): spinal.copy_file(old_path, new_path) data = { - 'filepath': (old_path.absolute_path, new_path.absolute_path), + 'id': self.id, + 'filepath': new_path.absolute_path, + 'basename': new_path.basename, } - self.photodb.sql_update(table='photos', pairs=data, where_key='filepath') + self.photodb.sql_update(table='photos', pairs=data, where_key='id') self.real_path = new_path if new_path.normcase == old_path.normcase: diff --git a/etiquette/photodb.py b/etiquette/photodb.py index 6f15c09..d25ec97 100644 --- a/etiquette/photodb.py +++ b/etiquette/photodb.py @@ -507,6 +507,7 @@ class PDBPhotoMixin: data = { 'id': photo_id, 'filepath': filepath.absolute_path, + 'basename': filepath.basename, 'override_filename': None, 'extension': filepath.extension.no_dot, 'created': helpers.now(), diff --git a/etiquette/searchhelpers.py b/etiquette/searchhelpers.py index 3af01ce..83d8cb6 100644 --- a/etiquette/searchhelpers.py +++ b/etiquette/searchhelpers.py @@ -338,6 +338,9 @@ def normalize_orderby(orderby, warning_bag=None): elif column == 'area': column = '(width * height)' + elif column == 'basename': + column = 'COALESCE(override_filename, basename)' + elif column == 'bitrate': column = '((bytes / 128) / duration)' diff --git a/frontends/etiquette_cli.py b/frontends/etiquette_cli.py index e9d808a..d76093f 100644 --- a/frontends/etiquette_cli.py +++ b/frontends/etiquette_cli.py @@ -192,7 +192,6 @@ def purge_empty_albums_argparse(args): def search_argparse(args): photos = search_by_argparse(args, yield_photos=True) - photos = sorted(photos, key=lambda p: p.real_path) for photo in photos: print(photo.real_path.absolute_path) @@ -357,7 +356,7 @@ def main(argv): p_search.add_argument('--tag_expression', '--tag-expression', dest='tag_expression', default=None) p_search.add_argument('--limit', dest='limit', default=None) p_search.add_argument('--offset', dest='offset', default=None) - p_search.add_argument('--orderby', dest='orderby', default=None) + p_search.add_argument('--orderby', dest='orderby', default='basename-ASC') # p_search.add_argument('--yield_albums', '--yield-albums', dest='yield_albums', default=None) p_search.set_defaults(func=search_argparse) diff --git a/utilities/database_upgrader/database_upgrader.py b/utilities/database_upgrader/database_upgrader.py index 9a2f49b..54083d8 100644 --- a/utilities/database_upgrader/database_upgrader.py +++ b/utilities/database_upgrader/database_upgrader.py @@ -1,4 +1,5 @@ import argparse +import os import sys from voussoirkit import sqlhelpers @@ -454,6 +455,66 @@ def upgrade_14_to_15(photodb): dev_ino = f'{dev},{ino}' photodb.sql_execute('UPDATE photos SET dev_ino = ? WHERE id == ?', [dev_ino, photo.id]) +def upgrade_15_to_16(photodb): + ''' + Added the basename column to photos. Added collate nocase to extension. + ''' + with Regenerator(photodb, except_tables='photos'): + photodb.sql_executescript(''' + PRAGMA foreign_keys = OFF; + + BEGIN; + + ALTER TABLE photos RENAME TO photos_old; + + CREATE TABLE photos( + id TEXT PRIMARY KEY NOT NULL, + filepath TEXT COLLATE NOCASE, + dev_ino TEXT, + basename TEXT COLLATE NOCASE, + override_filename TEXT COLLATE NOCASE, + extension TEXT COLLATE NOCASE, + width INT, + height INT, + ratio REAL, + area INT, + duration INT, + bytes INT, + created INT, + thumbnail TEXT, + tagged_at INT, + author_id TEXT, + searchhidden INT, + FOREIGN KEY(author_id) REFERENCES users(id) + ); + + INSERT INTO photos SELECT + id, + filepath, + dev_ino, + NULL, + override_filename, + extension, + width, + height, + ratio, + area, + duration, + bytes, + created, + thumbnail, + tagged_at, + author_id, + searchhidden + FROM photos_old; + + DROP TABLE photos_old; + ''') + + for (id, filepath) in photodb.sql_select('SELECT id, filepath FROM photos'): + basename = os.path.basename(filepath) + photodb.sql_execute('UPDATE photos SET basename = ? WHERE id == ?', [basename, id]) + def upgrade_all(data_directory): ''' Given the directory containing a phototagger database, apply all of the