CLI toolkit to audit, restore, and sync Google Photos metadata without re-uploading payloads
Project description
📸 Google Photo Meta Fixer (GPMF)
A unified CLI toolkit and React Native companion app to audit, restore, and sync Google Photos metadata — without re-uploading a single byte.
📖 Overview
The official Google Photos API hides storage quota details, strips GPS metadata, and provides no access to raw file locations. Google Photo Meta Fixer (GPMF) bypasses these limitations by providing:
| Capability | Description |
|---|---|
| 🔍 Metadata Audit | Identify original-quality files consuming storage quota |
| 🕐 Timestamp Restoration | Write correct EXIF dates from Takeout JSON or GPTK CSV |
| ☁️ Cloud-to-Cloud Sync | Copy files across Google Drive without downloading/uploading payloads |
| ✅ Verification | Audit local files against CSV or Takeout match logs |
🔄 High-Level Workflow
To identify, fix, and optionally back up your original-quality Google Photos:
- Filter & Group: Use the Google Photos Toolkit userscript in your browser with Tampermonkeyto find original-quality / storage-consuming photos, and add them to a new Google Photos album.
- Export Metadata: Use the toolkit to export the album's metadata as a CSV file and save it under
data/csv/. - Download Files: Choose one of two ways to download your photos:
- Direct Browser Download — Downloads photos directly from the Google Photos browser page.
- Google Takeout — Downloads the album with companion JSON sidecar files containing GPS, descriptions, and timestamps.
- Fix Local Metadata:
- For Browser Downloads:
gp-cleaner metadata fix-local --csv <csv_path> --dir <photos_dir> - For Takeout Downloads:
gp-cleaner process takeout --dir <takeout_dir>
- For Browser Downloads:
- Sync to Drive (Optional): Use
gp-cleaner synccommands to compare your CSV against Google Drive and copy files cloud-to-cloud without duplicates.
🚀 Quick Start Guide
Step 1: Install prerequisites
- Install rclone: Follow the rclone installation instructions.
- Configure your Google Drive remote: Run
rclone configto link your Google Drive (e.g. name the remotegdrive:). - Install exiftool (required for EXIF writes):
brew install exiftool # macOS sudo apt install libimage-exiftool-perl # Debian/Ubuntu
Step 2: Install this package
pip install google-photo-meta-fixer
# For macOS (Homebrew managed Python) or Linux:
pip install google-photo-meta-fixer --break-system-packages
Step 3: Export your Google Photos metadata
- Install the Tampermonkey browser extension.
- Install the userscript from the official Google Photos Toolkit repository.
- Open photos.google.com in your browser.
- Filter by "Consuming" space / "Original" quality, and click Export Metadata to download a CSV file.
- Save the CSV file locally in
data/csv/.
Step 4: Fix local metadata
Option A — Browser-downloaded photos: Write correct timestamps from CSV into EXIF headers and filesystem dates:
gp-cleaner metadata fix-local --csv "data/csv/your_metadata.csv" --dir "path/to/photos"
Option B — Google Takeout photos: Merge sidecar JSON metadata files back into your photos:
gp-cleaner process takeout --dir "path/to/takeout_folder"
Tip: Optionally verify that all timestamps were written correctly:
gp-cleaner metadata verify-csv --csv "data/csv/your_metadata.csv" --dir "path/to/photos"
Step 5: Run the synchronization (Optional)
Compare your metadata CSV against your Google Drive index and sync storage-consuming files cloud-to-cloud:
gp-cleaner sync consuming --csv "data/csv/your_metadata.csv" --remote gdrive:
Step 6: Fix timestamps in Google Drive (Optional)
Align remote file modification dates with original photo datetimes via rclone touch — no payload re-upload:
gp-cleaner metadata fix-drive --remote gdrive:
🔧 CLI Command Reference
All operations are triggered via the gp-cleaner CLI:
| Command | Action | Description |
|---|---|---|
gp-cleaner sync backup |
Cloud sync | Syncs backup photos into year-wise folders on Drive. |
gp-cleaner sync consuming |
Cloud copy | Compares CSV metadata and copies storage-consuming files. |
gp-cleaner sync upload-local |
Upload | Compares local folder and uploads missing files to Drive. |
gp-cleaner metadata fix-local |
Fix local dates | Writes EXIF headers and filesystem timestamps from CSV. |
gp-cleaner metadata fix-drive |
Fix cloud dates | Updates remote file modification dates on Drive. |
gp-cleaner metadata verify-csv |
Audit CSV | Audits local EXIF timestamps against a GPTK CSV export. |
gp-cleaner metadata verify-takeout |
Audit Takeout | Audits local files against the Takeout match log. |
gp-cleaner process takeout |
Takeout merge | Walks Google Takeout directories and merges JSON metadata. |
gp-cleaner process recover-timezone |
Recover timezone | Force shifts timestamps on already modified local photos to a specific timezone. |
For full argument details and advanced options, see the CLI Reference Guide.
🛠️ Developers & Contributors
- For system design guidelines, codebase architecture, and AI coding rules, see GEMINI.md.
- For deep dives into the Google Takeout fuzzy matching algorithm, see LEARNING.md.
- For the Takeout metadata merger guide, see JSON_MERGER.md.
📱 React Native Android Companion App
The repository includes a mobile companion app under the android-app/ directory.
To run it:
- Ensure Node.js (v18+) is installed.
- Navigate to the directory and install dependencies:
cd android-app npm install
- Start Expo:
npx expo start
- Scan the QR code with the Expo Go app on your Android device.
❓ FAQ & Troubleshooting
Why did my photos get shifted to UTC on my first run?
Older versions wrote UTC times directly to EXIF headers, which photo libraries parsed as naive local times. GPMF now defaults to using your system's timezone offset, or you can specify it using the --timezone flag (e.g. --timezone "+05:30").
How do I repair already modified photos?
Use the dedicated recover-timezone command:
gp-cleaner process recover-timezone --dir "/path/to/photos" --timezone "+05:30"
Why does the script skip files?
To prevent modifying file binary hashes (which forces cloud re-uploads), GPMF checks if metadata is already correct. If it is, the write operation is skipped automatically.
For the full setup instructions and step-by-step re-upload guide, see docs/Pixel_Reupload_Guide.md.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file google_photo_meta_fixer-2.0.tar.gz.
File metadata
- Download URL: google_photo_meta_fixer-2.0.tar.gz
- Upload date:
- Size: 26.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
dd83192f4b52387096b4eab63e08bc36d9c47a343a8b2e07a43865f508b1bf0b
|
|
| MD5 |
f8e6024f462756a6c9bf6ac8ca47e0fc
|
|
| BLAKE2b-256 |
29146c29bd21dd8f7f9b6b40ed56d67a32a78437994f45c6a8623b896236114d
|
File details
Details for the file google_photo_meta_fixer-2.0-py3-none-any.whl.
File metadata
- Download URL: google_photo_meta_fixer-2.0-py3-none-any.whl
- Upload date:
- Size: 30.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3c00f52f6fa981e516a5b3f11ce200ab1d024e016bf908449cbcb3bcb0523ac9
|
|
| MD5 |
4c4b91143d76ef736dfe2159ebcc1916
|
|
| BLAKE2b-256 |
495a779236d5fcc83953b516a7f0e07b29087bc7b0a85f6dac64840e41d6ae4b
|