Add yield_photos, count albums in search result limit.

This experiment of bringing Photos and Albums closer to parity in
search is going well so far. I have found some situations where it
is nice to only get albums back from search results.
This commit is contained in:
voussoir 2020-09-27 23:38:49 -07:00
parent c7eda36133
commit 63bc2dfed5
5 changed files with 43 additions and 9 deletions

View file

@ -193,6 +193,13 @@ class FeatureDisabled(EtiquetteException):
''' '''
error_message = 'This feature has been disabled. Requires {}.' error_message = 'This feature has been disabled. Requires {}.'
class NoYields(EtiquetteException):
'''
For when all of the yield_* arguments have been provided as False, and thus
there is nothing for the called function to yield.
'''
error_message = 'At least one of {} must be selected.'
class NotExclusive(EtiquetteException): class NotExclusive(EtiquetteException):
''' '''
For when two or more mutually exclusive actions have been requested. For when two or more mutually exclusive actions have been requested.

View file

@ -559,6 +559,7 @@ class PDBPhotoMixin:
give_back_parameters=False, give_back_parameters=False,
yield_albums=True, yield_albums=True,
yield_photos=True,
): ):
''' '''
PHOTO PROPERTIES PHOTO PROPERTIES
@ -683,6 +684,7 @@ class PDBPhotoMixin:
mimetype = searchhelpers.normalize_extension(mimetype) mimetype = searchhelpers.normalize_extension(mimetype)
within_directory = searchhelpers.normalize_within_directory(within_directory, warning_bag=warning_bag) 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)
yield_photos = searchhelpers.normalize_yield_photos(yield_photos)
if has_tags is False: if has_tags is False:
tag_musts = None tag_musts = None
@ -773,9 +775,19 @@ class PDBPhotoMixin:
'offset': offset or None, 'offset': offset or None,
'orderby': giveback_orderby or None, 'orderby': giveback_orderby or None,
'yield_albums': yield_albums, 'yield_albums': yield_albums,
'yield_photos': yield_photos,
} }
yield parameters yield parameters
if not yield_albums and not yield_photos:
exc = exceptions.NoYields(['yield_albums', 'yield_photos'])
if warning_bag:
warning_bag.add(exc)
yield warning_bag
return
else:
raise exceptions.NoYields(['yield_albums', 'yield_photos'])
photo_tag_rel_exist_clauses = searchhelpers.photo_tag_rel_exist_clauses( photo_tag_rel_exist_clauses = searchhelpers.photo_tag_rel_exist_clauses(
tag_musts, tag_musts,
tag_mays, tag_mays,
@ -826,6 +838,9 @@ class PDBPhotoMixin:
if has_tags is False: if has_tags is False:
wheres.append('NOT EXISTS (SELECT 1 FROM photo_tag_rel WHERE photoid == photos.id)') wheres.append('NOT EXISTS (SELECT 1 FROM photo_tag_rel WHERE photoid == photos.id)')
if yield_albums and not yield_photos:
wheres.append('EXISTS (SELECT 1 FROM album_photo_rel WHERE photoid == photos.id)')
if has_thumbnail is True: if has_thumbnail is True:
notnulls.add('thumbnail') notnulls.add('thumbnail')
elif has_thumbnail is False: elif has_thumbnail is False:
@ -875,7 +890,7 @@ class PDBPhotoMixin:
#print('\n'.join(str(x) for x in explain.fetchall())) #print('\n'.join(str(x) for x in explain.fetchall()))
generator = self.sql_select(query, bindings) generator = self.sql_select(query, bindings)
seen_albums = set() seen_albums = set()
photos_received = 0 results_received = 0
for row in generator: for row in generator:
photo = self.get_cached_instance('photo', row) photo = self.get_cached_instance('photo', row)
@ -898,16 +913,18 @@ class PDBPhotoMixin:
offset -= 1 offset -= 1
continue continue
if limit is not None and photos_received >= limit: if limit is not None and results_received >= limit:
break break
if yield_albums: if yield_albums:
new_albums = photo.get_containing_albums().difference(seen_albums) new_albums = photo.get_containing_albums().difference(seen_albums)
yield from new_albums yield from new_albums
results_received += len(new_albums)
seen_albums.update(new_albums) seen_albums.update(new_albums)
photos_received += 1 if yield_photos:
yield photo yield photo
results_received += 1
if warning_bag and warning_bag.warnings: if warning_bag and warning_bag.warnings:
yield warning_bag yield warning_bag

View file

@ -422,6 +422,12 @@ def normalize_yield_albums(yield_albums):
''' '''
return helpers.truthystring(yield_albums) return helpers.truthystring(yield_albums)
def normalize_yield_photos(yield_photos):
'''
See etiquette.helpers.truthystring.
'''
return helpers.truthystring(yield_photos)
EXIST_FORMAT = ''' EXIST_FORMAT = '''
{operator} ( {operator} (
SELECT 1 FROM photo_tag_rel WHERE photos.id == photo_tag_rel.photoid SELECT 1 FROM photo_tag_rel WHERE photos.id == photo_tag_rel.photoid

View file

@ -326,6 +326,7 @@ def get_search_core():
mimetype = request.args.get('mimetype') mimetype = request.args.get('mimetype')
is_searchhidden = request.args.get('is_searchhidden', False) is_searchhidden = request.args.get('is_searchhidden', False)
yield_albums = request.args.get('yield_albums', True) yield_albums = request.args.get('yield_albums', True)
yield_photos = request.args.get('yield_photos', True)
limit = request.args.get('limit') limit = request.args.get('limit')
# This is being pre-processed because the site enforces a maximum value # This is being pre-processed because the site enforces a maximum value
@ -382,6 +383,7 @@ def get_search_core():
'give_back_parameters': True, 'give_back_parameters': True,
'yield_albums': yield_albums, 'yield_albums': yield_albums,
'yield_photos': yield_photos,
} }
# print(search_kwargs) # print(search_kwargs)
search_generator = common.P.search(**search_kwargs) search_generator = common.P.search(**search_kwargs)
@ -394,14 +396,11 @@ def get_search_core():
warnings = set() warnings = set()
search_results = [] search_results = []
search_results_photo_count = 0
for item in search_generator: for item in search_generator:
if isinstance(item, etiquette.objects.WarningBag): if isinstance(item, etiquette.objects.WarningBag):
warnings.update(item.warnings) warnings.update(item.warnings)
continue continue
search_results.append(item) search_results.append(item)
if isinstance(item, etiquette.objects.Photo):
search_results_photo_count += 1
# TAGS ON THIS PAGE # TAGS ON THIS PAGE
total_tags = set() total_tags = set()
@ -415,7 +414,7 @@ def get_search_core():
original_params = request.args.to_dict() original_params = request.args.to_dict()
original_params['limit'] = limit original_params['limit'] = limit
if limit and search_results_photo_count >= limit: if limit and len(search_results) >= limit:
next_params = original_params.copy() next_params = original_params.copy()
next_params['offset'] = offset + limit next_params['offset'] = offset + limit
next_params = helpers.dict_to_params(next_params) next_params = helpers.dict_to_params(next_params)

View file

@ -298,6 +298,10 @@
<option value="yes" {{"selected" if search_kwargs['yield_albums']==True else ""}}>Include albums</option> <option value="yes" {{"selected" if search_kwargs['yield_albums']==True else ""}}>Include albums</option>
<option value="no" {{"selected" if search_kwargs['yield_albums']==False else ""}}>Don't include albums</option> <option value="no" {{"selected" if search_kwargs['yield_albums']==False else ""}}>Don't include albums</option>
</select> </select>
<select name="yield_photos" class="basic_param">
<option value="yes" {{"selected" if search_kwargs['yield_photos']==True else ""}}>Include photos</option>
<option value="no" {{"selected" if search_kwargs['yield_photos']==False else ""}}>Don't include photos</option>
</select>
<select name="view" class="basic_param"> <select name="view" class="basic_param">
<option value="grid" {{"selected" if search_kwargs['view']=="grid" else ""}}>Grid</option> <option value="grid" {{"selected" if search_kwargs['view']=="grid" else ""}}>Grid</option>
<option value="list" {{"selected" if search_kwargs['view']=="list" else ""}}>List</option> <option value="list" {{"selected" if search_kwargs['view']=="list" else ""}}>List</option>
@ -375,7 +379,8 @@ selected form values are these.
const PARAM_DEFAULTS = { const PARAM_DEFAULTS = {
'limit': 50, 'limit': 50,
'view': 'grid', 'view': 'grid',
'yield_albums': 'yes' 'yield_albums': 'yes',
'yield_photos': 'yes'
} }
function add_searchtag(ul, value, inputted_list, li_class) function add_searchtag(ul, value, inputted_list, li_class)
{ {