docs: diagrama de fuentes y clasificacion

De donde sale cada dato y como se etiqueta. Lo importante que explica: el
tema y el subtema no se calculan del texto, viajan escritos en el feed y el
articulo los hereda al entrar. Decision editorial, no estadistica.

Incluye los subtemas que existen de verdad en la base, que son geograficos y
de seccion, no los conceptuales que todavia ofrece el menu de la portada.
This commit is contained in:
hacklab 2026-08-23 17:43:37 +02:00
parent 4265909b55
commit b1411eb372
3 changed files with 347 additions and 0 deletions

View file

@ -0,0 +1,149 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1500 1160" width="1500" height="1160" font-family="DejaVu Sans Mono, Menlo, Consolas, monospace" role="img" aria-label="De donde salen los datos de UP-LEAKS y como se clasifican en temas, subtemas y filtros">
<defs>
<marker id="f1" markerWidth="9" markerHeight="9" refX="7" refY="3" orient="auto"><path d="M0,0 L7,3 L0,6 Z" fill="#3ad6ff" opacity="0.85"/></marker>
<marker id="f2" markerWidth="9" markerHeight="9" refX="7" refY="3" orient="auto"><path d="M0,0 L7,3 L0,6 Z" fill="#39ff14" opacity="0.85"/></marker>
<marker id="f3" markerWidth="9" markerHeight="9" refX="7" refY="3" orient="auto"><path d="M0,0 L7,3 L0,6 Z" fill="#ff5ea8" opacity="0.85"/></marker>
</defs>
<rect width="1500" height="1160" fill="#050505"/>
<text x="46" y="54" fill="#39ff14" font-size="27" text-anchor="start" font-weight="bold" letter-spacing="3">DE DÓNDE SALEN LOS DATOS</text>
<text x="46" y="80" fill="#8a938a" font-size="14" text-anchor="start" font-weight="normal" letter-spacing="0">Cuatro fuentes, una etiqueta que viaja con cada documento, y los filtros que salen de ahí.</text>
<line x1="46" y1="96" x2="1454" y2="96" stroke="#39ff14" stroke-opacity="0.28"/>
<text x="46" y="118" fill="#3ad6ff" font-size="13" text-anchor="start" font-weight="normal" letter-spacing="2">1 · LO QUE ENTRA</text>
<rect x="31" y="130" width="340" height="118" rx="4" fill="#0d0f0d" stroke="#3ad6ff" stroke-width="1.5" stroke-opacity="0.85"/>
<text x="49" y="160" fill="#3ad6ff" font-size="16" text-anchor="start" font-weight="bold" letter-spacing="0">236 feeds RSS</text>
<text x="49" y="186" fill="#8a938a" font-size="11.5" text-anchor="start" font-weight="normal" letter-spacing="0"> prensa de 5 idiomas</text>
<text x="49" y="206" fill="#8a938a" font-size="11.5" text-anchor="start" font-weight="normal" letter-spacing="0"> agencias y cabeceras</text>
<text x="49" y="226" fill="#8a938a" font-size="11.5" text-anchor="start" font-weight="normal" letter-spacing="0"> medios locales y de exilio</text>
<rect x="397" y="130" width="340" height="118" rx="4" fill="#0d0f0d" stroke="#3ad6ff" stroke-width="1.5" stroke-opacity="0.85"/>
<text x="415" y="160" fill="#3ad6ff" font-size="16" text-anchor="start" font-weight="bold" letter-spacing="0">API de Wikipedia</text>
<text x="415" y="186" fill="#8a938a" font-size="11.5" text-anchor="start" font-weight="normal" letter-spacing="0"> 28.266 artículos</text>
<text x="415" y="206" fill="#8a938a" font-size="11.5" text-anchor="start" font-weight="normal" letter-spacing="0"> por tema y palabra clave</text>
<text x="415" y="226" fill="#8a938a" font-size="11.5" text-anchor="start" font-weight="normal" letter-spacing="0"> el contexto histórico</text>
<rect x="763" y="130" width="340" height="118" rx="4" fill="#0d0f0d" stroke="#3ad6ff" stroke-width="1.5" stroke-opacity="0.85"/>
<text x="781" y="160" fill="#3ad6ff" font-size="16" text-anchor="start" font-weight="bold" letter-spacing="0">WikiLeaks</text>
<text x="781" y="186" fill="#8a938a" font-size="11.5" text-anchor="start" font-weight="normal" letter-spacing="0"> 36.182 documentos</text>
<text x="781" y="206" fill="#8a938a" font-size="11.5" text-anchor="start" font-weight="normal" letter-spacing="0"> archivo completo por torrent</text>
<text x="781" y="226" fill="#8a938a" font-size="11.5" text-anchor="start" font-weight="normal" letter-spacing="0"> cables, correos, informes</text>
<rect x="1129" y="130" width="340" height="118" rx="4" fill="#0d0f0d" stroke="#3ad6ff" stroke-width="1.5" stroke-opacity="0.85"/>
<text x="1147" y="160" fill="#3ad6ff" font-size="16" text-anchor="start" font-weight="bold" letter-spacing="0">Imágenes</text>
<text x="1147" y="186" fill="#8a938a" font-size="11.5" text-anchor="start" font-weight="normal" letter-spacing="0"> og:image de cada artículo</text>
<text x="1147" y="206" fill="#8a938a" font-size="11.5" text-anchor="start" font-weight="normal" letter-spacing="0"> fotos de Wikipedia</text>
<text x="1147" y="226" fill="#8a938a" font-size="11.5" text-anchor="start" font-weight="normal" letter-spacing="0"> descritas con Qwen3-VL</text>
<line x1="201" y1="252" x2="750" y2="334" stroke="#3ad6ff" stroke-opacity="0.35" stroke-width="1.1" marker-end="url(#f1)"/>
<line x1="567" y1="252" x2="750" y2="334" stroke="#3ad6ff" stroke-opacity="0.35" stroke-width="1.1" marker-end="url(#f1)"/>
<line x1="933" y1="252" x2="750" y2="334" stroke="#3ad6ff" stroke-opacity="0.35" stroke-width="1.1" marker-end="url(#f1)"/>
<line x1="1299" y1="252" x2="750" y2="334" stroke="#3ad6ff" stroke-opacity="0.35" stroke-width="1.1" marker-end="url(#f1)"/>
<rect x="46" y="344" width="1408" height="128" rx="4" fill="#0d0f0d" stroke="#39ff14" stroke-width="1.8" stroke-opacity="1.0"/>
<text x="64" y="372" fill="#39ff14" font-size="13" text-anchor="start" font-weight="normal" letter-spacing="2">2 · LA ETIQUETA NO SE CALCULA: VIAJA CON LA FUENTE</text>
<text x="64" y="400" fill="#8a938a" font-size="12.5" text-anchor="start" font-weight="normal" letter-spacing="0">Cada feed del catálogo lleva escrito su tema y su subtema. Al ingerir un artículo, el artículo los hereda.</text>
<text x="64" y="420" fill="#8a938a" font-size="12.5" text-anchor="start" font-weight="normal" letter-spacing="0">No hay clasificador automático: la decisión es editorial y está en el catálogo, no en el texto.</text>
<text x="64" y="448" fill="#5a625a" font-size="11.5" text-anchor="start" font-weight="normal" letter-spacing="0">Es simple y es auditable — se ve de un vistazo por qué un artículo está donde está — pero tiene un coste: si un</text>
<text x="64" y="464" fill="#5a625a" font-size="11.5" text-anchor="start" font-weight="normal" letter-spacing="0">medio de clima publica sobre geopolítica, ese artículo entra igualmente como clima.</text>
<rect x="1000" y="360" width="436" height="96" rx="4" fill="#12100a" stroke="#ffb020" stroke-width="1.2" stroke-opacity="0.8"/>
<text x="1016" y="382" fill="#ffb020" font-size="11.5" text-anchor="start" font-weight="normal" letter-spacing="1">coconews_feeds</text>
<text x="1016" y="404" fill="#5a625a" font-size="11.5" text-anchor="start" font-weight="normal" letter-spacing="0">nombre</text>
<text x="1110" y="404" fill="#8a938a" font-size="11.5" text-anchor="start" font-weight="normal" letter-spacing="0">"Ariana News Dari"</text>
<text x="1016" y="422" fill="#5a625a" font-size="11.5" text-anchor="start" font-weight="normal" letter-spacing="0">tema</text>
<text x="1110" y="422" fill="#7cff5a" font-size="11.5" text-anchor="start" font-weight="normal" letter-spacing="0">"guerra global"</text>
<text x="1016" y="440" fill="#5a625a" font-size="11.5" text-anchor="start" font-weight="normal" letter-spacing="0">subtema</text>
<text x="1110" y="440" fill="#7cff5a" font-size="11.5" text-anchor="start" font-weight="normal" letter-spacing="0">"Afganistán"</text>
<rect x="20" y="558" width="276" height="260" rx="4" fill="#0d0f0d" stroke="#ff3b3b" stroke-width="1.6" stroke-opacity="0.9"/>
<rect x="20" y="558" width="276" height="30" rx="4" fill="#ff3b3b" fill-opacity="0.16"/>
<text x="34" y="579" fill="#ff3b3b" font-size="14" text-anchor="start" font-weight="bold" letter-spacing="1">GLOB-WAR</text>
<text x="282" y="579" fill="#5a625a" font-size="11" text-anchor="end" font-weight="normal" letter-spacing="0">49 feeds</text>
<text x="34" y="602" fill="#5a625a" font-size="10.5" text-anchor="start" font-weight="normal" letter-spacing="0">guerra global</text>
<text x="34" y="624" fill="#8a938a" font-size="11.5" text-anchor="start" font-weight="normal" letter-spacing="0">· Internacional</text>
<text x="34" y="644" fill="#8a938a" font-size="11.5" text-anchor="start" font-weight="normal" letter-spacing="0">· Asia</text>
<text x="34" y="664" fill="#8a938a" font-size="11.5" text-anchor="start" font-weight="normal" letter-spacing="0">· Oriente Medio</text>
<text x="34" y="684" fill="#8a938a" font-size="11.5" text-anchor="start" font-weight="normal" letter-spacing="0">· Defensa</text>
<text x="34" y="704" fill="#8a938a" font-size="11.5" text-anchor="start" font-weight="normal" letter-spacing="0">· Geopolítica</text>
<text x="34" y="724" fill="#8a938a" font-size="11.5" text-anchor="start" font-weight="normal" letter-spacing="0">· Afganistán</text>
<text x="34" y="744" fill="#8a938a" font-size="11.5" text-anchor="start" font-weight="normal" letter-spacing="0">· Europa</text>
<text x="34" y="764" fill="#8a938a" font-size="11.5" text-anchor="start" font-weight="normal" letter-spacing="0">· Conflictos</text>
<text x="34" y="784" fill="#8a938a" font-size="11.5" text-anchor="start" font-weight="normal" letter-spacing="0">· Rusia</text>
<text x="34" y="804" fill="#8a938a" font-size="11.5" text-anchor="start" font-weight="normal" letter-spacing="0">· Humanitario</text>
<line x1="750" y1="476" x2="158" y2="554" stroke="#39ff14" stroke-opacity="0.28" stroke-width="1.1" marker-end="url(#f2)"/>
<rect x="316" y="558" width="276" height="260" rx="4" fill="#0d0f0d" stroke="#4a6bff" stroke-width="1.6" stroke-opacity="0.9"/>
<rect x="316" y="558" width="276" height="30" rx="4" fill="#4a6bff" fill-opacity="0.16"/>
<text x="330" y="579" fill="#4a6bff" font-size="14" text-anchor="start" font-weight="bold" letter-spacing="1">INT-SEC</text>
<text x="578" y="579" fill="#5a625a" font-size="11" text-anchor="end" font-weight="normal" letter-spacing="0">19 feeds</text>
<text x="330" y="602" fill="#5a625a" font-size="10.5" text-anchor="start" font-weight="normal" letter-spacing="0">inteligencia y seguridad</text>
<text x="330" y="624" fill="#8a938a" font-size="11.5" text-anchor="start" font-weight="normal" letter-spacing="0">· Ciberseguridad</text>
<text x="330" y="644" fill="#8a938a" font-size="11.5" text-anchor="start" font-weight="normal" letter-spacing="0">· Análisis</text>
<text x="330" y="664" fill="#8a938a" font-size="11.5" text-anchor="start" font-weight="normal" letter-spacing="0">· Defensa</text>
<text x="330" y="684" fill="#8a938a" font-size="11.5" text-anchor="start" font-weight="normal" letter-spacing="0">· Inteligencia</text>
<text x="330" y="704" fill="#8a938a" font-size="11.5" text-anchor="start" font-weight="normal" letter-spacing="0">· Internacional</text>
<text x="330" y="724" fill="#8a938a" font-size="11.5" text-anchor="start" font-weight="normal" letter-spacing="0">· Europa</text>
<text x="330" y="744" fill="#8a938a" font-size="11.5" text-anchor="start" font-weight="normal" letter-spacing="0">· España</text>
<text x="330" y="764" fill="#8a938a" font-size="11.5" text-anchor="start" font-weight="normal" letter-spacing="0">· EEUU</text>
<line x1="750" y1="476" x2="454" y2="554" stroke="#39ff14" stroke-opacity="0.28" stroke-width="1.1" marker-end="url(#f2)"/>
<rect x="612" y="558" width="276" height="260" rx="4" fill="#0d0f0d" stroke="#5fe36a" stroke-width="1.6" stroke-opacity="0.9"/>
<rect x="612" y="558" width="276" height="30" rx="4" fill="#5fe36a" fill-opacity="0.16"/>
<text x="626" y="579" fill="#5fe36a" font-size="14" text-anchor="start" font-weight="bold" letter-spacing="1">CLIMATE</text>
<text x="874" y="579" fill="#5a625a" font-size="11" text-anchor="end" font-weight="normal" letter-spacing="0">120 feeds</text>
<text x="626" y="602" fill="#5a625a" font-size="10.5" text-anchor="start" font-weight="normal" letter-spacing="0">cambio climático</text>
<text x="626" y="624" fill="#8a938a" font-size="11.5" text-anchor="start" font-weight="normal" letter-spacing="0">· Internacional</text>
<text x="626" y="644" fill="#8a938a" font-size="11.5" text-anchor="start" font-weight="normal" letter-spacing="0">· EEUU</text>
<text x="626" y="664" fill="#8a938a" font-size="11.5" text-anchor="start" font-weight="normal" letter-spacing="0">· Ciencia</text>
<text x="626" y="684" fill="#8a938a" font-size="11.5" text-anchor="start" font-weight="normal" letter-spacing="0">· Biodiversidad</text>
<text x="626" y="704" fill="#8a938a" font-size="11.5" text-anchor="start" font-weight="normal" letter-spacing="0">· Energía</text>
<text x="626" y="724" fill="#8a938a" font-size="11.5" text-anchor="start" font-weight="normal" letter-spacing="0">· Asia</text>
<text x="626" y="744" fill="#8a938a" font-size="11.5" text-anchor="start" font-weight="normal" letter-spacing="0">· Tecnología</text>
<text x="626" y="764" fill="#8a938a" font-size="11.5" text-anchor="start" font-weight="normal" letter-spacing="0">· ONG</text>
<text x="626" y="784" fill="#8a938a" font-size="11.5" text-anchor="start" font-weight="normal" letter-spacing="0">· Salud</text>
<text x="626" y="804" fill="#8a938a" font-size="11.5" text-anchor="start" font-weight="normal" letter-spacing="0">· España</text>
<line x1="750" y1="476" x2="750" y2="554" stroke="#39ff14" stroke-opacity="0.28" stroke-width="1.1" marker-end="url(#f2)"/>
<rect x="908" y="558" width="276" height="260" rx="4" fill="#0d0f0d" stroke="#ffe600" stroke-width="1.6" stroke-opacity="0.9"/>
<rect x="908" y="558" width="276" height="30" rx="4" fill="#ffe600" fill-opacity="0.16"/>
<text x="922" y="579" fill="#ffe600" font-size="14" text-anchor="start" font-weight="bold" letter-spacing="1">ECO-CORP</text>
<text x="1170" y="579" fill="#5a625a" font-size="11" text-anchor="end" font-weight="normal" letter-spacing="0">24 feeds</text>
<text x="922" y="602" fill="#5a625a" font-size="10.5" text-anchor="start" font-weight="normal" letter-spacing="0">economía y corporaciones</text>
<text x="922" y="624" fill="#8a938a" font-size="11.5" text-anchor="start" font-weight="normal" letter-spacing="0">· Internacional</text>
<text x="922" y="644" fill="#8a938a" font-size="11.5" text-anchor="start" font-weight="normal" letter-spacing="0">· Tecnología</text>
<text x="922" y="664" fill="#8a938a" font-size="11.5" text-anchor="start" font-weight="normal" letter-spacing="0">· EEUU</text>
<text x="922" y="684" fill="#8a938a" font-size="11.5" text-anchor="start" font-weight="normal" letter-spacing="0">· España</text>
<text x="922" y="704" fill="#8a938a" font-size="11.5" text-anchor="start" font-weight="normal" letter-spacing="0">· Gestión</text>
<text x="922" y="724" fill="#8a938a" font-size="11.5" text-anchor="start" font-weight="normal" letter-spacing="0">· Corporaciones</text>
<text x="922" y="744" fill="#8a938a" font-size="11.5" text-anchor="start" font-weight="normal" letter-spacing="0">· Comercio</text>
<line x1="750" y1="476" x2="1046" y2="554" stroke="#39ff14" stroke-opacity="0.28" stroke-width="1.1" marker-end="url(#f2)"/>
<rect x="1204" y="558" width="276" height="260" rx="4" fill="#0d0f0d" stroke="#ff9b30" stroke-width="1.6" stroke-opacity="0.9"/>
<rect x="1204" y="558" width="276" height="30" rx="4" fill="#ff9b30" fill-opacity="0.16"/>
<text x="1218" y="579" fill="#ff9b30" font-size="14" text-anchor="start" font-weight="bold" letter-spacing="1">POPL-UP</text>
<text x="1466" y="579" fill="#5a625a" font-size="11" text-anchor="end" font-weight="normal" letter-spacing="0">24 feeds</text>
<text x="1218" y="602" fill="#5a625a" font-size="10.5" text-anchor="start" font-weight="normal" letter-spacing="0">demografía y sociedad</text>
<text x="1218" y="624" fill="#8a938a" font-size="11.5" text-anchor="start" font-weight="normal" letter-spacing="0">· España</text>
<text x="1218" y="644" fill="#8a938a" font-size="11.5" text-anchor="start" font-weight="normal" letter-spacing="0">· Internacional</text>
<text x="1218" y="664" fill="#8a938a" font-size="11.5" text-anchor="start" font-weight="normal" letter-spacing="0">· EEUU</text>
<text x="1218" y="684" fill="#8a938a" font-size="11.5" text-anchor="start" font-weight="normal" letter-spacing="0">· Salud</text>
<text x="1218" y="704" fill="#8a938a" font-size="11.5" text-anchor="start" font-weight="normal" letter-spacing="0">· Derechos Humanos</text>
<text x="1218" y="724" fill="#8a938a" font-size="11.5" text-anchor="start" font-weight="normal" letter-spacing="0">· Política</text>
<text x="1218" y="744" fill="#8a938a" font-size="11.5" text-anchor="start" font-weight="normal" letter-spacing="0">· Migración</text>
<text x="1218" y="764" fill="#8a938a" font-size="11.5" text-anchor="start" font-weight="normal" letter-spacing="0">· Europa</text>
<text x="1218" y="784" fill="#8a938a" font-size="11.5" text-anchor="start" font-weight="normal" letter-spacing="0">· Reino Unido</text>
<line x1="750" y1="476" x2="1342" y2="554" stroke="#39ff14" stroke-opacity="0.28" stroke-width="1.1" marker-end="url(#f2)"/>
<rect x="40" y="528" width="461" height="26" fill="#050505"/>
<text x="46" y="547" fill="#7cff5a" font-size="13" text-anchor="start" font-weight="normal" letter-spacing="2">3 · CINCO TEMAS, Y LOS SUBTEMAS QUE EXISTEN DE VERDAD</text>
<text x="46" y="842" fill="#5a625a" font-size="11.5" text-anchor="start" font-weight="normal" letter-spacing="0">Los subtemas son geográficos y de sección, no conceptuales. No hay un subtema "energía renovable": hay "Energía", que es lo que</text>
<text x="46" y="858" fill="#5a625a" font-size="11.5" text-anchor="start" font-weight="normal" letter-spacing="0">trae el catálogo. El menú de la web todavía ofrece algunos que no existen en la base y por eso filtran a cero.</text>
<rect x="46" y="926" width="1408" height="180" rx="4" fill="#0d0f0d" stroke="#ff5ea8" stroke-width="1.5" stroke-opacity="1.0"/>
<rect x="40" y="896" width="217" height="26" fill="#050505"/>
<text x="46" y="915" fill="#ff5ea8" font-size="13" text-anchor="start" font-weight="normal" letter-spacing="2">4 · LO QUE PUEDES FILTRAR</text>
<text x="70" y="966" fill="#ff5ea8" font-size="12.5" text-anchor="start" font-weight="normal" letter-spacing="0">tema</text>
<text x="220" y="966" fill="#8a938a" font-size="12" text-anchor="start" font-weight="normal" letter-spacing="0">la vista que eliges: GLOB-WAR, INT-SEC…</text>
<text x="70" y="996" fill="#ff5ea8" font-size="12.5" text-anchor="start" font-weight="normal" letter-spacing="0">subtema</text>
<text x="220" y="996" fill="#8a938a" font-size="12" text-anchor="start" font-weight="normal" letter-spacing="0">desplegable, hereda del feed</text>
<text x="70" y="1026" fill="#ff5ea8" font-size="12.5" text-anchor="start" font-weight="normal" letter-spacing="0">fecha</text>
<text x="220" y="1026" fill="#8a938a" font-size="12" text-anchor="start" font-weight="normal" letter-spacing="0">Semanal (7 días) o Todas</text>
<text x="70" y="1056" fill="#ff5ea8" font-size="12.5" text-anchor="start" font-weight="normal" letter-spacing="0">palabra clave</text>
<text x="220" y="1056" fill="#8a938a" font-size="12" text-anchor="start" font-weight="normal" letter-spacing="0">busca dentro del texto</text>
<text x="750" y="966" fill="#ff5ea8" font-size="12.5" text-anchor="start" font-weight="normal" letter-spacing="0">nodos</text>
<text x="900" y="966" fill="#8a938a" font-size="12" text-anchor="start" font-weight="normal" letter-spacing="0">cuántos traer, hasta 500</text>
<text x="750" y="996" fill="#ff5ea8" font-size="12.5" text-anchor="start" font-weight="normal" letter-spacing="0">% similitud</text>
<text x="900" y="996" fill="#8a938a" font-size="12" text-anchor="start" font-weight="normal" letter-spacing="0">umbral mínimo para dibujar una arista</text>
<text x="750" y="1026" fill="#ff5ea8" font-size="12.5" text-anchor="start" font-weight="normal" letter-spacing="0">país / región</text>
<text x="900" y="1026" fill="#8a938a" font-size="12" text-anchor="start" font-weight="normal" letter-spacing="0">solo en coconews</text>
<text x="750" y="1056" fill="#ff5ea8" font-size="12.5" text-anchor="start" font-weight="normal" letter-spacing="0">entidad</text>
<text x="900" y="1056" fill="#8a938a" font-size="12" text-anchor="start" font-weight="normal" letter-spacing="0">persona u organización, vía NER</text>
<line x1="750" y1="876" x2="750" y2="918" stroke="#ff5ea8" stroke-width="1.5" stroke-opacity="0.5" marker-end="url(#f3)"/>
<text x="46" y="1138" fill="#5a625a" font-size="11" text-anchor="start" font-weight="normal" letter-spacing="0">upleaks.org — software libre — gitea.laenre.net/hacklab/FLUJOS</text>
</svg>

