feat(settings): configurable image types filter (issue #28 / DR-019) #42

Merged
ValleyGeek merged 7 commits from 0.1.18/issue-28-image-types into main 2026-06-11 17:50:29 +00:00
Member

Implements the feature requested in #28: a global setting to toggle which supported image formats (JPEG, PNG, WEBP, TIFF, GIF, BMP) the application loads.

Summary of changes

  • New Image Types group in the Settings workbench with checkboxes for each format family.
  • Global preference (PREF_ENABLED_IMAGE_EXTENSIONS) persisted in the application config DB.
  • Scan engine (image_scanner.py, ScanWorker) now respects the enabled extensions subset (the supported_exts parameter that had been a no-op is now wired through).
  • On directory open (and live when the setting changes): disabled-type images are pruned from the working DB via existing delete_images_by_relative_paths + ImageListModel.remove_images, followed by singleton Dupe_ cleanup and viewer reconcile.
  • Normalization added so dev-branch VERSION forms (e.g. 0.1.18-feature.28) do not break pip install -e, setuptools metadata, or builds (pyproject now uses the attr form; canonical_version() normalizes -+ for PEP 440 local version).
  • Agent/build script hardening (AGENTS.md, version-common.sh, manual-build-windows.ps1, etc.) so this class of packaging breakage cannot recur on future dev branches.
  • Bug fixes surfaced during development: open-directory crash after chooser when prior rows existed; build packaging on dev versions.

User-visible

  • Settings → Image Types: unchecking a type completely ignores those files (more than a tag filter).
  • Pruning happens immediately on change for the active workspace and on all future opens.
  • Documented in USER_GUIDE.md, CHANGELOG.md, README.md, DESIGN.md, TECHNICAL_OUTLINE.md.

Versioning

  • PR-prep commit bumps from the dev form on the branch to the next canonical release 0.1.19 (patch from main base 0.1.18).

Testing & verification

  • Unit tests (scanner subset filtering, version normalization).
  • ruff, pytest (relevant suites), check-version-bump, smoke-ui-exit, launcher/build smokes all green on the branch.
  • The enhancement was developed following the full AGENTS.md process (dev branch, grouped commits, always-push, self-verification, DR-019, label maintenance via MCP, etc.).

Resolves #28.

Implements the feature requested in #28: a global setting to toggle which supported image formats (JPEG, PNG, WEBP, TIFF, GIF, BMP) the application loads. ### Summary of changes - New **Image Types** group in the Settings workbench with checkboxes for each format family. - Global preference (`PREF_ENABLED_IMAGE_EXTENSIONS`) persisted in the application config DB. - Scan engine (`image_scanner.py`, `ScanWorker`) now respects the enabled extensions subset (the `supported_exts` parameter that had been a no-op is now wired through). - On directory open (and live when the setting changes): disabled-type images are pruned from the working DB via existing `delete_images_by_relative_paths` + `ImageListModel.remove_images`, followed by singleton Dupe_ cleanup and viewer reconcile. - Normalization added so dev-branch `VERSION` forms (e.g. `0.1.18-feature.28`) do not break `pip install -e`, setuptools metadata, or builds (pyproject now uses the `attr` form; `canonical_version()` normalizes `-` → `+` for PEP 440 local version). - Agent/build script hardening (AGENTS.md, version-common.sh, manual-build-windows.ps1, etc.) so this class of packaging breakage cannot recur on future dev branches. - Bug fixes surfaced during development: open-directory crash after chooser when prior rows existed; build packaging on dev versions. ### User-visible - Settings → Image Types: unchecking a type completely ignores those files (more than a tag filter). - Pruning happens immediately on change for the active workspace and on all future opens. - Documented in USER_GUIDE.md, CHANGELOG.md, README.md, DESIGN.md, TECHNICAL_OUTLINE.md. ### Versioning - PR-prep commit bumps from the dev form on the branch to the next canonical release `0.1.19` (patch from main base `0.1.18`). ### Testing & verification - Unit tests (scanner subset filtering, version normalization). - ruff, pytest (relevant suites), check-version-bump, smoke-ui-exit, launcher/build smokes all green on the branch. - The enhancement was developed following the full AGENTS.md process (dev branch, grouped commits, always-push, self-verification, DR-019, label maintenance via MCP, etc.). Resolves #28.
- Make scan_directory respect supported_exts (was dead param); fix falsy empty-set defaulting.
- Thread through scan_placeholders, scan_metadata, scan_and_upsert.
- ScanWorker accepts + forwards supported_exts (None means full).
- Add PREF_ENABLED_IMAGE_EXTENSIONS; IMAGE_TYPE_DEFINITIONS + get_default in path_utils.
- Set dev VERSION 0.1.18-feature.28 on first compiled-input touch.
- Added scanner unit test for subset/empty filtering.
- Threading: worker still only plain data + signals; no Qt objects.

Verification: ruff clean, pytest test_image_scanner (12/12) passed.
- SettingsWorkbench: _build_image_types_group (6 type checkboxes), _read/_store/_on toggles, reload support, image_types_changed Signal(list).
- MainWindow: connect handler, _get_enabled, _prune_disabled... helper (used on open and live), _on_image_types_changed (model remove + dupe cleanup + viewer reconcile).
- Pass supported_exts= to both ScanWorkers in _launch_directory_scan.
- Prune disabled types from DB on every open_directory (stale cleanup for future workspaces).
- Reuse existing delete/remove/reconcile paths; no new DB schema.
- ruff clean; relevant pytest (pr7/pr13) green.

Declarative: filter is global, applied at scan time and by explicit prune on change/open.
- Extended test_image_scanner with dedicated subset/empty supported_exts test (now 12 cases, all green).
- Recorded full decision in DECISIONS.md as DR-019 (per mandatory process for new capability).
- No USER_GUIDE/CHANGELOG/DESIGN updates in this commit (per AGENTS: PR-prep commit only, when requesting PR to main).
- ruff + pytest clean; check-version-bump previously passed on dev VERSION.

This completes implementation on the dev branch.
Root cause: _prune_disabled_types_from_current_db (called unconditionally from open_directory for DR-019/image types) did 'r.get("relative_path")' on items from working_db.get_all_images() which returns list[ImageRecord] (dataclass), not dicts. AttributeError on any workspace with prior rows aborted open_directory before setWindowTitle / _launch_directory_scan / preload, so chooser closed with no visible effect or scan.

- Made access robust with small _rp() helper (supports dict or record).
- Also wrapped the bare delete in the live _on_image_types_changed path.
- No behavior change for the filter itself; now open always reaches the visible 'this dir is open + scan' steps.

Verification: ruff clean, pytest (scanner+config+shell), check-version, smoke-ui-exit all green.
The committed VERSION file on development branches uses the documented
form  {base}-{kind}.{n}  (per VERSIONING.md / AGENTS.md / DR-017) for
branch naming and human tracking. However pyproject.toml used
{ file = "VERSION" } for dynamic version, and setuptools/pip editable
installs + egg_info feed the raw string to packaging.version.Version,
which strictly enforces PEP 440 and rejects the hyphenated dev suffix.

- Make canonical_version() (the fallback path) always return a PEP 440
  compliant string by turning the first '-' into '+' for the local
  version segment (0.1.18-feature.28 -> 0.1.18+feature.28).
- Switch pyproject.toml dynamic version to { attr = "...canonical_version" }
  so that build isolation / editable installs go through our helper
  instead of the raw file.
- Harden windows_file_version() against local version segments.
- Update version tests and the test helper to assert the new contract
  (normalization happens; reported values remain parseable).

This unblocks scripts/manual-build-windows.ps1 (and equivalent Linux
build flows) on dev branches without changing the VERSION file contents
or the documented development version policy.

The isolated build venvs created by the PowerShell script will now
succeed at the 'pip install -e .' step that previously died with
'InvalidVersion: 0.1.18-feature.28'.
- AGENTS.md: Added explicit 'Critical packaging note' under versioning rules + expanded the local testing bullet to require exercising build smokes / pip -e on dev branches (where VERSION has the hyphenated form). Agents must never feed raw VERSION content to packaging tools.
- docs/VERSIONING.md: Clarified 'Source form' (hyphen in committed VERSION, for branch policy) vs 'Packaging / PEP 440 form' (normalized with + via the helpers). Points to the enforcement in build scripts and core/version.py.
- scripts/version-common.sh: Introduced bio_raw_version() (the old raw read) and rewired bio_canonical_version() + bio_artifact_version() to go through 'get-version.py --canonical' (the normalized PEP 440 value). Added comments.
- scripts/manual-build-windows.ps1: Split Get-RawVersion / Get-PackagingVersion (the latter delegates to --canonical with fallback). Updated main flow, header logging, Get-WindowsExeBasename, and cache calls to prefer the packaging form. This makes the printed 'Version:' and all metadata/cache paths correct on dev branches.
- scripts/build-linux.sh: Updated the build header to log both display and packaging (canonical) versions for clarity.

These changes, combined with the earlier pyproject + canonical_version normalization, ensure that following the documented dev VERSION rules (AGENTS + VERSIONING) will no longer break , Nuitka builds, or other packaging steps.
docs: PR-prep for issue 28 (configurable image types filter) + release version bump
All checks were successful
CI / lint (pull_request) Successful in 16s
CI / test (pull_request) Successful in 1m25s
CI / nuitka-smoke (pull_request) Successful in 8m17s
2a0d5ced65
- resources/help/USER_GUIDE.md: Document the new Image Types setting under Settings and note its effect in Supported Formats.
- CHANGELOG.md: Add entry under [Unreleased] for the added Image Types global preference and pruning behavior (issue #28).
- docs/DESIGN.md: Note the filter in the config/UX module list and discovery scan responsibilities.
- docs/TECHNICAL_OUTLINE.md: Update Settings description and directory loading/scanning sections to cover the global enabled extensions preference.
- README.md: Mention that supported formats are now user-configurable via Settings.
- VERSION: Bumped from dev form (0.1.18-feature.28) to next canonical release 0.1.19 (patch from main base 0.1.18 per VERSIONING.md and AGENTS.md PR-prep rules). This is the final commit before requesting merge to main.

All prior feature work, bug fixes (open crash, build packaging), and hardening (agent/script updates to prevent future dev-version breakage) are included on the branch. Checks (check-version-bump, ruff) passed for this commit.
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
ai-collab/bulk-image-organizer!42
No description provided.