|
|
@ -7,8 +7,44 @@ from photoapp.utils import get_extension |
|
|
|
from photoapp.types import known_extensions, PhotoStatus |
|
|
|
from photoapp.common import pwhash |
|
|
|
from photoapp.ingest import get_photosets |
|
|
|
from urllib.parse import urlparse |
|
|
|
from tabulate import tabulate |
|
|
|
from concurrent.futures import ThreadPoolExecutor, as_completed |
|
|
|
import appdirs |
|
|
|
|
|
|
|
|
|
|
|
APPNAME = "photocli" |
|
|
|
DEFAULT_CONFIG = {"uri": None, |
|
|
|
"lastbatch": 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") |
|
|
|
super().__init__(**default) |
|
|
|
self.init_config() |
|
|
|
|
|
|
|
def init_config(self): |
|
|
|
os.makedirs(self.confdir, exist_ok=True) |
|
|
|
if os.path.exists(self.confpath): |
|
|
|
self.load() |
|
|
|
else: |
|
|
|
self.write() |
|
|
|
|
|
|
|
def load(self): |
|
|
|
with open(self.confpath) as f: |
|
|
|
self.update(**json.load(f)) |
|
|
|
|
|
|
|
def write(self): |
|
|
|
with open(self.confpath, "w") as f: |
|
|
|
json.dump(self, f, indent=4) |
|
|
|
|
|
|
|
def __setitem__(self, key, value): |
|
|
|
if key not in self: |
|
|
|
raise KeyError(key) |
|
|
|
super().__setitem__(key, value) |
|
|
|
self.write() |
|
|
|
|
|
|
|
|
|
|
|
class PhotoApiClient(object): |
|
|
@ -86,9 +122,7 @@ def confirm(message, options=None, accept=None, confirm_msg="Are you sure?"): |
|
|
|
def get_args(): |
|
|
|
parser = argparse.ArgumentParser(description="photo library cli") |
|
|
|
# TODO nicer uri parser |
|
|
|
parser.add_argument("--host", required=True, help="photo library server address") |
|
|
|
parser.add_argument("--user", required=True) |
|
|
|
parser.add_argument("--password", required=True) |
|
|
|
parser.add_argument("--host", default=os.environ.get("PHOTOLIB_URI", None), help="photo api server address") |
|
|
|
parser.add_argument("-y", "--yes", action="store_true", help="assume yes for all prompts") |
|
|
|
|
|
|
|
sp_action = parser.add_subparsers(dest="action", help="action to take") |
|
|
@ -122,13 +156,22 @@ def get_args(): |
|
|
|
p_delete = p_useraction.add_parser('delete', help='delete users') |
|
|
|
p_delete.add_argument("-u", "--username", help="username", required=True) |
|
|
|
|
|
|
|
return parser.parse_args() |
|
|
|
return parser.parse_args(), parser |
|
|
|
|
|
|
|
|
|
|
|
def main(): |
|
|
|
args = get_args() |
|
|
|
config = CliConfig(APPNAME, DEFAULT_CONFIG) |
|
|
|
args, parser = get_args() |
|
|
|
|
|
|
|
uri = urlparse(args.host or config["uri"]) |
|
|
|
|
|
|
|
if not uri.netloc: |
|
|
|
parser.error("need --host, $PHOTOLIB_URI, or config file") |
|
|
|
|
|
|
|
config["uri"] = uri.geturl() |
|
|
|
|
|
|
|
client = PhotoApiClient(args.host, (args.user, args.password, )) |
|
|
|
port = f":{uri.port}" if uri.port else "" |
|
|
|
client = PhotoApiClient(f"{uri.scheme}://{uri.hostname}{port}", (uri.username, uri.password, )) |
|
|
|
|
|
|
|
if args.action == "checkdupes": |
|
|
|
hashes = {} |
|
|
|