#!/usr/bin/env python3 """Grid view of Jan 28, 2024 images for quick date assignment.""" from http.server import HTTPServer, BaseHTTPRequestHandler import os import json import subprocess import urllib.parse LIBRARY = "/tank/immich/library/library/admin" JAN2024 = f"{LIBRARY}/2024/01" API_KEY = "GsWQUTR6EXlkKp1M82jDJ3KmzhM0fMAbbIbfHDyI" API_URL = "http://localhost:2283/api" def get_images_from_db(limit=500): """Get images from Immich database.""" result = subprocess.run([ "docker", "exec", "immich_postgres", "psql", "-U", "postgres", "-d", "immich", "-t", "-A", "-F", "|", "-c", f"""SELECT id, "originalFileName", "originalPath" FROM asset WHERE DATE("fileCreatedAt") = '2024-01-28' AND "deletedAt" IS NULL AND "type" = 'IMAGE' ORDER BY "originalFileName" LIMIT {limit};""" ], capture_output=True, text=True) images = [] for line in result.stdout.strip().split('\n'): if '|' in line: parts = line.split('|') if len(parts) >= 3: images.append({ 'id': parts[0], 'filename': parts[1], 'path': parts[2].replace('/data/library/admin/', '') }) return images def generate_html(limit=20): images = get_images_from_db(limit) cards = [] for img in images: cards.append(f'''
{img['filename']}
{img['id']}
''') return f''' Jan 28, 2024 - Grid View

Jan 28, 2024 Images ({len(images)} shown)

Click images to select. Selected IDs appear below for copying.

{''.join(cards)}
0 selected
Click images to select, then copy IDs or filenames
''' class Handler(BaseHTTPRequestHandler): def do_GET(self): path = urllib.parse.unquote(self.path) if path == '/' or path.startswith('/?'): # Parse limit from query string limit = 500 if '?' in path: params = urllib.parse.parse_qs(path.split('?')[1]) limit = int(params.get('limit', [500])[0]) html = generate_html(limit) self.send_response(200) self.send_header('Content-type', 'text/html; charset=utf-8') self.end_headers() self.wfile.write(html.encode()) elif path.startswith('/image/'): img_path = LIBRARY + "/" + path[7:] if os.path.exists(img_path): self.send_response(200) ext = img_path.lower().split('.')[-1] ctype = 'image/jpeg' if ext in ['jpg', 'jpeg'] else f'image/{ext}' self.send_header('Content-type', ctype) self.end_headers() with open(img_path, 'rb') as f: self.wfile.write(f.read()) else: self.send_response(404) self.end_headers() else: self.send_response(404) self.end_headers() def log_message(self, format, *args): pass if __name__ == '__main__': port = 5001 print(f"Grid view at http://localhost:{port}") print(f"Add ?limit=100 for more images") HTTPServer(('0.0.0.0', port), Handler).serve_forever()