Metadata-Version: 2.4
Name: photosync-tool
Version: 0.1.3
Summary: Local desktop tool for organizing, syncing, indexing, and reviewing photos.
Author: Filipluke
License-Expression: MIT
Project-URL: Homepage, https://github.com/Filipluke/PhotoSyncTool
Project-URL: Repository, https://github.com/Filipluke/PhotoSyncTool
Project-URL: Issues, https://github.com/Filipluke/PhotoSyncTool/issues
Keywords: photos,sync,desktop,pyside6,blur-detection,sqlite
Classifier: Development Status :: 3 - Alpha
Classifier: Environment :: Win32 (MS Windows)
Classifier: Environment :: X11 Applications :: Qt
Classifier: Intended Audience :: End Users/Desktop
Classifier: Operating System :: Microsoft :: Windows
Classifier: Operating System :: POSIX :: Linux
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Multimedia :: Graphics
Classifier: Topic :: Utilities
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: PySide6
Requires-Dist: Pillow
Requires-Dist: opencv-python
Requires-Dist: numpy
Requires-Dist: Send2Trash
Requires-Dist: watchdog
Requires-Dist: pywin32; platform_system == "Windows"
Provides-Extra: dev
Requires-Dist: build; extra == "dev"
Requires-Dist: pre-commit; extra == "dev"
Requires-Dist: pytest; extra == "dev"
Requires-Dist: ruff; extra == "dev"
Requires-Dist: twine; extra == "dev"
Provides-Extra: ai
Requires-Dist: pytesseract; extra == "ai"
Provides-Extra: exe
Requires-Dist: pyinstaller; extra == "exe"
Dynamic: license-file

# Photo Manager Pro

