cli beginnings
This commit is contained in:
parent
91b84710a4
commit
4f218f068a
|
@ -35,16 +35,22 @@ class PhotosApiV1(object):
|
||||||
@cherrypy.tools.json_out()
|
@cherrypy.tools.json_out()
|
||||||
def byhash(self, sha):
|
def byhash(self, sha):
|
||||||
f = db().query(Photo).filter(Photo.hash == sha).first()
|
f = db().query(Photo).filter(Photo.hash == sha).first()
|
||||||
|
if not f:
|
||||||
|
raise cherrypy.HTTPError(404)
|
||||||
return f.to_json()
|
return f.to_json()
|
||||||
|
|
||||||
@cherrypy.expose
|
@cherrypy.expose
|
||||||
@cherrypy.tools.json_out()
|
@cherrypy.tools.json_out()
|
||||||
def set(self, uuid):
|
def set(self, uuid):
|
||||||
s = db().query(PhotoSet).filter(PhotoSet.uuid == uuid).first()
|
s = db().query(PhotoSet).filter(PhotoSet.uuid == uuid).first()
|
||||||
|
if not s:
|
||||||
|
raise cherrypy.HTTPError(404)
|
||||||
return s.to_json()
|
return s.to_json()
|
||||||
|
|
||||||
@cherrypy.expose
|
@cherrypy.expose
|
||||||
def download(self, uuid):
|
def download(self, uuid):
|
||||||
f = db().query(Photo).filter(Photo.uuid == uuid).first()
|
f = db().query(Photo).filter(Photo.uuid == uuid).first()
|
||||||
|
if not f:
|
||||||
|
raise cherrypy.HTTPError(404)
|
||||||
return cherrypy.lib.static.serve_file(os.path.abspath(os.path.join("./library", f.path)),
|
return cherrypy.lib.static.serve_file(os.path.abspath(os.path.join("./library", f.path)),
|
||||||
f.format)#TODO no hardcode path
|
f.format)#TODO no hardcode path
|
||||||
|
|
|
@ -0,0 +1,68 @@
|
||||||
|
import argparse
|
||||||
|
import requests
|
||||||
|
from requests.exceptions import HTTPError
|
||||||
|
|
||||||
|
|
||||||
|
class PhotoApiClient(object):
|
||||||
|
def __init__(self, base_url):
|
||||||
|
self.session = requests.Session()
|
||||||
|
self.base_url = base_url
|
||||||
|
|
||||||
|
def byhash(self, sha):
|
||||||
|
return self.get("byhash", params={"sha": sha}).json()
|
||||||
|
|
||||||
|
def get(self, url, **params):
|
||||||
|
resp = self.session.get(self.base_url + "/api/v1/" + url, **params)
|
||||||
|
resp.raise_for_status()
|
||||||
|
return resp
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
parser = argparse.ArgumentParser(description="photo library cli")
|
||||||
|
parser.add_argument("-s", "--host", required=True, help="photo library server address")
|
||||||
|
|
||||||
|
sp_action = parser.add_subparsers(dest="action", help="action to take")
|
||||||
|
|
||||||
|
p_dupes = sp_action.add_parser("checkdupes", help="check if files/hash lists are already in the library")
|
||||||
|
p_dupes.add_argument("--sha-files", action="store_true", help="read hashes from a file instead of hashing images")
|
||||||
|
p_dupes.add_argument("files", nargs="+", help="files to check")
|
||||||
|
|
||||||
|
p_ingest = sp_action.add_parser("ingest", help="import images into the library")
|
||||||
|
p_ingest.add_argument("files", nargs="+", help="files to import")
|
||||||
|
p_ingest.add_argument("-c", "--copy-of", help="existing uuid the imported images will be placed under")
|
||||||
|
|
||||||
|
args = parser.parse_args()
|
||||||
|
print(args)
|
||||||
|
|
||||||
|
client = PhotoApiClient(args.host)
|
||||||
|
|
||||||
|
if args.action == "checkdupes":
|
||||||
|
hashes = {}
|
||||||
|
if args.sha_files:
|
||||||
|
# sha file format should look like the output of `find ./source -type f -exec shasum -a 256 {} \;`:
|
||||||
|
# e931d286a8377ea8f49ee928e793d9e1fd18a25402cac43afdee3eec3b3b18a5 source/2018-12-26 20.54.40.jpg
|
||||||
|
# 24c1cd20c961839f14d608f5719c4f380af902c4774ddb7cb9ff747f652ca302 source/2018-12-30 22.39.27.jpg
|
||||||
|
for fname in args.files:
|
||||||
|
with open(fname) as f:
|
||||||
|
for line in f.readlines():
|
||||||
|
if not line:
|
||||||
|
continue
|
||||||
|
sha, path = line.split(maxsplit=1)
|
||||||
|
hashes[sha] = path.rstrip("\n")
|
||||||
|
else:
|
||||||
|
raise NotImplementedError("must pass --sha-files for now")
|
||||||
|
|
||||||
|
for sha, path in hashes.items():
|
||||||
|
# hit http://localhost:8080/api/v1/byhash?sha=afe49172f709725a4503c9219fb4c6a9db8ad0354fc493f2f500269ac6faeaf6
|
||||||
|
# if the file is a dupe, do nothing
|
||||||
|
# if the file is original, print its path
|
||||||
|
try:
|
||||||
|
print(client.byhash(sha))
|
||||||
|
except HTTPError as he:
|
||||||
|
print(repr(he.response.status_code))
|
||||||
|
|
||||||
|
# print(hashes)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
|
@ -1,7 +1,10 @@
|
||||||
backports.functools-lru-cache==1.5
|
backports.functools-lru-cache==1.5
|
||||||
|
certifi==2019.6.16
|
||||||
|
chardet==3.0.4
|
||||||
cheroot==6.5.2
|
cheroot==6.5.2
|
||||||
CherryPy==18.1.1
|
CherryPy==18.1.1
|
||||||
contextlib2==0.5.5
|
contextlib2==0.5.5
|
||||||
|
idna==2.8
|
||||||
jaraco.functools==1.20
|
jaraco.functools==1.20
|
||||||
Jinja2==2.10.1
|
Jinja2==2.10.1
|
||||||
MarkupSafe==1.0
|
MarkupSafe==1.0
|
||||||
|
@ -10,7 +13,9 @@ Pillow==5.2.0
|
||||||
portend==2.3
|
portend==2.3
|
||||||
python-magic==0.4.15
|
python-magic==0.4.15
|
||||||
pytz==2018.5
|
pytz==2018.5
|
||||||
|
requests==2.22.0
|
||||||
six==1.11.0
|
six==1.11.0
|
||||||
SQLAlchemy==1.3.5
|
SQLAlchemy==1.3.5
|
||||||
tempora==1.13
|
tempora==1.13
|
||||||
|
urllib3==1.25.3
|
||||||
zc.lockfile==1.3.0
|
zc.lockfile==1.3.0
|
||||||
|
|
1
setup.py
1
setup.py
|
@ -22,6 +22,7 @@ setup(name='photoapp',
|
||||||
"photoinfo = photoapp.image:main",
|
"photoinfo = photoapp.image:main",
|
||||||
"photooffset = photoapp.dateoffset:main",
|
"photooffset = photoapp.dateoffset:main",
|
||||||
"photousers = photoapp.users:main",
|
"photousers = photoapp.users:main",
|
||||||
|
"photocli = photoapp.cli:main",
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
include_package_data=True,
|
include_package_data=True,
|
||||||
|
|
Loading…
Reference in New Issue