From 34ec69af6f10d4e72f8e21e77d0f29797d0e537d Mon Sep 17 00:00:00 2001 From: David Lynch Date: Mon, 6 Apr 2026 00:27:42 -0500 Subject: [PATCH] Use platformdirs to allow storing centralized config Search order is: , , --- leech.py | 42 +++++++++++++++++++++++++++++++++--------- poetry.lock | 17 ++++++----------- pyproject.toml | 1 + uv.lock | 2 ++ 4 files changed, 42 insertions(+), 20 deletions(-) diff --git a/leech.py b/leech.py index 68ba97d..9149497 100755 --- a/leech.py +++ b/leech.py @@ -9,6 +9,8 @@ import requests import requests_cache from click_default_group import DefaultGroup from functools import reduce +from pathlib import Path +from platformdirs import PlatformDirs import sites import ebook @@ -18,6 +20,17 @@ USER_AGENT = 'Leech/%s +http://davidlynch.org' % __version__ logger = logging.getLogger(__name__) +dirs = PlatformDirs('Leech', 'davidlynch.org', ensure_exists=True) + + +def likely_paths(*paths): + yield Path('.') + modpath = Path(__file__).resolve().parent + if modpath.resolve() != Path('.').resolve(): + yield modpath + for path in paths: + yield path + def configure_logging(verbose): if verbose: @@ -41,12 +54,16 @@ def create_session(cache): logger.debug("Uncached session") lwp_cookiejar = http.cookiejar.LWPCookieJar() - try: - lwp_cookiejar.load('leech.cookies', ignore_discard=True) - except Exception: - # This file is very much optional, so this log isn't really necessary - # logging.exception("Couldn't load cookies from leech.cookies") - pass + for directory in likely_paths(dirs.user_data_path): + if not os.path.exists(directory / 'leech.cookies'): + logger.debug("No leech.cookies present in %s", directory) + continue + try: + lwp_cookiejar.load(directory / 'leech.cookies', ignore_discard=True) + except Exception: + # This file is very much optional, so this log isn't really necessary + logger.exception("Couldn't load cookies from leech.cookies in %s", dirs.user_data_path) + break session.cookies.update(lwp_cookiejar) session.headers.update({ 'User-Agent': USER_AGENT, @@ -58,8 +75,13 @@ def create_session(cache): def load_on_disk_options(site): - try: - with open('leech.json') as store_file: + loaded = False + for directory in likely_paths(dirs.user_config_path): + if not os.path.exists(directory / 'leech.json'): + logger.debug("No leech.json present in %s", directory) + continue + logger.debug("Loading leech.json from %s", directory) + with open(directory / 'leech.json') as store_file: store = json.load(store_file) login = store.get('logins', {}).get(site.site_key(), False) cover_options = store.get('cover', {}) @@ -68,7 +90,9 @@ def load_on_disk_options(site): **{k: v for k, v in store.items() if k not in ('cover', 'images', 'logins')}, **store.get('site_options', {}).get(site.site_key(), {}) } - except FileNotFoundError: + loaded = True + break + if not loaded: logger.info("Unable to locate leech.json. Continuing assuming it does not exist.") login = False image_options = {} diff --git a/poetry.lock b/poetry.lock index 93dad63..27b14f4 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 2.3.2 and should not be changed by hand. +# This file is automatically @generated by Poetry 2.3.3 and should not be changed by hand. [[package]] name = "attrs" @@ -549,21 +549,16 @@ xmp = ["defusedxml"] [[package]] name = "platformdirs" -version = "4.4.0" +version = "4.9.4" description = "A small Python package for determining appropriate platform-specific dirs, e.g. a `user data dir`." optional = false -python-versions = ">=3.9" +python-versions = ">=3.10" groups = ["main"] files = [ - {file = "platformdirs-4.4.0-py3-none-any.whl", hash = "sha256:abd01743f24e5287cd7a5db3752faf1a2d65353f38ec26d98e25a6db65958c85"}, - {file = "platformdirs-4.4.0.tar.gz", hash = "sha256:ca753cf4d81dc309bc67b0ea38fd15dc97bc30ce419a7f58d13eb3bf14c4febf"}, + {file = "platformdirs-4.9.4-py3-none-any.whl", hash = "sha256:68a9a4619a666ea6439f2ff250c12a853cd1cbd5158d258bd824a7df6be2f868"}, + {file = "platformdirs-4.9.4.tar.gz", hash = "sha256:1ec356301b7dc906d83f371c8f487070e99d3ccf9e501686456394622a01a934"}, ] -[package.extras] -docs = ["furo (>=2024.8.6)", "proselint (>=0.14)", "sphinx (>=8.1.3)", "sphinx-autodoc-typehints (>=3)"] -test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=8.3.4)", "pytest-cov (>=6)", "pytest-mock (>=3.14)"] -type = ["mypy (>=1.14.1)"] - [[package]] name = "requests" version = "2.33.0" @@ -706,4 +701,4 @@ zstd = ["backports-zstd (>=1.0.0) ; python_version < \"3.14\""] [metadata] lock-version = "2.1" python-versions = "<4.0,>=3.10" -content-hash = "b4af0e85614a4888affdf1bffeb9bb47c6c9b9ef04f88182e0e22e652cc3fbd8" +content-hash = "b7e63998893588d3f3c7e865001506b06913fc5a97dc56673693b8b4f1e3030a" diff --git a/pyproject.toml b/pyproject.toml index 18a94f4..195ca4b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -14,6 +14,7 @@ dependencies = [ "pillow>=12.1.0,<13.0.0", "mintotp<1.0.0,>=0.3.0", "lxml<6.0.0,>=5.3.1", + "platformdirs>=4.9.4", ] name = "leech" version = "1.0.0" diff --git a/uv.lock b/uv.lock index 92e1411..2cfb956 100644 --- a/uv.lock +++ b/uv.lock @@ -202,6 +202,7 @@ dependencies = [ { name = "lxml" }, { name = "mintotp" }, { name = "pillow" }, + { name = "platformdirs" }, { name = "requests" }, { name = "requests-cache" }, ] @@ -220,6 +221,7 @@ requires-dist = [ { name = "lxml", specifier = ">=5.3.1,<6.0.0" }, { name = "mintotp", specifier = ">=0.3.0,<1.0.0" }, { name = "pillow", specifier = ">=12.1.0,<13.0.0" }, + { name = "platformdirs", specifier = ">=4.9.4" }, { name = "requests", specifier = ">=2.32.4,<3.0.0" }, { name = "requests-cache", specifier = ">=1.2.1,<2.0.0" }, ]