Spaces:
Runtime error
Runtime error
fix for turkish characters
Browse files
app.py
CHANGED
|
@@ -76,7 +76,6 @@ def translate_en_tr(text: str) -> str:
|
|
| 76 |
continue
|
| 77 |
|
| 78 |
try:
|
| 79 |
-
# docs'a uygun çağrı
|
| 80 |
result = client.translation(
|
| 81 |
text=line,
|
| 82 |
model=HF_MODEL,
|
|
@@ -84,8 +83,7 @@ def translate_en_tr(text: str) -> str:
|
|
| 84 |
translated = _extract_translation_text(result)
|
| 85 |
except Exception as e:
|
| 86 |
print("HF translation error:", repr(e))
|
| 87 |
-
# fallback: orijinal
|
| 88 |
-
translated = line
|
| 89 |
|
| 90 |
out_lines.append(translated)
|
| 91 |
|
|
@@ -100,7 +98,8 @@ def parse_srt(path: Path):
|
|
| 100 |
"""
|
| 101 |
SRT -> [{index, start, end, text}, ...]
|
| 102 |
"""
|
| 103 |
-
|
|
|
|
| 104 |
blocks = re.split(r"\n\s*\n", raw)
|
| 105 |
subs = []
|
| 106 |
|
|
@@ -148,21 +147,48 @@ def parse_srt(path: Path):
|
|
| 148 |
|
| 149 |
|
| 150 |
# ======================================================
|
| 151 |
-
# 3) KARAKTER ÇIKARMA + TEXT TEMİZLEME
|
| 152 |
# ======================================================
|
| 153 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 154 |
speaker_pattern = re.compile(
|
| 155 |
-
|
| 156 |
-
|
| 157 |
-
|
|
|
|
| 158 |
)
|
| 159 |
|
| 160 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 161 |
def extract_character_and_clean_text(block: str):
|
| 162 |
"""
|
| 163 |
block içinden:
|
| 164 |
-
- Character: ilk NAME:
|
| 165 |
- TEXT: NAME: prefix'leri atılmış metin
|
|
|
|
|
|
|
|
|
|
| 166 |
"""
|
| 167 |
if not block:
|
| 168 |
return "", ""
|
|
@@ -179,13 +205,21 @@ def extract_character_and_clean_text(block: str):
|
|
| 179 |
m = speaker_pattern.match(original)
|
| 180 |
if m:
|
| 181 |
name = m.group("name").strip()
|
| 182 |
-
if not character:
|
| 183 |
-
character = name
|
| 184 |
after = m.group("after").rstrip()
|
| 185 |
-
|
| 186 |
-
|
| 187 |
-
|
| 188 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 189 |
|
| 190 |
out_lines = [ln for ln in out_lines if ln.strip()]
|
| 191 |
return character, "\n".join(out_lines)
|
|
@@ -254,7 +288,7 @@ def srt_to_docx_bytes(srt_path: Path, translate_to_tr: bool) -> Tuple[bytes, str
|
|
| 254 |
row = table.add_row()
|
| 255 |
cells = row.cells
|
| 256 |
|
| 257 |
-
# Character
|
| 258 |
cells[0].text = character
|
| 259 |
|
| 260 |
# TC -> MM.SS
|
|
@@ -315,10 +349,12 @@ with gr.Blocks() as demo:
|
|
| 315 |
|
| 316 |
- Bir veya birden fazla **.srt** yükle.
|
| 317 |
- Her satır için:
|
| 318 |
-
- **Character**:
|
|
|
|
|
|
|
| 319 |
- **TC**: sadece **MM.SS** (start time).
|
| 320 |
-
- **TEXT**: `NAME:` prefix'
|
| 321 |
-
- İstersen TEXT'i **Helsinki-NLP/opus-mt-tc-big-en-tr** ile Türkçe'ye çevir.
|
| 322 |
- Çıktı: Tüm DOCX'leri içeren tek bir **ZIP**.
|
| 323 |
"""
|
| 324 |
)
|
|
|
|
| 76 |
continue
|
| 77 |
|
| 78 |
try:
|
|
|
|
| 79 |
result = client.translation(
|
| 80 |
text=line,
|
| 81 |
model=HF_MODEL,
|
|
|
|
| 83 |
translated = _extract_translation_text(result)
|
| 84 |
except Exception as e:
|
| 85 |
print("HF translation error:", repr(e))
|
| 86 |
+
translated = line # fallback: orijinal satır
|
|
|
|
| 87 |
|
| 88 |
out_lines.append(translated)
|
| 89 |
|
|
|
|
| 98 |
"""
|
| 99 |
SRT -> [{index, start, end, text}, ...]
|
| 100 |
"""
|
| 101 |
+
# Türkçe karakterleri korumak için utf-8-sig + errors="replace"
|
| 102 |
+
raw = path.read_text(encoding="utf-8-sig", errors="replace").strip()
|
| 103 |
blocks = re.split(r"\n\s*\n", raw)
|
| 104 |
subs = []
|
| 105 |
|
|
|
|
| 147 |
|
| 148 |
|
| 149 |
# ======================================================
|
| 150 |
+
# 3) KARAKTER ÇIKARMA + TEXT TEMİZLEME (TR HARFLER + GÜVENLİ HEURİSTİK)
|
| 151 |
# ======================================================
|
| 152 |
|
| 153 |
+
# Unicode harf tabanlı name-word:
|
| 154 |
+
# - [^\W\d_] = herhangi bir Unicode harfi (A-Z, a-z, Ç,Ğ,İ,Ö,Ş,Ü,ç,ğ,ı,ö,ş,ü vs.)
|
| 155 |
+
# - sonrasında harf, nokta, apostrof, tire gelebilir
|
| 156 |
+
name_word = r"[^\W\d_][^\W\d_.'-]*"
|
| 157 |
+
|
| 158 |
speaker_pattern = re.compile(
|
| 159 |
+
rf'^\s*(?:>{1,3}\s*)?(?:-+\s*)?'
|
| 160 |
+
rf'(?P<name>(?:{name_word}(?:\s+{name_word}){{0,4}}))'
|
| 161 |
+
rf'\s*:\s*(?P<after>.*)$',
|
| 162 |
+
flags=re.UNICODE,
|
| 163 |
)
|
| 164 |
|
| 165 |
|
| 166 |
+
def looks_like_speaker_name(name: str) -> bool:
|
| 167 |
+
"""
|
| 168 |
+
Çok agresif olmamak için:
|
| 169 |
+
- Sadece büyük harf oranı yüksek olan isimleri speaker olarak kabul et.
|
| 170 |
+
Örnek:
|
| 171 |
+
"DR. GREENE" -> EVET (çoğu büyük harf)
|
| 172 |
+
"HEMSİRE SELMA" -> EVET
|
| 173 |
+
"Doktor" -> HAYIR (ilk harf büyük ama tümü değil, normal cümle olabilir)
|
| 174 |
+
"Merhaba" -> HAYIR
|
| 175 |
+
"""
|
| 176 |
+
letters = [ch for ch in name if ch.isalpha()]
|
| 177 |
+
if not letters:
|
| 178 |
+
return False
|
| 179 |
+
upper_count = sum(1 for ch in letters if ch.isupper())
|
| 180 |
+
ratio = upper_count / len(letters)
|
| 181 |
+
return ratio >= 0.8
|
| 182 |
+
|
| 183 |
+
|
| 184 |
def extract_character_and_clean_text(block: str):
|
| 185 |
"""
|
| 186 |
block içinden:
|
| 187 |
+
- Character: ilk NAME: (büyük oranda uppercase olan)
|
| 188 |
- TEXT: NAME: prefix'leri atılmış metin
|
| 189 |
+
|
| 190 |
+
Eğer satır "normal cümle" ise (örn. Türkçe SRT):
|
| 191 |
+
- "Doğrusu: böyle değil." -> Character boş, TEXT = satırın tamamı
|
| 192 |
"""
|
| 193 |
if not block:
|
| 194 |
return "", ""
|
|
|
|
| 205 |
m = speaker_pattern.match(original)
|
| 206 |
if m:
|
| 207 |
name = m.group("name").strip()
|
|
|
|
|
|
|
| 208 |
after = m.group("after").rstrip()
|
| 209 |
+
|
| 210 |
+
# Sadece gerçekten speaker'e benzeyen isimleri ayır
|
| 211 |
+
if looks_like_speaker_name(name):
|
| 212 |
+
if not character:
|
| 213 |
+
character = name
|
| 214 |
+
if after:
|
| 215 |
+
out_lines.append(after)
|
| 216 |
+
# bu satırı TEXT'e orijinal haliyle eklemiyoruz
|
| 217 |
+
continue
|
| 218 |
+
|
| 219 |
+
# buraya düştüyse:
|
| 220 |
+
# - ya pattern tutmadı
|
| 221 |
+
# - ya da name speaker gibi görünmüyor => satırı olduğu gibi TEXT'e koy
|
| 222 |
+
out_lines.append(original)
|
| 223 |
|
| 224 |
out_lines = [ln for ln in out_lines if ln.strip()]
|
| 225 |
return character, "\n".join(out_lines)
|
|
|
|
| 288 |
row = table.add_row()
|
| 289 |
cells = row.cells
|
| 290 |
|
| 291 |
+
# Character (Türkçe harfler dahil; ama sadece yoğun uppercase ise dolduruluyor)
|
| 292 |
cells[0].text = character
|
| 293 |
|
| 294 |
# TC -> MM.SS
|
|
|
|
| 349 |
|
| 350 |
- Bir veya birden fazla **.srt** yükle.
|
| 351 |
- Her satır için:
|
| 352 |
+
- **Character**:
|
| 353 |
+
- `WOMAN:`, `DR. GREENE:`, `HEMSİRE SELMA:` gibi *büyük harf ağırlıklı* isimler otomatik alınır.
|
| 354 |
+
- Normal Türkçe cümleler (ör. "Doktor: bugün erken geldiniz.") bozulmaz, TEXT'e tam gider.
|
| 355 |
- **TC**: sadece **MM.SS** (start time).
|
| 356 |
+
- **TEXT**: `NAME:` prefix'i speaker olarak algılanamadıysa **tam satır**.
|
| 357 |
+
- İstersen TEXT'i **Helsinki-NLP/opus-mt-tc-big-en-tr** ile Türkçe'ye çevir (Character asla çevrilmez).
|
| 358 |
- Çıktı: Tüm DOCX'leri içeren tek bir **ZIP**.
|
| 359 |
"""
|
| 360 |
)
|