Add early author search; Load Photo.mimetype on instantiation

This commit is contained in:
voussoir 2016-12-23 19:49:51 -08:00
parent 5038d92b93
commit 564518f4d8
12 changed files with 69 additions and 46 deletions

View file

@ -121,7 +121,7 @@ DEFAULT_CONFIGURATION = {
'min_username_length': 2, 'min_username_length': 2,
'max_username_length': 24, 'max_username_length': 24,
'valid_username_chars': string.ascii_letters + string.digits + '~!@#$%^&*()[]{}:;,.<>/\\-_+=', 'valid_username_chars': string.ascii_letters + string.digits + '~!@#$%^*()[]{}:;,.<>/\\-_+=',
'min_password_length': 6, 'min_password_length': 6,
'id_length': 12, 'id_length': 12,

View file

@ -404,8 +404,8 @@ def get_search_core():
limit = 50 limit = 50
# OFFSET # OFFSET
offset = request.args.get('offset', None) offset = request.args.get('offset', '')
if offset: if offset.isdigit():
offset = int(offset) offset = int(offset)
else: else:
offset = None offset = None
@ -421,6 +421,15 @@ def get_search_core():
tag_mays = [qualname_map.get(tag, tag) for tag in tag_mays if tag != ''] tag_mays = [qualname_map.get(tag, tag) for tag in tag_mays if tag != '']
tag_forbids = [qualname_map.get(tag, tag) for tag in tag_forbids if tag != ''] tag_forbids = [qualname_map.get(tag, tag) for tag in tag_forbids if tag != '']
# AUTHOR
authors = request.args.get('author', None)
if authors:
authors = authors.split(',')
authors = [a.strip() for a in authors]
authors = [P.get_user(username=a) for a in authors]
else:
authors = None
# ORDERBY # ORDERBY
orderby = request.args.get('orderby', None) orderby = request.args.get('orderby', None)
if orderby: if orderby:
@ -430,11 +439,11 @@ def get_search_core():
orderby = None orderby = None
# HAS_TAGS # HAS_TAGS
has_tags = request.args.get('has_tags', '') has_tags = request.args.get('has_tags', None)
if has_tags == '': if has_tags:
has_tags = None
else:
has_tags = helpers.truthystring(has_tags) has_tags = helpers.truthystring(has_tags)
else:
has_tags = None
# MINMAXERS # MINMAXERS
area = request.args.get('area', None) area = request.args.get('area', None)
@ -454,6 +463,7 @@ def get_search_core():
'bytes': bytes, 'bytes': bytes,
'duration': duration, 'duration': duration,
'authors': authors,
'created': created, 'created': created,
'extension': extension_list, 'extension': extension_list,
'extension_not': extension_not_list, 'extension_not': extension_not_list,

View file

@ -38,7 +38,7 @@ def photo(p, include_albums=True, include_tags=True):
'has_thumbnail': bool(p.thumbnail), 'has_thumbnail': bool(p.thumbnail),
'created': p.created, 'created': p.created,
'filename': p.basename, 'filename': p.basename,
'mimetype': p.mimetype(), 'mimetype': p.mimetype,
} }
if include_albums: if include_albums:
j['albums'] = [album(a, minimal=True) for a in p.albums()] j['albums'] = [album(a, minimal=True) for a in p.albums()]

View file

