Mirror del Joomla antiguo: versionar los scripts y reponer los assets que faltaban
Los scripts del mirror (00-90) vivian solo en el disco. Van al repo; los datos que generan no (16 GB entre crawl, snapshot del origen y Joomla restaurado) -> .gitignore. Nuevo 91-repone-assets404.sh: repone los ficheros que el crawl no capturo porque se referencian SOLO desde CSS y el crawler seguia enlaces HTML (system.css, los fondos de fe_adulta_1, ratingstars.gif de K2). Salian como 404 en los logs de nginx del Hetzner. Descarga por HTTP desde el Joomla local aislado, nunca del filesystem -- mismo principio que el crawl, para no arrastrar los .php comprometidos del #183 -- y escanea PHP embebido antes de copiar a site/. Resultado sobre las 286 rutas unicas con 404 del log: 196 repuestas y verificadas en produccion (196/196 en 200 tras el rsync), 82 que dan 301->404 tambien en el origen (ya estaban rotas en la web original) y 8 rutas basura /%22/... de HTML mal formado. Refs #180 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,83 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Fase 5 (local): paridad entre el fichero capturado y lo que sirve ahora el Joomla local.
|
||||
|
||||
Detecta capturas truncadas, paginas de error congeladas y desfases de contenido.
|
||||
No toca produccion.
|
||||
"""
|
||||
import os, re, sys, random, hashlib, subprocess, json
|
||||
from urllib.parse import urlsplit
|
||||
|
||||
BASE = "/home/rafa/joomla-migration/mirror-antiguo"
|
||||
RUN = open(os.path.join(BASE, "CURRENT_RUN")).read().strip()
|
||||
DIR = os.path.join(BASE, "runs", RUN)
|
||||
RAW = os.path.join(DIR, "raw", "antiguo.feadulta.com")
|
||||
N = int(sys.argv[1]) if len(sys.argv) > 1 else 200
|
||||
|
||||
TITLE = re.compile(r"<title[^>]*>(.*?)</title>", re.I | re.S)
|
||||
SCRIPTS = re.compile(r"<(script|style)[^>]*>.*?</\1>", re.I | re.S)
|
||||
TAGS = re.compile(r"<[^>]+>")
|
||||
WS = re.compile(r"\s+")
|
||||
# bloques que cambian entre peticiones. El contador de visitas de K2 ("Read N times") se
|
||||
# incrementa con nuestra propia peticion, asi que dos lecturas de la MISMA pagina nunca coinciden:
|
||||
# se normaliza en vez de contarlo como diferencia.
|
||||
VOLATILE = re.compile(r"[0-9a-f]{32}|csrf|token", re.I)
|
||||
HITS = re.compile(r"(Read|Visto|Le[ií]do)\s+\d+\s+(times|veces)", re.I)
|
||||
|
||||
def texthash(s):
|
||||
s = SCRIPTS.sub(" ", s)
|
||||
s = TAGS.sub(" ", s)
|
||||
s = WS.sub(" ", s).strip()
|
||||
s = VOLATILE.sub("", s)
|
||||
s = HITS.sub("HITS", s)
|
||||
return hashlib.sha256(s.encode("utf-8", "replace")).hexdigest(), len(s)
|
||||
|
||||
def title(s):
|
||||
m = TITLE.search(s)
|
||||
return WS.sub(" ", m.group(1)).strip() if m else ""
|
||||
|
||||
urls = [l.strip() for l in open(os.path.join(BASE, "inventory", "urls-input.txt"))]
|
||||
random.seed(20260729)
|
||||
sample = random.sample(urls, min(N, len(urls)))
|
||||
|
||||
res = {"muestra": len(sample), "ok_status": 0, "falta_fichero": 0,
|
||||
"titulo_igual": 0, "titulo_distinto": 0, "texto_igual": 0, "texto_distinto": 0,
|
||||
"diffs": []}
|
||||
|
||||
for u in sample:
|
||||
path = urlsplit(u).path
|
||||
fp = os.path.join(RAW, path.lstrip("/"))
|
||||
if path.endswith("/"):
|
||||
fp = os.path.join(fp, "index.html")
|
||||
if not os.path.exists(fp):
|
||||
res["falta_fichero"] += 1
|
||||
res["diffs"].append({"url": u, "motivo": "fichero ausente"})
|
||||
continue
|
||||
res["ok_status"] += 1
|
||||
disk = open(fp, encoding="utf-8", errors="replace").read()
|
||||
live = subprocess.run(
|
||||
["curl", "-s", "--max-time", "60", "-H", "Host: antiguo.feadulta.com",
|
||||
"http://127.0.0.1:8086" + path],
|
||||
capture_output=True).stdout.decode("utf-8", "replace")
|
||||
|
||||
td, tl = title(disk), title(live)
|
||||
if td == tl:
|
||||
res["titulo_igual"] += 1
|
||||
else:
|
||||
res["titulo_distinto"] += 1
|
||||
res["diffs"].append({"url": u, "motivo": "titulo", "mirror": td[:120], "vivo": tl[:120]})
|
||||
|
||||
hd, ld = texthash(disk)
|
||||
hl, ll = texthash(live)
|
||||
if hd == hl:
|
||||
res["texto_igual"] += 1
|
||||
else:
|
||||
res["texto_distinto"] += 1
|
||||
res["diffs"].append({"url": u, "motivo": "texto", "len_mirror": ld, "len_vivo": ll})
|
||||
|
||||
out = os.path.join(DIR, "parity-report.json")
|
||||
json.dump(res, open(out, "w"), indent=2, ensure_ascii=False)
|
||||
for k in ("muestra", "falta_fichero", "titulo_igual", "titulo_distinto", "texto_igual", "texto_distinto"):
|
||||
print(k, "=", res[k])
|
||||
print("informe:", out)
|
||||
for d in res["diffs"][:15]:
|
||||
print(" ", d)
|
||||
Reference in New Issue
Block a user