diff --git a/photoapp/api.py b/photoapp/api.py index 1f6ab4c..87d4455 100644 --- a/photoapp/api.py +++ b/photoapp/api.py @@ -2,9 +2,9 @@ import os import cherrypy import json from datetime import datetime -from photoapp.types import Photo, PhotoSet, Tag, PhotoStatus, User, known_extensions, known_mimes, \ +from photoapp.types import Photo, PhotoSet, Tag, TagItem, PhotoStatus, User, known_extensions, known_mimes, \ genuuid, generate_storage_path -from photoapp.utils import copysha, get_extension +from photoapp.utils import copysha, get_extension, slugify from photoapp.image import special_magic_fobj from photoapp.storage import StorageAdapter from photoapp.dbutils import db @@ -207,3 +207,34 @@ class PhotosApiV1(object): page, pagesize = int(page), int(pagesize) 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, 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: # getting tag + t = db.query(Tag).filter(Tag.uuid == uuid).first() + if not t: + cherrypy.response.status = 404 + return {"error": "not found"} + return t.to_json() + else: # getting all tags + 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()] diff --git a/photoapp/cli.py b/photoapp/cli.py index 2938722..4df05e4 100644 --- a/photoapp/cli.py +++ b/photoapp/cli.py @@ -21,7 +21,7 @@ DEFAULT_CONFIG = {"uri": None, class CliConfig(dict): def __init__(self, appname, default): self.confdir = appdirs.user_config_dir(appname) - self.confpath = os.path.join(self.confdir, "cli.json") + self.confpath = os.path.join(self.confdir, "cli.json") # ~/Library/Application Support/name/cli.json super().__init__(**default) self.init_config() @@ -90,6 +90,15 @@ class PhotoApiClient(object): def list_photos(self, page=0, pagesize=25): return self.get("photos", params={"page": page, "pagesize": pagesize}).json() + def create_tag(self, name, title, description): + return self.post("tags", json={"name": name, "title": title, "description": description}) + + def list_tags(self): + return self.get("tags") + + # def delete_user(self, username): + # return self.delete("user", params={"username": username}) + def maybetruncate(s, length): if s and len(s) > length: @@ -143,6 +152,20 @@ def get_args(): p_list.add_argument("-z", "--page-size", default=25, help="page size") p_list.add_argument("-l", "--show-link", action="store_true", help="print urls to each photo") + # Tag section + p_tag = sp_action.add_parser("tag", help="tag manipulation functions") + p_tagaction = p_tag.add_subparsers(dest="action_tag", help="action to take") + + p_create = p_tagaction.add_parser('create', help='create tag') + p_create.add_argument("-n", "--name", required=True) + p_create.add_argument("-t", "--title") + p_create.add_argument("-d", "--description") + + p_tagaction.add_parser('list', help='list tags') + + p_delete = p_tagaction.add_parser('delete', help='delete tags') + p_delete.add_argument("-n", "--name", required=True) + # User section p_adduser = sp_action.add_parser("user", help="user manipulation functions") p_useraction = p_adduser.add_subparsers(dest="action_user", help="action to take") @@ -306,6 +329,15 @@ def main(): elif args.action_user == "delete": print(client.delete_user(args.username).json()) + elif args.action == "tag": + if args.action_tag == "create": + client.create_tag(args.name, args.title, args.description) + elif args.action_tag == "list": + rows = [] + for tag in client.list_tags().json(): + rows.append([tag["name"], tag["title"], maybetruncate(tag["description"], 24), tag["uuid"]]) + print(tabulate(rows, headers=["name", "title", "description", "uuid"])) + if __name__ == "__main__": main() diff --git a/photoapp/types.py b/photoapp/types.py index c73216d..389f4e1 100644 --- a/photoapp/types.py +++ b/photoapp/types.py @@ -127,6 +127,10 @@ class Tag(Base): entries = relationship("TagItem", back_populates="tag") + def to_json(self): + return {attr: getattr(self, attr) for attr in + {"uuid", "is_album", "name", "title", "description"}} + class TagItem(Base): __tablename__ = 'tag_items'