Metadata-Version: 2.4
Name: chronocatalog
Version: 0.4.0
Summary: Deterministic, verifiable naming for photo and video archives
Project-URL: Homepage, https://github.com/chronocatalog/chronocatalog
Project-URL: Repository, https://github.com/chronocatalog/chronocatalog
Project-URL: Changelog, https://github.com/chronocatalog/chronocatalog/blob/main/CHANGELOG.md
Project-URL: Issues, https://github.com/chronocatalog/chronocatalog/issues
Author-email: Jakub Stefanski <js@jakubstefanski.com>
License-Expression: MIT
License-File: LICENSE
Keywords: archive,checksum,exif,photography,raw,rename,sidecar,video
Classifier: Development Status :: 3 - Alpha
Classifier: Environment :: Console
Classifier: Intended Audience :: End Users/Desktop
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Topic :: Multimedia :: Graphics
Classifier: Topic :: System :: Archiving
Requires-Python: >=3.11
Requires-Dist: tzdata; sys_platform == 'win32'
Provides-Extra: dev
Requires-Dist: mypy>=1.13; extra == 'dev'
Requires-Dist: pytest-cov>=5.0; extra == 'dev'
Requires-Dist: pytest>=8.0; extra == 'dev'
Requires-Dist: ruff>=0.8; extra == 'dev'
Description-Content-Type: text/markdown

# ChronoCatalog

[![CI](https://github.com/chronocatalog/chronocatalog/actions/workflows/ci.yml/badge.svg)](https://github.com/chronocatalog/chronocatalog/actions/workflows/ci.yml)
[![PyPI](https://img.shields.io/pypi/v/chronocatalog)](https://pypi.org/project/chronocatalog/)

Deterministic, verifiable naming for photo and video archives.

`chronocatalog` renames every photo and video to an identity derived
purely from the file itself — the capture time plus a slice of the
content hash:

```
20260703_150727_9b677b64.nef
└──────┬──────┘ └──┬───┘
  capture time    hash
```

That name is a stable, unique identifier with properties a filename
usually doesn't have:

- **Chronological by construction.** Sorting by name is sorting by
  capture time, across every camera, phone and scanner — no rolling
  counters, no `IMG_0001 (2).jpg`.
- **Verifiable.** Because the name is reproducible from the file, the
  whole archive can be re-checked at any time: corruption is told apart
  from legitimate edits, and duplicates identify themselves.
- **Groups stay whole.** A RAW master, its XMP/PP3 sidecars and its
  editor derivatives share one name and are renamed together,
  atomically.

## Install

```console
$ pip install chronocatalog
```

Python 3.11+ and [ExifTool](https://exiftool.org/) on `PATH`; no other
dependencies.

## Usage

| command | what it does |
|---|---|
| `import` | copy a memory card into the archive, named on arrival; exit 0 certifies the card is fully accounted for — safe to format |
| `verify` | recompute every name and report what disagrees, classified by meaning (corruption vs. expected drift vs. date mismatch) |
| `rename` | bring stale names in line, atomically per file group |
| `inject` | let a DAM (Lightroom Classic) rename the masters it manages, via a metadata token |
| `organize` | report-only triage for messy trees: proposals, duplicates, undatable files |
| `history` / `undo` / `resume` | every apply is journaled: list runs, revert them, finish interrupted ones |

Safety first: every command is a dry run unless `--apply`. Applies are
validated as a whole before anything is touched, journaled before the
first change, applied atomically per group, resumable after
interruption and revertable — and a file whose capture time cannot be
resolved is reported, never renamed. Nothing is ever overwritten.

See the
[command guide](https://github.com/chronocatalog/chronocatalog/blob/main/docs/commands.md)
for details, output formats and the exit-code contract, and
[DESIGN.md](https://github.com/chronocatalog/chronocatalog/blob/main/DESIGN.md)
for why it works this way.

## Configuration

An archive is described by a TOML file; every setting has a sensible
default. See
[six complete example setups](https://github.com/chronocatalog/chronocatalog/blob/main/docs/examples.md)
— from a single folder of photos to a Lightroom workflow and a
naming-scheme migration — and the
[annotated example config](https://github.com/chronocatalog/chronocatalog/blob/main/examples/config.toml)
for every option.

## License

[MIT](https://github.com/chronocatalog/chronocatalog/blob/main/LICENSE)
