1+ from __future__ import annotations
2+
3+ import argparse
4+ import sys
5+ import time
6+ from datetime import datetime , timezone
7+ from pathlib import Path
8+
9+ from .schema import Record , content_hash , JsonlWriter
10+ from .clean import clean_sentence , split_sentences , strip_pii , normalize , strip_markup
11+
12+
13+ def process_text (raw : str ) -> list [str ]:
14+ norm = normalize (strip_pii (strip_markup (raw )))
15+ out = []
16+ for s in split_sentences (norm ):
17+ c = clean_sentence (s )
18+ if c :
19+ out .append (c )
20+ return out
21+
22+
23+ def load_fleurs_transcripts () -> list [str ]:
24+ try :
25+ from datasets import load_dataset
26+ except ImportError :
27+ print (" [fleurs] datasets library not installed; skip" )
28+ return []
29+ for cfg in ("bho_in" , "bho" , "bhojpuri" ):
30+ try :
31+ print (f" [fleurs] trying config '{ cfg } '" )
32+ ds = load_dataset ("google/fleurs" , cfg )
33+ texts = []
34+ for split in ds :
35+ for row in ds [split ]:
36+ t = row .get ("transcription" ) or row .get ("raw_transcription" ) or ""
37+ if t .strip ():
38+ texts .append (t )
39+ print (f" [fleurs] config '{ cfg } ' gave { len (texts )} transcripts" )
40+ return texts
41+ except Exception as e :
42+ print (f" [fleurs] config '{ cfg } ' failed: { str (e )[:80 ]} " )
43+ print (" [fleurs] no working Bhojpuri config found; skip" )
44+ return []
45+
46+
47+ def load_rural_women_transcripts () -> list [str ]:
48+ try :
49+ from datasets import load_dataset
50+ except ImportError :
51+ print (" [rural] datasets library not installed; skip" )
52+ return []
53+ try :
54+ ds = load_dataset ("ai4bharat/Rural_Women_Bhojpuri" )
55+ except Exception as e :
56+ print (f" [rural] load failed: { str (e )[:100 ]} " )
57+ return []
58+ texts = []
59+ for split in ds :
60+ for row in ds [split ]:
61+ if any ("syn" in str (k ).lower () for k in row .keys () if row .get (k ) is True ):
62+ continue
63+ t = (row .get ("transcription" ) or row .get ("transcript" )
64+ or row .get ("text" ) or row .get ("sentence" ) or "" )
65+ if isinstance (t , str ) and t .strip ():
66+ texts .append (t )
67+ print (f" [rural] { len (texts )} transcripts" )
68+ return texts
69+
70+
71+ def main ():
72+ ap = argparse .ArgumentParser ()
73+ ap .add_argument ("--output" , default = "data/hf_speech_transcripts.jsonl" )
74+ ap .add_argument ("--source" , choices = ["fleurs" , "rural" , "both" ], default = "both" )
75+ args = ap .parse_args ()
76+
77+ start = time .time ()
78+ sources = []
79+ if args .source in ("fleurs" , "both" ):
80+ print ("loading FLEURS Bhojpuri..." )
81+ sources .append (("fleurs" , load_fleurs_transcripts ()))
82+ if args .source in ("rural" , "both" ):
83+ print ("loading Rural_Women Bhojpuri..." )
84+ sources .append (("rural_women" , load_rural_women_transcripts ()))
85+
86+ kept = 0
87+ with JsonlWriter (args .output ) as writer :
88+ for src_name , transcripts in sources :
89+ for raw in transcripts :
90+ for sent in process_text (raw ):
91+ rec = Record (
92+ id = content_hash (sent ),
93+ raw_text = sent ,
94+ cleaned_text = sent ,
95+ source_url = f"huggingface:{ src_name } " ,
96+ source_name = f"hf_{ src_name } " ,
97+ scrape_timestamp = datetime .now (timezone .utc ).isoformat (),
98+ category = "speech_transcript" ,
99+ )
100+ if writer .add (rec ):
101+ kept += 1
102+ total = writer .written
103+ dupes = writer .skipped_dupes
104+
105+ elapsed = time .time () - start
106+ print (f"\n --- hf transcript summary ---" )
107+ for src_name , transcripts in sources :
108+ print (f"{ src_name } : { len (transcripts )} raw transcripts" )
109+ print (f"sentences kept : { total } " )
110+ print (f"dupes skipped : { dupes } " )
111+ print (f"elapsed : { elapsed :.0f} s" )
112+ print (f"output : { args .output } " )
113+
114+
115+ if __name__ == "__main__" :
116+ main ()
0 commit comments