Add search argument within_directory.

This commit is contained in:
voussoir 2020-09-27 10:48:01 -07:00
parent da67740689
commit 667c14f072
3 changed files with 53 additions and 0 deletions

View file

@ -550,6 +550,7 @@ class PDBPhotoMixin:
tag_mays=None, tag_mays=None,
tag_forbids=None, tag_forbids=None,
tag_expression=None, tag_expression=None,
within_directory=None,
limit=None, limit=None,
offset=None, offset=None,
@ -628,6 +629,11 @@ class PDBPhotoMixin:
'family AND (animals OR vacation)' 'family AND (animals OR vacation)'
'family vacation outdoors' (implicitly AND each term) 'family vacation outdoors' (implicitly AND each term)
within_directory:
A string or list of strings or pathclass Paths of directories.
Photos MUST have a `filepath` that is a child of one of these
directories.
QUERY OPTIONS QUERY OPTIONS
limit: limit:
The maximum number of *successful* results to yield. The maximum number of *successful* results to yield.
@ -675,6 +681,7 @@ class PDBPhotoMixin:
has_thumbnail = searchhelpers.normalize_has_thumbnail(has_thumbnail) has_thumbnail = searchhelpers.normalize_has_thumbnail(has_thumbnail)
is_searchhidden = searchhelpers.normalize_is_searchhidden(is_searchhidden) is_searchhidden = searchhelpers.normalize_is_searchhidden(is_searchhidden)
mimetype = searchhelpers.normalize_extension(mimetype) mimetype = searchhelpers.normalize_extension(mimetype)
within_directory = searchhelpers.normalize_within_directory(within_directory, warning_bag=warning_bag)
yield_albums = searchhelpers.normalize_yield_albums(yield_albums) yield_albums = searchhelpers.normalize_yield_albums(yield_albums)
if has_tags is False: if has_tags is False:
@ -761,6 +768,7 @@ class PDBPhotoMixin:
'tag_mays': tag_mays or None, 'tag_mays': tag_mays or None,
'tag_forbids': tag_forbids or None, 'tag_forbids': tag_forbids or None,
'tag_expression': giveback_tag_expression or None, 'tag_expression': giveback_tag_expression or None,
'within_directory': within_directory or None,
'limit': limit, 'limit': limit,
'offset': offset or None, 'offset': offset or None,
'orderby': giveback_orderby or None, 'orderby': giveback_orderby or None,
@ -802,6 +810,17 @@ class PDBPhotoMixin:
if mimetype: if mimetype:
notnulls.add('extension') notnulls.add('extension')
if within_directory:
patterns = {f'{d.absolute_path}{os.sep}%' for d in within_directory}
clauses = ['filepath LIKE ?'] * len(patterns)
if len(clauses) > 1:
clauses = ' OR '.join(clauses)
clauses = f'({clauses})'
else:
clauses = clauses.pop()
wheres.append(clauses)
bindings.extend(patterns)
if has_tags is True: if has_tags is True:
wheres.append('EXISTS (SELECT 1 FROM photo_tag_rel WHERE photoid == photos.id)') wheres.append('EXISTS (SELECT 1 FROM photo_tag_rel WHERE photoid == photos.id)')
if has_tags is False: if has_tags is False:

View file

@ -9,6 +9,7 @@ from . import helpers
from . import objects from . import objects
from voussoirkit import expressionmatch from voussoirkit import expressionmatch
from voussoirkit import pathclass
from voussoirkit import sqlhelpers from voussoirkit import sqlhelpers
def expand_mmf(tag_musts, tag_mays, tag_forbids): def expand_mmf(tag_musts, tag_mays, tag_forbids):
@ -385,6 +386,36 @@ def normalize_tag_expression(expression):
return expression return expression
def normalize_within_directory(paths, warning_bag=None):
if paths is None:
return set()
if isinstance(paths, set):
pass
elif isinstance(paths, (str, pathclass.Path)):
paths = {paths}
elif isinstance(paths, (list, tuple)):
paths = set(paths)
else:
exc = TypeError(paths)
if warning_bag:
warning_bag.add(exc)
return set()
else:
raise exc
paths = {pathclass.Path(p) for p in paths}
directories = {p for p in paths if p.is_dir}
not_directories = paths.difference(directories)
if not_directories:
exc = pathclass.NotDirectory(not_directories)
if warning_bag:
warning_bag.add(exc)
else:
raise exc
return directories
def normalize_yield_albums(yield_albums): def normalize_yield_albums(yield_albums):
''' '''
See etiquette.helpers.truthystring. See etiquette.helpers.truthystring.

View file

@ -387,6 +387,9 @@ def get_search_core():
search_generator = common.P.search(**search_kwargs) search_generator = common.P.search(**search_kwargs)
# Because of the giveback, first element is cleaned up kwargs # Because of the giveback, first element is cleaned up kwargs
search_kwargs = next(search_generator) search_kwargs = next(search_generator)
# Web UI users aren't allowed to use within_directory anyway, so don't
# show it to them.
search_kwargs.pop('within_directory', None)
# print(search_kwargs) # print(search_kwargs)
warnings = set() warnings = set()