feat: portfolio-led redesign with Shootings umbrella, original logo and motion layer
This commit is contained in:
@@ -7,6 +7,10 @@ Sources
|
||||
We pull the pre-derived `web` variant (long edge 2560 px) instead of the
|
||||
20-60 MB camera originals. Only assets we are allowed to publish as the
|
||||
rights holder are listed in src/images.json.
|
||||
* Own portfolio files of the existing site (www.dennyschulz.de/legacy/<file>).
|
||||
These carry the concert, band and free-work photographs that are missing from
|
||||
the pool; they are fetched as-is and downscaled by the build. Also used for
|
||||
the operator's original logo (www.dennyschulz.de/logo.png).
|
||||
* Google Fonts (open licensed, OFL) - downloaded once, then self-hosted.
|
||||
Licences are written to docs/.
|
||||
* YouTube poster frame for the own music video "Thjodroerir - Skogamor".
|
||||
@@ -26,10 +30,13 @@ from pathlib import Path
|
||||
ROOT = Path(__file__).resolve().parents[1]
|
||||
SRC = ROOT / "assets-src"
|
||||
IMG_OUT = SRC / "images"
|
||||
BRAND_OUT = SRC / "brand"
|
||||
FONT_OUT = SRC / "fonts"
|
||||
TTF_OUT = SRC / "fonts-ttf"
|
||||
DOCS = ROOT / "docs"
|
||||
|
||||
LOGO_URL = "https://www.dennyschulz.de/logo.png"
|
||||
|
||||
UA = "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0 Safari/537.36"
|
||||
# Old Safari advertises truetype-only support, so Google serves real .ttf
|
||||
# files (the MSIE 6 UA returns EOT, which PIL/FreeType cannot read).
|
||||
@@ -81,22 +88,26 @@ def try_fetch(url: str, *, ua: str = UA) -> bytes | None:
|
||||
def fetch_images() -> None:
|
||||
manifest = json.loads((ROOT / "src" / "images.json").read_text(encoding="utf-8"))
|
||||
base = manifest["pool_base"].rstrip("/")
|
||||
legacy_base = manifest["legacy_base"].rstrip("/")
|
||||
suffixes = (".webp", ".src", ".jpg", ".jpeg", ".png")
|
||||
ok = skipped = 0
|
||||
for entry in manifest["images"]:
|
||||
slug, raw = entry["slug"], entry["raw"]
|
||||
rel = raw.replace("\\", "/")
|
||||
target = IMG_OUT / f"{slug}.webp"
|
||||
source = IMG_OUT / f"{slug}.src"
|
||||
if target.exists() or source.exists():
|
||||
if any((IMG_OUT / f"{slug}{suffix}").exists() for suffix in suffixes):
|
||||
skipped += 1
|
||||
continue
|
||||
data = try_fetch(f"{base}/_derived/web/{rel}.webp")
|
||||
if data is None:
|
||||
print(f" [!] web variant missing, falling back to original: {rel}")
|
||||
data = fetch(f"{base}/{rel}")
|
||||
source.write_bytes(data)
|
||||
if entry.get("source") == "legacy":
|
||||
data = fetch(f"{legacy_base}/{rel}")
|
||||
(IMG_OUT / f"{slug}.jpg").write_bytes(data)
|
||||
else:
|
||||
target.write_bytes(data)
|
||||
data = try_fetch(f"{base}/_derived/web/{rel}.webp")
|
||||
if data is None:
|
||||
print(f" [!] web variant missing, falling back to original: {rel}")
|
||||
data = fetch(f"{base}/{rel}")
|
||||
(IMG_OUT / f"{slug}.src").write_bytes(data)
|
||||
else:
|
||||
(IMG_OUT / f"{slug}.webp").write_bytes(data)
|
||||
ok += 1
|
||||
print(f" [ok] {slug} ({len(data) / 1024:.0f} KiB)")
|
||||
print(f"images: {ok} fetched, {skipped} already present")
|
||||
@@ -110,6 +121,18 @@ def fetch_images() -> None:
|
||||
print(f" [ok] video poster ({len(data) / 1024:.0f} KiB)")
|
||||
|
||||
|
||||
def fetch_brand() -> None:
|
||||
"""The operator's original logo (used for the brand mark and all icons)."""
|
||||
BRAND_OUT.mkdir(parents=True, exist_ok=True)
|
||||
target = BRAND_OUT / "logo.png"
|
||||
if target.exists():
|
||||
print(f"brand: logo already present ({target.stat().st_size / 1024:.0f} KiB)")
|
||||
return
|
||||
data = fetch(LOGO_URL)
|
||||
target.write_bytes(data)
|
||||
print(f" [ok] logo ({len(data) / 1024:.0f} KiB)")
|
||||
|
||||
|
||||
def fetch_fonts() -> None:
|
||||
FONT_OUT.mkdir(parents=True, exist_ok=True)
|
||||
for family, spec in FAMILIES.items():
|
||||
@@ -160,8 +183,10 @@ def fetch_fonts() -> None:
|
||||
|
||||
|
||||
def main() -> int:
|
||||
for path in (IMG_OUT, FONT_OUT, DOCS):
|
||||
for path in (IMG_OUT, BRAND_OUT, FONT_OUT, DOCS):
|
||||
path.mkdir(parents=True, exist_ok=True)
|
||||
print("== brand ==")
|
||||
fetch_brand()
|
||||
print("== images ==")
|
||||
fetch_images()
|
||||
print("== fonts ==")
|
||||
|
||||
Reference in New Issue
Block a user