Created
October 29, 2024 04:15
-
-
Save okwes/d00c6e064a5ba7731ff31db853489dcc to your computer and use it in GitHub Desktop.
Immich Bulk Date Shift. The Immich web ui only supports setting one time for many assets, this code allows the date of many assets to be shifted by x days, seconds etc. This will shift the date/time for all photos in a given album
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# under CC0/Public Domain. Do as you like. NO WARRANTY | |
# make venv, pip install requests python-dateutil | |
# Replace the 3 variables at the top and adjust the function call for adjust_iso8601_time() to suit your desired time change for all photos in the album you give. | |
# Better code may exist but this is a quick fix to a problem I had | |
import requests | |
from datetime import datetime, timedelta | |
from zoneinfo import ZoneInfo | |
import json | |
API_URL = "https://immich.example.com/api/" | |
API_KEY = "don't share me!" | |
ALBUM_ID = "uuid" # this can be copied from the album view url when viewing | |
def adjust_iso8601_time(iso_string: str, days=0, hours=0, minutes=0, timezone='UTC') -> str | None: | |
try: | |
# Parse the ISO 8601 string, handling time zones manually | |
if 'Z' in iso_string: | |
iso_string = iso_string.replace('Z', '+00:00') # Convert 'Z' to UTC offset | |
dt = datetime.fromisoformat(iso_string) | |
# Convert to the specified time zone if necessary | |
if timezone != 'UTC': | |
dt = dt.astimezone(ZoneInfo(timezone)) | |
# Adjust the datetime object by specified amounts | |
adjusted_dt = dt + timedelta(days=days, hours=hours, minutes=minutes) | |
# Convert back to ISO 8601 format in UTC | |
new_iso_string = adjusted_dt.astimezone(ZoneInfo('UTC')).isoformat(timespec='milliseconds').replace('+00:00', 'Z') | |
return new_iso_string | |
except ValueError as e: | |
print(f"Error parsing date: {e}") | |
return None | |
def change_date_immich(photo_uuid: str, new_date: str) -> requests.Response: | |
url = f"{API_URL}assets" | |
payload = json.dumps({ | |
"dateTimeOriginal": new_date, | |
"ids": [ | |
photo_uuid | |
] | |
}) | |
headers: dict[str, str] = { | |
'Content-Type': 'application/json', | |
'x-api-key': API_KEY | |
} | |
return requests.request("PUT", url, headers=headers, data=payload) | |
def main(): | |
album_url = f"{API_URL}albums/{ALBUM_ID}" | |
payload = {} | |
headers = { | |
'Accept': 'application/json', | |
'x-api-key': API_KEY | |
} | |
response = requests.request("GET", album_url, headers=headers, data=payload) | |
for asset in response.json()["assets"]: | |
exif_data = asset.get("exifInfo") | |
if exif_data: | |
og_time = exif_data.get("dateTimeOriginal") | |
if og_time: | |
new_time = adjust_iso8601_time(og_time, -31, 0, 0) | |
print(f"Oldtime: {og_time}, adjusted: {new_time}") | |
if new_time: | |
print(change_date_immich(asset["id"], new_time).text) | |
if __name__ == "__main__": | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment