Merlintxu commited on
Commit
4d72032
·
verified ·
1 Parent(s): 0f46479

Update conversation_storyline/io.py

Browse files
Files changed (1) hide show
  1. conversation_storyline/io.py +97 -49
conversation_storyline/io.py CHANGED
@@ -1,49 +1,97 @@
1
- import re
2
- from typing import List
3
- from .schemas import Interaction
4
-
5
-
6
- SPEAKER_PATTERNS = [
7
- # Speaker A: ...
8
- re.compile(r"^(?P<speaker>Speaker\s+[A-Za-z0-9_\- ]{1,64})\s*:\s*(?P<text>.+)\s*$"),
9
- # A: ...
10
- re.compile(r"^(?P<speaker>[A-Za-zÁÉÍÓÚÜÑáéíóúüñ0-9_\- ]{1,32})\s*:\s*(?P<text>.+)\s*$"),
11
- ]
12
-
13
-
14
- def parse_transcript(text: str) -> List[Interaction]:
15
- """
16
- Robusto para texto pegado:
17
- - Cada línea que matchee "SPEAKER: ..." crea nuevo mensaje.
18
- - Líneas sin speaker se anexan al texto del último mensaje (continuación).
19
- """
20
- lines = [l.rstrip() for l in (text or "").splitlines()]
21
- interactions: List[Interaction] = []
22
- cur = None
23
-
24
- for raw in lines:
25
- line = raw.strip()
26
- if not line:
27
- continue
28
-
29
- matched = None
30
- for pat in SPEAKER_PATTERNS:
31
- m = pat.match(line)
32
- if m:
33
- matched = m
34
- break
35
-
36
- if matched:
37
- speaker = matched.group("speaker").strip()
38
- msg = matched.group("text").strip()
39
- cur = Interaction(message_id=len(interactions), speaker=speaker, text=msg)
40
- interactions.append(cur)
41
- else:
42
- # continuation line
43
- if cur is None:
44
- cur = Interaction(message_id=0, speaker="Unknown", text=line)
45
- interactions.append(cur)
46
- else:
47
- cur.text = (cur.text + " " + line).strip()
48
-
49
- return interactions
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import re
2
+ from typing import List
3
+ from .schemas import Interaction
4
+
5
+
6
+ SPEAKER_PATTERNS = [
7
+ # Speaker A: ...
8
+ re.compile(r"^(?P<speaker>Speaker\s+[A-Za-z0-9_\- ]{1,64})\s*:\s*(?P<text>.+)\s*$"),
9
+ # A: ...
10
+ re.compile(r"^(?P<speaker>[A-Za-zÁÉÍÓÚÜÑáéíóúüñ0-9_\- ]{1,32})\s*:\s*(?P<text>.+)\s*$"),
11
+ ]
12
+
13
+
14
+ def parse_transcript(text: str) -> List[Interaction]:
15
+ """
16
+ Robusto para texto pegado:
17
+ - Cada línea que matchee "SPEAKER: ..." crea nuevo mensaje.
18
+ - Líneas sin speaker se anexan al texto del último mensaje (continuación).
19
+ """
20
+ lines = [l.rstrip() for l in (text or "").splitlines()]
21
+ interactions: List[Interaction] = []
22
+ cur = None
23
+
24
+ for raw in lines:
25
+ line = raw.strip()
26
+ if not line:
27
+ continue
28
+
29
+ matched = None
30
+ for pat in SPEAKER_PATTERNS:
31
+ m = pat.match(line)
32
+ if m:
33
+ matched = m
34
+ break
35
+
36
+ if matched:
37
+ speaker = matched.group("speaker").strip()
38
+ msg = matched.group("text").strip()
39
+ cur = Interaction(message_id=len(interactions), speaker=speaker, text=msg)
40
+ interactions.append(cur)
41
+ else:
42
+ # continuation line
43
+ if cur is None:
44
+ cur = Interaction(message_id=0, speaker="Unknown", text=line)
45
+ interactions.append(cur)
46
+ else:
47
+ cur.text = (cur.text + " " + line).strip()
48
+
49
+ return interactions
50
+ def load_messages_from_text(transcript_text: str) -> List[RawMessage]:
51
+ """
52
+ Parse transcript from a raw string blob, same logic as TXT loader.
53
+
54
+ Supported formats:
55
+ - [00:01] Ana: texto
56
+ - 00:01 Ana: texto
57
+ - Ana: texto
58
+
59
+ Lines that don't match any pattern are treated as continuation lines.
60
+ """
61
+ lines = [ln.strip() for ln in (transcript_text or "").splitlines() if ln.strip()]
62
+ if not lines:
63
+ return []
64
+
65
+ parsed = []
66
+ speakers = []
67
+
68
+ for ln in lines:
69
+ m = None
70
+ for pat in LINE_PATTERNS:
71
+ m = pat.match(ln)
72
+ if m:
73
+ break
74
+ if not m:
75
+ if parsed:
76
+ parsed[-1]["content"] += "\n" + ln
77
+ else:
78
+ parsed.append({"ts": None, "speaker": "Unknown", "content": ln})
79
+ continue
80
+
81
+ gd = m.groupdict()
82
+ speaker = normalize_speaker(gd.get("speaker") or "Unknown")
83
+ speakers.append(speaker)
84
+ parsed.append({"ts": gd.get("ts"), "speaker": speaker, "content": (gd.get("content") or "").strip()})
85
+
86
+ speakers_norm, _ = normalize_speakers(speakers)
87
+
88
+ msgs: List[RawMessage] = []
89
+ sp_i = 0
90
+ for i, r in enumerate(parsed):
91
+ sp = r["speaker"]
92
+ if sp != "Unknown" and sp_i < len(speakers_norm):
93
+ sp = speakers_norm[sp_i]
94
+ sp_i += 1
95
+ msgs.append(RawMessage(id=i, speaker=sp, content=r["content"], timestamp=r.get("ts")))
96
+ return msgs
97
+