Commit Graph

16 Commits

Author SHA1 Message Date
drjones
3f67efb379 Add smart recategorize (auto-discovered categories) and fix stale category-keyword accumulation
- New "Smart Recategorize" panel: analyzes existing journal descriptions
  (no vision re-run, no images touched) to propose a richer category list
  when one bucket dominates the library, then reclassifies every tagged
  photo into it using a fast local text-only model pass in batches of 25.
  Verified end-to-end on the real library: correctly split "Objects &
  Stuff" (35% of 15k photos) into specific categories like Electronics &
  Hardware, Cannabis Cultivation, Minerals & Crystals, Tools & Workshop
  based on what's actually in the descriptions.
- New ollama_generate_text() for text-only local model calls (the
  existing ollama_generate always sent an "images" key, unsuitable for
  pure text classification).
- FIX: write_metadata only ever appended category/photon-tagged keywords
  (+=) to the list-type XMP/IPTC tags, so retagging a photo left every
  category it ever had stacked in its metadata, and even rewriting with
  the same category duplicated "photon-tagged" each time. Found via a
  live test while building this feature (which recategorizes at library
  scale). Now strips old values before adding, making every write
  idempotent regardless of how many times a photo is retagged. Wired
  through all four write sites (pipeline, write_single, redo_single,
  bulk_recategorize).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-29 17:16:00 -07:00
drjones
501bfe2916 Add per-folder recursive/top-level-only scanning, fix a dangerous empty-folder-list fallback
- Each source folder now has its own recursive flag (checkbox on add,
  toggle badge on its chip). scan_folder/sync_metadata_from_folder both
  honor it, so "top-level only" actually excludes subfolders end-to-end
  instead of just the tagging queue while sync still scanned recursively.
- New /api/set_folder_recursive to flip an existing folder's mode without
  removing/re-adding it.
- SAFETY FIX: found while testing — when the configured folder list is
  empty, the app fell back to the parent directory of wherever server.py
  lives, which for a typical install (PHOTON dropped directly in the
  user's home folder) means defaulting to the entire home directory.
  Caught this before any scan/start actually ran against it. Fixed so an
  explicitly-configured empty list (config file exists, list is empty)
  is respected as "zero folders" instead of silently substituted with a
  guessed default — the guessed default now only applies on a genuinely
  fresh install where no config file exists yet at all.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-23 11:22:55 -07:00
drjones
1f41ee5352 Add support for multiple source folders
- Server: S.folder (singular) -> S.folders (list). New /api/add_folder
  and /api/remove_folder endpoints; /api/scan and /api/choose_folder
  updated to work with the list (choose_folder now appends instead of
  replacing). Legacy single-folder config migrates transparently.
- All folders feed one combined pending queue/journal/search, per the
  simpler of the two designs discussed.
- organize_alias now resolves each photo's own source folder via
  find_owning_folder(), so category aliases land next to the original
  instead of in one designated folder -- verified live with two
  configured folders that the alias for each photo lands in its own
  folder and nothing leaks into the other.
- Delete path-safety, thumbnail/photo serving, resolve_portable_path,
  undo_all, and sync-on-scan all extended to check/act across every
  configured folder instead of just one.
- Frontend: folder list renders as removable chips; Add (typed path) and
  Browse (native picker, now appends) both wired to the new endpoints;
  Rescan All re-scans the current set without changing it.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-23 04:22:31 -07:00
drjones
00e86dc758 Add PHOTON app icon
Native-drawn dark squircle with a cyan aperture/spark motif matching the
console's own color palette. Menu bar icon stays a plain SF Symbol by
design (colorful icons look muddy at that size); this is the Finder/Dock/
Get Info identity.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-23 03:59:58 -07:00
drjones
7fc81daaa0 Fix six buttons sending GET instead of POST, causing 404s
The api() helper only sends POST when a body argument is passed;
Browse Folder, Pause, Stop, Retry Failed (x2), Undo All, and Scan for
Duplicates were all called with no body, so they defaulted to GET
against POST-only server routes and 404'd. Verified live via the actual
browser: Pause/Stop now correctly transition server status
(running -> paused -> idle) instead of silently failing.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-23 03:55:10 -07:00
drjones
52442d6a6d Fix pipeline shutdown hang, delete path safety, organize folder scoping, journal duplication; add PHOTON.app menu-bar launcher
- Stop/pause could block the downscale thread for up to 60s and throw an
  unhandled exception on shutdown; queue puts are now stop-aware
- /api/delete_photo(s) now refuse to delete anything outside the
  configured photo folder
- organize_alias used a stale startup-time default folder instead of the
  folder actually being scanned/tagged
- journal_write is append-only, so retagging a photo left stale duplicate
  lines that inflated category counts and search results; reads now dedupe
  by path and the journal is compacted once on startup
- batch delete now does one journal rewrite for the whole set instead of
  one per file
- add PHOTON.app: a signed, dependency-free Swift menu-bar app that starts
  server.py in the background (or attaches to an already-running instance),
  opens the console, and exposes Open/Restart/Stop/Show Log/Quit

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-23 03:43:41 -07:00
drjones
007fbd21f7 CRITICAL FIX: Remove duplicate closing block that caused SyntaxError killing all JS on page load 2026-07-20 23:05:16 -07:00
drjones
517785ce59 Fix folder picker window focus and ensure auto-sync of embedded metadata on scan 2026-07-20 22:36:33 -07:00
drjones
a8b2062efd Fix root-cause JS initialization error and make all button handlers 100% robust 2026-07-20 22:00:07 -07:00
drjones
031fccb3ff Add explicit Documents & Texts tab and native Image-to-PDF converter (/api/convert_pdf) 2026-07-20 21:52:36 -07:00
drjones
2d3ef6a06c Add self-healing path relocation for multi-disk portability, macOS native folder picker, and double-clickable launch.command 2026-07-20 21:18:12 -07:00
drjones
82e93972c1 Enable cross-search persistent selection, explicit disk deletion confirmations, and 1-click duplicate copy deletion 2026-07-20 21:15:06 -07:00
drjones
d017297007 Add search clear button and visual thumbnail badges (screenshot/video/ext) 2026-07-20 21:11:01 -07:00
drjones
c07fb9d971 Complete photo deletion on disk, snappy lightbox, keyboard shortcuts, prefetching, and perfected documentation 2026-07-20 21:08:07 -07:00
drjones
5208c5ecef Add full-text photo library, bulk select/download, duplicate detection, video support, and zero-config folder detection
- Search & Edit becomes a multi-view library: Tagged/Untagged/Failed/Videos/Duplicates
- Bulk select (click, shift-click range, select-all-matching) with bulk recategorize,
  CSV/JSON export, and original-quality ZIP download (verified byte-identical)
- Video browsing/tagging via ffmpeg frame extraction, native playback with range support
- Duplicate detection via a lightweight perceptual-hash index (no new dependencies)
- Full-resolution photo/video viewer with editable metadata, prev/next navigation
- Date range, file-type, and category quick-filters; saved searches (localStorage)
- Appearance settings: accent color picker, grid density, results-per-page; full dark mode
- Auto-detects its photo folder (CLI arg > env var > last used > parent directory),
  so the app can be dropped into any photo collection and just work
2026-07-18 19:43:26 -07:00
drjones
adbe4d8f24 Initial commit of PHOTON photo intelligence app
Ollama-based photo tagging with exiftool metadata writes.
2026-07-18 09:21:10 -07:00