photo editing and misc template refactor
This commit is contained in:
parent
fcfa7005d6
commit
b81cad8b71
@ -6,7 +6,7 @@ from photoapp.library import PhotoLibrary
|
||||
from photoapp.types import Photo, PhotoSet, Tag, TagItem, PhotoStatus
|
||||
from jinja2 import Environment, FileSystemLoader, select_autoescape
|
||||
from sqlalchemy import desc
|
||||
from sqlalchemy import func, and_
|
||||
from sqlalchemy import func, and_, or_
|
||||
import math
|
||||
from urllib.parse import urlparse
|
||||
|
||||
@ -342,22 +342,34 @@ class PhotoView(object):
|
||||
|
||||
@cherrypy.expose
|
||||
def index(self, uuid):
|
||||
uuid = uuid.split(".")[0]
|
||||
# uuid = uuid.split(".")[0]
|
||||
s = self.master.session()
|
||||
photo = photo_auth_filter(s.query(PhotoSet)).filter(PhotoSet.uuid == uuid).first()
|
||||
photo = photo_auth_filter(s.query(PhotoSet)).filter(or_(PhotoSet.uuid == uuid, PhotoSet.slug == uuid)).first()
|
||||
yield self.master.render("photo.html", image=photo)
|
||||
|
||||
@cherrypy.expose
|
||||
@require_auth
|
||||
def op(self, uuid, op):
|
||||
def op(self, uuid, op, title=None, description=None, offset=None):
|
||||
s = self.master.session()
|
||||
photo = s.query(PhotoSet).filter(PhotoSet.uuid == uuid).first()
|
||||
if op == "Make public":
|
||||
photo.status = PhotoStatus.public
|
||||
elif op == "Make private":
|
||||
photo.status = PhotoStatus.private
|
||||
elif op == "Save":
|
||||
photo.title = title
|
||||
photo.description = description
|
||||
photo.slug = slugify(title) or None
|
||||
photo.date_offset = int(offset) if offset else 0
|
||||
s.commit()
|
||||
raise cherrypy.HTTPRedirect('/photo/{}'.format(photo.uuid), 302)
|
||||
raise cherrypy.HTTPRedirect('/photo/{}'.format(photo.slug or photo.uuid), 302)
|
||||
|
||||
@cherrypy.expose
|
||||
@require_auth
|
||||
def edit(self, uuid):
|
||||
s = self.master.session()
|
||||
photo = photo_auth_filter(s.query(PhotoSet)).filter(PhotoSet.uuid == uuid).first()
|
||||
yield self.master.render("photo_edit.html", image=photo)
|
||||
|
||||
|
||||
@cherrypy.popargs('uuid')
|
||||
@ -379,14 +391,18 @@ class TagView(object):
|
||||
numphotos = photo_auth_filter(s.query(func.count(PhotoSet.id))). \
|
||||
filter(~PhotoSet.id.in_(s.query(TagItem.set_id))).scalar()
|
||||
photos = photo_auth_filter(s.query(PhotoSet)).filter(~PhotoSet.id.in_(s.query(TagItem.set_id))).\
|
||||
offset(page * pgsize).limit(pgsize).all()
|
||||
offset(page * pgsize). \
|
||||
limit(pgsize).all()
|
||||
yield self.master.render("untagged.html", images=photos, total_items=numphotos, pgsize=pgsize, page=page)
|
||||
else:
|
||||
tag = s.query(Tag).filter(Tag.uuid == uuid).first()
|
||||
tag = s.query(Tag).filter(or_(Tag.uuid == uuid, Tag.slug == uuid)).first()
|
||||
numphotos = photo_auth_filter(s.query(func.count(Tag.id)).join(TagItem).join(PhotoSet)). \
|
||||
filter(Tag.uuid == uuid).scalar()
|
||||
photos = photo_auth_filter(s.query(PhotoSet)).join(TagItem).join(Tag).filter(Tag.uuid == uuid). \
|
||||
order_by(PhotoSet.date.desc()).offset(page * pgsize).limit(pgsize).all()
|
||||
filter(Tag.id == tag.id).scalar()
|
||||
photos = photo_auth_filter(s.query(PhotoSet)).join(TagItem).join(Tag). \
|
||||
filter(Tag.id == tag.id). \
|
||||
order_by(PhotoSet.date.desc()). \
|
||||
offset(page * pgsize). \
|
||||
limit(pgsize).all()
|
||||
yield self.master.render("album.html", tag=tag, images=photos,
|
||||
total_items=numphotos, pgsize=pgsize, page=page)
|
||||
|
||||
@ -402,7 +418,7 @@ class TagView(object):
|
||||
- Make all private: mark all photos under this tag as private
|
||||
"""
|
||||
s = self.master.session()
|
||||
tag = s.query(Tag).filter(Tag.uuid == uuid).first()
|
||||
tag = s.query(Tag).filter(or_(Tag.uuid == uuid, Tag.slug == uuid)).first()
|
||||
if op == "Demote to tag":
|
||||
tag.is_album = 0
|
||||
elif op == "Promote to album":
|
||||
@ -414,11 +430,11 @@ class TagView(object):
|
||||
raise cherrypy.HTTPRedirect('/', 302)
|
||||
elif op == "Make all public":
|
||||
# TODO smarter query
|
||||
for photo in s.query(PhotoSet).join(TagItem).join(Tag).filter(Tag.uuid == uuid).all():
|
||||
for photo in s.query(PhotoSet).join(TagItem).join(Tag).filter(Tag.id == tag.id).all():
|
||||
photo.status = PhotoStatus.public
|
||||
elif op == "Make all private":
|
||||
# TODO smarter query
|
||||
for photo in s.query(PhotoSet).join(TagItem).join(Tag).filter(Tag.uuid == uuid).all():
|
||||
for photo in s.query(PhotoSet).join(TagItem).join(Tag).filter(Tag.id == tag.id).all():
|
||||
photo.status = PhotoStatus.private
|
||||
else:
|
||||
raise Exception("Invalid op: '{}'".format(op))
|
||||
|
1
setup.py
1
setup.py
@ -25,5 +25,6 @@ setup(name='photoapp',
|
||||
},
|
||||
include_package_data=True,
|
||||
package_data={'photoapp': ['../templates/*.html',
|
||||
'../templates/fragments/*.html',
|
||||
'../styles/dist/*']},
|
||||
zip_safe=False)
|
||||
|
@ -124,9 +124,12 @@ a {
|
||||
.email-content-controls {
|
||||
margin-top: 2em;
|
||||
text-align: right;
|
||||
}
|
||||
.email-content-controls .secondary-button {
|
||||
margin-bottom: 0.3em;
|
||||
.secondary-button {
|
||||
margin-bottom: 0.3em;
|
||||
}
|
||||
form {
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
|
||||
.email-avatar {
|
||||
|
@ -1,6 +1,6 @@
|
||||
{% extends "page.html" %}
|
||||
{% set title = "Photos by date" %}
|
||||
{% set subtitle = "By date, descending" %}
|
||||
{% block title %}{{ tag.title or tag.name }}{% endblock %}
|
||||
{% block subtitle %}{{ tag.description }}{% endblock %}
|
||||
|
||||
{% block buttons %}
|
||||
<form action="/tag/{{ tag.uuid }}/op" method="post">
|
||||
@ -25,11 +25,7 @@
|
||||
{% set locals.im_date = newdate %}
|
||||
<div class="feed-divider year"><h4>{{ locals.im_date }}</h4></div>
|
||||
{% endif %}
|
||||
<div class="photo">
|
||||
<a href="/photo/{{ item.uuid }}">
|
||||
<img src="/thumb/set/feed/{{ item.uuid }}.jpg" />
|
||||
</a>
|
||||
</div>
|
||||
{% include "fragments/feed-photo.html" %}
|
||||
{% endfor %}
|
||||
<br style="clear:both" />
|
||||
<div class="pager">
|
||||
|
@ -1,6 +1,6 @@
|
||||
{% extends "page.html" %}
|
||||
{% set title = "Photos on {}".format(date.strftime("%b %d, %Y")) %}
|
||||
{% set subtitle = "By date, descending" %}
|
||||
{% block title %}{{ "Photos on {}".format(date.strftime("%b %d, %Y")) }}{% endblock %}
|
||||
{% block subtitle %}{% endblock %}
|
||||
|
||||
{% block buttons %}
|
||||
<form action="/create_tags" method="post">
|
||||
@ -25,11 +25,7 @@
|
||||
{% set locals.im_date = newdate %}
|
||||
<div class="feed-divider year"><h4>{{ locals.im_date }}</h4></div>
|
||||
{% endif %}
|
||||
<div class="photo">
|
||||
<a href="/photo/{{ item.uuid }}">
|
||||
<img src="/thumb/set/feed/{{ item.uuid }}.jpg" />
|
||||
</a>
|
||||
</div>
|
||||
{% include "fragments/feed-photo.html" %}
|
||||
{% endfor %}
|
||||
<br style="clear:both" />
|
||||
<div class="pager">
|
||||
|
@ -1,6 +1,6 @@
|
||||
{% extends "page.html" %}
|
||||
{% set title = "All photos" %}
|
||||
{% set subtitle = "By date, descending" %}
|
||||
{% block title %}Photo Dates{% endblock %}
|
||||
{% block subtitle %}Count per day{% endblock %}
|
||||
|
||||
{% block buttons %}
|
||||
xxx
|
||||
|
@ -1,10 +1,7 @@
|
||||
{% extends "page.html" %}
|
||||
{% set title = "Photos by date" %}
|
||||
{% set subtitle = "By date, descending" %}
|
||||
|
||||
{% block buttons %}
|
||||
xxx
|
||||
{% endblock %}
|
||||
{% block title %}Photos by date{% endblock %}
|
||||
{% block subtitle %}By date, descending{% endblock %}
|
||||
{% block buttons %}{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
|
||||
@ -20,11 +17,7 @@
|
||||
{% set locals.im_date = newdate %}
|
||||
<div class="feed-divider year"><h4>{{ locals.im_date }}</h4></div>
|
||||
{% endif %}
|
||||
<div class="photo">
|
||||
<a href="/photo/{{ item.uuid }}">
|
||||
<img src="/thumb/set/feed/{{ item.uuid }}.jpg" />
|
||||
</a>
|
||||
</div>
|
||||
{% include "fragments/feed-photo.html" %}
|
||||
{% endfor %}
|
||||
<br style="clear:both" />
|
||||
{% include "pager.html" %}
|
||||
|
5
templates/fragments/feed-photo.html
Normal file
5
templates/fragments/feed-photo.html
Normal file
@ -0,0 +1,5 @@
|
||||
<div class="photo">
|
||||
<a href="/photo/{{ item.slug or item.uuid }}">
|
||||
<img src="/thumb/set/feed/{{ item.uuid }}.jpg" />
|
||||
</a>
|
||||
</div>
|
@ -1,10 +1,7 @@
|
||||
{% extends "page.html" %}
|
||||
{% set title = "Photo map" %}
|
||||
{% set subtitle = "GPS data" %}
|
||||
|
||||
{% block buttons %}
|
||||
xxx
|
||||
{% endblock %}
|
||||
{% block title %}Photo map{% endblock %}
|
||||
{% block subtitle %}GPS data{% endblock %}
|
||||
{% block buttons %}{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
|
||||
|
@ -1,10 +1,7 @@
|
||||
{% extends "page.html" %}
|
||||
{% set title = "Server statistics" %}
|
||||
{% set subtitle = "Placeholder" %}
|
||||
|
||||
{% block buttons %}
|
||||
xxx
|
||||
{% endblock %}
|
||||
{% block title %}Server statistics{% endblock %}
|
||||
{% block subtitle %}{% endblock %}
|
||||
{% block buttons %}{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
|
||||
|
@ -22,11 +22,11 @@
|
||||
<li class="pure-menu-item"><a href="/admin/trash" class="pure-menu-link">Trash</a></li>
|
||||
<li class="pure-menu-heading">Albums</li>
|
||||
{% for tag in all_albums %}
|
||||
<li class="pure-menu-item"><a href="/album/{{ tag.uuid }}" class="pure-menu-link"><span class="tag-icon tag-icon-mod-6-{{ tag.id % 6 }}"></span>{{ tag.title }}</a></li>
|
||||
<li class="pure-menu-item"><a href="/album/{{ tag.slug }}" class="pure-menu-link"><span class="tag-icon tag-icon-mod-6-{{ tag.id % 6 }}"></span>{{ tag.name }}</a></li>
|
||||
{% endfor %}
|
||||
<li class="pure-menu-heading">Tags</li>
|
||||
{% for tag in all_tags %}
|
||||
<li class="pure-menu-item"><a href="/tag/{{ tag.uuid }}" class="pure-menu-link"><span class="tag-icon tag-icon-mod-6-{{ tag.id % 6 }}"></span>{{ tag.title }}</a></li>
|
||||
<li class="pure-menu-item"><a href="/tag/{{ tag.slug }}" class="pure-menu-link"><span class="tag-icon tag-icon-mod-6-{{ tag.id % 6 }}"></span>{{ tag.name }}</a></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
@ -45,9 +45,9 @@
|
||||
<div class="email-content">
|
||||
<div class="email-content-header pure-g">
|
||||
<div class="pure-u-1-2">
|
||||
<h1 class="email-content-title">{{ title }}</h1>
|
||||
<h1 class="email-content-title">{% block title %}DEFAULT TITLE{% endblock %}</h1>
|
||||
<p class="email-content-subtitle">
|
||||
{{ subtitle }}
|
||||
{% block subtitle %}DEFAULT SUBTITLE{% endblock %}
|
||||
</p>
|
||||
</div>
|
||||
{% if auth %}
|
||||
|
@ -1,6 +1,6 @@
|
||||
{% extends "page.html" %}
|
||||
{% set title = "Placeholder Title" %}
|
||||
{% set subtitle = image.uuid %}
|
||||
{% block title %}{{ image.title or image.uuid }}{% endblock %}
|
||||
{% block subtitle %}{{ image.date }}{% endblock %}
|
||||
|
||||
{% block buttons %}
|
||||
<form action="/photo/{{ image.uuid }}/op" method="post">
|
||||
@ -10,6 +10,7 @@
|
||||
<input type="submit" class="secondary-button pure-button" name="op" value="Make private" />
|
||||
{% endif %}
|
||||
</form>
|
||||
<a href="/photo/{{ image.uuid }}/edit"><button class="secondary-button pure-button">Edit</button></a>
|
||||
{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
@ -21,6 +22,12 @@
|
||||
</a>
|
||||
</div>
|
||||
<div class="photo-info pure-u-1-3">
|
||||
{% if image.description %}
|
||||
<div class="photo-description">
|
||||
<h2>Description</h2>
|
||||
<p>{{ image.description }}</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
<div class="photo-metadata">
|
||||
<h2>Information</h2>
|
||||
<ul>
|
||||
@ -88,7 +95,7 @@
|
||||
<ul class="tags-picker">
|
||||
{% for tagi in image.tags %}
|
||||
<li>
|
||||
<a href="/tag/{{ tagi.tag.uuid }}">{{ tagi.tag.title }}</a>
|
||||
<a href="/tag/{{ tagi.tag.slug }}">{{ tagi.tag.name }}</a>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
|
36
templates/photo_edit.html
Normal file
36
templates/photo_edit.html
Normal file
@ -0,0 +1,36 @@
|
||||
{% extends "page.html" %}
|
||||
{% block title %}Editing {{ image.uuid }}{% endblock %}
|
||||
{% block subtitle %}{{ image.date }}{% endblock %}
|
||||
|
||||
{% block buttons %}
|
||||
<a href="/photo/{{ image.uuid }}"><button class="secondary-button pure-button">Back</button></a>
|
||||
{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
|
||||
<div class="photo-view pure-g">
|
||||
<div class="photo-form pure-u-2-3">
|
||||
<form action="/photo/{{ image.uuid }}/op" method="post" class="pure-form pure-form-stacked">
|
||||
<fieldset>
|
||||
<fieldset class="pure-group pure-u-1">
|
||||
<input name="title" type="text" class="pure-input-1" placeholder="Image title" value="{{ image.title or "" }}" />
|
||||
<textarea name="description" class="pure-input-1" placeholder="Description" rows="15">{{ image.description or "" }}</textarea>
|
||||
</fieldset>
|
||||
<div class="pure-u-1">
|
||||
<label for="offset">Offset (minutes)</label>
|
||||
<input id="offset" class="pure-u-1-2" type="text" name="offset" value="{{ image.date_offset }}" />
|
||||
</div>
|
||||
<div class="pure-u-1">
|
||||
<input type="submit" class="pure-button pure-button-primary" name="op" value="Save" />
|
||||
</div>
|
||||
</fieldset>
|
||||
</form>
|
||||
</div>
|
||||
<div class="photo-info pure-u-1-3">
|
||||
<a href="/photo/{{ image.uuid }}" class="pure-g-1-4">
|
||||
<img src="/thumb/set/feed/{{ image.uuid }}.jpg" />
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
@ -1,6 +1,6 @@
|
||||
{% extends "page.html" %}
|
||||
{% set title = "Untagged photos" %}
|
||||
{% set subtitle = "By date, descending" %}
|
||||
{% block title %}Untagged photos{% endblock %}
|
||||
{% block subtitle %}By date, descending{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
|
||||
@ -15,11 +15,7 @@
|
||||
{% set locals.im_date = newdate %}
|
||||
<div class="feed-divider year"><h4><a href="/date/{{ item.date.strftime("%Y-%m-%d") }}">{{ locals.im_date }}</a></h4></div>
|
||||
{% endif %}
|
||||
<div class="photo">
|
||||
<a href="/photo/{{ item.uuid }}">
|
||||
<img src="/thumb/set/feed/{{ item.uuid }}.jpg" />
|
||||
</a>
|
||||
</div>
|
||||
{% include "fragments/feed-photo.html" %}
|
||||
{% endfor %}
|
||||
<br style="clear:both" />
|
||||
{% include "pager.html" %}
|
||||
|
Loading…
x
Reference in New Issue
Block a user