daemon to use newer db access api
This commit is contained in:
parent
022f4a90a7
commit
6589f71052
|
@ -112,6 +112,7 @@ Roadmap
|
||||||
- ~~Standardize on API ingest~~ done
|
- ~~Standardize on API ingest~~ done
|
||||||
- Display and retrieval of images from the abstracted image store
|
- Display and retrieval of images from the abstracted image store
|
||||||
- Database support
|
- Database support
|
||||||
|
- Get the web UI code (daemon.py) using the same db access method as the api
|
||||||
- Support any connection URI sqlalchemy is happy with
|
- Support any connection URI sqlalchemy is happy with
|
||||||
- Tune certain databases if their uri is detected (sqlite and threads lol)
|
- Tune certain databases if their uri is detected (sqlite and threads lol)
|
||||||
- ~~Cache~~ done
|
- ~~Cache~~ done
|
||||||
|
|
|
@ -79,7 +79,6 @@ class GfapiAdapter(StorageAdapter):
|
||||||
pass # TODO gluster storage backend
|
pass # TODO gluster storage backend
|
||||||
|
|
||||||
|
|
||||||
# This is largely duplicated from library.py, but written with intent for later refactoring to support abstract storage.
|
|
||||||
class LibraryManager(object):
|
class LibraryManager(object):
|
||||||
def __init__(self, storage):
|
def __init__(self, storage):
|
||||||
assert isinstance(storage, StorageAdapter)
|
assert isinstance(storage, StorageAdapter)
|
||||||
|
@ -98,7 +97,8 @@ class PhotosApiV1(object):
|
||||||
|
|
||||||
@cherrypy.expose
|
@cherrypy.expose
|
||||||
def index(self):
|
def index(self):
|
||||||
yield f"<plaintext>hello, this is the api. my database is: {db}\n"
|
cherrypy.response.headers["Content-type"] = "text/plain"
|
||||||
|
return "Hello! This is the Photolib V1 API.\n"
|
||||||
|
|
||||||
@cherrypy.expose
|
@cherrypy.expose
|
||||||
@cherrypy.tools.json_out()
|
@cherrypy.tools.json_out()
|
||||||
|
|
|
@ -13,6 +13,7 @@ from photoapp.dbutils import SAEnginePlugin, SATool
|
||||||
import math
|
import math
|
||||||
from urllib.parse import urlparse
|
from urllib.parse import urlparse
|
||||||
from photoapp.utils import mime2ext, auth, require_auth, photo_auth_filter, slugify
|
from photoapp.utils import mime2ext, auth, require_auth, photo_auth_filter, slugify
|
||||||
|
from photoapp.dbutils import db
|
||||||
|
|
||||||
|
|
||||||
APPROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), "../"))
|
APPROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), "../"))
|
||||||
|
@ -45,14 +46,13 @@ class PhotosWeb(object):
|
||||||
"""
|
"""
|
||||||
Return a dict containing variables expected to be on every page
|
Return a dict containing variables expected to be on every page
|
||||||
"""
|
"""
|
||||||
s = self.session()
|
|
||||||
# all tags / albums with photos visible under the current auth context
|
# all tags / albums with photos visible under the current auth context
|
||||||
tagq = s.query(Tag).join(TagItem).join(PhotoSet)
|
tagq = db.query(Tag).join(TagItem).join(PhotoSet)
|
||||||
if not auth():
|
if not auth():
|
||||||
tagq = tagq.filter(PhotoSet.status == PhotoStatus.public)
|
tagq = tagq.filter(PhotoSet.status == PhotoStatus.public)
|
||||||
tagq = tagq.filter(Tag.is_album == False).order_by(Tag.name).all() # pragma: manual auth
|
tagq = tagq.filter(Tag.is_album == False).order_by(Tag.name).all() # pragma: manual auth
|
||||||
|
|
||||||
albumq = s.query(Tag).join(TagItem).join(PhotoSet)
|
albumq = db.query(Tag).join(TagItem).join(PhotoSet)
|
||||||
if not auth():
|
if not auth():
|
||||||
albumq = albumq.filter(PhotoSet.status == PhotoStatus.public)
|
albumq = albumq.filter(PhotoSet.status == PhotoStatus.public)
|
||||||
albumq = albumq.filter(Tag.is_album == True).order_by(Tag.name).all() # pragma: manual auth
|
albumq = albumq.filter(Tag.is_album == True).order_by(Tag.name).all() # pragma: manual auth
|
||||||
|
@ -64,15 +64,8 @@ class PhotosWeb(object):
|
||||||
"auth": auth(),
|
"auth": auth(),
|
||||||
"PhotoStatus": PhotoStatus
|
"PhotoStatus": PhotoStatus
|
||||||
}
|
}
|
||||||
s.close()
|
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
def session(self):
|
|
||||||
"""
|
|
||||||
Get a database session
|
|
||||||
"""
|
|
||||||
return self.library.session()
|
|
||||||
|
|
||||||
@cherrypy.expose
|
@cherrypy.expose
|
||||||
def index(self):
|
def index(self):
|
||||||
"""
|
"""
|
||||||
|
@ -85,10 +78,9 @@ class PhotosWeb(object):
|
||||||
"""
|
"""
|
||||||
/feed - main photo feed - show photos sorted by date, newest first
|
/feed - main photo feed - show photos sorted by date, newest first
|
||||||
"""
|
"""
|
||||||
s = self.session()
|
|
||||||
page, pgsize = int(page), int(pgsize)
|
page, pgsize = int(page), int(pgsize)
|
||||||
total_sets = photo_auth_filter(s.query(func.count(PhotoSet.id))).first()[0]
|
total_sets = photo_auth_filter(db.query(func.count(PhotoSet.id))).first()[0]
|
||||||
images = photo_auth_filter(s.query(PhotoSet)).order_by(PhotoSet.date.desc()). \
|
images = photo_auth_filter(db.query(PhotoSet)).order_by(PhotoSet.date.desc()). \
|
||||||
offset(pgsize * page).limit(pgsize).all()
|
offset(pgsize * page).limit(pgsize).all()
|
||||||
yield self.render("feed.html", images=[i for i in images], page=page, pgsize=int(pgsize), total_sets=total_sets)
|
yield self.render("feed.html", images=[i for i in images], page=page, pgsize=int(pgsize), total_sets=total_sets)
|
||||||
|
|
||||||
|
@ -97,12 +89,11 @@ class PhotosWeb(object):
|
||||||
"""
|
"""
|
||||||
/stats - show server statistics
|
/stats - show server statistics
|
||||||
"""
|
"""
|
||||||
s = self.session()
|
images = photo_auth_filter(db.query(func.count(PhotoSet.uuid),
|
||||||
images = photo_auth_filter(s.query(func.count(PhotoSet.uuid),
|
func.strftime('%Y', PhotoSet.date).label('year'),
|
||||||
func.strftime('%Y', PhotoSet.date).label('year'),
|
func.strftime('%m', PhotoSet.date).label('month'))). \
|
||||||
func.strftime('%m', PhotoSet.date).label('month'))). \
|
|
||||||
group_by('year', 'month').order_by(desc('year'), desc('month')).all()
|
group_by('year', 'month').order_by(desc('year'), desc('month')).all()
|
||||||
tsize = photo_auth_filter(s.query(func.sum(Photo.size)).join(PhotoSet)).scalar() # pragma: manual auth
|
tsize = photo_auth_filter(db.query(func.sum(Photo.size)).join(PhotoSet)).scalar() # pragma: manual auth
|
||||||
yield self.render("monthly.html", images=images, tsize=tsize)
|
yield self.render("monthly.html", images=images, tsize=tsize)
|
||||||
|
|
||||||
@cherrypy.expose
|
@cherrypy.expose
|
||||||
|
@ -112,8 +103,7 @@ class PhotosWeb(object):
|
||||||
the given tag.
|
the given tag.
|
||||||
TODO using so many coordinates is slow in the browser. dedupe them somehow.
|
TODO using so many coordinates is slow in the browser. dedupe them somehow.
|
||||||
"""
|
"""
|
||||||
s = self.session()
|
query = photo_auth_filter(db.query(PhotoSet)).filter(PhotoSet.lat != 0, PhotoSet.lon != 0)
|
||||||
query = photo_auth_filter(s.query(PhotoSet)).filter(PhotoSet.lat != 0, PhotoSet.lon != 0)
|
|
||||||
if a:
|
if a:
|
||||||
query = query.join(TagItem).join(Tag).filter(Tag.uuid == a)
|
query = query.join(TagItem).join(Tag).filter(Tag.uuid == a)
|
||||||
if i:
|
if i:
|
||||||
|
@ -131,44 +121,43 @@ class PhotosWeb(object):
|
||||||
:param remove: target photos will have the tag specified by this uuid removed
|
:param remove: target photos will have the tag specified by this uuid removed
|
||||||
:param newtag: new tag name to create
|
:param newtag: new tag name to create
|
||||||
"""
|
"""
|
||||||
s = self.session()
|
|
||||||
|
|
||||||
def get_photos():
|
def get_photos():
|
||||||
if fromdate:
|
if fromdate:
|
||||||
dt = datetime.strptime(fromdate, "%Y-%m-%d")
|
dt = datetime.strptime(fromdate, "%Y-%m-%d")
|
||||||
dt_end = dt + timedelta(days=1)
|
dt_end = dt + timedelta(days=1)
|
||||||
photos = s.query(PhotoSet).filter(and_(PhotoSet.date >= dt,
|
photos = db.query(PhotoSet).filter(and_(PhotoSet.date >= dt,
|
||||||
PhotoSet.date < dt_end)).order_by(PhotoSet.date)
|
PhotoSet.date < dt_end)).order_by(PhotoSet.date)
|
||||||
num_photos = s.query(func.count(PhotoSet.id)). \
|
num_photos = db.query(func.count(PhotoSet.id)). \
|
||||||
filter(and_(PhotoSet.date >= dt, PhotoSet.date < dt_end)).order_by(PhotoSet.date).scalar()
|
filter(and_(PhotoSet.date >= dt, PhotoSet.date < dt_end)).order_by(PhotoSet.date).scalar()
|
||||||
|
|
||||||
if uuid:
|
if uuid:
|
||||||
photos = s.query(PhotoSet).filter(PhotoSet.uuid == uuid)
|
photos = db.query(PhotoSet).filter(PhotoSet.uuid == uuid)
|
||||||
num_photos = s.query(func.count(PhotoSet.id)).filter(PhotoSet.uuid == uuid).scalar()
|
num_photos = db.query(func.count(PhotoSet.id)).filter(PhotoSet.uuid == uuid).scalar()
|
||||||
return photos, num_photos
|
return photos, num_photos
|
||||||
|
|
||||||
if remove:
|
if remove:
|
||||||
rmtag = s.query(Tag).filter(Tag.uuid == remove).first()
|
rmtag = db.query(Tag).filter(Tag.uuid == remove).first()
|
||||||
photoq, _ = get_photos()
|
photoq, _ = get_photos()
|
||||||
for photo in photoq:
|
for photo in photoq:
|
||||||
s.query(TagItem).filter(TagItem.tag_id == rmtag.id, TagItem.set_id == photo.id).delete()
|
db.query(TagItem).filter(TagItem.tag_id == rmtag.id, TagItem.set_id == photo.id).delete()
|
||||||
s.commit()
|
db.commit()
|
||||||
|
|
||||||
if newtag:
|
if newtag:
|
||||||
s.add(Tag(title=newtag.capitalize(), name=newtag, slug=slugify(newtag)))
|
db.add(Tag(title=newtag.capitalize(), name=newtag, slug=slugify(newtag)))
|
||||||
s.commit()
|
db.commit()
|
||||||
|
|
||||||
photos, num_photos = get_photos()
|
photos, num_photos = get_photos()
|
||||||
|
|
||||||
if tag: # Create the tag on all the photos
|
if tag: # Create the tag on all the photos
|
||||||
tag = s.query(Tag).filter(Tag.uuid == tag).first()
|
tag = db.query(Tag).filter(Tag.uuid == tag).first()
|
||||||
for photo in photos.all():
|
for photo in photos.all():
|
||||||
if 0 == s.query(func.count(TagItem.id)).filter(TagItem.tag_id == tag.id,
|
if 0 == db.query(func.count(TagItem.id)).filter(TagItem.tag_id == tag.id,
|
||||||
TagItem.set_id == photo.id).scalar():
|
TagItem.set_id == photo.id).scalar():
|
||||||
s.add(TagItem(tag_id=tag.id, set_id=photo.id))
|
db.add(TagItem(tag_id=tag.id, set_id=photo.id))
|
||||||
s.commit()
|
db.commit()
|
||||||
|
|
||||||
alltags = s.query(Tag).order_by(Tag.name).all()
|
alltags = db.query(Tag).order_by(Tag.name).all()
|
||||||
yield self.render("create_tags.html", images=photos, alltags=alltags,
|
yield self.render("create_tags.html", images=photos, alltags=alltags,
|
||||||
num_photos=num_photos, fromdate=fromdate, uuid=uuid)
|
num_photos=num_photos, fromdate=fromdate, uuid=uuid)
|
||||||
|
|
||||||
|
@ -207,21 +196,20 @@ class DateView(object):
|
||||||
|
|
||||||
@cherrypy.expose
|
@cherrypy.expose
|
||||||
def index(self, date=None, page=0):
|
def index(self, date=None, page=0):
|
||||||
s = self.master.session()
|
|
||||||
if date:
|
if date:
|
||||||
page = int(page)
|
page = int(page)
|
||||||
pgsize = 100
|
pgsize = 100
|
||||||
dt = datetime.strptime(date, "%Y-%m-%d")
|
dt = datetime.strptime(date, "%Y-%m-%d")
|
||||||
dt_end = dt + timedelta(days=1)
|
dt_end = dt + timedelta(days=1)
|
||||||
total_sets = photo_auth_filter(s.query(func.count(PhotoSet.id))). \
|
total_sets = photo_auth_filter(db.query(func.count(PhotoSet.id))). \
|
||||||
filter(and_(PhotoSet.date >= dt, PhotoSet.date < dt_end)).first()[0]
|
filter(and_(PhotoSet.date >= dt, PhotoSet.date < dt_end)).first()[0]
|
||||||
images = photo_auth_filter(s.query(PhotoSet)).filter(and_(PhotoSet.date >= dt,
|
images = photo_auth_filter(db.query(PhotoSet)).filter(and_(PhotoSet.date >= dt,
|
||||||
PhotoSet.date < dt_end)).order_by(PhotoSet.date). \
|
PhotoSet.date < dt_end)).order_by(PhotoSet.date). \
|
||||||
offset(page * pgsize).limit(pgsize).all()
|
offset(page * pgsize).limit(pgsize).all()
|
||||||
yield self.master.render("date.html", page=page, pgsize=pgsize, total_sets=total_sets,
|
yield self.master.render("date.html", page=page, pgsize=pgsize, total_sets=total_sets,
|
||||||
images=[i for i in images], date=dt)
|
images=[i for i in images], date=dt)
|
||||||
return
|
return
|
||||||
images = photo_auth_filter(s.query(PhotoSet, func.strftime('%Y-%m-%d',
|
images = photo_auth_filter(db.query(PhotoSet, func.strftime('%Y-%m-%d',
|
||||||
PhotoSet.date).label('gdate'),
|
PhotoSet.date).label('gdate'),
|
||||||
func.count('photos.id'),
|
func.count('photos.id'),
|
||||||
func.strftime('%Y', PhotoSet.date).label('year'),
|
func.strftime('%Y', PhotoSet.date).label('year'),
|
||||||
|
@ -242,9 +230,7 @@ class ThumbnailView(object):
|
||||||
@cherrypy.expose
|
@cherrypy.expose
|
||||||
def index(self, item_type, thumb_size, uuid):
|
def index(self, item_type, thumb_size, uuid):
|
||||||
uuid = uuid.split(".")[0]
|
uuid = uuid.split(".")[0]
|
||||||
s = self.master.session()
|
query = photo_auth_filter(db.query(Photo).join(PhotoSet))
|
||||||
|
|
||||||
query = photo_auth_filter(s.query(Photo).join(PhotoSet))
|
|
||||||
|
|
||||||
query = query.filter(Photo.set.has(uuid=uuid)) if item_type == "set" \
|
query = query.filter(Photo.set.has(uuid=uuid)) if item_type == "set" \
|
||||||
else query.filter(Photo.uuid == uuid) if item_type == "one" \
|
else query.filter(Photo.uuid == uuid) if item_type == "one" \
|
||||||
|
@ -284,10 +270,8 @@ class DownloadView(object):
|
||||||
@cherrypy.expose
|
@cherrypy.expose
|
||||||
def index(self, item_type, uuid, preview=False):
|
def index(self, item_type, uuid, preview=False):
|
||||||
uuid = uuid.split(".")[0]
|
uuid = uuid.split(".")[0]
|
||||||
s = self.master.session()
|
|
||||||
|
|
||||||
query = None if item_type == "set" \
|
query = None if item_type == "set" \
|
||||||
else photo_auth_filter(s.query(Photo)).filter(Photo.uuid == uuid) if item_type == "one" \
|
else photo_auth_filter(db.query(Photo)).filter(Photo.uuid == uuid) if item_type == "one" \
|
||||||
else None # TODO set download query
|
else None # TODO set download query
|
||||||
|
|
||||||
item = query.first()
|
item = query.first()
|
||||||
|
@ -311,8 +295,7 @@ class PhotoView(object):
|
||||||
@cherrypy.expose
|
@cherrypy.expose
|
||||||
def index(self, uuid):
|
def index(self, uuid):
|
||||||
# uuid = uuid.split(".")[0]
|
# uuid = uuid.split(".")[0]
|
||||||
s = self.master.session()
|
photo = photo_auth_filter(db.query(PhotoSet)).filter(or_(PhotoSet.uuid == uuid, PhotoSet.slug == uuid)).first()
|
||||||
photo = photo_auth_filter(s.query(PhotoSet)).filter(or_(PhotoSet.uuid == uuid, PhotoSet.slug == uuid)).first()
|
|
||||||
if not photo:
|
if not photo:
|
||||||
raise cherrypy.HTTPError(404)
|
raise cherrypy.HTTPError(404)
|
||||||
yield self.master.render("photo.html", image=photo)
|
yield self.master.render("photo.html", image=photo)
|
||||||
|
@ -327,8 +310,7 @@ class PhotoView(object):
|
||||||
* "Make private":
|
* "Make private":
|
||||||
* "Save": update the photo's title, description, and date_offset fields
|
* "Save": update the photo's title, description, and date_offset fields
|
||||||
"""
|
"""
|
||||||
s = self.master.session()
|
photo = db.query(PhotoSet).filter(PhotoSet.uuid == uuid).first()
|
||||||
photo = s.query(PhotoSet).filter(PhotoSet.uuid == uuid).first()
|
|
||||||
if op == "Make public":
|
if op == "Make public":
|
||||||
photo.status = PhotoStatus.public
|
photo.status = PhotoStatus.public
|
||||||
elif op == "Make private":
|
elif op == "Make private":
|
||||||
|
@ -338,14 +320,13 @@ class PhotoView(object):
|
||||||
photo.description = description
|
photo.description = description
|
||||||
photo.slug = slugify(title) or None
|
photo.slug = slugify(title) or None
|
||||||
photo.date_offset = int(offset) if offset else 0
|
photo.date_offset = int(offset) if offset else 0
|
||||||
s.commit()
|
db.commit()
|
||||||
raise cherrypy.HTTPRedirect('/photo/{}'.format(photo.slug or photo.uuid), 302)
|
raise cherrypy.HTTPRedirect('/photo/{}'.format(photo.slug or photo.uuid), 302)
|
||||||
|
|
||||||
@cherrypy.expose
|
@cherrypy.expose
|
||||||
@require_auth
|
@require_auth
|
||||||
def edit(self, uuid):
|
def edit(self, uuid):
|
||||||
s = self.master.session()
|
photo = photo_auth_filter(db.query(PhotoSet)).filter(PhotoSet.uuid == uuid).first()
|
||||||
photo = photo_auth_filter(s.query(PhotoSet)).filter(PhotoSet.uuid == uuid).first()
|
|
||||||
yield self.master.render("photo_edit.html", image=photo)
|
yield self.master.render("photo_edit.html", image=photo)
|
||||||
|
|
||||||
|
|
||||||
|
@ -361,20 +342,18 @@ class TagView(object):
|
||||||
def index(self, uuid, page=0):
|
def index(self, uuid, page=0):
|
||||||
page = int(page)
|
page = int(page)
|
||||||
pgsize = 100
|
pgsize = 100
|
||||||
s = self.master.session()
|
|
||||||
|
|
||||||
if uuid == "untagged":
|
if uuid == "untagged":
|
||||||
numphotos = photo_auth_filter(s.query(func.count(PhotoSet.id))). \
|
numphotos = photo_auth_filter(db.query(func.count(PhotoSet.id))). \
|
||||||
filter(~PhotoSet.id.in_(s.query(TagItem.set_id))).scalar()
|
filter(~PhotoSet.id.in_(db.query(TagItem.set_id))).scalar()
|
||||||
photos = photo_auth_filter(s.query(PhotoSet)).filter(~PhotoSet.id.in_(s.query(TagItem.set_id))).\
|
photos = photo_auth_filter(db.query(PhotoSet)).filter(~PhotoSet.id.in_(db.query(TagItem.set_id))).\
|
||||||
offset(page * pgsize). \
|
offset(page * pgsize). \
|
||||||
limit(pgsize).all()
|
limit(pgsize).all()
|
||||||
yield self.master.render("untagged.html", images=photos, total_items=numphotos, pgsize=pgsize, page=page)
|
yield self.master.render("untagged.html", images=photos, total_items=numphotos, pgsize=pgsize, page=page)
|
||||||
else:
|
else:
|
||||||
tag = s.query(Tag).filter(or_(Tag.uuid == uuid, Tag.slug == uuid)).first()
|
tag = db.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)). \
|
numphotos = photo_auth_filter(db.query(func.count(Tag.id)).join(TagItem).join(PhotoSet)). \
|
||||||
filter(Tag.id == tag.id).scalar()
|
filter(Tag.id == tag.id).scalar()
|
||||||
photos = photo_auth_filter(s.query(PhotoSet)).join(TagItem).join(Tag). \
|
photos = photo_auth_filter(db.query(PhotoSet)).join(TagItem).join(Tag). \
|
||||||
filter(Tag.id == tag.id). \
|
filter(Tag.id == tag.id). \
|
||||||
order_by(PhotoSet.date.desc()). \
|
order_by(PhotoSet.date.desc()). \
|
||||||
offset(page * pgsize). \
|
offset(page * pgsize). \
|
||||||
|
@ -393,24 +372,23 @@ class TagView(object):
|
||||||
- Make all public: mark all photos under this tag as public
|
- Make all public: mark all photos under this tag as public
|
||||||
- Make all private: mark all photos under this tag as private
|
- Make all private: mark all photos under this tag as private
|
||||||
"""
|
"""
|
||||||
s = self.master.session()
|
tag = db.query(Tag).filter(or_(Tag.uuid == uuid, Tag.slug == uuid)).first()
|
||||||
tag = s.query(Tag).filter(or_(Tag.uuid == uuid, Tag.slug == uuid)).first()
|
|
||||||
if op == "Demote to tag":
|
if op == "Demote to tag":
|
||||||
tag.is_album = 0
|
tag.is_album = 0
|
||||||
elif op == "Promote to album":
|
elif op == "Promote to album":
|
||||||
tag.is_album = 1
|
tag.is_album = 1
|
||||||
elif op == "Delete tag":
|
elif op == "Delete tag":
|
||||||
s.query(TagItem).filter(TagItem.tag_id == tag.id).delete()
|
db.query(TagItem).filter(TagItem.tag_id == tag.id).delete()
|
||||||
s.delete(tag)
|
db.delete(tag)
|
||||||
s.commit()
|
db.commit()
|
||||||
raise cherrypy.HTTPRedirect('/', 302)
|
raise cherrypy.HTTPRedirect('/', 302)
|
||||||
elif op == "Make all public":
|
elif op == "Make all public":
|
||||||
# TODO smarter query
|
# TODO smarter query
|
||||||
for photo in s.query(PhotoSet).join(TagItem).join(Tag).filter(Tag.id == tag.id).all():
|
for photo in db.query(PhotoSet).join(TagItem).join(Tag).filter(Tag.id == tag.id).all():
|
||||||
photo.status = PhotoStatus.public
|
photo.status = PhotoStatus.public
|
||||||
elif op == "Make all private":
|
elif op == "Make all private":
|
||||||
# TODO smarter query
|
# TODO smarter query
|
||||||
for photo in s.query(PhotoSet).join(TagItem).join(Tag).filter(Tag.id == tag.id).all():
|
for photo in db.query(PhotoSet).join(TagItem).join(Tag).filter(Tag.id == tag.id).all():
|
||||||
photo.status = PhotoStatus.private
|
photo.status = PhotoStatus.private
|
||||||
elif op == "Save":
|
elif op == "Save":
|
||||||
tag.title = title
|
tag.title = title
|
||||||
|
@ -418,14 +396,13 @@ class TagView(object):
|
||||||
tag.slug = slugify(title)
|
tag.slug = slugify(title)
|
||||||
else:
|
else:
|
||||||
raise Exception("Invalid op: '{}'".format(op))
|
raise Exception("Invalid op: '{}'".format(op))
|
||||||
s.commit()
|
db.commit()
|
||||||
raise cherrypy.HTTPRedirect('/tag/{}'.format(tag.slug or tag.uuid), 302)
|
raise cherrypy.HTTPRedirect('/tag/{}'.format(tag.slug or tag.uuid), 302)
|
||||||
|
|
||||||
@cherrypy.expose
|
@cherrypy.expose
|
||||||
@require_auth
|
@require_auth
|
||||||
def edit(self, uuid):
|
def edit(self, uuid):
|
||||||
s = self.master.session()
|
tag = db.query(Tag).filter(Tag.uuid == uuid).first()
|
||||||
tag = s.query(Tag).filter(Tag.uuid == uuid).first()
|
|
||||||
yield self.master.render("tag_edit.html", tag=tag)
|
yield self.master.render("tag_edit.html", tag=tag)
|
||||||
|
|
||||||
|
|
||||||
|
@ -453,12 +430,12 @@ def main():
|
||||||
web = PhotosWeb(library, tpl_dir)
|
web = PhotosWeb(library, tpl_dir)
|
||||||
|
|
||||||
def validate_password(realm, username, password):
|
def validate_password(realm, username, password):
|
||||||
s = library.session()
|
if db.query(User).filter(User.name == username, User.password == pwhash(password)).first():
|
||||||
if s.query(User).filter(User.name == username, User.password == pwhash(password)).first():
|
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
cherrypy.tree.mount(web, '/', {'/': {'tools.trailing_slash.on': False,
|
cherrypy.tree.mount(web, '/', {'/': {'tools.trailing_slash.on': False,
|
||||||
|
'tools.db.on': True,
|
||||||
'error_page.403': web.error,
|
'error_page.403': web.error,
|
||||||
'error_page.404': web.error},
|
'error_page.404': web.error},
|
||||||
'/static': {"tools.staticdir.on": True,
|
'/static': {"tools.staticdir.on": True,
|
||||||
|
|
Loading…
Reference in New Issue