Skip to main content

Organize Google Takeout photos into YYYY/MM/ folders with dedup and reporting

Reason this release was yanked:

Needs bake time

Project description

Degoogle-Photos

Organize Google Takeout photo exports into a clean YYYY/MM/ folder structure with deduplication, album symlinks, and a browsable HTML report.

Why this exists

If you're not paying for the product, you are the product.

Google Photos is free because Google's business model is advertising and data. Their terms of service grant them a worldwide, royalty-free license to use, reproduce, modify, and distribute anything you upload -- including training AI models and creating derivative works. Your "private" album is private from other users, not from Google.

I decided to leave Google Photos for good, but getting out is harder than getting in. Google Takeout -- the only official export tool -- dumps your collection into dozens of numbered zip files with a chaotic structure: albums split across chunks, JSON metadata sidecars with truncated filenames, duplicates scattered everywhere, and no usable date-based organization. For my ~20,000 photos across 46 archives, it was a mess.

The go-to recommendation is the Google Photos Takeout Helper. I tried it. It crashed on a missing geoDataExif field in a JSON sidecar. Moved the problem file out, restarted. Crashed again on the next file. Moved the whole album folder. Crashed on a different folder with the same error. Each crash meant starting from scratch -- no resume support. After several rounds of this whack-a-mole I gave up. With 20,000 files and wildly inconsistent metadata across 46 archives, a tool that dies on the first unexpected field is effectively unusable.

So I built this from scratch with Claude

Sharing it because leaving Google shouldn't require a computer science degree. If the only thing keeping you on Google Photos is "I don't know how to get my photos out," this is how.

What it does

  • Scans multiple Takeout*/Google Photos/ directories and builds a global index
  • Extracts the best date for each file (EXIF > JSON photoTakenTime > filename > JSON creationTime > file mtime)
  • Deduplicates by MD5 hash + date (rounded to the minute)
  • Copies media files into YYYY/MM/ folders, preserving JSON sidecars alongside
  • Creates Albums/ folder with relative symlinks for named albums
  • Generates a multi-page HTML report with thumbnails, metadata tooltips, and Finder links

Prerequisites

  • Python 3.9+
  • A Google Takeout export with one or more Takeout*/Google Photos/ directories

Installation

pip install degoogle-photos

That's it. Pillow (for EXIF extraction) is installed automatically.

Alternative: run from source

git clone https://github.com/couzteau/Degoogle-Photos.git
cd Degoogle-Photos
pip install -e .

Usage

# Preview what would happen (no files copied)
degoogle-photos --source /path/to/takeouts --output /path/to/organized --dry-run

# Run the migration
degoogle-photos --source /path/to/takeouts --output /path/to/organized

Options

Flag Description
--source PATH Root directory containing Takeout*/ folders (required)
--output PATH Destination for organized photos (required)
--dry-run Report what would be done without copying any files

How it works

  1. Index -- Scan all Takeout directories, index media files and JSON sidecars by album
  2. Match -- Link each media file to its JSON sidecar via title field or filename stripping
  3. Date extraction -- Extract the best date using a priority cascade (EXIF > JSON > filename > mtime)
  4. Deduplication -- Skip files with identical MD5 + date (within the same minute)
  5. Copy -- Copy to YYYY/MM/filename with collision resolution (_2, _3, etc.)
  6. Albums -- Create Albums/<name>/ with relative symlinks to the copied files
  7. Report -- Generate a browsable HTML report with per-folder and per-album pages

HTML Report

The report is written to <output>/report/index.html and includes:

  • Dashboard with copy/duplicate/error counts and date-source breakdown
  • Per-folder pages with image thumbnails in a responsive grid
  • Per-album pages for named albums (generic "Photos from YYYY" albums are excluded)
  • Hover tooltips showing EXIF data (camera, ISO, focal length, GPS) and JSON metadata (people, geo, description)
  • "Finder" buttons to open the containing folder in macOS Finder

Project structure

degoogle_photos/
  __init__.py          # Package version
  indexing.py          # Takeout directory scanning and JSON sidecar indexing
  dates.py             # Date extraction (EXIF, JSON, filename, mtime)
  metadata.py          # Rich metadata extraction for report tooltips
  dedup.py             # MD5 hashing and deduplication keys
  copy.py              # File copying with collision resolution
  report.py            # Multi-page HTML report generation
  logging_util.py      # Migration logging and progress reporting
  albums.py            # Album symlink creation
  cli.py               # CLI entry point and orchestration
tests/
  conftest.py          # Shared test fixtures
  test_indexing.py
  test_dates.py
  test_metadata.py
  test_dedup.py
  test_copy.py
  test_report.py
  test_albums.py
migrate_photos.py      # Thin wrapper for backward compatibility
pyproject.toml         # Project metadata and dependencies

Running tests

pip install -e ".[dev]"
pytest -v

Where to put your photos after

Once your photos are organized, you have options with better privacy terms:

Service Terms summary Cross-platform
Apple iCloud Minimal rights -- just enough to sync and store. No ad business model. Apple devices + web (non-Apple users can upload via browser to shared albums)
Adobe Lightroom Rights limited to operating services. No generative AI training on customer content. Full cross-platform
Dropbox / OneDrive Rights limited to providing the service. No promotional or AI training use. Full cross-platform
Self-hosted (Immich, PhotoPrism) You retain all rights. Requires technical setup. Web-based, any device
Local storage + backup Your files, your rights. Use the generated report/index.html to browse and review. Back up to an external drive or NAS. Any device with file access

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

degoogle_photos-1.0.0.tar.gz (25.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

degoogle_photos-1.0.0-py3-none-any.whl (21.8 kB view details)

Uploaded Python 3

File details

Details for the file degoogle_photos-1.0.0.tar.gz.

File metadata

  • Download URL: degoogle_photos-1.0.0.tar.gz
  • Upload date:
  • Size: 25.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.9.6

File hashes

Hashes for degoogle_photos-1.0.0.tar.gz
Algorithm Hash digest
SHA256 7bae5e2b071aa49c3f31a4d9a7b379d6f713000546e4a2d3f05f79227fa91482
MD5 cbc77e4bdd2845c8a34156d8cd62f506
BLAKE2b-256 f1f79d85330abfc71f82a44c87a3074b4768f038ed7eadc6e080eaf199be7d20

See more details on using hashes here.

File details

Details for the file degoogle_photos-1.0.0-py3-none-any.whl.

File metadata

File hashes

Hashes for degoogle_photos-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 b7e2b6e64b0cf28045bd0faa5187bf3b5eb0d4b8b39c64d530c05db8a72115ec
MD5 cb07a7b0bd27c3d306ffccfd55eff60b
BLAKE2b-256 a673a1ba6c8ee141e0755c36ff37b2b2aff6c8ce54cb01cff5cc3a0f4086b491

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page