___ _______ ________ ________ ___ ________ ________ ___ ________
|\ \ |\ ___ \ |\ ___ \|\ ____\|\ \ |\ __ \|\ ____\|\ \|\ ____\
\ \ \ \ \ __/|\ \ \\ \ \ \ \___|\ \ \ \ \ \|\ \ \ \___|\ \ \ \ \___|
\ \ \ \ \ \_|/_\ \ \\ \ \ \_____ \ \ \ \ \ \\\ \ \ \ __\ \ \ \ \
\ \ \____\ \ \_|\ \ \ \\ \ \|____|\ \ \ \____\ \ \\\ \ \ \|\ \ \ \ \ \____
\ \_______\ \_______\ \__\\ \__\____\_\ \ \_______\ \_______\ \_______\ \__\ \_______\
\|_______|\|_______|\|__| \|__|\_________\|_______|\|_______|\|_______|\|__|\|_______|
\|_________|
Smart photo & video organization powered by metadata
A comprehensive Python CLI tool for organizing photo and video libraries with advanced features including EXIF data extraction, geolocation, duplicate detection, and customizable organization patterns.
- Smart File Organization: Automatically organize photos and videos based on EXIF metadata
- Customizable Naming Patterns: Flexible file naming using metadata variables
- Folder Structure Templates: Create custom folder hierarchies based on date, camera, location
- RAW/JPEG Separation: Automatically separate RAW files from processed images
- Duplicate Detection: Find and handle duplicate files using hash, pixel, or histogram comparison
- Auto-Rotate Images: Automatically correct image orientation based on EXIF data
- Session Detection: Group photos by shooting sessions (time-based)
- Advanced Statistics: Comprehensive analytics with charts (camera usage, shooting patterns)
- Backup Verification: Checksum validation of backup integrity
- Social Media Export: Optimize images for Instagram, Facebook, Twitter with proper sizing
- Incremental Sync: Smart backup that only syncs changed files
- Geolocation Support:
- Extract GPS coordinates from photos
- Reverse geocoding to get location names
- Organize by location (country/city)
- Export GPS data to KML files for mapping
- Interactive Menu System: User-friendly menu-driven interface with Rich UI
- Configuration Wizard: Step-by-step setup with
--config-wizard - Dry Run Mode: Preview changes before applying them
- Progress Tracking: Real-time progress bars and detailed statistics
- Sidecar XMP Files: Generate metadata sidecar files for RAW processors
# Clone the repository
git clone https://github.com/jaydotsee/lenslogic.git
cd lenslogic
# Install dependencies
pip install -r requirements.txt
# Run from source
python src/main.py --help# Build executable using PyInstaller
pyinstaller lenslogic.spec
# Build with security checks (recommended)
./build.sh
# The executable will be in the dist/ directory
./dist/lenslogic --helpGit Hooks - Automatic building and validation:
# Post-commit hook automatically builds after commits (already active)
# Triggers on source code, config, or build file changes
# Optional: Enable pre-commit validation
mv .git/hooks/pre-commit.example .git/hooks/pre-commit
chmod +x .git/hooks/pre-commit
# Disable automation if needed
chmod -x .git/hooks/post-commit # Disable auto-build
chmod -x .git/hooks/pre-commit # Disable validation# Basic usage - organize photos from current directory
lenslogic
# Specify source and destination
lenslogic -s /path/to/photos -d /path/to/organized
# Dry run to preview changes
lenslogic --dry-run
# Interactive mode
lenslogic --interactive
# Analyze library statistics
lenslogic --analyze
# Export GPS locations to KML
lenslogic --export-gps locations.kml-s, --source Source directory containing photos
-d, --destination Destination directory for organized photos
--custom-destination Custom destination for this run only (doesn't modify config)
-c, --config Path to custom configuration file
--dry-run Preview changes without modifying files
-p, --pattern File naming pattern
-f, --folder-structure Folder organization structure
--create-xmp Create XMP sidecar files with metadata
--no-xmp Disable XMP sidecar file creation
--no-preserve Move files instead of copying
-v, --verbose Enable verbose output
--quiet Suppress output except errors
--analyze Basic library statistics
--advanced-stats Comprehensive statistics with charts
--chart-dir DIR Directory for generated charts
--detect-sessions Detect shooting sessions
--organize-sessions Organize photos by sessions
--social-media PLATFORM Optimize for platform (instagram/facebook/twitter)
--social-format FORMAT Format type (post/story/cover)
--social-output DIR Output directory for social media files
--export-gps FILE Export GPS locations to KML file
--backup Backup to configured destinations
--backup-to DEST Backup to specific destinations
--verify-backup Verify backup integrity
--config-wizard Run interactive configuration wizard
--quick-setup Quick configuration setup
--reset-config Reset configuration to defaults
--save-config Save current configuration
-i, --interactive Launch interactive menu
--logo Display LensLogic logo
Launch the interactive menu with:
lenslogic --interactiveThe menu provides options for:
- Quick organize with current settings
- Organize with custom destination (one-time override)
- Configure all settings interactively
- Select directories
- Preview changes (dry run)
- Analyze library statistics
- Export GPS locations
- Advanced options (cache management, config import/export)
The tool uses a hierarchical configuration system:
- Default Configuration: Built-in defaults
- User Configuration:
~/.lenslogic/config.yaml - Custom Configuration: Specified with
-cflag - Command Line Arguments: Override any setting
general:
source_directory: "."
destination_directory: "./organized"
dry_run: false
verbose: true
preserve_originals: true
skip_duplicates: true
file_types:
images: [jpg, jpeg, png, heic, heif]
raw: [raw, cr2, cr3, nef, arw, dng]
videos: [mp4, avi, mov, mkv]
organization:
folder_structure: "{year}/{month:02d}/{day:02d}"
separate_raw: true
raw_folder: "RAW"
jpg_folder: "JPG"
naming:
pattern: "{year}{month:02d}{day:02d}_{hour:02d}{minute:02d}{second:02d}_{camera}_{original_name}"
include_sequence: true
camera_names:
"Canon EOS R5": "R5"
"NIKON D850": "D850"
geolocation:
enabled: true
reverse_geocode: true
add_location_to_folder: false
duplicate_detection:
method: "hash" # hash, pixel, histogram
threshold: 0.95
action: "skip" # skip, rename, moveAvailable variables for naming patterns and folder structures:
Date/Time Variables:
{year},{month},{day}- Date components{hour},{minute},{second}- Time components{date}- YYYYMMDD format{time}- HHMMSS format{month_name},{month_short}- Month names{weekday}- Day of week
Camera Variables:
{camera}- Simplified camera name{camera_make},{camera_model}- Full camera info{lens}- Lens model
Technical Variables:
{iso},{f_number},{focal_length}- Camera settings{width},{height}- Image dimensions
Location Variables (when geolocation enabled):
{country},{city},{state}- Location components
Other:
{original_name}- Original filename without extension{original_sequence}- Sequence number extracted from original filename (e.g., ZF0_8151.JPG β 8151)
lenslogic -s ~/Pictures/Unsorted -d ~/Pictures/OrganizedOrganizes photos from Unsorted folder into Organized folder using default settings.
lenslogic --dry-run -p "{camera}_{date}_{time}_{original_name}" -f "{year}/{camera}/{month_name}"Preview organization with custom naming and folder patterns.
lenslogic -s /media/card -d ~/Photos --no-preserveMove (not copy) files from memory card, automatically separating RAW and JPEG files.
Edit config to enable location folders:
geolocation:
add_location_to_folder: true
location_folder_pattern: "{country}/{city}"Then run:
lenslogic -s ~/Travel/Photos -d ~/Travel/Organized# Full interactive wizard
lenslogic --config-wizard
# Quick setup for beginners
lenslogic --quick-setupSet up LensLogic with guided configuration.
# Generate comprehensive statistics with charts
lenslogic --advanced-stats
# Save charts to specific directory
lenslogic --advanced-stats --chart-dir ~/Photos/AnalyticsAnalyze your photo library with detailed statistics and visual charts.
# Detect shooting sessions
lenslogic --detect-sessions
# Detect and organize by sessions
lenslogic --detect-sessions --organize-sessionsGroup photos by shooting sessions based on time and location.
# Optimize for Instagram posts
lenslogic --social-media instagram
# Optimize for Instagram stories
lenslogic --social-media instagram --social-format story
# Optimize for Facebook with custom output
lenslogic --social-media facebook --social-output ~/Social/FacebookAutomatically resize and optimize images for social media platforms.
# Organize wedding photos to client-specific folder
lenslogic --custom-destination ~/Projects/Smith-Wedding --source ~/Imports/Wedding
# Preview organization to custom location
lenslogic --custom-destination ~/Client/Jones-Event --dry-run
# Interactive mode with custom destination option
lenslogic --interactive
# Then select "π― Organize with Custom Destination"Perfect for organizing client work, wedding shoots, or project-specific photos without changing your main configuration.
# Backup to configured destinations
lenslogic --backup
# Backup to specific locations
lenslogic --backup-to /media/backup1 /media/backup2
# Verify backup integrity
lenslogic --verify-backupIncremental backup with integrity verification.
To create a standalone executable:
# Install PyInstaller
pip install pyinstaller
# Build using spec file
pyinstaller lenslogic.spec
# Or build with custom options
pyinstaller --onefile --name lenslogic \
--add-data "config/default_config.yaml:config" \
src/main.py-
"No EXIF data found": Some image formats may not contain EXIF data. The tool will use file modification date as fallback.
-
Geolocation not working: Ensure you have internet connection for reverse geocoding. The tool caches lookups to minimize API calls.
-
Duplicate detection slow: For large libraries, use "hash" method instead of "pixel" or "histogram" for faster processing.
-
Permission errors: Ensure you have read/write permissions for source and destination directories.
- Use
--dry-runfirst to preview changes - Enable caching for geolocation lookups
- For large libraries (>10,000 files), consider processing in batches
- Use hash-based duplicate detection for speed
- Disable verbose output for faster processing
LensLogic features multiple ASCII logo styles you can display:
# Display the logo
lenslogic --logo
# Different styles available in the app:Camera Style:
ββββββββββββββββββββββββββββββββββββββββ
β β
β πΈπ¬ LensLogic β
β Smart photo & video organization β
β powered by metadata β
β β
ββββββββββββββββββββββββββββββββββββββββ
Simple Style:
ββ LensLogic ββββββββββββββββββββββββββββββ
β πΈπ¬ Smart photo & video organization β
β powered by metadata β
βββββββββββββββββββββββββββββββββββββββββββ
MIT License
Contributions are welcome! Please feel free to submit pull requests or open issues for bugs and feature requests.# Local builds disabled - use manual build with ./build.sh or GitHub Actions