Add basename in separate column so we can orderby it.
For a while I've wanted to be able to sort search results by the file's basename. This is especially important for the cli. SQLite doesn't have an easy way to split the filepath column by the slash, so the only choice is to store basename as a separate column. I put it off for a while but I think it's the right move. However we must not forget to update it every time we update filepath, which is a bummer.
This commit is contained in:
parent
f9dc720ff8
commit
6522bda09c
6 changed files with 75 additions and 6 deletions
|
@ -41,7 +41,7 @@ ffmpeg = _load_ffmpeg()
|
||||||
|
|
||||||
# Database #########################################################################################
|
# Database #########################################################################################
|
||||||
|
|
||||||
DATABASE_VERSION = 15
|
DATABASE_VERSION = 16
|
||||||
DB_VERSION_PRAGMA = f'''
|
DB_VERSION_PRAGMA = f'''
|
||||||
PRAGMA user_version = {DATABASE_VERSION};
|
PRAGMA user_version = {DATABASE_VERSION};
|
||||||
'''
|
'''
|
||||||
|
@ -91,8 +91,9 @@ CREATE TABLE IF NOT EXISTS photos(
|
||||||
id TEXT PRIMARY KEY NOT NULL,
|
id TEXT PRIMARY KEY NOT NULL,
|
||||||
filepath TEXT COLLATE NOCASE,
|
filepath TEXT COLLATE NOCASE,
|
||||||
dev_ino TEXT,
|
dev_ino TEXT,
|
||||||
|
basename TEXT COLLATE NOCASE,
|
||||||
override_filename TEXT COLLATE NOCASE,
|
override_filename TEXT COLLATE NOCASE,
|
||||||
extension TEXT,
|
extension TEXT COLLATE NOCASE,
|
||||||
width INT,
|
width INT,
|
||||||
height INT,
|
height INT,
|
||||||
ratio REAL,
|
ratio REAL,
|
||||||
|
@ -195,6 +196,7 @@ SQL_INDEX = sqlhelpers.reverse_table_column_map(SQL_COLUMNS)
|
||||||
|
|
||||||
ALLOWED_ORDERBY_COLUMNS = {
|
ALLOWED_ORDERBY_COLUMNS = {
|
||||||
'area',
|
'area',
|
||||||
|
'basename',
|
||||||
'bitrate',
|
'bitrate',
|
||||||
'bytes',
|
'bytes',
|
||||||
'created',
|
'created',
|
||||||
|
|
|
@ -1097,6 +1097,7 @@ class Photo(ObjectBase):
|
||||||
data = {
|
data = {
|
||||||
'id': self.id,
|
'id': self.id,
|
||||||
'filepath': new_filepath.absolute_path,
|
'filepath': new_filepath.absolute_path,
|
||||||
|
'basename': new_filepath.basename,
|
||||||
}
|
}
|
||||||
self.photodb.sql_update(table='photos', pairs=data, where_key='id')
|
self.photodb.sql_update(table='photos', pairs=data, where_key='id')
|
||||||
self.real_path = new_filepath
|
self.real_path = new_filepath
|
||||||
|
@ -1180,9 +1181,11 @@ class Photo(ObjectBase):
|
||||||
spinal.copy_file(old_path, new_path)
|
spinal.copy_file(old_path, new_path)
|
||||||
|
|
||||||
data = {
|
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
|
self.real_path = new_path
|
||||||
|
|
||||||
if new_path.normcase == old_path.normcase:
|
if new_path.normcase == old_path.normcase:
|
||||||
|
|
|
@ -507,6 +507,7 @@ class PDBPhotoMixin:
|
||||||
data = {
|
data = {
|
||||||
'id': photo_id,
|
'id': photo_id,
|
||||||
'filepath': filepath.absolute_path,
|
'filepath': filepath.absolute_path,
|
||||||
|
'basename': filepath.basename,
|
||||||
'override_filename': None,
|
'override_filename': None,
|
||||||
'extension': filepath.extension.no_dot,
|
'extension': filepath.extension.no_dot,
|
||||||
'created': helpers.now(),
|
'created': helpers.now(),
|
||||||
|
|
|
@ -338,6 +338,9 @@ def normalize_orderby(orderby, warning_bag=None):
|
||||||
elif column == 'area':
|
elif column == 'area':
|
||||||
column = '(width * height)'
|
column = '(width * height)'
|
||||||
|
|
||||||
|
elif column == 'basename':
|
||||||
|
column = 'COALESCE(override_filename, basename)'
|
||||||
|
|
||||||
elif column == 'bitrate':
|
elif column == 'bitrate':
|
||||||
column = '((bytes / 128) / duration)'
|
column = '((bytes / 128) / duration)'
|
||||||
|
|
||||||
|
|
|
@ -192,7 +192,6 @@ def purge_empty_albums_argparse(args):
|
||||||
|
|
||||||
def search_argparse(args):
|
def search_argparse(args):
|
||||||
photos = search_by_argparse(args, yield_photos=True)
|
photos = search_by_argparse(args, yield_photos=True)
|
||||||
photos = sorted(photos, key=lambda p: p.real_path)
|
|
||||||
for photo in photos:
|
for photo in photos:
|
||||||
print(photo.real_path.absolute_path)
|
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('--tag_expression', '--tag-expression', dest='tag_expression', default=None)
|
||||||
p_search.add_argument('--limit', dest='limit', default=None)
|
p_search.add_argument('--limit', dest='limit', default=None)
|
||||||
p_search.add_argument('--offset', dest='offset', 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.add_argument('--yield_albums', '--yield-albums', dest='yield_albums', default=None)
|
||||||
p_search.set_defaults(func=search_argparse)
|
p_search.set_defaults(func=search_argparse)
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import argparse
|
import argparse
|
||||||
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
from voussoirkit import sqlhelpers
|
from voussoirkit import sqlhelpers
|
||||||
|
@ -454,6 +455,66 @@ def upgrade_14_to_15(photodb):
|
||||||
dev_ino = f'{dev},{ino}'
|
dev_ino = f'{dev},{ino}'
|
||||||
photodb.sql_execute('UPDATE photos SET dev_ino = ? WHERE id == ?', [dev_ino, photo.id])
|
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):
|
def upgrade_all(data_directory):
|
||||||
'''
|
'''
|
||||||
Given the directory containing a phototagger database, apply all of the
|
Given the directory containing a phototagger database, apply all of the
|
||||||
|
|
Loading…
Reference in a new issue