Install Exiftool
BASH
sudo apt install libimage-exiftool-perl
BASH
import os
import json
import subprocess
from datetime import datetime
# The root directory to scan (current directory)
root_dir = "."
def update_media_file(file_path, json_path):
try:
with open(json_path, 'r') as f:
data = json.load(f)
# Extract timestamp from Ente's JSON format
# Key path: photoTakenTime -> timestamp
timestamp = int(data.get('photoTakenTime', {}).get('timestamp', 0))
if timestamp == 0:
print(f"[SKIP] No timestamp found in JSON for: {file_path}")
return
# Convert epoch to formatted date string for ExifTool
# Format: YYYY:MM:DD HH:MM:SS
dt_object = datetime.fromtimestamp(timestamp)
formatted_date = dt_object.strftime("%Y:%m:%d %H:%M:%S")
print(f"[PROCESSING] {file_path} -> {formatted_date}")
# Construct ExifTool command
# We update:
# 1. DateTimeOriginal (Standard EXIF)
# 2. CreateDate (Standard EXIF)
# 3. MediaCreateDate (For Video)
# 4. FileModifyDate (The actual file system time - vital for Immich backups)
cmd = [
"exiftool",
"-overwrite_original",
"-q", # Quiet mode
f"-DateTimeOriginal={formatted_date}",
f"-CreateDate={formatted_date}",
f"-MediaCreateDate={formatted_date}",
f"-TrackCreateDate={formatted_date}",
f"-FileModifyDate={formatted_date}",
file_path
]
subprocess.run(cmd, check=True)
except Exception as e:
print(f"[ERROR] Could not process {file_path}: {e}")
def main():
# Walk through all directories
for subdir, dirs, files in os.walk(root_dir):
# Skip the 'metadata' folders themselves so we don't process JSONs
if 'metadata' in subdir:
continue
for filename in files:
# Only process images and videos
if filename.lower().endswith(('.jpg', '.jpeg', '.png', '.mp4', '.mov', '.heic')):
file_path = os.path.join(subdir, filename)
# specific logic for Ente structure:
# Image: ./Camera/IMG1.jpg
# JSON: ./Camera/metadata/IMG1.jpg.json
json_filename = f"{filename}.json"
json_path = os.path.join(subdir, "metadata", json_filename)
if os.path.exists(json_path):
update_media_file(file_path, json_path)
else:
print(f"[MISSING JSON] Could not find metadata for: {filename}")
if __name__ == "__main__":
main()
