100 lines
4.1 KiB
Python
100 lines
4.1 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 files: (filename, corrupted path)
|
|
CORRUPTED_FILES = [
|
|
("2010-04-14_07-38-01_290_Heerenveen+1.mp4", "/data/library/admin/2010/04/2010-04-14_07-38-01_290_Heerenveen+1.mp4"),
|
|
("IMG_0259+1.mov", "/data/library/admin/2012/01/IMG_0259+1.mov"),
|
|
("IMG_0262+1.mov", "/data/library/admin/2012/01/IMG_0262+1.mov"),
|
|
("IMG_0169+1.mov", "/data/library/admin/2010/08/IMG_0169+1.mov"),
|
|
("MVI_0342+1.mov", "/data/library/admin/2012/08/MVI_0342+1.mov"),
|
|
("MVI_0496+1.mov", "/data/library/admin/2012/08/MVI_0496+1.mov"),
|
|
("MVI_0462+1.mov", "/data/library/admin/2012/08/MVI_0462+1.mov"),
|
|
("MVI_0452+1.mov", "/data/library/admin/2012/08/MVI_0452+1.mov"),
|
|
("MVI_0448+1.mov", "/data/library/admin/2012/08/MVI_0448+1.mov"),
|
|
("MVI_0463+1.mov", "/data/library/admin/2012/08/MVI_0463+1.mov"),
|
|
("MVI_0468+1.mov", "/data/library/admin/2012/08/MVI_0468+1.mov"),
|
|
("MVI_0534+1.mov", "/data/library/admin/2012/08/MVI_0534+1.mov"),
|
|
("MVI_0446+1.mov", "/data/library/admin/2012/08/MVI_0446+1.mov"),
|
|
("MVI_0466+1.mov", "/data/library/admin/2012/08/MVI_0466+1.mov"),
|
|
("MVI_0335+1.mov", "/data/library/admin/2012/08/MVI_0335+1.mov"),
|
|
("MVI_0495+1.mov", "/data/library/admin/2012/08/MVI_0495+1.mov"),
|
|
("MVI_0531+1.mov", "/data/library/admin/2012/08/MVI_0531+1.mov"),
|
|
("MVI_0404+1.mov", "/data/library/admin/2012/08/MVI_0404+1.mov"),
|
|
("MVI_0467+1.mov", "/data/library/admin/2012/08/MVI_0467+1.mov"),
|
|
("MVI_0454+1.mov", "/data/library/admin/2012/08/MVI_0454+1.mov"),
|
|
("MVI_0389+1.mov", "/data/library/admin/2012/08/MVI_0389+1.mov"),
|
|
("MVI_0469+1.mov", "/data/library/admin/2012/08/MVI_0469+1.mov"),
|
|
("IMG_0147+1.mov", "/data/library/admin/2011/06/IMG_0147+1.mov"),
|
|
("MVI_0465+1.mov", "/data/library/admin/2012/08/MVI_0465+1.mov"),
|
|
("MVI_0444+1.mov", "/data/library/admin/2012/08/MVI_0444+1.mov"),
|
|
("MVI_0470+1.mov", "/data/library/admin/2012/08/MVI_0470+1.mov"),
|
|
("MVI_0440+1.mov", "/data/library/admin/2012/08/MVI_0440+1.mov"),
|
|
("2010-04-04_16-06-22_374_Noordoostpolder+1.mp4", "/data/library/admin/2010/04/2010-04-04_16-06-22_374_Noordoostpolder+1.mp4"),
|
|
("MVI_0060+1.mov", "/data/library/admin/2012/06/MVI_0060+1.mov"),
|
|
("IMG_0582+1.mov", "/data/library/admin/2012/11/IMG_0582+1.mov"),
|
|
]
|
|
|
|
def search_file(filename):
|
|
resp = requests.post(
|
|
f"{BASE_URL}/search/metadata",
|
|
headers={"x-api-key": API_KEY, "Content-Type": "application/json"},
|
|
json={"originalFileName": filename}
|
|
)
|
|
if resp.status_code == 200:
|
|
return resp.json().get("assets", {}).get("items", [])
|
|
return []
|
|
|
|
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
|
|
|
|
deleted = 0
|
|
not_found = 0
|
|
|
|
for filename, expected_path in CORRUPTED_FILES:
|
|
# Search for this filename
|
|
# The filename in Immich might not have +1 in the originalFileName
|
|
# Try searching without the +1
|
|
base_name = filename.replace("+1", "")
|
|
assets = search_file(base_name)
|
|
|
|
found = False
|
|
for asset in assets:
|
|
if asset["originalPath"] == expected_path:
|
|
if delete_asset(asset["id"], expected_path):
|
|
deleted += 1
|
|
found = True
|
|
break
|
|
|
|
if not found:
|
|
# Try with +1 in filename
|
|
assets = search_file(filename)
|
|
for asset in assets:
|
|
if asset["originalPath"] == expected_path:
|
|
if delete_asset(asset["id"], expected_path):
|
|
deleted += 1
|
|
found = True
|
|
break
|
|
|
|
if not found:
|
|
print(f"NOT FOUND: {filename} at {expected_path}")
|
|
not_found += 1
|
|
|
|
print(f"\nTotal deleted: {deleted}")
|
|
print(f"Not found: {not_found}")
|