Skip to content

Instantly share code, notes, and snippets.

@marnix
Created March 23, 2024 19:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save marnix/8ec27386a8c74dcff5238bc72be97238 to your computer and use it in GitHub Desktop.
Save marnix/8ec27386a8c74dcff5238bc72be97238 to your computer and use it in GitHub Desktop.
Add EXIF date-time from Google Photos takeout zip-file
#!/usr/bin/env python3
import shutil
import zipfile
import glob
import os.path
import json
import subprocess
from datetime import datetime, timezone
import exif
import pytz
shutil.rmtree('Takeout', ignore_errors=True)
with zipfile.ZipFile('/home/marnix/Downloads/takeout-20240323T163712Z-001.zip') as takeoutZipFile:
takeoutZipFile.extractall()
shutil.rmtree('result', ignore_errors=True)
os.makedirs('result')
for jsonFileName in glob.glob('Takeout/**/*.*.json', recursive=True):
with open(jsonFileName, 'rb') as jsonFile:
metadata = json.load(jsonFile)
imageFileName = jsonFileName[0:-len('.json')]
if imageFileName.endswith('.mp4'):
# skip non-images
continue
with open(imageFileName, 'rb') as imageFile:
image = exif.Image(imageFile)
hasDateTime = image.has_exif and 'datetime_original' in image.list_all()
newImageFileName = os.path.join('result', os.path.basename(imageFileName))
shutil.copy(imageFileName, newImageFileName)
if hasDateTime:
# don't update the EXIF timestamp in the file
continue
print(metadata)
utcSeconds = int(metadata['photoTakenTime']['timestamp'])
dt = datetime.fromtimestamp(utcSeconds, timezone.utc)
dt = dt.astimezone(pytz.timezone('Europe/Amsterdam'))
date = dt.strftime("%Y:%m:%d %H:%M:%S.%f%z")
print(date)
try:
proc = subprocess.run([
"exiftool",
f"-SubSecDateTimeOriginal={date}",
"-overwrite_original",
newImageFileName
], check=True, capture_output=True)
except Exception as ex:
print("stdout:", ex.stdout)
print("stderr:", ex.stderr)
raise
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment