Album: Download im Profil — zwei ZIPs (DE+EN) mit Cover, ID3-Tags, Liner Notes (v1302)
- Profil-Karte "Ban Yaro — das Album" in settings.js mit Cover-Thumbnail +
zwei Download-Buttons (Deutsch/English), rein deklarativ (CSP-safe)
- /downloads StaticFiles-Mount in main.py (makedirs-Schutz); ZIPs matchen
keine SW-Cache-Regel -> fluten den Cache nicht
- backend/static/downloads/ban-yaro-album-{de,en}.zip: je 7 MP3s mit ID3-Tags
+ eingebettetem Cover, cover.jpg, LIESMICH.txt/README.txt (Tracklist + Lizenz)
- Cover aus Fruehling-Playdate-Foto (quadr. Crop + Wortmarke), DE/EN-Variante;
textfreies album-thumb.jpg fuer die Karte
- Reproduzierbar: make album (tools/album-build/build.sh + Liner-Notes)
- LIVE auf Prod + Staging v1302
This commit is contained in:
parent
aea489aa5a
commit
1a03cab5dd
15 changed files with 213 additions and 18 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
|
@ -21,3 +21,6 @@ tiles/build/
|
|||
*.mbtiles
|
||||
tiles/build.log
|
||||
tiles/.DS_Store
|
||||
|
||||
# Album-Build: Zwischendateien (ZIPs + Thumbnail werden committet)
|
||||
tools/album-build/dist/
|
||||
|
|
|
|||
9
Makefile
9
Makefile
|
|
@ -28,7 +28,7 @@ TAR_EXCLUDE := --exclude='.git' \
|
|||
--exclude='./.DS_Store'
|
||||
|
||||
.PHONY: help deploy deploy-clean staging release sync push restart build stop status \
|
||||
logs logs-f shell db dev clean-cache check-ssh reports bump test tiles tiles-deploy
|
||||
logs logs-f shell db dev clean-cache check-ssh reports bump test tiles tiles-deploy album
|
||||
|
||||
# ----------------------------------------------------------
|
||||
# SSH-Prüfung — Abhängigkeit aller DS-Befehle
|
||||
|
|
@ -343,6 +343,13 @@ bump:
|
|||
sed -i.bak -E "s/\?v=[0-9]+/?v=$$NEW/g" backend/static/landing.html && rm -f backend/static/landing.html.bak; \
|
||||
echo " ✓ APP_VER $$CUR → $$NEW (VERSION, sw.js, app.js, index.html, landing.html aktualisiert)"
|
||||
|
||||
# ----------------------------------------------------------
|
||||
# ALBUM — die zwei Download-ZIPs (DE+EN) neu bauen (Cover, ID3-Tags, Liner Notes)
|
||||
# Nur nötig, wenn sich Songs/Cover/Beschreibung ändern. Braucht ImageMagick + ffmpeg.
|
||||
# ----------------------------------------------------------
|
||||
album:
|
||||
@bash tools/album-build/build.sh
|
||||
|
||||
# ----------------------------------------------------------
|
||||
# TEST — Smoke-Tests gegen isolierte Test-DB (kein Docker, kein DS)
|
||||
# ----------------------------------------------------------
|
||||
|
|
|
|||
2
VERSION
2
VERSION
|
|
@ -1 +1 @@
|
|||
1301
|
||||
1302
|
||||
|
|
@ -375,6 +375,8 @@ app.mount("/js", StaticFiles(directory=f"{STATIC_DIR}/js"), name="js")
|
|||
app.mount("/icons", StaticFiles(directory=f"{STATIC_DIR}/icons"), name="icons")
|
||||
app.mount("/img", StaticFiles(directory=f"{STATIC_DIR}/img"), name="img")
|
||||
app.mount("/sounds", StaticFiles(directory=f"{STATIC_DIR}/sounds"), name="sounds") # Yaro-Navi-Sounds
|
||||
os.makedirs(f"{STATIC_DIR}/downloads", exist_ok=True) # Album-ZIPs (vom Build-Skript erzeugt)
|
||||
app.mount("/downloads", StaticFiles(directory=f"{STATIC_DIR}/downloads"), name="downloads")
|
||||
|
||||
# Selbst-gehostete Vektor-Tiles (.pmtiles) — liegen im data-Volume, NICHT im Image.
|
||||
# WICHTIG: Starlettes StaticFiles/FileResponse liefert hinter unserer BaseHTTPMiddleware
|
||||
|
|
|
|||
BIN
backend/static/downloads/ban-yaro-album-de.zip
Normal file
BIN
backend/static/downloads/ban-yaro-album-de.zip
Normal file
Binary file not shown.
BIN
backend/static/downloads/ban-yaro-album-en.zip
Normal file
BIN
backend/static/downloads/ban-yaro-album-en.zip
Normal file
Binary file not shown.
BIN
backend/static/img/banyaro/album-thumb.jpg
Normal file
BIN
backend/static/img/banyaro/album-thumb.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 175 KiB |
|
|
@ -86,14 +86,14 @@
|
|||
<title>Ban Yaro</title>
|
||||
|
||||
<!-- Theme + theme-color Statusleiste vor CSS setzen -->
|
||||
<script src="/js/boot-early.js?v=1301"></script>
|
||||
<script src="/js/boot-early.js?v=1302"></script>
|
||||
|
||||
<!-- CSS: Reihenfolge ist wichtig — ?v= zwingt Browser zur Neuladung -->
|
||||
<link rel="stylesheet" href="/css/design-system.css?v=1301">
|
||||
<link rel="stylesheet" href="/css/layout.css?v=1301">
|
||||
<link rel="stylesheet" href="/css/components.css?v=1301">
|
||||
<link rel="stylesheet" href="/css/utilities.css?v=1301">
|
||||
<link rel="stylesheet" href="/css/lists.css?v=1301">
|
||||
<link rel="stylesheet" href="/css/design-system.css?v=1302">
|
||||
<link rel="stylesheet" href="/css/layout.css?v=1302">
|
||||
<link rel="stylesheet" href="/css/components.css?v=1302">
|
||||
<link rel="stylesheet" href="/css/utilities.css?v=1302">
|
||||
<link rel="stylesheet" href="/css/lists.css?v=1302">
|
||||
</head>
|
||||
<body>
|
||||
|
||||
|
|
@ -624,12 +624,12 @@
|
|||
<div id="modal-container"></div>
|
||||
|
||||
<!-- JS: Reihenfolge ist wichtig — erst Basis, dann Features -->
|
||||
<script src="/js/api.js?v=1301"></script>
|
||||
<script src="/js/ui.js?v=1301"></script>
|
||||
<script src="/js/app.js?v=1301"></script>
|
||||
<script src="/js/worlds.js?v=1301"></script>
|
||||
<script src="/js/offline-indicator.js?v=1301"></script>
|
||||
<script src="/js/contact-form.js?v=1301"></script>
|
||||
<script src="/js/api.js?v=1302"></script>
|
||||
<script src="/js/ui.js?v=1302"></script>
|
||||
<script src="/js/app.js?v=1302"></script>
|
||||
<script src="/js/worlds.js?v=1302"></script>
|
||||
<script src="/js/offline-indicator.js?v=1302"></script>
|
||||
<script src="/js/contact-form.js?v=1302"></script>
|
||||
|
||||
<!-- Feature-Seiten werden lazy geladen -->
|
||||
|
||||
|
|
@ -639,7 +639,7 @@
|
|||
|
||||
|
||||
<!-- Boot: Offline-Banner + SW-Registration (extrahiert für CSP) -->
|
||||
<script src="/js/boot.js?v=1301"></script>
|
||||
<script src="/js/boot.js?v=1302"></script>
|
||||
|
||||
|
||||
</body>
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
Router, State-Management, Navigation, Initialisierung.
|
||||
============================================================ */
|
||||
|
||||
const APP_VER = '1301'; // ← bei jedem Deploy mit Frontend-Änderungen erhöhen
|
||||
const APP_VER = '1302'; // ← bei jedem Deploy mit Frontend-Änderungen erhöhen
|
||||
const APP_VERSION = '1.6.0'; // ← semantische Version, wird bei make release gesetzt
|
||||
window.APP_VER = APP_VER; // global verfügbar für andere Module (z.B. offline-indicator)
|
||||
window.APP_VERSION = APP_VERSION;
|
||||
|
|
|
|||
|
|
@ -877,6 +877,35 @@ window.Page_settings = (() => {
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Album herunterladen -->
|
||||
<div class="card mb-4">
|
||||
<div class="by-card-section-header">Ban Yaro — das Album</div>
|
||||
<div style="padding:var(--space-4);display:flex;gap:var(--space-4);align-items:center">
|
||||
<img src="/img/banyaro/album-thumb.jpg" alt="Ban Yaro — Album-Cover"
|
||||
width="84" height="84" loading="lazy"
|
||||
style="width:84px;height:84px;border-radius:var(--radius-md);object-fit:cover;flex-shrink:0">
|
||||
<div style="min-width:0">
|
||||
<div style="font-weight:600">7 Songs zum Behalten 🎸</div>
|
||||
<div class="text-xs-secondary" style="margin-top:2px">
|
||||
Das ganze Album als Download — auf Deutsch oder Englisch.
|
||||
Behalten & teilen ausdrücklich erwünscht.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div style="padding:0 var(--space-4) var(--space-4);display:flex;gap:var(--space-2);flex-wrap:wrap">
|
||||
<a class="btn btn-primary" href="/downloads/ban-yaro-album-de.zip"
|
||||
download="Ban Yaro - Das Album.zip"
|
||||
style="flex:1;min-width:140px;justify-content:center;text-decoration:none">
|
||||
${UI.icon('download-simple')} Deutsch · 33 MB
|
||||
</a>
|
||||
<a class="btn btn-secondary" href="/downloads/ban-yaro-album-en.zip"
|
||||
download="Ban Yaro - The Album.zip"
|
||||
style="flex:1;min-width:140px;justify-content:center;text-decoration:none">
|
||||
${UI.icon('download-simple')} English · 36 MB
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- App empfehlen -->
|
||||
<div class="card" style="margin-bottom:var(--space-5)" id="referral-card">
|
||||
<div style="padding:var(--space-4);border-bottom:1px solid var(--c-border)">
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="color-scheme" content="light dark">
|
||||
<script src="/js/landing-init.js?v=1301"></script>
|
||||
<script src="/js/landing-init.js?v=1302"></script>
|
||||
<title>Ban Yaro — Die Hunde-App für Deutschland, Österreich & Schweiz</title>
|
||||
<meta name="description" content="Ban Yaro: Die kostenlose All-in-One Hunde-App für DACH. Tagebuch, Giftköder-Alarm, Training mit KI, Forum, Wurfbörse, Stammbaum, Inzucht-Check — DSGVO-konform, offline-fähig, direkt im Browser oder als native iPhone-App (Ban Yaro Go).">
|
||||
<meta name="keywords" content="Hunde App, Hunde Community, Wurfbörse, Züchter, Welpen kaufen, Stammbaum Hund, Inzuchtkoeffizient, Hundezucht, Impfpass Hund, Giftköder Alarm, Gassi Community, Hundetraining App, Hunde Forum, Hunde KI, Hundefilm Datenbank, Welpen Marktplatz">
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
============================================================ */
|
||||
|
||||
// ← EINZIGE Stelle für die Version — STATIC_ASSETS und CACHE_VERSION leiten sich ab
|
||||
const VER = '1301';
|
||||
const VER = '1302';
|
||||
const CACHE_VERSION = `by-v${VER}`;
|
||||
const CACHE_STATIC = `${CACHE_VERSION}-static`;
|
||||
const CACHE_TILES = 'ban-yaro-tiles-v1'; // bleibt über SW-Updates erhalten
|
||||
|
|
|
|||
86
tools/album-build/build.sh
Executable file
86
tools/album-build/build.sh
Executable file
|
|
@ -0,0 +1,86 @@
|
|||
#!/usr/bin/env bash
|
||||
# Baut die zwei Album-Downloads (DE + EN) reproduzierbar:
|
||||
# Cover (Foto quadr. + Wortmarke) → ID3-Tags + eingebettetes Cover → ZIP mit Liner Notes.
|
||||
# Quelle: die committeten MP3s in backend/static/sounds/ + ein Hi-Res-Foto.
|
||||
# Ausgabe: backend/static/downloads/ban-yaro-album-{de,en}.zip + img/banyaro/album-thumb.jpg
|
||||
# Benötigt: ImageMagick (magick), ffmpeg, zip. Aufruf: make album (oder bash tools/album-build/build.sh)
|
||||
set -euo pipefail
|
||||
|
||||
ROOT="$(cd "$(dirname "$0")/../.." && pwd)"
|
||||
SND="$ROOT/backend/static/sounds"
|
||||
PHOTO="$ROOT/backend/static/img/banyaro/hires/banyaro_fruehling_playdate_hires.jpg"
|
||||
FONT="/System/Library/Fonts/Supplemental/Arial Bold.ttf"
|
||||
BUILD="$ROOT/tools/album-build"
|
||||
DIST="$BUILD/dist"
|
||||
DL="$ROOT/backend/static/downloads"
|
||||
IMG="$ROOT/backend/static/img/banyaro"
|
||||
|
||||
rm -rf "$DIST"; mkdir -p "$DIST" "$DL" "$IMG"
|
||||
|
||||
# --- 1) Cover (quadratischer Crop auf die Hunde + Verlauf unten + Wortmarke) ---
|
||||
make_cover() { # $1=subtitle $2=outfile
|
||||
magick "$PHOTO" -auto-orient -crop 2648x2648+551+0 +repage -resize 2000x2000 \
|
||||
\( -size 2000x950 gradient:none-'rgba(0,0,0,0.80)' \) -gravity south -compose over -composite \
|
||||
-gravity south -font "$FONT" -kerning 10 \
|
||||
-fill 'rgba(0,0,0,0.55)' -pointsize 168 -annotate +4+254 "BAN YARO" \
|
||||
-fill white -pointsize 168 -annotate +0+250 "BAN YARO" \
|
||||
-kerning 7 -fill 'rgba(255,255,255,0.92)' -pointsize 60 -annotate +0+160 "$1" \
|
||||
-quality 90 "$2"
|
||||
}
|
||||
make_cover "DAS ALBUM · 7 SONGS" "$DIST/cover-de.jpg"
|
||||
make_cover "THE ALBUM · 7 SONGS" "$DIST/cover-en.jpg"
|
||||
# Eingebettetes Albumart kleiner halten (sonst blähen sich die MP3s auf)
|
||||
magick "$DIST/cover-de.jpg" -resize 800x800 -quality 85 "$DIST/art-de.jpg"
|
||||
magick "$DIST/cover-en.jpg" -resize 800x800 -quality 85 "$DIST/art-en.jpg"
|
||||
# Neutrales Thumbnail (ohne Text) für die Profil-Karte — der Titel steht dort im HTML
|
||||
magick "$PHOTO" -auto-orient -crop 2648x2648+551+0 +repage -resize 600x600 -quality 85 "$IMG/album-thumb.jpg"
|
||||
|
||||
# --- 2)+3) pro Sprache: taggen + zippen ---
|
||||
# Zeilenformat: "quelldatei(ohne .mp3)|Titel|Untertitel"
|
||||
DE_TRACKS=(
|
||||
"ban-yaro-blues|Ban Yaro Blues|Die Hymne"
|
||||
"ban-yaro-mobil|Ban Yaro Mobil|Erste Fahrt im Anhänger"
|
||||
"amy|Amy|Eine Liebesromanze"
|
||||
"beim-friseur|Beim Friseur|Halbes Fell, Energie pur"
|
||||
"leckerli-paradies|Leckerli-Paradies|Voller Napf, volles Glück"
|
||||
"platsch|Platsch!|Ab ins kühle Nass"
|
||||
"bester-freund|Bester Freund|Du und ich"
|
||||
)
|
||||
EN_TRACKS=(
|
||||
"ban-yaro-blues-en|Ban Yaro Blues|The anthem"
|
||||
"ban-yaro-mobil-en|Ban Yaro Mobile|First ride in the trailer"
|
||||
"amy-en|Amy|A love duet"
|
||||
"at-the-groomers-en|At the Groomer's|Half the fur, all the energy"
|
||||
"treat-paradise-en|Treat Paradise|Full bowl, full heart"
|
||||
"splash-en|Splash!|Into the cool water"
|
||||
"best-friend-en|Best Friend|You and me"
|
||||
)
|
||||
|
||||
zip_album() { # $1=lang $2=AlbumName(ID3, Em-Dash ok) $3=Ordner(ASCII) $4=art $5=liner shift 5; rest=tracks
|
||||
local lang="$1" album="$2" fname="$3" art="$4" liner="$5"; shift 5
|
||||
local folder="$DIST/$fname"; rm -rf "$folder"; mkdir -p "$folder"
|
||||
if [ "$lang" = "de" ]; then cp "$liner" "$folder/LIESMICH.txt"; else cp "$liner" "$folder/README.txt"; fi
|
||||
cp "$art" "$folder/cover.jpg"
|
||||
local n=0 line src title sub nn
|
||||
for line in "$@"; do
|
||||
n=$((n+1)); nn=$(printf "%02d" "$n")
|
||||
IFS='|' read -r src title sub <<<"$line"
|
||||
ffmpeg -y -loglevel error -i "$SND/$src.mp3" -i "$art" \
|
||||
-map 0:a -map 1:v -c copy -id3v2_version 3 \
|
||||
-metadata title="$title" -metadata artist="Ban Yaro" \
|
||||
-metadata album="$album" -metadata album_artist="Ban Yaro" \
|
||||
-metadata track="$n/7" -metadata date="2026" -metadata genre="Blues" \
|
||||
-metadata comment="$sub" -disposition:v:0 attached_pic \
|
||||
"$folder/$nn $title.mp3"
|
||||
done
|
||||
( cd "$DIST" && rm -f "$DL/ban-yaro-album-$lang.zip" && zip -r -X -q "$DL/ban-yaro-album-$lang.zip" "$fname" )
|
||||
echo " ✓ $fname → ban-yaro-album-$lang.zip ($(du -h "$DL/ban-yaro-album-$lang.zip" | cut -f1))"
|
||||
}
|
||||
|
||||
# LIESMICH.txt für DE, README.txt für EN
|
||||
cp "$BUILD/liner-de.txt" "$DIST/_liner-de.txt"
|
||||
cp "$BUILD/liner-en.txt" "$DIST/_liner-en.txt"
|
||||
zip_album "de" "Ban Yaro — Das Album" "Ban Yaro - Das Album" "$DIST/art-de.jpg" "$DIST/_liner-de.txt" "${DE_TRACKS[@]}"
|
||||
zip_album "en" "Ban Yaro — The Album" "Ban Yaro - The Album" "$DIST/art-en.jpg" "$DIST/_liner-en.txt" "${EN_TRACKS[@]}"
|
||||
|
||||
echo "Fertig. Downloads in backend/static/downloads/, Thumbnail in img/banyaro/album-thumb.jpg"
|
||||
34
tools/album-build/liner-de.txt
Normal file
34
tools/album-build/liner-de.txt
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
==================================================
|
||||
BAN YARO — DAS ALBUM
|
||||
7 Songs
|
||||
==================================================
|
||||
|
||||
Sieben Lieder über einen Hund namens Ban Yaro:
|
||||
übers Gassigehen bei jedem Wetter, die erste Fahrt
|
||||
im Anhänger, die große Liebe, den Friseur, den
|
||||
vollen Napf, das kühle Wasser — und den besten
|
||||
Freund, den ein Mensch haben kann.
|
||||
|
||||
Selbst gemacht, mit viel Herz. Aus der Ban-Yaro-App.
|
||||
|
||||
--------------------------------------------------
|
||||
TRACKLIST
|
||||
--------------------------------------------------
|
||||
1. Ban Yaro Blues Die Hymne
|
||||
2. Ban Yaro Mobil Erste Fahrt im Anhänger
|
||||
3. Amy Eine Liebesromanze
|
||||
4. Beim Friseur Halbes Fell, Energie pur
|
||||
5. Leckerli-Paradies Voller Napf, volles Glück
|
||||
6. Platsch! Ab ins kühle Nass
|
||||
7. Bester Freund Du und ich
|
||||
|
||||
--------------------------------------------------
|
||||
Ein Ban-Yaro-Original · banyaro.app
|
||||
(c) 2026 Ban Yaro
|
||||
|
||||
Diese Aufnahmen sind ein kleines Geschenk:
|
||||
behalten und teilen ausdrucklich erwunscht —
|
||||
nur bitte nicht kommerziell verwenden.
|
||||
|
||||
Viel Freude beim Horen und einen schonen
|
||||
Gassi-Gang! Wuff. 🐾
|
||||
34
tools/album-build/liner-en.txt
Normal file
34
tools/album-build/liner-en.txt
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
==================================================
|
||||
BAN YARO — THE ALBUM
|
||||
7 Songs
|
||||
==================================================
|
||||
|
||||
Seven songs about a dog named Ban Yaro:
|
||||
about walks in every kind of weather, the first
|
||||
ride in the trailer, falling in love, the groomer,
|
||||
a full bowl, cool water — and the best friend a
|
||||
human could ever ask for.
|
||||
|
||||
Homemade, with all our heart. From the Ban Yaro app.
|
||||
|
||||
--------------------------------------------------
|
||||
TRACKLIST
|
||||
--------------------------------------------------
|
||||
1. Ban Yaro Blues The anthem
|
||||
2. Ban Yaro Mobile First ride in the trailer
|
||||
3. Amy A love duet
|
||||
4. At the Groomer's Half the fur, all the energy
|
||||
5. Treat Paradise Full bowl, full heart
|
||||
6. Splash! Into the cool water
|
||||
7. Best Friend You and me
|
||||
|
||||
--------------------------------------------------
|
||||
A Ban Yaro original · banyaro.app
|
||||
(c) 2026 Ban Yaro
|
||||
|
||||
These recordings are a little gift:
|
||||
keep them and share them freely —
|
||||
just please don't use them commercially.
|
||||
|
||||
Enjoy the music, and have a wonderful walk!
|
||||
Woof. 🐾
|
||||
Loading…
Add table
Add a link
Reference in a new issue