| Crates.io | photosync |
| lib.rs | photosync |
| version | 0.1.1 |
| created_at | 2026-01-12 18:03:04.316993+00 |
| updated_at | 2026-01-14 16:09:35.190167+00 |
| description | Tool for copying photos from SD cards |
| homepage | |
| repository | https://github.com/rolandd/photosync |
| max_upload_size | |
| id | 2038411 |
| size | 140,764 |
A Rust utility for syncing photos from camera memory cards to organized directories based on EXIF metadata.
Photosync scans source directories (typically mounted SD cards at
/media/<username>) for photos and videos, extracts EXIF metadata,
and copies files to a date-organized folder structure:
~/Pictures/<camera_dir>/YYYY/MM/DD/<original_filename>
For example, a photo shot on October 25, 2023 with a Canon EOS R6 would be copied to:
~/Pictures/CanonR6-images/2023/10/25/IMG_1234.CR3
The directory structure is configurable using a template system.
Note: Photosync is primarily developed and tested on
Linux. Support for macOS and Windows is implemented but considered
experimental and untested. Please verify your configuration with a
dry run (-n) before usage.
/Volumes. Running
photosync --init on macOS will automatically suggest source = "/Volumes" and exclude = ["Macintosh HD"] to avoid scanning your
system drive.source = "D:/")./) in
configuration paths, even on Windows. For example, use D:/Photos
or Canon/EOS/R6, not D:\Photos or Canon\EOS\R6.--init on Windows will
default to excluding common system folders like System Volume Information and $RECYCLE.BIN.exclude list uses exact, case-sensitive
matching. Ensure the casing in your config matches the actual directory
names (e.g., "Macintosh HD", not "macintosh hd").Requires Rust 2024 edition.
cargo install photosync
# Or build from source:
cargo build --release
# Create a configuration file
photosync --init
# Edit the config to add your camera mappings
# (location shown by --init output)
# Run a dry run to see what would be copied
photosync -n
# Sync your photos
photosync
# Run with defaults (scans /media/$USER, copies to ~/Pictures)
photosync
# Dry run to see what would be copied
photosync -n
# Override source and target directories
photosync --source /path/to/card --target /path/to/photos
# Use a custom directory structure
photosync --template "{year}/{month}/{camera}"
# Disable TUI for piping/scripting
photosync --no-tui
| Option | Description |
|---|---|
--init |
Create a starter configuration file |
-n, --dry-run |
Print what would be done without copying |
--no-tui |
Disable interactive UI, use plain text output |
--source <PATH> |
Override source directory |
--target <PATH> |
Override target directory |
--template <FMT> |
Override destination directory template |
Create photosync.toml in the current directory or
~/.config/photosync/photosync.toml:
# Optional: Override default paths
# Supported variables: $HOME, $XDG_PICTURES_DIR (also ${VAR} syntax)
[dirs]
source = "/media/roland"
target = "$XDG_PICTURES_DIR"
template = "{camera}/{year}/{month}/{day}"
# Map camera model substrings to destination folders
[cameras]
"EOS R6" = "CanonR6-images"
"6D" = "Canon6D-images"
"Hero13" = "GoPro-Hero13"
"HERO13" = "GoPro-Hero13"
The destination directory structure can be customized using the template option.
The following tags are available:
{camera}: The matched camera directory name (from config){year}: 4-digit year (e.g., "2023"){month}: 2-digit month (e.g., "10"){day}: 2-digit day (e.g., "25")The default template is {camera}/{year}/{month}/{day}.
Note on Safety:
/), not
backslashes. They will be converted to the appropriate separator
for your platform... (parent directory traversal).Camera matching uses longest-match-first semantics, so more specific patterns take precedence.
MIT License - Copyright 2026 Roland Dreier roland@kernel.org