feat: soporte dias propuestos (param d) en formulario de invitados
This commit is contained in:
@@ -142,6 +142,27 @@ def invitado(n, f):
|
|||||||
return (n, ts) if -10 <= delta <= 14 else None
|
return (n, ts) if -10 <= delta <= 14 else None
|
||||||
|
|
||||||
|
|
||||||
|
def parse_dias(d_str):
|
||||||
|
"""Valida una lista de timestamps separados por comas. Devuelve lista de ints o None."""
|
||||||
|
if not d_str:
|
||||||
|
return None
|
||||||
|
parts = str(d_str).replace(' ', '').split(',')
|
||||||
|
if not 1 <= len(parts) <= 10:
|
||||||
|
return None
|
||||||
|
today = datetime.date.today()
|
||||||
|
result = []
|
||||||
|
for p in parts:
|
||||||
|
try:
|
||||||
|
ts = int(p)
|
||||||
|
day = datetime.datetime.fromtimestamp(ts, datetime.timezone.utc).date()
|
||||||
|
if not (-1 <= (day - today).days <= 60):
|
||||||
|
return None
|
||||||
|
result.append(ts)
|
||||||
|
except (ValueError, OverflowError, OSError):
|
||||||
|
return None
|
||||||
|
return result if result else None
|
||||||
|
|
||||||
|
|
||||||
class H(BaseHTTPRequestHandler):
|
class H(BaseHTTPRequestHandler):
|
||||||
server_version = 'aqnsn'
|
server_version = 'aqnsn'
|
||||||
|
|
||||||
@@ -166,8 +187,22 @@ class H(BaseHTTPRequestHandler):
|
|||||||
if limited(check_hits, self.client_ip(), 40):
|
if limited(check_hits, self.client_ip(), 40):
|
||||||
return self.reply(429, {'ok': False})
|
return self.reply(429, {'ok': False})
|
||||||
q = parse_qs(urlparse(self.path).query)
|
q = parse_qs(urlparse(self.path).query)
|
||||||
inv = invitado(q.get('n', [''])[0], q.get('f', [''])[0])
|
n_raw = q.get('n', [''])[0]
|
||||||
return self.reply(200, {'ok': True, 'nombre': inv[0], 'cita': inv[1]} if inv else {'ok': False})
|
f_raw = q.get('f', [''])[0]
|
||||||
|
d_raw = q.get('d', [''])[0]
|
||||||
|
if f_raw:
|
||||||
|
inv = invitado(n_raw, f_raw)
|
||||||
|
return self.reply(200, {'ok': True, 'nombre': inv[0], 'cita': inv[1]} if inv else {'ok': False})
|
||||||
|
if d_raw:
|
||||||
|
n = ' '.join(str(n_raw or '').split())
|
||||||
|
if not n or not NAME_RE.match(n):
|
||||||
|
return self.reply(200, {'ok': False})
|
||||||
|
dias = parse_dias(d_raw)
|
||||||
|
if not dias:
|
||||||
|
return self.reply(200, {'ok': False})
|
||||||
|
return self.reply(200, {'ok': True, 'nombre': n,
|
||||||
|
'dias': [{'ts': ts, 'txt': cita_txt(ts)} for ts in dias]})
|
||||||
|
return self.reply(200, {'ok': False})
|
||||||
|
|
||||||
def invitados(self):
|
def invitados(self):
|
||||||
try:
|
try:
|
||||||
@@ -181,8 +216,28 @@ class H(BaseHTTPRequestHandler):
|
|||||||
return self.reply(200, {'ok': True}) # trampa o demasiado rápido: no se envía
|
return self.reply(200, {'ok': True}) # trampa o demasiado rápido: no se envía
|
||||||
if limited(guest_hits, self.client_ip(), 8):
|
if limited(guest_hits, self.client_ip(), 8):
|
||||||
return self.reply(429, {'ok': False, 'error': 'Demasiados envíos. Inténtalo más tarde.'})
|
return self.reply(429, {'ok': False, 'error': 'Demasiados envíos. Inténtalo más tarde.'})
|
||||||
inv = invitado(d.get('n'), d.get('f'))
|
f_raw = str(d.get('f') or '').strip()
|
||||||
nombre, ts = inv if inv else (None, None)
|
d_raw = str(d.get('d') or '').strip()
|
||||||
|
dia_raw = str(d.get('dia') or '').strip()
|
||||||
|
if f_raw:
|
||||||
|
inv = invitado(d.get('n'), f_raw)
|
||||||
|
nombre, ts = inv if inv else (None, None)
|
||||||
|
elif d_raw and dia_raw:
|
||||||
|
n_val = ' '.join(str(d.get('n') or '').split())
|
||||||
|
if not n_val or not NAME_RE.match(n_val):
|
||||||
|
nombre, ts = None, None
|
||||||
|
else:
|
||||||
|
dias = parse_dias(d_raw)
|
||||||
|
try:
|
||||||
|
dia_ts = int(dia_raw)
|
||||||
|
except (ValueError, TypeError):
|
||||||
|
dia_ts = None
|
||||||
|
if dias and dia_ts is not None and dia_ts in dias:
|
||||||
|
nombre, ts = n_val, dia_ts
|
||||||
|
else:
|
||||||
|
nombre, ts = None, None
|
||||||
|
else:
|
||||||
|
nombre, ts = None, None
|
||||||
if not nombre:
|
if not nombre:
|
||||||
return self.reply(403, {'ok': False, 'error': 'Enlace no válido o caducado.'})
|
return self.reply(403, {'ok': False, 'error': 'Enlace no válido o caducado.'})
|
||||||
if d.get('consent') is not True:
|
if d.get('consent') is not True:
|
||||||
|
|||||||
Reference in New Issue
Block a user