@ -300,6 +300,8 @@ class Photo(ObjectBase):
self.ratio = row_tuple['ratio'] self.ratio = row_tuple['ratio']
self.thumbnail = row_tuple['thumbnail'] self.thumbnail = row_tuple['thumbnail']
self.mimetype = helpers.get_mimetype(self.real_filepath)
def __reinit__(self): def __reinit__(self):
''' '''
Reload the row from the database and do __init__ with them. Reload the row from the database and do __init__ with them.
@ -392,8 +394,7 @@ class Photo(ObjectBase):
hopeful_filepath = self.make_thumbnail_filepath() hopeful_filepath = self.make_thumbnail_filepath()
return_filepath = None return_filepath = None
mime = self.mimetype() if self.mimetype == 'image':
if mime == 'image':
self.photodb.log.debug('Thumbnailing %s' % self.real_filepath) self.photodb.log.debug('Thumbnailing %s' % self.real_filepath)
try: try:
image = PIL.Image.open(self.real_filepath) image = PIL.Image.open(self.real_filepath)
@ -413,7 +414,7 @@ class Photo(ObjectBase):
image.save(hopeful_filepath, quality=50) image.save(hopeful_filepath, quality=50)
return_filepath = hopeful_filepath return_filepath = hopeful_filepath
elif mime == 'video' and constants.ffmpeg: elif self.mimetype == 'video' and constants.ffmpeg:
#print('video') #print('video')
probe = constants.ffmpeg.probe(self.real_filepath) probe = constants.ffmpeg.probe(self.real_filepath)
try: try:
@ -495,9 +496,6 @@ class Photo(ObjectBase):
hopeful_filepath = os.path.join(folder, basename) + '.jpg' hopeful_filepath = os.path.join(folder, basename) + '.jpg'
return hopeful_filepath return hopeful_filepath
def mimetype(self):
return helpers.get_mimetype(self.real_filepath)
@decorators.time_me @decorators.time_me
def reload_metadata(self, *, commit=True): def reload_metadata(self, *, commit=True):
''' '''
@ -510,8 +508,7 @@ class Photo(ObjectBase):
self.ratio = None self.ratio = None
self.duration = None self.duration = None
mime = self.mimetype() if self.mimetype == 'image':
if mime == 'image':
try: try:
image = PIL.Image.open(self.real_filepath) image = PIL.Image.open(self.real_filepath)
except (OSError, ValueError): except (OSError, ValueError):
@ -521,7 +518,7 @@ class Photo(ObjectBase):
image.close() image.close()
self.photodb.log.debug('Loaded image data for {photo:r}'.format(photo=self)) self.photodb.log.debug('Loaded image data for {photo:r}'.format(photo=self))
elif mime == 'video' and constants.ffmpeg: elif self.mimetype == 'video' and constants.ffmpeg:
try: try:
probe = constants.ffmpeg.probe(self.real_filepath) probe = constants.ffmpeg.probe(self.real_filepath)
if probe and probe.video: if probe and probe.video:
@ -531,7 +528,7 @@ class Photo(ObjectBase):
except: except:
traceback.print_exc() traceback.print_exc()
elif mime == 'audio': elif self.mimetype == 'audio':
try: try:
probe = constants.ffmpeg.probe(self.real_filepath) probe = constants.ffmpeg.probe(self.real_filepath)
if probe and probe.audio: if probe and probe.audio:

View file

@ -452,6 +452,8 @@ class PDBPhotoMixin:
elif author is not None: elif author is not None:
# Just to confirm # Just to confirm
author_id = self.get_user(id=author).id author_id = self.get_user(id=author).id
else:
author_id = None
extension = os.path.splitext(filename)[1] extension = os.path.splitext(filename)[1]
extension = extension.replace('.', '') extension = extension.replace('.', '')
@ -524,6 +526,7 @@ class PDBPhotoMixin:
bytes=None, bytes=None,
duration=None, duration=None,
authors=None,
created=None, created=None,
extension=None, extension=None,
extension_not=None, extension_not=None,
@ -541,11 +544,14 @@ class PDBPhotoMixin:
orderby=None orderby=None
): ):
''' '''
PHOTO PROPERTISE PHOTO PROPERTIES
area, width, height, ratio, bytes, duration: area, width, height, ratio, bytes, duration:
A hyphen_range string representing min and max. Or just a number for lower bound. A hyphen_range string representing min and max. Or just a number for lower bound.
TAGS AND FILTERS TAGS AND FILTERS
authors:
A list of User object or users IDs.
created: created:
A hyphen_range string respresenting min and max. Or just a number for lower bound. A hyphen_range string respresenting min and max. Or just a number for lower bound.
@ -615,6 +621,11 @@ class PDBPhotoMixin:
extension_not = helpers._normalize_extensions(extension_not) extension_not = helpers._normalize_extensions(extension_not)
mimetype = helpers._normalize_extensions(mimetype) mimetype = helpers._normalize_extensions(mimetype)
if authors is not None:
if isinstance(authors, str):
authors = {authors, }
authors = set(a.id if isinstance(a, objects.User) else a for a in authors)
if filename is not None: if filename is not None:
if not isinstance(filename, str): if not isinstance(filename, str):
filename = ' '.join(filename) filename = ' '.join(filename)
@ -669,10 +680,13 @@ class PDBPhotoMixin:
#print('Failed extension_not') #print('Failed extension_not')
continue continue
if mimetype and photo.mimetype() not in mimetype: if mimetype and photo.mimetype not in mimetype:
#print('Failed mimetype') #print('Failed mimetype')
continue continue
if authors and photo.author_id not in authors:
continue
if filename and not _helper_filenamefilter(subject=photo.basename, terms=filename): if filename and not _helper_filenamefilter(subject=photo.basename, terms=filename):
#print('Failed filename') #print('Failed filename')
continue continue

