All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
.github/workflows/ci.yml with ruff lint, ruff format-check, pytest, and build jobs using uv and hatchling..github/workflows/release.yml triggered on v* tags — builds distributions, creates a GitHub release, and publishes to PyPI via Trusted Publishing (OIDC).mkdocs.yml with Material theme; docs/ containing index.md, installation.md, usage.md, api.md.docs/assets/icon.png, referenced from the README.MidjourneyDownloader.generate_image_path(): Extracted image-path construction from download_missing() into a dedicated, testable method.MidjourneyDownloader.read_jobs(): Now handles missing jobs_upscale.json gracefully (returns [] instead of raising FileNotFoundError).setuptools + setuptools_scm to hatchling + hatch-vcs; removed the legacy setup.py, setup.cfg, and tox.ini.dimjournal.py and __init__.py are now ruff and mypy clean; added return/variable annotations and explanatory comments (e.g. why undetected_chromedriver is required).pyproject.toml: Added [tool.ruff], [tool.ruff.lint], [tool.ruff.format], [tool.mypy], and [tool.hatch.*] sections; removed [tool.black] and [tool.isort]; dropped --cov-fail-under from default pytest run.MidjourneyAPI.__init__(): cookies_path is now initialised in __init__ so save_cookies() works even when log_in() is mocked in tests.MidjourneyJobCrawler.load_archive_data(): Now returns self.archive_data for easier testing.download_missing(): Refactored to call generate_image_path(); fixed an invalid except dt.datetime.strptime clause (replaced with except ValueError).fetch_and_write_image() referenced an undefined img_array in a broken, unreachable except block. Rewritten so a pymtpng failure cleanly falls back to writing the raw image bytes.request_recent_jobs(): Guard against a missing <pre> payload (no longer raises AttributeError on None), and repaired the JSON-decode error-log snippet.2024-03-01 − 90 days (is 2023-12-02, not 2023-12-01).test_load_archive_data_* — aligned JSON file format with actual flat-list storage and updated assertions.test_update_archive_data — set crawler.archive_data to a list instead of a {"jobs": [...]} dict.test_crawl_with_limit — added required enqueue_time field to mock job data.test_download_missing_images — corrected filename (jobs_upscale.json) and data format (flat list).test_download_function_success — updated assert_called_once_with to use keyword arguments matching the download() call site.PLAN.md to outline project tasks and strategy.TODO.md to track pending tasks.CHANGELOG.md (this file) to document project changes.dimjournal.py with more specific exceptions, detailed logging messages (including exc_info=True for exceptions), and checks for common failure points (e.g., missing elements, network issues, file I/O problems)..github/workflows/ci.yml) to use newer versions of actions/checkout (v4) and actions/setup-python (v5).flake8 to the CI workflow.importlib.metadata).tests/test_dimjournal.py.get_date_ninety_days_prior).MidjourneyAPI (login, user info fetching, job requests).MidjourneyJobCrawler (archive loading, data updates, crawl logic).MidjourneyDownloader (job reading, folder creation, image fetching/writing, download loop).pytest-mock and tmp_path fixtures for effective testing.dimjournal.py:
src/dimjournal/__init__.py: Simplified importlib.metadata import for Python 3.10+ and set dist_name explicitly to dimjournal.download() function now uses a base midjourney folder under user’s Pictures, then dimjournal (e.g., ~/Pictures/midjourney/dimjournal).