immich-compare/delete_corrupted_plus1.py

93 lines
3.0 KiB
Python

#!/usr/bin/env python3
"""Delete corrupted +1 video files from Immich."""
import requests
API_KEY = "GsWQUTR6EXlkKp1M82jDJ3KmzhM0fMAbbIbfHDyI"
BASE_URL = "http://localhost:2283/api"
# Corrupted +1 files (path -> container path)
CORRUPTED_FILES = [
"/data/library/admin/2010/04/2010-04-14_07-38-01_290_Heerenveen+1.mp4",
"/data/library/admin/2012/01/IMG_0259+1.mov",
"/data/library/admin/2012/01/IMG_0262+1.mov",
"/data/library/admin/2010/08/IMG_0169+1.mov",
"/data/library/admin/2012/08/MVI_0342+1.mov",
"/data/library/admin/2012/08/MVI_0496+1.mov",
"/data/library/admin/2012/08/MVI_0462+1.mov",
"/data/library/admin/2012/08/MVI_0452+1.mov",
"/data/library/admin/2012/08/MVI_0448+1.mov",
"/data/library/admin/2012/08/MVI_0463+1.mov",
"/data/library/admin/2012/08/MVI_0468+1.mov",
"/data/library/admin/2012/08/MVI_0534+1.mov",
"/data/library/admin/2012/08/MVI_0446+1.mov",
"/data/library/admin/2012/08/MVI_0466+1.mov",
"/data/library/admin/2012/08/MVI_0335+1.mov",
"/data/library/admin/2012/08/MVI_0495+1.mov",
"/data/library/admin/2012/08/MVI_0531+1.mov",
"/data/library/admin/2012/08/MVI_0404+1.mov",
"/data/library/admin/2012/08/MVI_0467+1.mov",
"/data/library/admin/2012/08/MVI_0454+1.mov",
"/data/library/admin/2012/08/MVI_0389+1.mov",
"/data/library/admin/2012/08/MVI_0469+1.mov",
"/data/library/admin/2011/06/IMG_0147+1.mov",
"/data/library/admin/2012/08/MVI_0465+1.mov",
"/data/library/admin/2012/08/MVI_0444+1.mov",
"/data/library/admin/2012/08/MVI_0470+1.mov",
"/data/library/admin/2012/08/MVI_0440+1.mov",
"/data/library/admin/2010/04/2010-04-04_16-06-22_374_Noordoostpolder+1.mp4",
"/data/library/admin/2012/06/MVI_0060+1.mov",
"/data/library/admin/2012/11/IMG_0582+1.mov",
]
def get_all_assets():
"""Get all assets to find by path."""
assets = []
page = 1
while True:
resp = requests.get(
f"{BASE_URL}/assets",
headers={"x-api-key": API_KEY},
params={"page": page, "size": 1000}
)
if resp.status_code != 200:
break
data = resp.json()
if not data:
break
assets.extend(data)
page += 1
if len(data) < 1000:
break
return assets
def delete_asset(asset_id, path):
resp = requests.delete(
f"{BASE_URL}/assets",
headers={"x-api-key": API_KEY, "Content-Type": "application/json"},
json={"ids": [asset_id], "force": True}
)
if resp.status_code == 204:
print(f"DELETED: {path}")
return True
else:
print(f"FAILED: {path} - {resp.status_code}")
return False
print("Fetching all assets...")
assets = get_all_assets()
print(f"Found {len(assets)} assets")
# Build path -> id map
path_to_id = {a["originalPath"]: a["id"] for a in assets}
deleted = 0
for path in CORRUPTED_FILES:
if path in path_to_id:
if delete_asset(path_to_id[path], path):
deleted += 1
else:
print(f"NOT FOUND: {path}")
print(f"\nTotal deleted: {deleted}")