[![CI](https://github.com/Filipluke/PhotoSyncTool/actions/workflows/ci.yml/badge.svg)](https://github.com/Filipluke/PhotoSyncTool/actions/workflows/ci.yml)
[![Windows EXE](https://github.com/Filipluke/PhotoSyncTool/actions/workflows/windows-exe.yml/badge.svg)](https://github.com/Filipluke/PhotoSyncTool/actions/workflows/windows-exe.yml)
[![GitHub Pages](https://github.com/Filipluke/PhotoSyncTool/actions/workflows/pages.yml/badge.svg)](https://github.com/Filipluke/PhotoSyncTool/actions/workflows/pages.yml)
[![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](LICENSE)

Photo Manager Pro is a local-first desktop tool for organizing photos and videos on Windows and Linux. It has a PySide6 GUI, one-shot sync, background folder watching, blur detection, a local SQLite index, duplicate review, and safe cleanup tools.

The project is currently alpha. The main workflow works, but distribution still needs clean-machine testing, more service-mode hardening, and better automated GUI checks.

## What Works

- Sort files from a source folder into year-based folders.
- Detect dates from EXIF, filename patterns like `20210924_132556.jpg`, then `mtime` or `ctime`.
- Copy files with verification by fast fingerprint or full SHA256.
- Optionally delete source files after successful synchronization.
- Background sync mode powered by `watchdog`.
- CSV synchronization log and dashboard sync report export.
- Blur scanning with OpenCV.
- Local SQLite metadata index for files, sync events, blur scores, and AI metadata.
- Automatic background sync after app launch.
- Optional app startup on Windows login.
- Single-instance startup guard, so reopening the app focuses the existing process instead of creating another tray icon.
- Headless runner, Windows Service commands, and Linux systemd user-service commands.
- Dashboard with library totals, year counts, top folders, sync errors, and recent events.
- Thumbnail gallery with cached thumbnails, filters, preview, and text/tag search.
- Duplicate review tab that scans by content hash, supports scan cancellation, and queues removals for review.
- Safe Delete Queue with cancel, CSV export, and recycle-bin deletion.
- Local Light AI pass for rough tags, captions, optional OCR, and search.

## Running From Source

```powershell
py -m pip install -r requirements.txt
py photo_manager_gui.py
```

`photo_manager_gui.py` is just the launcher. The main GUI lives in `photo_manager_qt.py`.

After the first PyPI release, installation should look like this:

```powershell
python -m pip install photosync-tool
photo-manager-pro
```

## Project Layout

```text
photo_manager_core.py       Core sync, date detection, copy, and file helpers
photo_manager_features.py   Gallery, delete queue, duplicate review, and AI helpers
photo_manager_index.py      SQLite library index and related commands
photo_manager_qt.py         Main PySide6 desktop interface
photo_manager_service.py    Headless runner and platform service entry point
blur_tool.py                Blur detection workflow
sort_photos_script.py       Legacy/simple CLI sorter
tests/                      Pytest coverage for core workflows
docs/                       GitHub Pages site and screenshots
installer/                  Inno Setup installer definition
```

## Configuration

User settings are stored outside the repository/application folder.

On Windows, the default config path is:

```text
%APPDATA%\PhotoManagerPro\photo_manager_config.json
```

On Linux, the default config path is:

```text
~/.config/PhotoManagerPro/photo_manager_config.json
```

The headless service uses the same default config path, and writes its log to:

```text
%APPDATA%\PhotoManagerPro\photo_manager_service.log
~/.config/PhotoManagerPro/photo_manager_service.log
```

If an old `photo_manager_config.json` exists next to the source files, the GUI can still read it as a legacy fallback. New saves go to the AppData location.

## Windows EXE

The Windows distribution target is `PhotoManagerPro.exe`. The GitHub release workflow builds it with PyInstaller, uploads it as an artifact, and attaches it to GitHub Releases.

Local build:

```powershell
py -m pip install --upgrade ".[exe]"
pyinstaller --noconfirm --onefile --windowed --name PhotoManagerPro --icon photosync_tool_assets/photo_manager_icon.ico --add-data "photosync_tool_assets;photosync_tool_assets" photo_manager_gui.py
```

The executable is written to `dist/PhotoManagerPro.exe`. `build/` and `dist/` are build outputs and should not be committed.

## Linux Install

Linux currently runs from the Python package or from source:

```bash
python3 -m pip install --user photosync-tool
photo-manager-pro
```

The GUI uses PySide6, so some distributions may need Qt runtime libraries installed through the system package manager. Headless sync can run without opening the GUI after the config file exists.

## Release Build Script

The Bash release script builds the local release set:

- Python source/wheel distributions for PyPI in `dist/`,
- `dist/PhotoManagerPro.exe`,
- `release/PhotoManagerProSetup-<version>.exe` when Inno Setup `iscc` is available.

```bash
PYTHON=py scripts/build_release.sh
```

Run it from Git Bash, WSL, or another Bash environment.

Publishing to PyPI is opt-in:

```bash
PYTHON=py scripts/build_release.sh --upload-pypi
```

## Windows Installer

An Inno Setup script is available at `installer/PhotoManagerPro.iss`. It packages the built executable into a regular Windows installer.

Build order:

```powershell
py -m pip install --upgrade ".[exe]"
pyinstaller --noconfirm --onefile --windowed --name PhotoManagerPro --icon photosync_tool_assets/photo_manager_icon.ico --add-data "photosync_tool_assets;photosync_tool_assets" photo_manager_gui.py
iscc installer\PhotoManagerPro.iss
```

The installer output is written to `release/`.

## Tests

```powershell
py -m pip install -e ".[dev]"
py -m ruff check .
py -m pytest
```

The current tests cover date parsing, copy verification, safe destination naming, media filtering, sync schedule logic, duplicate scanning, and sync report export.

See `CONTRIBUTING.md` for the public-repository quality bar and release checks.

Optional local pre-commit setup:

```powershell
py -m pre_commit install
py -m pre_commit run --all-files
```

## Screenshots

Core screenshots are committed under `docs/screenshots/`. The capture plan and recommended filenames are documented in `docs/SCREENSHOTS.md`.

## GitHub Pages

The static GitHub Pages site lives in `docs/`. The page is deployed by `.github/workflows/pages.yml` and uses screenshots in `docs/screenshots/`.

Currently linked screenshots:

- `docs/screenshots/dashboard.png`
- `docs/screenshots/gallery.png`
- `docs/screenshots/duplicates.png`

## Roadmap

The public roadmap lives in `ROADMAP.md`.

Related design notes:

- `docs/SYSTEMD.md` for Linux background sync with systemd.
- `docs/GOOGLE_DRIVE_SYNC.md` for the planned Google Drive backend.

## Library Index

The app keeps a local SQLite index named `photo_manager_index.sqlite3` inside the selected photo root. The index is local and disposable: it can be rebuilt from the library, sync logs, and blur CSVs.

The index stores:

- media file paths, sizes, timestamps, years, dimensions, status, and optional quick hashes,
- sync events from batch sync, background sync, and the headless service,
- blur scores imported from `blur_tool.py`,
- captions, tags, OCR text, and future AI embedding data.

In the GUI, `Library Index -> Rebuild Index` scans the current root folder. `Import Blur CSV` imports existing blur scan results. Batch sync, background sync, Windows Service, Linux systemd service, blur scan, and blur auto-delete all update the index.

Dashboard, Gallery, Duplicates, Delete Queue, and Light AI use this same index. After changing the root folder or importing a large existing library, rebuild the index first.

The Dashboard can export indexed sync events to `photo_manager_sync_report.csv` for release testing, troubleshooting, or archival review.

## Gallery, Duplicates, And Delete Queue

Gallery thumbnails are cached in `.photo_manager_cache/thumbnails` inside the selected root. The cache is ignored by the indexer and can be deleted safely; it will be rebuilt as needed.

Duplicate Review does not delete files directly. It adds candidates to the Safe Delete Queue. From there, decisions can be cancelled, exported to CSV, or moved to the system recycle bin.

## Privacy And Safety

Photo Manager Pro is designed for local photo-library maintenance. The normal sync, index, duplicate, blur, gallery, and Light AI workflows operate on files on the current machine and store metadata in the selected library root or the per-user app configuration folder.

The default app does not upload photos to a cloud service. Update checks read public PyPI package metadata, and optional OCR only runs when the user installs and enables local OCR dependencies. Google Drive synchronization is a planned optional backend and should require explicit OAuth setup, user-selected scopes, and clear dry-run/reporting behavior before uploads happen.

Potentially destructive actions are staged through review-oriented flows:

- batch source deletion only runs after successful synchronization and verification,
- Duplicate Review queues candidates instead of deleting them directly,
- Safe Delete Queue moves files to the system recycle bin by default,
- hard delete options are explicit and should only be used with disposable test libraries or confirmed backups.

## Light AI

Light AI is currently a local heuristic backend, not a heavy model. It can tag likely screenshots, documents, food, landscapes, people, and low-quality photos. OCR is optional.

Optional OCR install:

```powershell
python -m pip install "photosync-tool[ai]"
```

OCR also needs a local Tesseract installation.

## Startup And Background Work

The GUI has two startup options:

- `Autostart background on launch` starts folder watching after the app launches.
- `Open on Windows startup` adds an entry to `HKCU\Software\Microsoft\Windows\CurrentVersion\Run`, so the app starts when the current user logs in.

There is also a headless entry point in `photo_manager_service.py`. It can run a one-shot sync, run as a foreground watcher, or expose platform service commands:

```powershell
photo-manager-service once
photo-manager-service run
photo-manager-service install
photo-manager-service start
photo-manager-service status
photo-manager-service stop
photo-manager-service uninstall
```

On Windows, `install/start/stop/uninstall` use Windows Services through `pywin32`. On Linux, those same commands manage a systemd user service named `photo-manager-pro.service`.

Linux systemd flow:

```bash
python3 -m pip install --user photosync-tool
photo-manager-pro
photo-manager-service once
photo-manager-service install
photo-manager-service start
photo-manager-service status
journalctl --user -u photo-manager-pro.service -f
```

Use `systemctl --user start|stop|restart|status photo-manager-pro.service` when you want to manage the service directly. If the service should keep running after logout on a desktop/server machine, enable lingering with `loginctl enable-linger "$USER"`.

Service mode is implemented, but still needs real-world install/start/stop testing on clean Windows and Linux machines and better setup around logs, permissions, and uninstall behavior.

## Schedule

The GUI has a `Sync hours` field and a simple weekly schedule editor. The hour field accepts one or more ranges:

- `0-24` means all day.
- `8-18` means sync only during that time window.
- `22-7` means an overnight window crossing midnight.
- `8-12,14-18` means multiple windows in one day.

In background sync mode, files detected outside the allowed window are queued and processed when the window opens again.

Still open:

- separate schedules for sync, blur analysis, and AI metadata,
- a `pause until` mode,
- restricting heavier work to nighttime,
- a more durable retry queue for background tasks.

## AI Direction

Full Torch should not be a hard dependency for the desktop app. The better path is to keep heavier AI optional:

1. Start with an API backend or ONNX Runtime as an optional backend.
2. Use SQLite as the cache for tags, captions, embeddings, and review decisions.
3. For local models, use `onnxruntime` with CLIP/SigLIP embeddings for similarity and search.
4. Add `torch` later as a separate `requirements-ai.txt` package only when training or GPU-heavy models are needed.

Torch is powerful, but heavy. For a desktop tool that should stay easy to run, ONNX Runtime or an API backend is the more practical default.

## Still Open

- Test and harden Windows Service install/start/stop on a clean Windows machine.
- Test and harden Linux systemd install/start/stop on a clean Linux machine.
- Test and polish the Inno Setup installer flow.
- Add a signed release flow for `PhotoManagerPro.exe` and the installer.
- Add pause controls and separate schedules for sync, blur, and AI work.
- Add optional Google Drive sync with explicit OAuth setup, a dry-run plan, upload/download conflict handling, and resumable background transfer queue.
- Add an optional hard-AI panel: ONNX/SigLIP or CLIP embeddings, backend, model, batch size, GPU/CPU, and embedding cache.

## License

This project is licensed under the MIT License.
