Initial commit - FLUJOS codebase (production branch)
Includes: FLUJOS app (Node/Flask/Python), FLUJOS_DATOS scripts (scrapers, Keras, Django) Excludes: MongoDB, scraped data, Wikipedia/WikiLeaks dumps, Python venv, node_modules
This commit is contained in:
commit
a40b946163
158 changed files with 196645 additions and 0 deletions
497
FLUJOS_DATOS/NOTICIAS/DOCS/arquitectura_main.txt
Normal file
497
FLUJOS_DATOS/NOTICIAS/DOCS/arquitectura_main.txt
Normal file
|
|
@ -0,0 +1,497 @@
|
|||
┌───────────────────────────────────────────────────┐
|
||||
│ main() │
|
||||
└──────────────┬────────────────────────────────────┘
|
||||
│
|
||||
Lista de URLs de medios y leaks
|
||||
│
|
||||
▼
|
||||
┌───────────────────────────────────────────────────────────────┐
|
||||
│ register_processed_notifications(base_folder, urls) │
|
||||
│ - Crea/lee processed_articles.txt │
|
||||
│ - Filtra duplicados │
|
||||
└──────────────┬───────────────────────────────────────────────┘
|
||||
│ urls_to_process
|
||||
┌─────────────────┴───────────────────────────┐
|
||||
│ │
|
||||
▼ ▼
|
||||
┌──────────────────────────────┐ ┌──────────────────────────────┐
|
||||
│ explore_and_extract_articles │ │ explore_wayback_machine │
|
||||
│ (crawling + extracción) │ │ (consulta Wayback y extrae) │
|
||||
└────────────┬─────────────────┘ └────────────┬─────────────────┘
|
||||
│ │
|
||||
│ guarda │ guarda
|
||||
▼ ▼
|
||||
┌────────────────────┐ ┌────────────────────┐
|
||||
│ articulos/ (txt) │ │ articulos/ (txt) │
|
||||
└────────────────────┘ └────────────────────┘
|
||||
▲ ▲
|
||||
│ │
|
||||
▼ ▼
|
||||
┌────────────────────┐ ┌────────────────────┐
|
||||
│ archivos/ (bin) │ ← descarga │ (no aplica) │
|
||||
└────────────────────┘ └────────────────────┘
|
||||
|
||||
┌────────────────────────────────────────────────┐
|
||||
│ process_files(archivos/ → tokenized/) │
|
||||
│ tokenize_all_articles(articulos/ → tokenized/) │
|
||||
└──────────────┬─────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌────────────────────┐
|
||||
│ tokenized/ (ids) │ ← ids BERT (máx 512)
|
||||
└────────────────────┘
|
||||
|
||||
▼
|
||||
┌──────────────────────────┐
|
||||
│ get_folder_info + logs │
|
||||
└──────────────────────────┘
|
||||
|
||||
Entrada: url raíz, folders, processed_urls, size_limit, depth=0..6
|
||||
│
|
||||
▼
|
||||
┌──────────────────────────┐
|
||||
│ HTMLSession().get(url) │
|
||||
│ response.html.render() │ ← render JS (headless)
|
||||
└─────────────┬────────────┘
|
||||
│
|
||||
▼
|
||||
Conjunto de absolute_links
|
||||
│
|
||||
┌────────────────┴─────────────────┐
|
||||
│ │
|
||||
Si extensión conocida Si página HTML genérica
|
||||
(.pdf .csv .txt .xlsx .docx (sin extensión/otra cosa)
|
||||
.html .md .zip) │
|
||||
│ ▼
|
||||
▼ ┌──────────────────────────────┐
|
||||
┌──────────────────────────┐ │ extract_and_save_article() │
|
||||
│ download_and_save_file() │ │ - parse <title>, <p> │
|
||||
│ → archivos/ │ │ - translate → clean → txt │
|
||||
└───────────┬──────────────┘ │ - guardar en articulos/ │
|
||||
│ └──────────────┬───────────────┘
|
||||
│ (tras cada acción) │
|
||||
▼ ▼ (recursivo)
|
||||
get_folder_info(articulos/, archivos/) explore_and_extract_articles(link, depth+1)
|
||||
│
|
||||
▼
|
||||
¿total_size >= 50GB? ──► Sí: detener │ No: continuar
|
||||
|
||||
|
||||
archivos/ ──────────────────────────────────────────────────────┐
|
||||
▼
|
||||
Para cada archivo según extensión:
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ .pdf → read_pdf() → texto │
|
||||
│ .csv → read_csv() → texto │
|
||||
│ .txt → open().read() → texto │
|
||||
│ .docx → read_docx() → texto │
|
||||
│ .xlsx → read_xlsx() → texto │
|
||||
│ .zip → read_zip() → texto concatenado │
|
||||
│ .html/.md → read_html_md() → format_content()(*) → texto │
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
translate_text(deep_translator → 'es')
|
||||
│
|
||||
▼
|
||||
clean_text( BeautifulSoup strip + minúsculas
|
||||
+ quita URLs + solo letras/espacios
|
||||
+ colapsa espacios + STOPWORDS_ES )
|
||||
│
|
||||
▼
|
||||
tokenize_and_save(texto_limpio, filename, tokenized/)
|
||||
│
|
||||
▼
|
||||
tokenized/ contiene IDs BERT (máx 512)
|
||||
(*) Nota: `format_content()` está vacío en tu snippet; hoy actúa como no-op.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
articulos/ (txt limpios/es) ─────► para cada .txt:
|
||||
│
|
||||
▼
|
||||
tokenizer.encode(text, max_length=512, add_special_tokens=True)
|
||||
│
|
||||
▼
|
||||
'id id id ...' → escribe en tokenized/ con
|
||||
mismo nombre de archivo
|
||||
|
||||
|
||||
|
||||
clean_filename(name)
|
||||
- reemplaza \ / * ? : " < > | por "_"
|
||||
- espacios → '_'
|
||||
- corta a 100 chars
|
||||
|
||||
register_processed_notifications(base_folder, urls)
|
||||
- lee base_folder/processed_articles.txt (si existe)
|
||||
- devuelve solo URLs no vistas
|
||||
- añade nuevas al final (append)
|
||||
|
||||
explore_wayback_machine(url)
|
||||
- GET http://archive.org/wayback/available?url=...
|
||||
- si hay 'closest' → extract_and_save_article(archive_url)
|
||||
|
||||
|
||||
|
||||
translate_text(text) ──► GoogleTranslator(auto→'es') ──► texto_en_es
|
||||
│
|
||||
▼
|
||||
clean_text():
|
||||
1) quita CDATA variantes: <! [ CDATA [ ... ] ] >
|
||||
2) BeautifulSoup → .get_text()
|
||||
3) lower()
|
||||
4) elimina URLs (regex http\S+)
|
||||
5) deja solo letras españolas y espacio (regex)
|
||||
6) colapsa espacios
|
||||
7) filtra STOPWORDS (lista extensa ES)
|
||||
|
||||
|
||||
/var/www/theflows.net/flujos/FLUJOS_DATOS/NOTICIAS/
|
||||
├── articulos/ (txt limpios en ES, de páginas HTML/Wayback)
|
||||
├── archivos/ (descargas crudas: pdf, csv, xlsx, docx, zip, html, md, txt)
|
||||
├── tokenized/ (mismos nombres, contenido = IDs BERT separados por espacio)
|
||||
└── processed_articles.txt (histórico de URLs procesadas)
|
||||
|
||||
|
||||
logging.basicConfig(level=INFO)
|
||||
- Traza etapas (descarga, extracción, tokenización)
|
||||
- Resumen final:
|
||||
* nº ficheros en articulos/, archivos/, tokenized/
|
||||
* tamaños totales (MB)
|
||||
- Cortafuegos de tamaño: 50 GB entre articulos/ + archivos/
|
||||
|
||||
|
||||
|
||||
[ main() ]
|
||||
│
|
||||
▼
|
||||
register_processed_notifications()
|
||||
│ → filtra URLs ya procesadas
|
||||
▼
|
||||
+---------------------------+
|
||||
| urls_to_process (nuevas) |
|
||||
+---------------------------+
|
||||
│
|
||||
▼
|
||||
explore_and_extract_articles()
|
||||
│
|
||||
├─► Si enlace a archivo (.pdf, .csv, .txt, .xlsx, .docx, .html, .md, .zip)
|
||||
│ └─► download_and_save_file() → guarda en /archivos
|
||||
│
|
||||
├─► Si enlace HTML → extract_and_save_article()
|
||||
│ ├─ traduce (translate_text)
|
||||
│ ├─ limpia (clean_text)
|
||||
│ └─ guarda .txt en /articulos
|
||||
│
|
||||
└─► Recursivo hasta max_depth o límite 50 GB
|
||||
│
|
||||
▼
|
||||
explore_wayback_machine() → descarga versión archivada si existe
|
||||
│
|
||||
▼
|
||||
process_files(/archivos → /tokenized)
|
||||
│ ├─ read_pdf/csv/docx/xlsx/zip/html_md/txt
|
||||
│ ├─ translate_text()
|
||||
│ ├─ clean_text()
|
||||
│ └─ tokenize_and_save() con BERT
|
||||
│
|
||||
▼
|
||||
tokenize_all_articles(/articulos → /tokenized)
|
||||
│ └─ encode con BERT en IDs separados por espacio
|
||||
│
|
||||
▼
|
||||
get_folder_info() → logs resumen final
|
||||
|
||||
|
||||
===========================================================
|
||||
Flujo simplificado de procesamiento de un archivo
|
||||
===========================================================
|
||||
|
||||
archivo descargado
|
||||
│
|
||||
▼
|
||||
read_*() según extensión
|
||||
│
|
||||
▼
|
||||
translate_text() → GoogleTranslator(auto→es)
|
||||
│
|
||||
▼
|
||||
clean_text()
|
||||
├─ elimina CDATA y HTML
|
||||
├─ minúsculas, sin URLs, solo letras/es
|
||||
├─ colapsa espacios
|
||||
└─ filtra stopwords ES
|
||||
│
|
||||
▼
|
||||
tokenize_and_save()
|
||||
├─ tokenizer.encode(max 512 tokens)
|
||||
└─ guarda IDs BERT en /tokenized
|
||||
|
||||
|
||||
===========================================================
|
||||
Estructura de carpetas
|
||||
===========================================================
|
||||
|
||||
NOTICIAS/
|
||||
├── articulos/ ← .txt limpios en español
|
||||
├── archivos/ ← binarios crudos descargados
|
||||
├── tokenized/ ← tokens BERT (IDs)
|
||||
└── processed_articles.txt ← historial de URLs
|
||||
|
||||
|
||||
===========================================================
|
||||
Control y límites
|
||||
===========================================================
|
||||
|
||||
- Profundidad máxima de crawling: max_depth = 6
|
||||
- Tamaño combinado artículos+archivos: límite 50 GB
|
||||
- Evita duplicados con processed_articles.txt
|
||||
- Logs detallados en consola
|
||||
|
||||
|
||||
|
||||
████████████████████████████████████ FLUJOS: ESQUEMA TÉCNICO (ASCII) ████████████████████████████████████
|
||||
|
||||
[ ENTORNO / DEPENDENCIAS ]
|
||||
- GoogleTranslator (deep_translator) → API web de Google Translate (auto→es)
|
||||
- requests / requests_html.HTMLSession → HTTP + renderizado JS (chromium/headless)
|
||||
- BeautifulSoup (bs4) → Parseo HTML, extracción de texto
|
||||
- PyPDF2.PdfReader → Extracción texto de PDFs (si embebido/copiable)
|
||||
- openpyxl → Lectura de .xlsx
|
||||
- python-docx (docx) → Lectura de .docx
|
||||
- zipfile → Descompresión y lectura (texto) de ficheros en ZIP
|
||||
- html2text (no usado aquí en format_content)→ [placeholder]
|
||||
- transformers.BertTokenizer → Tokenizador BERT ES (dccuchile/bert-base-spanish-wwm-cased)
|
||||
- tqdm, logging, os, re, json, time, csv, hashlib, urllib.parse (urlparse/urljoin) → utilidades
|
||||
|
||||
[ ESTRUCTURA DE CARPETAS (I/O) ]
|
||||
/var/www/theflows.net/flujos/FLUJOS_DATOS/NOTICIAS/
|
||||
├── articulos/ (TXT limpios en español, derivados de HTML/Wayback)
|
||||
├── archivos/ (descargas crudas: .pdf .csv .txt .xlsx .docx .html .md .zip)
|
||||
├── tokenized/ (TXT con IDs de tokens BERT, máx 512 tokens por archivo)
|
||||
└── processed_articles.txt (histórico de URLs ya procesadas → evita duplicados)
|
||||
|
||||
=============================================================================================================
|
||||
[ main() ]
|
||||
- Inicializa: URLs objetivo, rutas base, límite de 50GB, carpetas si no existen
|
||||
- Flujo:
|
||||
1) urls_to_process = register_processed_notifications(base_folder, urls)
|
||||
2) Para url en urls_to_process:
|
||||
a) explore_and_extract_articles(url, articulos/, archivos/, processed_urls, size_limit)
|
||||
b) explore_wayback_machine(url, articulos/)
|
||||
3) process_files(archivos/ → tokenized/)
|
||||
4) tokenize_all_articles(articulos/ → tokenized/)
|
||||
5) get_folder_info() sobre cada carpeta y logging resumen
|
||||
- Side effects: Escritura en articulos/, archivos/, tokenized/, processed_articles.txt; logs INFO
|
||||
|
||||
=============================================================================================================
|
||||
[ register_processed_notifications(base_folder, urls) ]
|
||||
- Lee/crea processed_articles.txt
|
||||
- Devuelve: lista de URLs no presentes (nuevas)
|
||||
- Efectos:
|
||||
* append de nuevas URLs al fichero
|
||||
- Riesgos:
|
||||
* Fichero grande con el tiempo (puede optimizarse a DB/Set persistente)
|
||||
* No bloquea concurrencia (carreras si hay procesos paralelos)
|
||||
|
||||
=============================================================================================================
|
||||
[ explore_and_extract_articles(url, articulos/, archivos/, processed_urls, size_limit, depth=0..6) ]
|
||||
- Hace GET + render JS:
|
||||
session = HTMLSession(); response = session.get(url); response.html.render()
|
||||
- Obtiene absolute_links (con JS resuelto)
|
||||
- Para cada link:
|
||||
* Si ya está en processed_urls → skip
|
||||
* Marca link como procesado (set in-memory)
|
||||
* Detecta extensión: [.pdf .csv .txt .xlsx .docx .html .md .zip]
|
||||
- Coincide → download_and_save_file(link, archivos/)
|
||||
- mailto:/tel: → ignora
|
||||
- Otro/HTML → extract_and_save_article(link, articulos/); recursión depth+1
|
||||
- Control de tamaño:
|
||||
* get_folder_info(articulos/) + get_folder_info(archivos/) → si ≥ 50GB → cortar
|
||||
- Notas:
|
||||
* render() requiere Chromium instalado y recursos; costoso en CPU/RAM
|
||||
* Cuidado con sitios SPA/anti-bot; timeouts (30s)
|
||||
* max_depth=6 limita explosión de enlaces; se puede poner filtro de dominio
|
||||
|
||||
=============================================================================================================
|
||||
[ download_and_save_file(url, archivos/) ]
|
||||
- Descarga streaming (chunk 8192) con requests.get(url, stream=True, timeout=30)
|
||||
- Filename = clean_filename(último segmento URL) || 'archivo_descargado'
|
||||
- Escribe binario en archivos/
|
||||
- Errores:
|
||||
* response.status_code != 200 → log
|
||||
* timeouts/conexión → log
|
||||
- Seguridad:
|
||||
* No ejecuta nada; sólo guarda
|
||||
* Riesgo: HTML/JS guardado como .html/.md puede contener scripts (pero se procesa como texto después)
|
||||
|
||||
=============================================================================================================
|
||||
[ extract_and_save_article(url, articulos/) ]
|
||||
- GET simple (requests.get, timeout=30)
|
||||
- Parse HTML: <title> y todos los <p> → concatena texto
|
||||
- Procesa:
|
||||
* translate_text() (auto→es)
|
||||
* clean_text()
|
||||
- Nombre archivo:
|
||||
* title → clean_filename(title) + '.txt'
|
||||
* fallback: último segmento de path URL + '.txt'
|
||||
- Guarda .txt en articulos/
|
||||
- Riesgos:
|
||||
* Páginas con contenido en divs/aria/role no capturado por <p> → menos texto
|
||||
* Limitaciones del traductor (cuotas, longitudes, errores temporales)
|
||||
* Si content vacío → log y skip
|
||||
|
||||
=============================================================================================================
|
||||
[ explore_wayback_machine(url, articulos/) ]
|
||||
- Consulta API: http://archive.org/wayback/available?url={url}
|
||||
- Si hay 'closest' → archive_url → extract_and_save_article(archive_url)
|
||||
- Usos:
|
||||
* Resiliencia ante 404/robots o contenido rotativo
|
||||
- Riesgos:
|
||||
* No todas las páginas están archivadas
|
||||
* Rate limits
|
||||
|
||||
=============================================================================================================
|
||||
[ process_files(archivos/, tokenized/) ]
|
||||
- Itera archivos descargados por extensión:
|
||||
.pdf → read_pdf() (PdfReader.extract_text por página)
|
||||
.csv → read_csv() (csv.reader → " ".join(row))
|
||||
.txt → open().read() (texto tal cual)
|
||||
.docx → read_docx() (docx.Document → concat párrafos)
|
||||
.xlsx → read_xlsx() (openpyxl → concat celdas por fila)
|
||||
.zip → read_zip() (abre cada entrada, decode utf-8 ignore)
|
||||
.html/.md → read_html_md() → format_content() [*format_content está vacía → no-op]
|
||||
- Para cada contenido (si hay texto):
|
||||
translate_text() → clean_text() → tokenize_and_save(cleaned, filename, tokenized/)
|
||||
- Notas:
|
||||
* Archivos binarios dentro del ZIP no-UTF8 se ignoran por decode errors (ignore)
|
||||
* PDF sin capa de texto → extract_text() puede devolver None
|
||||
* XLSX grande → memoria/tiempo; iter_rows() es razonable
|
||||
|
||||
=============================================================================================================
|
||||
[ tokenize_all_articles(articulos/, tokenized/) ]
|
||||
- Para cada .txt en articulos/:
|
||||
tokenizer.encode(text, truncation=True, max_length=512, add_special_tokens=True)
|
||||
→ 'ids' separados por espacio → guarda con mismo filename en tokenized/
|
||||
- Notas:
|
||||
* Truncation a 512 tokens: se pierde contenido largo (considerar sliding windows)
|
||||
* add_special_tokens=True añade [CLS]/[SEP]
|
||||
|
||||
=============================================================================================================
|
||||
[ tokenize_and_save(text, filename, tokenized/) ]
|
||||
- Encapsula la llamada a tokenizer.encode(...) con truncation=512
|
||||
- Crea tokenized/ si no existe
|
||||
- Escribe "id id id ..." en archivo de salida
|
||||
- Riesgos:
|
||||
* Diferente encoding de entrada → normalizado por clean_text()
|
||||
* Si filename colisiona con otro (mismo nombre) → se sobrescribe
|
||||
|
||||
=============================================================================================================
|
||||
[ translate_text(text) ]
|
||||
- GoogleTranslator(source='auto', target='es').translate(text)
|
||||
- Devuelve texto traducido o el original si error (catch + log)
|
||||
- Limitaciones:
|
||||
* Longitudes excesivas → errores (“Text length need to be between 0 and 5000”)
|
||||
- Solución futura: fragmentar en bloques y recomponer
|
||||
* Rate limits/cambios API
|
||||
|
||||
=============================================================================================================
|
||||
[ clean_text(text) ]
|
||||
1) Quita CDATA: regex '<!\[\s*CDATA\s*\[.*?\]\]>' con flags=re.S
|
||||
2) BeautifulSoup(text, 'html.parser').get_text(separator=" ")
|
||||
3) lower()
|
||||
4) Elimina URLs: regex r'http\S+'
|
||||
5) Deja sólo letras españolas y espacios: r'[^a-záéíóúñü\s]' → ''
|
||||
6) Colapsa espacios: r'\s+' → ' ' + strip()
|
||||
7) Filtra STOPWORDS (set ES) palabra a palabra
|
||||
- Resulta en texto normalizado listo para BERT
|
||||
- Notas:
|
||||
* Pierde números, signos y acentos raros fuera de set
|
||||
* STOPWORDS puede ajustarse por dominio (noticias vs. técnico)
|
||||
|
||||
=============================================================================================================
|
||||
[ read_pdf(pdf_path) ]
|
||||
- Abre en binario, PdfReader(f)
|
||||
- Recorre páginas → page.extract_text() → concat + '\n'
|
||||
- Devuelve string (puede estar vacío)
|
||||
- Limitaciones:
|
||||
* PDFs escaneados → sin OCR (no texto)
|
||||
* Layouts complejos → texto desordenado
|
||||
|
||||
[ read_csv(csv_path) ]
|
||||
- csv.reader → por cada fila ' '.join(row) + '\n'
|
||||
- Simple y robusto; no maneja tipos/formato especial
|
||||
|
||||
[ read_docx(docx_path) ]
|
||||
- docx.Document → concat paragraph.text + '\n'
|
||||
- Pierde estilos/tablas; conserva sólo texto base
|
||||
|
||||
[ read_xlsx(xlsx_path) ]
|
||||
- openpyxl.load_workbook → por cada hoja → por cada fila
|
||||
- ' '.join(str(cell.value or '')) + '\n'
|
||||
- Pierde formato/tipos; sólo valores en orden de fila
|
||||
|
||||
[ read_zip(zip_path) ]
|
||||
- zipfile.ZipFile → recorre cada entry
|
||||
- z.open(filename).read().decode('utf-8', errors='ignore')
|
||||
- Concatena todo a un sólo string
|
||||
- Peligros: ZIP enorme → memoria; entries binarias → ignoradas por decode
|
||||
|
||||
[ read_html_md(file_path) ]
|
||||
- open(file, 'utf-8', errors='replace').read()
|
||||
- Retorna string crudo (sin limpieza HTML aquí)
|
||||
- format_content() se invoca después (actualmente vacío)
|
||||
|
||||
[ format_content(html_content) ]
|
||||
- [PLACEHOLDER] En el snippet está sin implementar.
|
||||
- Potencial:
|
||||
* html2text → Markdown plano
|
||||
* Limpieza de scripts/estilos/menus
|
||||
* Normalización de espacios/entidades
|
||||
- Hoy actúa como NO-OP (debería rellenarse)
|
||||
|
||||
=============================================================================================================
|
||||
[ get_page_title(url) ]
|
||||
- GET(url, timeout=10) → BeautifulSoup → <title>.text.strip()
|
||||
- Devuelve None si falla o no hay <title>
|
||||
- Usado para nombrar archivos de artículos
|
||||
|
||||
[ clean_filename(name) ]
|
||||
- Reemplaza caracteres prohibidos [\/*?:"<>|] por "_"
|
||||
- Espacios → "_"; corta a 100 chars
|
||||
- Evita errores en FS; normaliza nombres
|
||||
|
||||
[ get_folder_info(path) ]
|
||||
- Recorre recursivo → suma tamaño de ficheros y cuenta
|
||||
- Devuelve (total_size_bytes, total_files)
|
||||
- Usado para métricas y para detener por límite
|
||||
|
||||
=============================================================================================================
|
||||
[ LOGGING / MÉTRICAS / LÍMITES ]
|
||||
- logging.INFO por etapas (descargar, extraer, traducir, limpiar, tokenizar)
|
||||
- Límite de tamaño: 50GB (archivos + artículos) → detiene crawling
|
||||
- Resumen final:
|
||||
* Artículos descargados (# y MB)
|
||||
* Archivos descargados (# y MB)
|
||||
* Archivos tokenizados (# y MB)
|
||||
- Sugerencias:
|
||||
* Añadir manejo de reintentos/backoff a requests
|
||||
* Cache de traducciones por hash (ahorro de coste/tiempo)
|
||||
* Paralelización controlada (cola + límites I/O/CPU)
|
||||
* Particionar tokenized/ por subcarpetas si #ficheros crece
|
||||
|
||||
=============================================================================================================
|
||||
[ DATA FLOW (RESUMEN) ]
|
||||
URLs ──► register_processed_notifications ──► explore_* (HTMLSession/render/links)
|
||||
└────────► extract_and_save_article ──► translate_text ─► clean_text ─► articulos/*.txt
|
||||
└────────► download_and_save_file ─────────────────────────────────────► archivos/*
|
||||
archivos/* ──► process_files (read_* → translate → clean → tokenize) ──► tokenized/*
|
||||
articulos/*.txt ──► tokenize_all_articles ───────────────────────────────► tokenized/*
|
||||
tokenized/*, articulos/*, archivos/* ──► get_folder_info + logs
|
||||
|
||||
████████████████████████████████████████████████████████████████████████████████████
|
||||
Loading…
Add table
Add a link
Reference in a new issue