Binary file not shown.

View file

@ -154,6 +154,10 @@ li
bottom: 0; bottom: 0;
right: 0; right: 0;
} }
.photo_card_grid_filename
{
word-break:break-word;
}
.photo_card_grid_tags .photo_card_grid_tags
{ {
position: absolute; position: absolute;
@ -195,8 +199,3 @@ li
{ {
background-color: #faa; background-color: #faa;
} }
@font-face {
font-family: 'Highlander';
src: url('/static/Highlander_Normal.ttf');
}

View file

@ -47,12 +47,12 @@ p
{% endfor %} {% endfor %}
</ul> </ul>
{% endif %} {% endif %}
{% set photos = album.photos() %}
<span> <span>
Download: Download:
<a href="/album/{{album.id}}.zip?recursive=no">These files</a> {% if photos %}<a href="/album/{{album.id}}.zip?recursive=no">These files</a>{% endif %}
{% if sub_albums %} | <a href="/album/{{album.id}}.zip?recursive=yes">Include children</a>{% endif %} {% if sub_albums %}<a href="/album/{{album.id}}.zip?recursive=yes">Include children</a>{% endif %}
</span> </span>
{% set photos = album.photos() %}
{% if photos %} {% if photos %}
<h3>Photos</h3> <h3>Photos</h3>
<ul> <ul>

View file

@ -8,7 +8,6 @@
<script src="/static/common.js"></script> <script src="/static/common.js"></script>
{% set filename = photo.id + "." + photo.extension %} {% set filename = photo.id + "." + photo.extension %}
{% set link = "/file/" + filename %} {% set link = "/file/" + filename %}
{% set mimetype=photo.mimetype() %}
<style> <style>
#content_body #content_body
@ -21,6 +20,7 @@
#left #left
{ {
display: flex; display: flex;
padding: 8px;
flex-direction: column; flex-direction: column;
justify-content: flex-start; justify-content: flex-start;
background-color: rgba(0, 0, 0, 0.1); background-color: rgba(0, 0, 0, 0.1);
@ -117,10 +117,10 @@
{% if photo.width %} {% if photo.width %}
<li>Dimensions: {{photo.width}}x{{photo.height}} px</li> <li>Dimensions: {{photo.width}}x{{photo.height}} px</li>
<li>Aspect ratio: {{photo.ratio}}</li> <li>Aspect ratio: {{photo.ratio}}</li>
<li>Size: {{photo.bytestring()}}</li>
{% endif %} {% endif %}
<li>Size: {{photo.bytestring()}}</li>
{% if photo.duration %} {% if photo.duration %}
<li>Duration: {{photo.duration_str}}</li> <li>Duration: {{photo.duration_string()}}</li>
{% endif %} {% endif %}
<li><a href="/file/{{photo.id}}.{{photo.extension}}?download=1">Download as {{photo.id}}.{{photo.extension}}</a></li> <li><a href="/file/{{photo.id}}.{{photo.extension}}?download=1">Download as {{photo.id}}.{{photo.extension}}</a></li>
<li><a href="/file/{{photo.id}}.{{photo.extension}}?download=1&original_filename=1">Download as "{{photo.basename}}"</a></li> <li><a href="/file/{{photo.id}}.{{photo.extension}}?download=1&original_filename=1">Download as "{{photo.basename}}"</a></li>
@ -144,12 +144,12 @@
<div id="right"> <div id="right">
<!-- THE PHOTO ITSELF --> <!-- THE PHOTO ITSELF -->
<div class="photo_viewer"> <div class="photo_viewer">
{% if mimetype == "image" %} {% if photo.mimetype == "image" %}
<div id="photo_img_holder"><img id="photo_img" src="{{link}}" onclick="toggle_hoverzoom()" onload="this.style.opacity=0.99"></div> <div id="photo_img_holder"><img id="photo_img" src="{{link}}" onclick="toggle_hoverzoom()" onload="this.style.opacity=0.99"></div>
<!-- <img src="{{link}}"> --> <!-- <img src="{{link}}"> -->
{% elif mimetype == "video" %} {% elif photo.mimetype == "video" %}
<video src="{{link}}" controls preload=none {%if photo.thumbnail%}poster="/thumbnail/{{photo.id}}.jpg"{%endif%}></video> <video src="{{link}}" controls preload=none {%if photo.thumbnail%}poster="/thumbnail/{{photo.id}}.jpg"{%endif%}></video>
{% elif mimetype == "audio" %} {% elif photo.mimetype == "audio" %}
<audio src="{{link}}" controls></audio> <audio src="{{link}}" controls></audio>
{% else %} {% else %}
<a href="{{link}}">View {{filename}}</a> <a href="{{link}}">View {{filename}}</a>

View file

@ -37,7 +37,7 @@
</a> </a>
</div> </div>
<div class="photo_card_grid_info"> <div class="photo_card_grid_info">
<a target="_blank" href="/photo/{{photo.id}}" style="word-break:break-all">{{photo.basename}}</a> <a target="_blank" class="photo_card_grid_filename" href="/photo/{{photo.id}}">{{photo.basename}}</a>
<span class="photo_card_grid_file_metadata"> <span class="photo_card_grid_file_metadata">
{% if photo.width %} {% if photo.width %}
{{photo.width}}x{{photo.height}}, {{photo.width}}x{{photo.height}},

View file

@ -33,7 +33,7 @@ form
#left, #right #left, #right
{ {
/* Keep the prev-next buttons from scraping the floor */ /* Keep the prev-next buttons from scraping the floor */
padding-bottom: 30px; /*padding-bottom: 30px;*/
} }
#left #left
{ {
@ -44,26 +44,27 @@ form
#right #right
{ {
flex: 1; flex: 1;
padding: 8px;
width: auto; width: auto;
} }
.prev_next_holder .prev_next_holder
{ {
/* Makes div match size of content */ display: flex;
overflow: auto; flex-direction: row;
} }
.prev_page .prev_page
{ {
float: left; margin-right: 10px;
} }
.next_page .next_page
{ {
float: right; margin-left: 10px;
} }
.prev_page, .next_page .prev_page, .next_page
{ {
display: inline-block; flex: 1;
width: 48%; display: flex;
height: auto; justify-content: center;
background-color: #ffffd4; background-color: #ffffd4;
font-size: 20; font-size: 20;
border: 1px solid black; border: 1px solid black;
@ -79,7 +80,6 @@ form
{% macro prev_next_buttons() %} {% macro prev_next_buttons() %}
{% if prev_page_url or next_page_url %} {% if prev_page_url or next_page_url %}
<div class="prev_next_holder"> <div class="prev_next_holder">
<center>
{% if prev_page_url %} {% if prev_page_url %}
<a class="prev_page" href="{{prev_page_url}}">Previous</a> <a class="prev_page" href="{{prev_page_url}}">Previous</a>
{% else %} {% else %}
@ -90,7 +90,6 @@ form
{% else %} {% else %}
<a class="next_page"><br></a> <a class="next_page"><br></a>
{% endif %} {% endif %}
</center>
</div> </div>
{% endif %} {% endif %}
{% endmacro %} {% endmacro %}
@ -238,11 +237,14 @@ form
{% endif %} {% endif %}
</div> </div>
<div id="right"> <div id="right">
<p>You got {{photos|length}} items</p><br> <p>You got {{photos|length}} items</p>
{{prev_next_buttons()}} {{prev_next_buttons()}}
<div id="search_results_holder">
{% for photo in photos %} {% for photo in photos %}
{{photo_card.create_photo_card(photo, view=search_kwargs["view"])}} {{photo_card.create_photo_card(photo, view=search_kwargs["view"])}}
{% endfor %} {% endfor %}
</div>
{{prev_next_buttons()}} {{prev_next_buttons()}}
</div> </div>
</div> </div>

View file

@ -29,6 +29,7 @@ body
right: 8px; right: 8px;
bottom: 8px; bottom: 8px;
top: 30px; top: 30px;
padding: 8px;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
justify-content: center; justify-content: center;