diff --git a/docs/options.md b/docs/options.md index d1c8f81e..c356926c 100644 --- a/docs/options.md +++ b/docs/options.md @@ -85,6 +85,8 @@ --config-yaml FILE Additional configuration files in YAML format --config-toml FILE Additional configuration files in TOML format --config-create Create a basic configuration file + --config-status Show configuration file status + --config-open Open configuration file in external application --config-ignore Do not read default configuration files ## Authentication Options: diff --git a/gallery_dl/__init__.py b/gallery_dl/__init__.py index bc44b353..1d4215ec 100644 --- a/gallery_dl/__init__.py +++ b/gallery_dl/__init__.py @@ -220,8 +220,13 @@ def main(): cnt, "entry" if cnt == 1 else "entries", cache._path(), ) - elif args.config_init: - return config.initialize() + elif args.config: + if args.config == "init": + return config.initialize() + elif args.config == "status": + return config.status() + else: + return config.open_extern() else: if not args.urls and not args.input_files: diff --git a/gallery_dl/config.py b/gallery_dl/config.py index 4be6c532..b9a55255 100644 --- a/gallery_dl/config.py +++ b/gallery_dl/config.py @@ -90,6 +90,78 @@ def initialize(): return 0 +def open_extern(): + for path in _default_configs: + path = util.expand_path(path) + if os.access(path, os.R_OK | os.W_OK): + break + else: + log.warning("Unable to find any writable configuration file") + return 1 + + if util.WINDOWS: + openers = ("explorer", "notepad") + else: + openers = ("xdg-open", "open") + editor = os.environ.get("EDITOR") + if editor: + openers = (editor,) + openers + + import shutil + for opener in openers: + opener = shutil.which(opener) + if opener: + break + else: + log.warning("Unable to find a program to open '%s' with", path) + return 1 + + log.info("Running '%s %s'", opener, path) + retcode = util.Popen((opener, path)).wait() + + if not retcode: + try: + with open(path, encoding="utf-8") as fp: + util.json_loads(fp.read()) + except Exception as exc: + log.warning("%s when parsing '%s': %s", + exc.__class__.__name__, path, exc) + return 2 + + return retcode + + +def status(): + from .output import stdout_write + + paths = [] + for path in _default_configs: + path = util.expand_path(path) + + try: + with open(path, encoding="utf-8") as fp: + util.json_loads(fp.read()) + except FileNotFoundError: + status = "Not Present" + except OSError: + status = "Inaccessible" + except ValueError: + status = "Invalid JSON" + except Exception as exc: + log.debug(exc) + status = "Unknown" + else: + status = "OK" + + paths.append((path, status)) + + fmt = "{{:<{}}} : {{}}\n".format( + max(len(p[0]) for p in paths)).format + + for path, status in paths: + stdout_write(fmt(path, status)) + + def load(files=None, strict=False, loads=util.json_loads): """Load JSON configuration files""" for pathfmt in files or _default_configs: diff --git a/gallery_dl/option.py b/gallery_dl/option.py index 12622d0e..2165b25b 100644 --- a/gallery_dl/option.py +++ b/gallery_dl/option.py @@ -461,9 +461,19 @@ def build_parser(): ) configuration.add_argument( "--config-create", - dest="config_init", action="store_true", + dest="config", action="store_const", const="init", help="Create a basic configuration file", ) + configuration.add_argument( + "--config-status", + dest="config", action="store_const", const="status", + help="Show configuration file status", + ) + configuration.add_argument( + "--config-open", + dest="config", action="store_const", const="open", + help="Open configuration file in external application", + ) configuration.add_argument( "--config-ignore", dest="config_load", action="store_false",