Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TSyR5Zw5eGj6oPTRVjvP1b
89 lines
4.3 KiB
Python
89 lines
4.3 KiB
Python
"""Genera public/invitados.html a partir de guest_form.json (copia de las preguntas del formulario de Google)."""
|
|
import html, json
|
|
|
|
esc = html.escape
|
|
F = json.load(open('guest_form.json', encoding='utf-8'))
|
|
|
|
secciones, actual, nq = [], None, 0
|
|
consent = None
|
|
for it in F['items']:
|
|
t = it['type']
|
|
if t == 8:
|
|
actual = {'titulo': it['title'], 'nota': it['desc'], 'preguntas': []}
|
|
secciones.append(actual)
|
|
elif t in (0, 1):
|
|
nq += 1
|
|
actual['preguntas'].append({'id': f'q{nq:02d}', 'titulo': it['title'], 'desc': it['desc'],
|
|
'req': it['required'], 'largo': t == 1})
|
|
elif t == 4:
|
|
consent = {'titulo': it['title'], 'opcion': it['options'][0], 'req': it['required']}
|
|
consent_text = secciones[-1]['nota']
|
|
secciones.pop() # la última sección solo contiene las condiciones
|
|
|
|
def pregunta(q):
|
|
mark = ' <span class="req" title="Obligatoria">*</span>' if q['req'] else ''
|
|
campo = (f'<textarea name="{q["id"]}" rows="4" maxlength="3000"{" required" if q["req"] else ""}></textarea>'
|
|
if q['largo'] else
|
|
f'<input name="{q["id"]}" type="text" maxlength="300"{" required" if q["req"] else ""}>')
|
|
d = f'<small>{esc(q["desc"])}</small>' if q['desc'] else ''
|
|
return f' <label><span>{esc(q["titulo"])}{mark}</span>{d}\n {campo}\n </label>'
|
|
|
|
bloques = []
|
|
for s in secciones:
|
|
nota = f'\n <p class="note">{esc(s["nota"])}</p>' if s['nota'] else ''
|
|
bloques.append(f' <fieldset class="sec">\n <legend>{esc(s["titulo"])}</legend>{nota}\n' +
|
|
'\n'.join(pregunta(q) for q in s['preguntas']) + '\n </fieldset>')
|
|
|
|
page = f'''<!doctype html>
|
|
<html lang="es">
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
<meta name="robots" content="noindex, nofollow, noarchive">
|
|
<title>Ficha del invitado · Anda Que No Sabes Ná</title>
|
|
<meta name="theme-color" content="#06080d">
|
|
<link rel="icon" href="img/avatar.jpg">
|
|
<link rel="stylesheet" href="styles.css">
|
|
</head>
|
|
<body>
|
|
<header class="top">
|
|
<a class="brand" href="/" aria-label="Anda Que No Sabes Ná, inicio"><img src="img/avatar.jpg" alt="" width="40" height="40"><span>Anda que no sabes ná</span></a>
|
|
</header>
|
|
|
|
<main class="legal contact guest">
|
|
<h1>Ficha del <em>invitado</em></h1>
|
|
<p id="hola" class="lead-c" hidden></p>
|
|
<p id="malo" class="status err" hidden>Este enlace no es válido o ha caducado. Escríbenos a <a href="mailto:andaquenosabesnada@gmail.com">andaquenosabesnada@gmail.com</a> y te mandamos uno nuevo.</p>
|
|
<p id="intro" class="lead-c" hidden>{esc(F['description'])}</p>
|
|
|
|
<form id="g" class="form" novalidate hidden data-ok="¡Gracias! Hemos recibido tu ficha. Te escribiremos pronto con los siguientes pasos.">
|
|
<label>Tu correo electrónico (opcional, para poder responderte)
|
|
<input name="email" type="email" autocomplete="email" maxlength="200">
|
|
</label>
|
|
{chr(10).join(bloques)}
|
|
<fieldset class="sec">
|
|
<legend>Antes de enviar</legend>
|
|
<p class="note">Este podcast se realiza de forma altruista y colaborativa.</p>
|
|
<div class="trap" aria-hidden="true"><label>No rellenes este campo <input name="web" type="text" tabindex="-1" autocomplete="off"></label></div>
|
|
<label class="check">
|
|
<input name="consent" type="checkbox" required>
|
|
<span>He leído y acepto las <a href="terminos.html#participacion" target="_blank" rel="noopener">condiciones de participación</a> descritas. <span class="req">*</span></span>
|
|
</label>
|
|
<label class="check">
|
|
<input name="privacy" type="checkbox" required>
|
|
<span>He leído la <a href="privacidad.html" target="_blank" rel="noopener">política de privacidad</a> y acepto que usen estos datos para preparar el episodio. <span class="req">*</span></span>
|
|
</label>
|
|
</fieldset>
|
|
<button class="btn primary" type="submit">Enviar mi ficha</button>
|
|
<p id="st" class="status" role="status" aria-live="polite"></p>
|
|
<p class="note">Tus respuestas se guardan en este navegador mientras escribes, por si cierras la página. Se borran al enviarlas.</p>
|
|
</form>
|
|
</main>
|
|
|
|
<script src="invitados.js"></script>
|
|
</body>
|
|
</html>
|
|
'''
|
|
open('public/invitados.html', 'w', encoding='utf-8').write(page)
|
|
print('invitados.html:', len(page), 'bytes;', nq, 'preguntas;', len(secciones), 'secciones')
|