#!/usr/bin/env python3 """make_content.py OUTDIR — the bench's test content. Generated, or public domain. No personal data. photos/ 140 generated 4000x3000 JPEGs (gradients + noise, phone-photo sized) + up to 60 CC0 portrait PAINTINGS from The Met's Open Access API (isPublicDomain=true), resized to 4000 px — faces for Immich's face detection, of people long dead. pdfs/ 20 image-only A4 "scans" at 300 dpi (rendered text, slight skew + noise) — OCR has work video/ 3 generated 1080p H.264 clips (testsrc2 + tone), 3 min each upload/ 50 x 10 MiB random files = 500 MiB books/ 20 minimal EPUB 3 books (generated text) roms/ a few generated dummy files in platform folders (RomM's scan only; no real ROMs) Run with `python3 -I`. Needs Pillow and ffmpeg (both present on DooPlex). """ import io, json, os, random, subprocess, sys, urllib.request, zipfile from PIL import Image, ImageDraw, ImageFilter, ImageFont OUT = sys.argv[1] rnd = random.Random(20261013) def mk(p): os.makedirs(os.path.join(OUT, p), exist_ok=True) return os.path.join(OUT, p) def photos(): d = mk("photos") for i in range(140): w, h = 4000, 3000 c1 = tuple(rnd.randrange(256) for _ in range(3)); c2 = tuple(rnd.randrange(256) for _ in range(3)) g = Image.linear_gradient("L").resize((w, h)) im = Image.composite(Image.new("RGB", (w, h), c1), Image.new("RGB", (w, h), c2), g) dr = ImageDraw.Draw(im) for _ in range(40): x, y = rnd.randrange(w), rnd.randrange(h); r = rnd.randrange(50, 600) dr.ellipse([x - r, y - r, x + r, y + r], fill=tuple(rnd.randrange(256) for _ in range(3))) noise = Image.effect_noise((w, h), 40).convert("RGB") im = Image.blend(im, noise, 0.25) im.save(os.path.join(d, f"gen-{i:03d}.jpg"), quality=92) # CC0 portrait paintings (The Met, European Paintings, public domain) try: q = "https://collectionapi.metmuseum.org/public/collection/v1.1/search?departmentId=11&hasImages=true&q=portrait&limit=150&offset=0" ids = json.load(urllib.request.urlopen(q, timeout=60))["objectIDs"] except Exception as e: print("met search failed:", e); ids = [] got, credits = 0, [] for oid in ids: if got >= 60: break try: o = json.load(urllib.request.urlopen(f"https://collectionapi.metmuseum.org/public/collection/v1/objects/{oid}", timeout=60)) if not o.get("isPublicDomain") or not o.get("primaryImage"): continue raw = urllib.request.urlopen(o["primaryImage"], timeout=120).read() im = Image.open(io.BytesIO(raw)).convert("RGB") im.thumbnail((4000, 4000)) im.save(os.path.join(d, f"met-{oid}.jpg"), quality=92) credits.append(f"{oid}\t{o.get('title','')[:80]}\t{o.get('objectURL','')}\tCC0") got += 1 except Exception as e: print("skip", oid, e) open(os.path.join(OUT, "photos-credits.tsv"), "w").write("\n".join(credits) + "\n") print("photos:", 140 + got, "of which paintings:", got) WORDS = ("alma korte szilva haz kert konyv level szamla ugyfel datum osszeg fizetes hatarido " "szerzodes biztositas orvos recept iskola munka berlet viz gaz aram adoszam").split() def text(n): return " ".join(rnd.choice(WORDS) for _ in range(n)) def pdfs(): d = mk("pdfs") try: font = ImageFont.truetype("/usr/share/fonts/truetype/dejavu/DejaVuSerif.ttf", 38) except OSError: font = ImageFont.load_default() for i in range(20): im = Image.new("L", (2480, 3508), 245) dr = ImageDraw.Draw(im) y = 200 dr.text((200, y), f"Bench document {i + 1:02d} - 2026-10-13", font=font, fill=20); y += 120 while y < 3300: dr.text((200, y), text(9), font=font, fill=30); y += 62 im = im.rotate(rnd.uniform(-1.2, 1.2), fillcolor=235).filter(ImageFilter.GaussianBlur(0.6)) im = Image.blend(im, Image.effect_noise(im.size, 25).convert("L"), 0.08) im.save(os.path.join(d, f"scan-{i + 1:02d}.pdf"), resolution=300) print("pdfs: 20") def video(): d = mk("video/Bench Films") for i in range(3): sub = os.path.join(d, f"Bench Film {i + 1} (2026)") os.makedirs(sub, exist_ok=True) subprocess.run(["ffmpeg", "-loglevel", "error", "-y", "-f", "lavfi", "-i", f"testsrc2=size=1920x1080:rate=30", "-f", "lavfi", "-i", f"sine=frequency={440 + 110 * i}:sample_rate=48000", "-t", "180", "-c:v", "libx264", "-preset", "veryfast", "-b:v", "8M", "-pix_fmt", "yuv420p", "-c:a", "aac", "-b:a", "192k", os.path.join(sub, f"Bench Film {i + 1} (2026).mkv")], check=True) print("video: 3 x 180 s 1080p") def upload(): d = mk("upload") for i in range(50): with open(os.path.join(d, f"blob-{i:02d}.bin"), "wb") as f: f.write(os.urandom(10 * 1024 * 1024)) print("upload: 500 MiB") def books(): d = mk("books") for i in range(20): p = os.path.join(d, f"bench-book-{i + 1:02d}.epub") with zipfile.ZipFile(p, "w") as z: z.writestr(zipfile.ZipInfo("mimetype"), "application/epub+zip", compress_type=zipfile.ZIP_STORED) z.writestr("META-INF/container.xml", '' '') z.writestr("OEBPS/content.opf", f'' f'bench-{i}' f'Bench Book {i + 1}Felhom Benchhu' f'2026-10-13T00:00:00Z' f'' f'' f'') z.writestr("OEBPS/nav.xhtml", '' '') z.writestr("OEBPS/c.xhtml", '' + "".join(f"

{text(80)}

" for _ in range(200)) + "") print("books: 20") def roms(): for plat, ext in (("nes", "nes"), ("snes", "sfc"), ("gb", "gb")): d = mk(f"roms/{plat}") for i in range(5): with open(os.path.join(d, f"Bench Game {i + 1}.{ext}"), "wb") as f: f.write(os.urandom(256 * 1024)) print("roms: 15 dummy files") if __name__ == "__main__": for fn in (pdfs, books, roms, upload, video, photos): fn()