From 3767558c6652bf875f1ce17a706a1b2b98fb9853 Mon Sep 17 00:00:00 2001 From: Ethan Dalool Date: Wed, 28 Sep 2022 19:49:01 -0700 Subject: [PATCH] Add search filter has_albums. Sometimes it's nice to search just for the free spirits. --- etiquette/photodb.py | 15 ++++++++++++++- etiquette/searchhelpers.py | 6 ++++++ frontends/etiquette_cli.py | 11 +++++++++++ .../backend/endpoints/album_endpoints.py | 13 +++++-------- .../backend/endpoints/photo_endpoints.py | 2 ++ frontends/etiquette_flask/templates/search.html | 5 +++++ 6 files changed, 43 insertions(+), 9 deletions(-) diff --git a/etiquette/photodb.py b/etiquette/photodb.py index 5297f86..7b6193e 100644 --- a/etiquette/photodb.py +++ b/etiquette/photodb.py @@ -426,6 +426,7 @@ class PDBPhotoMixin: extension=None, extension_not=None, filename=None, + has_albums=None, has_tags=None, has_thumbnail=None, is_searchhidden=False, @@ -475,6 +476,11 @@ class PDBPhotoMixin: '.pdf AND (programming OR "survival guide")' '.pdf programming python' (implicitly AND each term) + has_albums: + If True, require that the Photo belongs to >=1 album. + If False, require that the Photo belongs to no albums. + If None, either is okay. + has_tags: If True, require that the Photo has >=1 tag. If False, require that the Photo has no tags. @@ -569,6 +575,7 @@ class PDBPhotoMixin: extension = searchhelpers.normalize_extension(extension) extension_not = searchhelpers.normalize_extension(extension_not) filename = searchhelpers.normalize_filename(filename) + has_albums = searchhelpers.normalize_has_tags(has_albums) has_tags = searchhelpers.normalize_has_tags(has_tags) has_thumbnail = searchhelpers.normalize_has_thumbnail(has_thumbnail) is_searchhidden = searchhelpers.normalize_is_searchhidden(is_searchhidden) @@ -660,6 +667,7 @@ class PDBPhotoMixin: 'extension': list(extension) or None, 'extension_not': list(extension_not) or None, 'filename': filename or None, + 'has_albums': has_albums, 'has_tags': has_tags, 'has_thumbnail': has_thumbnail, 'mimetype': list(mimetype) or None, @@ -731,9 +739,14 @@ class PDBPhotoMixin: wheres.append(clauses) bindings.extend(patterns) + if has_albums is True: + wheres.append('EXISTS (SELECT 1 FROM album_photo_rel WHERE photoid == photos.id)') + elif has_albums is False: + wheres.append('NOT EXISTS (SELECT 1 FROM album_photo_rel WHERE photoid == photos.id)') + if has_tags is True: wheres.append('EXISTS (SELECT 1 FROM photo_tag_rel WHERE photoid == photos.id)') - if has_tags is False: + elif has_tags is False: wheres.append('NOT EXISTS (SELECT 1 FROM photo_tag_rel WHERE photoid == photos.id)') if yield_albums and not yield_photos: diff --git a/etiquette/searchhelpers.py b/etiquette/searchhelpers.py index cdcbe92..34fed27 100644 --- a/etiquette/searchhelpers.py +++ b/etiquette/searchhelpers.py @@ -192,6 +192,12 @@ def normalize_filename(filename_terms): return filename_terms +def normalize_has_albums(has_albums): + ''' + See voussoirkit.stringtools.truthystring. + ''' + return stringtools.truthystring(has_albums, None) + def normalize_has_tags(has_tags): ''' See voussoirkit.stringtools.truthystring. diff --git a/frontends/etiquette_cli.py b/frontends/etiquette_cli.py index 9fb8ff0..b2f13e8 100644 --- a/frontends/etiquette_cli.py +++ b/frontends/etiquette_cli.py @@ -140,6 +140,7 @@ def search_by_argparse(args, yield_albums=False, yield_photos=False): extension=args.extension, extension_not=args.extension_not, filename=args.filename, + has_albums=args.has_albums, has_tags=args.has_tags, has_thumbnail=args.has_thumbnail, is_searchhidden=args.is_searchhidden, @@ -1417,6 +1418,16 @@ def main(argv): Search for strings within Photos' filenames. ''', ) + p_search.add_argument( + '--has_albums', + '--has-albums', + default=None, + help=''' + If "yes", Photo must belong to at least one album. + If "no", Photo must not belong to any albums. + If "null", doesn't matter. + ''', + ) p_search.add_argument( '--has_tags', '--has-tags', diff --git a/frontends/etiquette_flask/backend/endpoints/album_endpoints.py b/frontends/etiquette_flask/backend/endpoints/album_endpoints.py index e99558c..22a24c9 100644 --- a/frontends/etiquette_flask/backend/endpoints/album_endpoints.py +++ b/frontends/etiquette_flask/backend/endpoints/album_endpoints.py @@ -205,14 +205,10 @@ def get_all_album_names(): response = {'albums': all_albums} return flasktools.json_response(response) -def get_albums_core(): - albums = list(common.P.get_root_albums()) - albums.sort(key=lambda x: x.display_name.lower()) - return albums - @site.route('/albums') def get_albums_html(): - albums = get_albums_core() + albums = list(common.P.get_root_albums()) + albums.sort(key=lambda x: x.display_name.lower()) response = common.render_template( request, 'album.html', @@ -223,8 +219,9 @@ def get_albums_html(): @site.route('/albums.json') def get_albums_json(): - albums = get_albums_core() - albums = [album.jsonify(minimal=True) for album in albums] + albums = list(common.P.get_albums()) + albums.sort(key=lambda x: x.display_name.lower()) + albums = [album.jsonify(include_photos=False) for album in albums] return flasktools.json_response(albums) # Album create and delete ########################################################################## diff --git a/frontends/etiquette_flask/backend/endpoints/photo_endpoints.py b/frontends/etiquette_flask/backend/endpoints/photo_endpoints.py index 2042021..3d44511 100644 --- a/frontends/etiquette_flask/backend/endpoints/photo_endpoints.py +++ b/frontends/etiquette_flask/backend/endpoints/photo_endpoints.py @@ -401,6 +401,7 @@ def get_search_core(): height = request.args.get('height') aspectratio = request.args.get('aspectratio') bytes = request.args.get('bytes') + has_albums = request.args.get('has_albums') has_thumbnail = request.args.get('has_thumbnail') duration = request.args.get('duration') bitrate = request.args.get('bitrate') @@ -421,6 +422,7 @@ def get_search_core(): 'extension': extension, 'extension_not': extension_not, 'filename': filename_terms, + 'has_albums': has_albums, 'has_tags': has_tags, 'has_thumbnail': has_thumbnail, 'is_searchhidden': is_searchhidden, diff --git a/frontends/etiquette_flask/templates/search.html b/frontends/etiquette_flask/templates/search.html index eaf78be..16272a2 100644 --- a/frontends/etiquette_flask/templates/search.html +++ b/frontends/etiquette_flask/templates/search.html @@ -296,6 +296,11 @@ {% endfor %} +