""" Extrage lecțiile FĂRĂ video (text/quiz) — pe care extract_audio.py le sare, pentru că el caută doar un MP4. API-ul de lecție întoarce conținutul în câmpul `html`, împreună cu tot CSS-ul paginii systeme.io. Curățăm style/script, apoi tagurile, și scriem text în același loc cu transcrierile, ca să intre în același flux de sumarizare. """ import argparse import html as html_mod import logging import os import re import sys from pathlib import Path import requests from dotenv import load_dotenv from download import BASE, get_course_id, get_lecture_video_url, get_menu, login, slugify from extract_audio import CORE_MODULES logging.basicConfig(level=logging.INFO, format="%(asctime)s [%(levelname)s] %(message)s") log = logging.getLogger(__name__) def lecture_text(session: requests.Session, lecture_id: int) -> str: raw = session.get(f"{BASE}/api/membership/lecture/{lecture_id}").json().get("html") or "" raw = re.sub(r"(?is)<(style|script)\b.*?", " ", raw) text = html_mod.unescape(re.sub(r"<[^>]+>", "\n", raw)) lines = [ln.strip() for ln in text.split("\n") if ln.strip()] return "\n".join(lines) def main(): p = argparse.ArgumentParser(description="Extrage lecțiile text din cursul ATM") p.add_argument("--out", default="transcripts") p.add_argument("--only", default=None, help="Un singur modul (ocolește CORE_MODULES)") args = p.parse_args() load_dotenv() email, password = os.getenv("ATM_EMAIL", ""), os.getenv("ATM_PASSWORD", "") if not email or not password: log.error("Setează ATM_EMAIL și ATM_PASSWORD în .env") sys.exit(1) session = requests.Session() session.headers.update({"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)"}) login(session, email, password) modules = get_menu(session, get_course_id(session)) done = skipped = 0 for mod_idx, mod in enumerate(modules, 1): if args.only: if mod["name"] != args.only: continue elif mod["name"] not in CORE_MODULES: continue for lec_idx, lec in enumerate(mod["lectures"], 1): try: if get_lecture_video_url(session, lec["id"]): continue # are video -> îl ia extract_audio.py except requests.exceptions.HTTPError as e: if e.response is not None and e.response.status_code == 403: continue # fără acces raise dest = Path(args.out) / f"{mod_idx:02d}_{slugify(mod['name'])}" / f"{lec_idx:02d}_{slugify(lec['name'])}.txt" if dest.exists() and dest.stat().st_size > 200: log.info(f" Există deja: {dest.name}") skipped += 1 continue text = lecture_text(session, lec["id"]) if len(text) < 200: log.info(f" Prea puțin text, probabil quiz gol: {lec['name']}") continue dest.parent.mkdir(parents=True, exist_ok=True) dest.write_text(text, encoding="utf-8") log.info(f" Extras ({len(text)} caractere): {dest}") done += 1 log.info("=" * 60) log.info(f"Lecții text extrase: {done}, sărite: {skipped}.") if __name__ == "__main__": main()