tagging on import

This commit is contained in:
dave 2019-10-14 19:25:53 -07:00
parent 6765425be5
commit 4f10129c5a
2 changed files with 44 additions and 11 deletions

View File

@ -72,7 +72,7 @@ class PhotosApiV1(object):
ext = get_extension(file.filename)
assert ext in known_extensions
photo_path = generate_storage_path(photo_date, photo_meta['hash'][0:8], ext)
# shouldn't we just trust the database?
if self.library.storage.exists(photo_path):
return abort_upload(f"file already in library: {photo_path}")
@ -84,7 +84,7 @@ class PhotosApiV1(object):
# misc input validation
# also if sha doesn't match uploaded metadata, abort
# todo don't use asserts
# TODO don't use asserts
try:
assert shasum == photo_meta["hash"], "uploaded file didn't match provided sha"
@ -130,8 +130,14 @@ class PhotosApiV1(object):
lat=Decimal(meta["lat"]) if meta["lat"] else None,
lon=Decimal(meta["lon"]) if meta["lon"] else None,
files=photo_objs) # TODO support title field et
db.add(ps)
for tag_name in meta["tags"]:
tag = db.query(Tag).filter(Tag.name == tag_name).first()
assert tag, "unknown tag name"
db.add(TagItem(tag_id=tag.id, set=ps))
ps_json = ps.to_json() # we do this now to avoid a sqlalchemy bug where the object disappears after the commit
try:
@ -211,7 +217,7 @@ class PhotosApiV1(object):
@cherrypy.expose
@cherrypy.tools.json_out()
@cherrypy.popargs("uuid")
def tags(self, uuid=None, page=0, pagesize=50):
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")
@ -228,12 +234,17 @@ class PhotosApiV1(object):
db.delete(tag)
db.commit()
return {}
elif uuid: # getting tag
t = db.query(Tag).filter(Tag.uuid == uuid).first()
elif uuid or name: # getting tag
q = db.query(Tag)
if uuid:
q = q.filter(Tag.uuid == uuid)
if name:
q = q.filter(Tag.name == name)
t = q.first()
if not t:
cherrypy.response.status = 404
return {"error": "not found"}
return t.to_json()
return [t.to_json()]
else: # getting all tags
page, pagesize = int(page), int(pagesize)
return [t.to_json() for t in

View File

@ -4,7 +4,7 @@ import argparse
import requests
from requests.exceptions import HTTPError
from photoapp.utils import get_extension
from photoapp.types import known_extensions, PhotoStatus
from photoapp.types import known_extensions, PhotoStatus, Tag
from photoapp.common import pwhash
from photoapp.ingest import get_photosets
from urllib.parse import urlparse
@ -93,8 +93,11 @@ class PhotoApiClient(object):
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 list_tags(self, name):
params = {}
if name:
params["name"] = name
return self.get("tags", params=params)
# def delete_user(self, username):
# return self.delete("user", params={"username": username})
@ -143,6 +146,7 @@ def get_args():
p_ingest = sp_action.add_parser("ingest", help="import images into the library")
p_ingest.add_argument("-c", "--copy-of", help="existing uuid the imported images will be placed under")
p_ingest.add_argument("-w", "--workers", default=1, type=int, help="number of parallel uploads")
p_ingest.add_argument("-t", "--tag", help="tag name to apply to the import")
p_ingest.add_argument("files", nargs="+", help="files to import")
sp_action.add_parser("stats", help="show library statistics")
@ -161,7 +165,8 @@ def get_args():
p_create.add_argument("-t", "--title")
p_create.add_argument("-d", "--description")
p_tagaction.add_parser('list', help='list tags')
p_tag_list = p_tagaction.add_parser('list', help='list tags')
p_tag_list.add_argument("-n", "--name", help="tag name to lookup")
p_delete = p_tagaction.add_parser('delete', help='delete tags')
p_delete.add_argument("-n", "--name", required=True)
@ -228,6 +233,16 @@ def main():
raise
elif args.action == "ingest":
tag = None
if args.tag:
tag = args.tag.lower()
try:
client.list_tags(name=tag).json()
except requests.exceptions.HTTPError as he:
if he.response.status_code != 404:
raise
client.create_tag(tag, tag, "")
sets, skipped = get_photosets(args.files)
rows = []
@ -255,6 +270,13 @@ def main():
def upload_set(set_):
payload = set_.to_json()
# add tags to set
if args.tag:
# it's kinda cheap to do this in json instead of building out the PhotoSet data structure
# but trust me it's worth it
payload["tags"] = [tag]
payload["files"] = {os.path.basename(photo.path): photo.to_json() for photo in set_.files}
files = []
@ -334,7 +356,7 @@ def main():
client.create_tag(args.name, args.title, args.description)
elif args.action_tag == "list":
rows = []
for tag in client.list_tags().json():
for tag in client.list_tags(name=args.name).json():
rows.append([tag["name"], tag["title"], maybetruncate(tag["description"], 24), tag["uuid"]])
print(tabulate(rows, headers=["name", "title", "description", "uuid"]))