After

Width:  |  Height:  |  Size: 20 KiB

View file

@ -0,0 +1,188 @@
#!/usr/bin/env python3
# Genera el diagrama de fuentes y clasificacion de UP-LEAKS.
import io, sys
W = 1500
NEON, NEON2 = "#39ff14", "#7cff5a"
BG, PANEL = "#050505", "#0d0f0d"
GRIS, GRIS2 = "#8a938a", "#5a625a"
CIAN, AMBAR, MAGENTA, ROJO = "#3ad6ff", "#ffb020", "#ff5ea8", "#ff4d4d"
# color por tema, el mismo de la web
TEMAS = [
("GLOB-WAR", "guerra global", "#ff3b3b", 49,
["Internacional", "Asia", "Oriente Medio", "Defensa", "Geopolítica",
"Afganistán", "Europa", "Conflictos", "Rusia", "Humanitario"]),
("INT-SEC", "inteligencia y seguridad", "#4a6bff", 19,
["Ciberseguridad", "Análisis", "Defensa", "Inteligencia",
"Internacional", "Europa", "España", "EEUU"]),
("CLIMATE", "cambio climático", "#5fe36a", 120,
["Internacional", "EEUU", "Ciencia", "Biodiversidad", "Energía",
"Asia", "Tecnología", "ONG", "Salud", "España"]),
("ECO-CORP", "economía y corporaciones", "#ffe600", 24,
["Internacional", "Tecnología", "EEUU", "España",
"Gestión", "Corporaciones", "Comercio"]),
("POPL-UP", "demografía y sociedad", "#ff9b30", 24,
["España", "Internacional", "EEUU", "Salud", "Derechos Humanos",
"Política", "Migración", "Europa", "Reino Unido"]),
]
FUENTES = [
("236 feeds RSS", CIAN, ["prensa de 5 idiomas", "agencias y cabeceras",
"medios locales y de exilio"]),
("API de Wikipedia", CIAN, ["28.266 artículos", "por tema y palabra clave",
"el contexto histórico"]),
("WikiLeaks", CIAN, ["36.182 documentos", "archivo completo por torrent",
"cables, correos, informes"]),
("Imágenes", CIAN, ["og:image de cada artículo", "fotos de Wikipedia",
"descritas con Qwen3-VL"]),
]
FILTROS = [
("tema", "la vista que eliges: GLOB-WAR, INT-SEC…"),
("subtema", "desplegable, hereda del feed"),
("fecha", "Semanal (7 días) o Todas"),
("palabra clave","busca dentro del texto"),
("nodos", "cuántos traer, hasta 500"),
("% similitud", "umbral mínimo para dibujar una arista"),
("país / región","solo en coconews"),
("entidad", "persona u organización, vía NER"),
]
o = []
a = o.append
def caja(x, y, w, h, color, ancho=1.5, relleno=PANEL, op=1.0):
a(f'<rect x="{x:.0f}" y="{y:.0f}" width="{w:.0f}" height="{h:.0f}" rx="4" fill="{relleno}" '
f'stroke="{color}" stroke-width="{ancho}" stroke-opacity="{op}"/>')
def txt(x, y, s, color=GRIS, size=12, anchor="start", peso="normal", ls=0):
a(f'<text x="{x:.0f}" y="{y:.0f}" fill="{color}" font-size="{size}" '
f'text-anchor="{anchor}" font-weight="{peso}" letter-spacing="{ls}">{s}</text>')
# ── cabecera ──────────────────────────────────────────────────────────────
cuerpo = []
a_real = a
o_head = []
Y = 130
# FUENTES
fw, fgap = 340, 26
fx0 = (W - (4 * fw + 3 * fgap)) / 2
fh = 118
# CLASIFICACION
Y2 = Y + fh + 96
h_clas = 128
# TEMAS
Y3 = Y2 + h_clas + 86
tw, tgap = 276, 20
tx0 = (W - (5 * tw + 4 * tgap)) / 2
th = 44 + 10 * 20 + 16
# FILTROS
Y4 = Y3 + th + 108
h_filt = 44 + 4 * 30 + 16
H = Y4 + h_filt + 54
a(f'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 {W} {H}" width="{W}" height="{H}" '
f'font-family="DejaVu Sans Mono, Menlo, Consolas, monospace" role="img" '
f'aria-label="De donde salen los datos de UP-LEAKS y como se clasifican en temas, subtemas y filtros">')
a('<defs>')
for nom, col in (("f1", CIAN), ("f2", NEON), ("f3", MAGENTA)):
a(f'<marker id="{nom}" markerWidth="9" markerHeight="9" refX="7" refY="3" orient="auto">'
f'<path d="M0,0 L7,3 L0,6 Z" fill="{col}" opacity="0.85"/></marker>')
a('</defs>')
a(f'<rect width="{W}" height="{H}" fill="{BG}"/>')
txt(46, 54, 'DE DÓNDE SALEN LOS DATOS', NEON, 27, peso="bold", ls=3)
txt(46, 80, 'Cuatro fuentes, una etiqueta que viaja con cada documento, y los filtros que salen de ahí.', GRIS, 14)
a(f'<line x1="46" y1="96" x2="{W-46}" y2="96" stroke="{NEON}" stroke-opacity="0.28"/>')
# ── 1. FUENTES ────────────────────────────────────────────────────────────
txt(46, Y - 12, '1 · LO QUE ENTRA', CIAN, 13, ls=2)
centros = []
for i, (nom, col, lineas) in enumerate(FUENTES):
x = fx0 + i * (fw + fgap)
caja(x, Y, fw, fh, col, 1.5, PANEL, 0.85)
txt(x + 18, Y + 30, nom, col, 16, peso="bold")
for j, l in enumerate(lineas):
txt(x + 18, Y + 56 + j * 20, ' ' + l, GRIS, 11.5)
centros.append(x + fw / 2)
# ── 2. LA ETIQUETA ────────────────────────────────────────────────────────
cx = W / 2
for c in centros:
a(f'<line x1="{c:.0f}" y1="{Y+fh+4}" x2="{cx:.0f}" y2="{Y2-10}" stroke="{CIAN}" '
f'stroke-opacity="0.35" stroke-width="1.1" marker-end="url(#f1)"/>')
caja(46, Y2, W - 92, h_clas, NEON, 1.8)
txt(64, Y2 + 28, '2 · LA ETIQUETA NO SE CALCULA: VIAJA CON LA FUENTE', NEON, 13, ls=2)
txt(64, Y2 + 56,
'Cada feed del catálogo lleva escrito su tema y su subtema. Al ingerir un artículo, el artículo los hereda.', GRIS, 12.5)
txt(64, Y2 + 76,
'No hay clasificador automático: la decisión es editorial y está en el catálogo, no en el texto.', GRIS, 12.5)
txt(64, Y2 + 104,
'Es simple y es auditable — se ve de un vistazo por qué un artículo está donde está — pero tiene un coste: si un', GRIS2, 11.5)
txt(64, Y2 + 120,
'medio de clima publica sobre geopolítica, ese artículo entra igualmente como clima.', GRIS2, 11.5)
# tarjeta de ejemplo, a la derecha del bloque
ex_x, ex_w = W - 500, 436
caja(ex_x, Y2 + 16, ex_w, 96, AMBAR, 1.2, "#12100a", 0.8)
txt(ex_x + 16, Y2 + 38, 'coconews_feeds', AMBAR, 11.5, ls=1)
for j, (k, v) in enumerate([('nombre', '"Ariana News Dari"'),
('tema', '"guerra global"'),
('subtema', '"Afganistán"')]):
txt(ex_x + 16, Y2 + 60 + j * 18, k, GRIS2, 11.5)
txt(ex_x + 110, Y2 + 60 + j * 18, v, NEON2 if k != 'nombre' else GRIS, 11.5)
# ── 3. TEMAS Y SUBTEMAS ───────────────────────────────────────────────────
_e3 = '3 · CINCO TEMAS, Y LOS SUBTEMAS QUE EXISTEN DE VERDAD'
for i, (etq, tema, col, nfeeds, subs) in enumerate(TEMAS):
x = tx0 + i * (tw + tgap)
caja(x, Y3, tw, th, col, 1.6, PANEL, 0.9)
a(f'<rect x="{x:.0f}" y="{Y3:.0f}" width="{tw}" height="30" rx="4" fill="{col}" fill-opacity="0.16"/>')
txt(x + 14, Y3 + 21, etq, col, 14, peso="bold", ls=1)
txt(x + tw - 14, Y3 + 21, f'{nfeeds} feeds', GRIS2, 11, anchor="end")
txt(x + 14, Y3 + 44, tema, GRIS2, 10.5)
for j, s in enumerate(subs[:10]):
txt(x + 14, Y3 + 66 + j * 20, '· ' + s, GRIS, 11.5)
a(f'<line x1="{cx:.0f}" y1="{Y2+h_clas+4}" x2="{x+tw/2:.0f}" y2="{Y3-4}" '
f'stroke="{NEON}" stroke-opacity="0.28" stroke-width="1.1" marker-end="url(#f2)"/>')
a(f'<rect x="40" y="{Y3-30}" width="{len(_e3)*8.7:.0f}" height="26" fill="{BG}"/>')
txt(46, Y3 - 11, _e3, NEON2, 13, ls=2)
txt(46, Y3 + th + 24,
'Los subtemas son geográficos y de sección, no conceptuales. No hay un subtema "energía renovable": hay "Energía", que es lo que',
GRIS2, 11.5)
txt(46, Y3 + th + 40,
'trae el catálogo. El menú de la web todavía ofrece algunos que no existen en la base y por eso filtran a cero.',
GRIS2, 11.5)
# ── 4. FILTROS ────────────────────────────────────────────────────────────
caja(46, Y4, W - 92, h_filt, MAGENTA, 1.5)
_e4 = '4 · LO QUE PUEDES FILTRAR'
a(f'<rect x="40" y="{Y4-30}" width="{len(_e4)*8.7:.0f}" height="26" fill="{BG}"/>')
txt(46, Y4 - 11, _e4, MAGENTA, 13, ls=2)
for i, (nom, desc) in enumerate(FILTROS):
col_i, fila = divmod(i, 4)
x = 70 + col_i * ((W - 140) / 2)
y = Y4 + 40 + fila * 30
txt(x, y, nom, MAGENTA, 12.5)
txt(x + 150, y, desc, GRIS, 12)
a(f'<line x1="{cx:.0f}" y1="{Y3+th+58}" x2="{cx:.0f}" y2="{Y4-8}" stroke="{MAGENTA}" '
f'stroke-width="1.5" stroke-opacity="0.5" marker-end="url(#f3)"/>')
txt(46, H - 22, 'upleaks.org — software libre — gitea.laenre.net/hacklab/FLUJOS', GRIS2, 11)
a('</svg>')
io.open(sys.argv[1], 'w', encoding='utf-8').write('\n'.join(o))
print("escrito", sys.argv[1], "| alto:", H)

View file

@ -31,6 +31,16 @@ qué había escrito sobre eso antes de que se contara.
| Fragmentos vectorizados | 531.306 |
| Aristas del grafo | 115.035.059 |
## De dónde salen los datos
![De dónde salen los datos](INFO/DOCS/diagramas/fuentes-y-clasificacion.svg)
Cuatro fuentes. La etiqueta de tema y subtema no se calcula del texto: viaja con el feed,
y el artículo la hereda al entrar. Es una decisión editorial, no estadística — auditable, y
corregible editando una fila del catálogo.
Más detalle en [De dónde salen los datos](https://gitea.laenre.net/hacklab/FLUJOS/wiki/Fuentes-y-clasificacion).
## Arquitectura
![Arquitectura](INFO/DOCS/diagramas/arquitectura.svg)