feat: Excel-Felder auto-fill + Amazon/AllGames4You Affiliate

- Spielname, Verlag, Autor, Komplexität werden automatisch aus Excel gelesen
- Formular-Felder sind jetzt optional (Excel hat Vorrang)
- Autor-Erkennung aus 'Test von'-Feld jetzt immer aktiv
- Neue Affiliate-Partner: Amazon + AllGames4You
- Banner-Pfade: images/banners/amazon/ + images/banners/allgames4you/
This commit is contained in:
Hermes Agent
2026-07-13 19:03:04 +02:00
parent 7c63321663
commit e07c1437d3
+14 -4
View File
@@ -1916,7 +1916,7 @@ textarea{{min-height:100px;resize:vertical}}
<p style="font-size:.8em;color:var(--muted);margin-top:6px">Auto-Resize: 1920x1080 @ 72dpi</p></div>
<div class="card"><h2>3. Metadaten</h2>
<div class="row-2">
<div><label>Spielname *</label><input type="text" name="spielname" id="spielname" required></div>
<div><label>Spielname (aus Excel)</label><input type="text" name="spielname" id="spielname" placeholder="Automatisch aus Excel"></div>
<div><label>Autor *</label><select name="autor" id="autor" required><option value="">Autor wahlen...</option>{author_opts}</select></div>
</div>
<div class="row-2">
@@ -1930,6 +1930,10 @@ textarea{{min-height:100px;resize:vertical}}
<div class="row-2">
<div><label>Fantasywelt URL</label><input type="text" name="fantasywelt_url" id="fantasywelt_url"></div>
<div><label>Spiele-Offensive URL</label><input type="text" name="so_url" id="so_url"></div>
</div>
<div class="row-2">
<div><label>Amazon URL</label><input type="text" name="amazon_url" id="amazon_url"></div>
<div><label>AllGames4You URL</label><input type="text" name="allgames4you_url" id="allgames4you_url"></div>
</div></div>
<div class="btn-group">
<button type="button" class="btn btn-outline" id="previewBtn">Vorschau</button>
@@ -1955,7 +1959,7 @@ imageDrop.addEventListener('dragleave',function(){{imageDrop.classList.remove('d
imageDrop.addEventListener('drop',function(e){{e.preventDefault();imageDrop.classList.remove('dragover');aif(e.dataTransfer.files)}});
imageInput.addEventListener('change',function(){{aif(imageInput.files)}});
function aif(files){{for(var i=0;i<files.length;i++){{(function(f){{imageFiles.push(f);var li=document.createElement('li');li.innerHTML=f.name+' ('+(f.size/1024).toFixed(1)+' KB) <span class="remove">X</span>';li.querySelector('.remove').onclick=function(){{imageFiles=imageFiles.filter(function(x){{return x!==f}});li.remove()}};imageList.appendChild(li)}})(files[i])}}}}
async function submitForm(publish){{var s=document.getElementById('spielname').value.trim();if(!s){{st('Spielname fehlt','err');return}}if(!excelFile){{st('Excel-Datei fehlt','err');return}}var fd=new FormData();fd.append('excel',excelFile);imageFiles.forEach(function(f){{fd.append('images',f)}});fd.append('spielname',s);fd.append('autor',document.getElementById('autor').value);fd.append('rubrik',document.getElementById('rubrik').value);fd.append('komplexitaet',document.getElementById('komplexitaet').value);fd.append('disclosure',document.getElementById('disclosure').value);fd.append('verlag',document.getElementById('verlag').value.trim());fd.append('fantasywelt_url',document.getElementById('fantasywelt_url').value.trim());fd.append('so_url',document.getElementById('so_url').value.trim());fd.append('publish',publish?'1':'0');st(publish?'Veroffentliche...':'Baue Vorschau...','info');try{{var resp=await fetch('/review-builder/build?key={access_token}',{{method:'POST',body:fd}});var data=await resp.json();if(!data.ok){{st(data.error||'Fehler','err');return}}var box=document.getElementById('resultBox');box.classList.add('visible');document.getElementById('resultTitle').textContent=data.title;document.getElementById('resultLink').innerHTML=data.published?'<a href="'+data.article_url+'" target="_blank">Artikel online: '+data.article_url+'</a>':'<a href="/'+data.filename+'?key={access_token}" target="_blank">Vorschau: '+data.filename+'</a>';st(data.published?'Veroffentlicht!':'Vorschau bereit','ok')}}catch(e){{st('Fehler: '+e.message,'err')}}}}
async function submitForm(publish){{var s=document.getElementById('spielname').value.trim();if(!excelFile){{st('Excel-Datei fehlt','err');return}}var fd=new FormData();fd.append('excel',excelFile);imageFiles.forEach(function(f){{fd.append('images',f)}});fd.append('spielname',s);fd.append('autor',document.getElementById('autor').value);fd.append('rubrik',document.getElementById('rubrik').value);fd.append('komplexitaet',document.getElementById('komplexitaet').value);fd.append('disclosure',document.getElementById('disclosure').value);fd.append('verlag',document.getElementById('verlag').value.trim());fd.append('fantasywelt_url',document.getElementById('fantasywelt_url').value.trim());fd.append('so_url',document.getElementById('so_url').value.trim());fd.append('amazon_url',document.getElementById('amazon_url').value.trim());fd.append('allgames4you_url',document.getElementById('allgames4you_url').value.trim());fd.append('publish',publish?'1':'0');st(publish?'Veroffentliche...':'Baue Vorschau...','info');try{{var resp=await fetch('/review-builder/build?key={access_token}',{{method:'POST',body:fd}});var data=await resp.json();if(!data.ok){{st(data.error||'Fehler','err');return}}var box=document.getElementById('resultBox');box.classList.add('visible');document.getElementById('resultTitle').textContent=data.title;document.getElementById('resultLink').innerHTML=data.published?'<a href="'+data.article_url+'" target="_blank">Artikel online: '+data.article_url+'</a>':'<a href="/'+data.filename+'?key={access_token}" target="_blank">Vorschau: '+data.filename+'</a>';st(data.published?'Veroffentlicht!':'Vorschau bereit','ok')}}catch(e){{st('Fehler: '+e.message,'err')}}}}
document.getElementById('previewBtn').addEventListener('click',function(){{submitForm(false)}});
document.getElementById('publishBtn').addEventListener('click',function(){{submitForm(true)}});
</script></body></html>"""
@@ -2014,10 +2018,10 @@ document.getElementById('publishBtn').addEventListener('click',function(){{submi
zusatz = xl.get("Zusatztitel", "").strip()
tester = xl.get("Test von", "").strip()
# Autor-Mapping: "Jan Maguna" → autor_key
# Autor-Mapping: "Jan Maguna" → autor_key (immer aus Excel, Form nur Fallback)
autor_key = meta.get("autor", "basti").strip()
cfg = REVIEW_CONFIG
if tester and autor_key == "basti":
if tester:
for k, v in cfg.get("authors", {}).items():
if v["name"].lower() == tester.lower():
autor_key = k
@@ -2028,6 +2032,8 @@ document.getElementById('publishBtn').addEventListener('click',function(){{submi
do_publish = meta.get("publish", "0") == "1"
fantasywelt_url = meta.get("fantasywelt_url", "").strip()
so_url = meta.get("so_url", "").strip()
amazon_url = meta.get("amazon_url", "").strip()
allgames4you_url = meta.get("allgames4you_url", "").strip()
# Excel-Felder
komplex = xl.get("Komplexität des Spiels", "").strip()
@@ -2133,6 +2139,10 @@ document.getElementById('publishBtn').addEventListener('click',function(){{submi
aff_html += f'<p><a href="{fantasywelt_url}" target="_blank" rel="noopener"><img style="margin:10px auto;display:block;" src="images/banners/fantasywelt/banner_fantasywelt-jetzt-kaufen.jpg" alt="Bei Fantasywelt kaufen"></a></p>\n'
if so_url:
aff_html += f'<p><a href="{so_url}" target="_blank" rel="noopener"><img style="margin:10px auto;display:block;" src="images/banners/fantasywelt/SO_kaufen_button.jpg" alt="Bei Spiele-Offensive kaufen"></a></p>\n'
if amazon_url:
aff_html += f'<p><a href="{amazon_url}" target="_blank" rel="noopener"><img style="margin:10px auto;display:block;" src="images/banners/amazon/amazon-kaufen-button.jpg" alt="Bei Amazon kaufen"></a></p>\n'
if allgames4you_url:
aff_html += f'<p><a href="{allgames4you_url}" target="_blank" rel="noopener"><img style="margin:10px auto;display:block;" src="images/banners/allgames4you/allgames4you-kaufen-button.jpg" alt="Bei AllGames4You kaufen"></a></p>\n'
gal_path = f"01/{erster}/{ordner}"
tags_str = ", ".join(tags) if tags else f"{spielname}, Brettspiel, Review, Bewertung, {autor_name}"