|
|
|
@ -19,24 +19,38 @@ class LibraryManager(object):
|
|
|
|
|
self.storage = storage
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@cherrypy.expose
|
|
|
|
|
class PhotosApi(object):
|
|
|
|
|
def __init__(self, library):
|
|
|
|
|
self.library = library
|
|
|
|
|
self.v1 = PhotosApiV1(self.library)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@cherrypy.expose
|
|
|
|
|
class PhotosApiV1(object):
|
|
|
|
|
def __init__(self, library):
|
|
|
|
|
self.library = library
|
|
|
|
|
|
|
|
|
|
@cherrypy.expose
|
|
|
|
|
def index(self):
|
|
|
|
|
self.library = library # TODO: move library to a cherrypy tool
|
|
|
|
|
self.upload = PhotosApiV1Upload(library)
|
|
|
|
|
self.byhash = PhotosApiV1ByHash()
|
|
|
|
|
self.set = PhotosApiV1Set()
|
|
|
|
|
self.download = PhotosApiV1Download()
|
|
|
|
|
self.user = PhotosApiV1User()
|
|
|
|
|
self.stats = PhotosApiV1Stats()
|
|
|
|
|
self.photos = PhotosApiV1Photos()
|
|
|
|
|
self.tags = PhotosApiV1PhotoTags()
|
|
|
|
|
|
|
|
|
|
def GET(self):
|
|
|
|
|
cherrypy.response.headers["Content-type"] = "text/plain"
|
|
|
|
|
return "Hello! This is the Photolib V1 API.\n"
|
|
|
|
|
|
|
|
|
|
@cherrypy.expose
|
|
|
|
|
@cherrypy.tools.json_out()
|
|
|
|
|
def upload(self, files, meta):
|
|
|
|
|
|
|
|
|
|
@cherrypy.expose
|
|
|
|
|
@cherrypy.tools.json_out()
|
|
|
|
|
class PhotosApiV1Upload(object):
|
|
|
|
|
def __init__(self, library):
|
|
|
|
|
self.library = library
|
|
|
|
|
|
|
|
|
|
def POST(self, files, meta):
|
|
|
|
|
"""
|
|
|
|
|
upload accepts one photoset (multiple images)
|
|
|
|
|
"""
|
|
|
|
@ -150,24 +164,31 @@ class PhotosApiV1(object):
|
|
|
|
|
|
|
|
|
|
return ps_json
|
|
|
|
|
|
|
|
|
|
@cherrypy.expose
|
|
|
|
|
@cherrypy.tools.json_out()
|
|
|
|
|
def byhash(self, sha):
|
|
|
|
|
|
|
|
|
|
@cherrypy.expose
|
|
|
|
|
@cherrypy.tools.json_out()
|
|
|
|
|
class PhotosApiV1ByHash(object):
|
|
|
|
|
|
|
|
|
|
def GET(self, sha):
|
|
|
|
|
f = db.query(Photo).filter(Photo.hash == sha).first()
|
|
|
|
|
if not f:
|
|
|
|
|
raise cherrypy.HTTPError(404)
|
|
|
|
|
return f.to_json()
|
|
|
|
|
|
|
|
|
|
@cherrypy.expose
|
|
|
|
|
@cherrypy.tools.json_out()
|
|
|
|
|
def set(self, uuid):
|
|
|
|
|
|
|
|
|
|
@cherrypy.expose
|
|
|
|
|
@cherrypy.tools.json_out()
|
|
|
|
|
class PhotosApiV1Set(object):
|
|
|
|
|
def GET(self, uuid):
|
|
|
|
|
s = db.query(PhotoSet).filter(PhotoSet.uuid == uuid).first()
|
|
|
|
|
if not s:
|
|
|
|
|
raise cherrypy.HTTPError(404)
|
|
|
|
|
return s.to_json()
|
|
|
|
|
|
|
|
|
|
@cherrypy.expose
|
|
|
|
|
def download(self, uuid):
|
|
|
|
|
|
|
|
|
|
@cherrypy.expose
|
|
|
|
|
class PhotosApiV1Download(object):
|
|
|
|
|
def GET(self, uuid):
|
|
|
|
|
#TODO fix me
|
|
|
|
|
f = db.query(Photo).filter(Photo.uuid == uuid).first()
|
|
|
|
|
if not f:
|
|
|
|
@ -175,37 +196,45 @@ class PhotosApiV1(object):
|
|
|
|
|
return cherrypy.lib.static.serve_file(os.path.abspath(os.path.join("./library", f.path)),
|
|
|
|
|
f.format)#TODO no hardcode path
|
|
|
|
|
|
|
|
|
|
@cherrypy.expose
|
|
|
|
|
@cherrypy.tools.json_out()
|
|
|
|
|
def user(self, username=None, password_hash=None):
|
|
|
|
|
if username is None: # list all users
|
|
|
|
|
return [u.to_json() for u in db.query(User).all()]
|
|
|
|
|
elif username and cherrypy.request.method == "DELETE": # delete user
|
|
|
|
|
u = db.query(User).filter(User.name == username).first()
|
|
|
|
|
if not u:
|
|
|
|
|
raise cherrypy.HTTPError(404)
|
|
|
|
|
db.delete(u)
|
|
|
|
|
elif username and password_hash: # create/update user
|
|
|
|
|
u = db.query(User).filter(User.name == username).first()
|
|
|
|
|
if u:
|
|
|
|
|
u.password = password_hash
|
|
|
|
|
else:
|
|
|
|
|
db.add(User(name=username, password=password_hash))
|
|
|
|
|
|
|
|
|
|
@cherrypy.expose
|
|
|
|
|
@cherrypy.tools.json_out()
|
|
|
|
|
class PhotosApiV1User(object):
|
|
|
|
|
def GET(self): # list all users
|
|
|
|
|
return [u.to_json() for u in db.query(User).all()]
|
|
|
|
|
|
|
|
|
|
def DELETE(self, username): # delete user
|
|
|
|
|
u = db.query(User).filter(User.name == username).first()
|
|
|
|
|
if not u:
|
|
|
|
|
raise cherrypy.HTTPError(404)
|
|
|
|
|
db.delete(u)
|
|
|
|
|
return "ok"
|
|
|
|
|
|
|
|
|
|
def POST(self, username, password_hash): # create/update user
|
|
|
|
|
u = db.query(User).filter(User.name == username).first()
|
|
|
|
|
if u:
|
|
|
|
|
u.password = password_hash
|
|
|
|
|
else:
|
|
|
|
|
db.add(User(name=username, password=password_hash))
|
|
|
|
|
return "ok"
|
|
|
|
|
|
|
|
|
|
@cherrypy.expose
|
|
|
|
|
@cherrypy.tools.json_out()
|
|
|
|
|
def stats(self):
|
|
|
|
|
|
|
|
|
|
@cherrypy.expose
|
|
|
|
|
@cherrypy.tools.json_out()
|
|
|
|
|
class PhotosApiV1Stats(object):
|
|
|
|
|
def GET(self):
|
|
|
|
|
return {"photos": db.query(PhotoSet).count(),
|
|
|
|
|
"files": db.query(Photo).count(),
|
|
|
|
|
"tags": db.query(Tag).count(),
|
|
|
|
|
"users": db.query(User).count(),
|
|
|
|
|
"public_photos": db.query(PhotoSet).filter(PhotoSet.status == PhotoStatus.public).count()}
|
|
|
|
|
|
|
|
|
|
@cherrypy.expose
|
|
|
|
|
@cherrypy.tools.json_out()
|
|
|
|
|
@cherrypy.popargs("uuid")
|
|
|
|
|
def photos(self, uuid=None, page=0, pagesize=50):
|
|
|
|
|
|
|
|
|
|
@cherrypy.expose
|
|
|
|
|
@cherrypy.tools.json_out()
|
|
|
|
|
@cherrypy.popargs("uuid")
|
|
|
|
|
class PhotosApiV1Photos(object):
|
|
|
|
|
def GET(self, uuid=None, page=0, pagesize=50):
|
|
|
|
|
if uuid:
|
|
|
|
|
p = db.query(PhotoSet).filter(PhotoSet.uuid == uuid).first()
|
|
|
|
|
if not p:
|
|
|
|
@ -217,27 +246,13 @@ class PhotosApiV1(object):
|
|
|
|
|
return [p.to_json() for p in
|
|
|
|
|
db.query(PhotoSet).order_by(PhotoSet.id).offset(pagesize * page).limit(pagesize).all()]
|
|
|
|
|
|
|
|
|
|
@cherrypy.expose
|
|
|
|
|
@cherrypy.tools.json_out()
|
|
|
|
|
@cherrypy.popargs("uuid")
|
|
|
|
|
def tags(self, uuid=None, name=None, page=0, pagesize=50):
|
|
|
|
|
if cherrypy.request.method == "POST": # creating tag
|
|
|
|
|
tagdata = json.loads(cherrypy.request.body.read())
|
|
|
|
|
tagname = tagdata.get("name")
|
|
|
|
|
db.add(Tag(name=tagname,
|
|
|
|
|
title=tagdata.get("title", None) or tagname.capitalize(),
|
|
|
|
|
description=tagdata.get("description", None),
|
|
|
|
|
slug=slugify(tagname)))
|
|
|
|
|
db.commit()
|
|
|
|
|
return {}
|
|
|
|
|
|
|
|
|
|
elif uuid and cherrypy.request.method == "DELETE": # deleting tag
|
|
|
|
|
tag = db.query(Tag).filter(Tag.uuid == uuid).first()
|
|
|
|
|
db.query(TagItem).fitler(TagItem.tag_id == tag.id).delete()
|
|
|
|
|
db.delete(tag)
|
|
|
|
|
db.commit()
|
|
|
|
|
return {}
|
|
|
|
|
elif uuid or name: # getting tag
|
|
|
|
|
@cherrypy.expose
|
|
|
|
|
@cherrypy.tools.json_out()
|
|
|
|
|
@cherrypy.popargs("uuid")
|
|
|
|
|
class PhotosApiV1PhotoTags(object):
|
|
|
|
|
def GET(self, uuid=None, name=None, page=0, pagesize=50): # getting tag/s
|
|
|
|
|
if uuid or name:
|
|
|
|
|
q = db.query(Tag)
|
|
|
|
|
if uuid:
|
|
|
|
|
q = q.filter(Tag.uuid == uuid)
|
|
|
|
@ -252,3 +267,20 @@ class PhotosApiV1(object):
|
|
|
|
|
page, pagesize = int(page), int(pagesize)
|
|
|
|
|
return [t.to_json() for t in
|
|
|
|
|
db.query(Tag).order_by(Tag.id).offset(pagesize * page).limit(pagesize).all()]
|
|
|
|
|
|
|
|
|
|
def DELETE(self, uuid): # deleting tag
|
|
|
|
|
tag = db.query(Tag).filter(Tag.uuid == uuid).first()
|
|
|
|
|
db.query(TagItem).fitler(TagItem.tag_id == tag.id).delete()
|
|
|
|
|
db.delete(tag)
|
|
|
|
|
db.commit()
|
|
|
|
|
return {}
|
|
|
|
|
|
|
|
|
|
def POST(self): # creating tag
|
|
|
|
|
tagdata = json.loads(cherrypy.request.body.read())
|
|
|
|
|
tagname = tagdata.get("name")
|
|
|
|
|
db.add(Tag(name=tagname,
|
|
|
|
|
title=tagdata.get("title", None) or tagname.capitalize(),
|
|
|
|
|
description=tagdata.get("description", None),
|
|
|
|
|
slug=slugify(tagname)))
|
|
|
|
|
db.commit()
|
|
|
|
|
return {}
|
|
|
|
|