Files
urieljareth 621bbc5f5c feat: local content-mining platform for YouTube creator scraping
Scraper de canales de YouTube hacia notas Markdown para base de conocimiento
(Obsidian-ready), con plataforma web local.

Engine + CLI (Workstream A):
- Modular pipeline: discover/extract/parse/chapters/render/store + ratelimit
- SQLite store con migración idempotente: FTS5 (transcript search), columnas
  de metadata enriquecida, tablas cookies_meta y scrape_jobs
- Módulos: segments, cookies (Netscape vault), export (json/csv/srt/html),
  analysis (word freq/timeline/wordcloud), monitor (watch loop), pipeline
- CLI Click group: search, export, audio, channels, watch, analyze, re-render
- Fix del bug de scoping de cookies en cli.py

Webapp local (Workstream B):
- FastAPI backend: dashboard, channels, videos facetado, transcript, search
  FTS, analysis, scrape jobs con SSE, cookies drag-and-drop, exports,
  folders (abrir en OS), tools (re-render, formato)
- SPA no-build (Alpine.js + Tailwind + Chart.js por CDN): 9 vistas, tema
  dark command-center con acento rojo→rosa, cookie vault drag-drop,
  consola de scrapeo con progreso live vía SSE

Launcher + subagentes (Workstream C):
- start-server.bat / stop-server.bat con auto port-scan + browser open
- .opencode/agent/webapp-builder.md + .opencode/goals/webapp-build.md

Tests: 38 pytest verdes. Sin funcionalidad de IA (enfoque data-mining).
2026-07-26 23:19:34 -06:00

59 lines
1.8 KiB
Python

from __future__ import annotations
from yt_scraper.chapters import align_chapters, chapters_from_info, Chapter, Section
from yt_scraper.parse import Segment
def test_align_no_chapters():
segs = [Segment(0.0, 1.0, "a"), Segment(1.0, 2.0, "b")]
sections = align_chapters(segs, [])
assert len(sections) == 1
assert sections[0].title == "Transcripcion"
assert len(sections[0].segments) == 2
def test_align_with_chapters():
segs = [
Segment(0.0, 1.0, "intro"),
Segment(5.0, 6.0, "mid"),
Segment(20.0, 21.0, "end"),
]
chapters = [
Chapter(title="Intro", start_time=0.0, end_time=10.0),
Chapter(title="Desarrollo", start_time=10.0, end_time=30.0),
]
sections = align_chapters(segs, chapters)
assert len(sections) == 2
assert sections[0].title == "Intro"
assert len(sections[0].segments) == 2
assert sections[1].title == "Desarrollo"
assert len(sections[1].segments) == 1
assert sections[1].segments[0].text == "end"
def test_align_pre_chapter_segments():
segs = [Segment(0.0, 1.0, "antes")]
chapters = [Chapter(title="Cap 1", start_time=5.0, end_time=10.0)]
sections = align_chapters(segs, chapters)
assert len(sections) == 2
assert sections[0].title == "Inicio"
assert sections[0].segments[0].text == "antes"
def test_chapters_from_info():
info = {
"chapters": [
{"title": "Cap 1", "start_time": 0, "end_time": 60},
{"title": "Cap 2", "start_time": 60, "end_time": 120},
]
}
chapters = chapters_from_info(info)
assert len(chapters) == 2
assert chapters[0].title == "Cap 1"
assert chapters[1].start_time == 60.0
def test_chapters_from_info_empty():
assert chapters_from_info({}) == []
assert chapters_from_info({"chapters": []}) == []