""" Găsește sesiuni Q&A duplicate (același videoclip urcat sub două date). Compară transcrierile la nivel de cuvinte normalizate (fără diacritice, fără punctuație), pentru că whisper produce text ușor diferit la două rulări pe aceeași sursă — un md5 pe audio nu le prinde. Prag: >60% cuvinte potrivite ȘI un bloc comun de >=40 de cuvinte consecutive. Blocul lung e cel care contează: două sesiuni diferite pe aceleași subiecte împart multe cuvinte, dar niciodată 40 la rând. """ import difflib import re import sys import unicodedata from itertools import combinations from pathlib import Path def words(path: Path) -> list[str]: t = unicodedata.normalize("NFKD", path.read_text(encoding="utf-8").lower()) return re.findall(r"[a-z]+", t.encode("ascii", "ignore").decode()) def is_duplicate(a: list[str], b: list[str]) -> tuple[bool, float, int]: if not a or not b or min(len(a), len(b)) / max(len(a), len(b)) < 0.7: return False, 0.0, 0 # lungimi prea diferite ca să fie același video blocks = difflib.SequenceMatcher(None, a, b, autojunk=False).get_matching_blocks() pct = 200 * sum(bl.size for bl in blocks) / (len(a) + len(b)) longest = max(bl.size for bl in blocks) return pct > 60 and longest >= 40, pct, longest def selftest(): base = "cand pretul ajunge in suport major si apare un buy doji intri cu toata pozitia".split() * 12 same = base[:-3] + "intri cu jumatate".split() # mici diferente de transcriere other = "volumul arata cine domina piata in fiecare moment al zilei".split() * 12 assert is_duplicate(base, same)[0], "acelasi video nu a fost detectat" assert not is_duplicate(base, other)[0], "sesiuni diferite marcate ca duplicat" assert not is_duplicate(base, [])[0], "transcriere goala (inca se scrie) trebuie ignorata" assert not is_duplicate(base, base[:20])[0], "lungimi foarte diferite trebuie ignorate" print("selftest ok") def main(): if "--selftest" in sys.argv: selftest() return 0 d = Path(sys.argv[1] if len(sys.argv) > 1 else "transcripts/09_Q_and_A") docs = {p.stem: words(p) for p in sorted(d.glob("*.txt"))} found = [] for x, y in combinations(docs, 2): dup, pct, longest = is_duplicate(docs[x], docs[y]) if dup: found.append((x, y)) print(f"DUPLICAT: {x} == {y} ({pct:.1f}% potrivite, bloc comun {longest} cuvinte)") if not found: print(f"Niciun duplicat între cele {len(docs)} transcrieri.") return 0 if __name__ == "__main__": sys.exit(main())