added changes
This commit is contained in:
Binary file not shown.
Binary file not shown.
+122
@@ -0,0 +1,122 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import argparse
|
||||||
|
import socket
|
||||||
|
from dotenv import load_dotenv
|
||||||
|
from tqdm import tqdm
|
||||||
|
|
||||||
|
# Load config
|
||||||
|
script_dir = os.path.dirname(os.path.abspath(__file__))
|
||||||
|
env_path = os.path.abspath(os.path.join(script_dir, '../../.env_files/.env.aitranscribe'))
|
||||||
|
if os.path.exists(env_path):
|
||||||
|
load_dotenv(env_path)
|
||||||
|
else:
|
||||||
|
load_dotenv()
|
||||||
|
|
||||||
|
from utils import check_srt_duration_match, check_path_permissions, detect_file_encoding
|
||||||
|
|
||||||
|
def analyze_directory(folder_path, target_lang="English"):
|
||||||
|
print(f"🔍 Analyzing {folder_path} for broken/partial translations...")
|
||||||
|
|
||||||
|
# Check Permissions
|
||||||
|
perm_ok, perm_msg = check_path_permissions(folder_path)
|
||||||
|
if not perm_ok:
|
||||||
|
print(perm_msg)
|
||||||
|
return
|
||||||
|
|
||||||
|
issues_found = []
|
||||||
|
total_scanned = 0
|
||||||
|
|
||||||
|
# Walk through directory
|
||||||
|
for root, dirs, files in os.walk(folder_path):
|
||||||
|
for file in files:
|
||||||
|
if file.endswith(".srt") and \
|
||||||
|
not file.endswith(f".{target_lang}.srt") and \
|
||||||
|
not file.endswith(f".{target_lang}.deep_translate.srt") and \
|
||||||
|
not file.endswith(f".{target_lang}.local_llm.srt") and \
|
||||||
|
not file.endswith(".invalid") and \
|
||||||
|
not file.endswith(".failed_validation"):
|
||||||
|
|
||||||
|
source_srt_path = os.path.join(root, file)
|
||||||
|
base_name = os.path.splitext(file)[0]
|
||||||
|
|
||||||
|
# Paths to check
|
||||||
|
path_gemini = os.path.join(root, f"{base_name}.{target_lang}.srt")
|
||||||
|
path_deep = os.path.join(root, f"{base_name}.{target_lang}.deep_translate.srt")
|
||||||
|
path_local = os.path.join(root, f"{base_name}.{target_lang}.local_llm.srt")
|
||||||
|
|
||||||
|
existing_translation_path = None
|
||||||
|
method = "None"
|
||||||
|
|
||||||
|
if os.path.exists(path_local):
|
||||||
|
existing_translation_path = path_local
|
||||||
|
method = "Local LLM"
|
||||||
|
elif os.path.exists(path_gemini):
|
||||||
|
existing_translation_path = path_gemini
|
||||||
|
method = "Gemini"
|
||||||
|
elif os.path.exists(path_deep):
|
||||||
|
existing_translation_path = path_deep
|
||||||
|
method = "DeepTranslate"
|
||||||
|
|
||||||
|
total_scanned += 1
|
||||||
|
|
||||||
|
if existing_translation_path:
|
||||||
|
# Validate duration
|
||||||
|
is_valid, msg = check_srt_duration_match(source_srt_path, existing_translation_path)
|
||||||
|
if not is_valid:
|
||||||
|
issues_found.append({
|
||||||
|
"source": source_srt_path,
|
||||||
|
"translation": existing_translation_path,
|
||||||
|
"method": method,
|
||||||
|
"reason": msg
|
||||||
|
})
|
||||||
|
else:
|
||||||
|
# Missing translation
|
||||||
|
issues_found.append({
|
||||||
|
"source": source_srt_path,
|
||||||
|
"translation": "MISSING",
|
||||||
|
"method": "None",
|
||||||
|
"reason": "No translation file found."
|
||||||
|
})
|
||||||
|
|
||||||
|
# --- Report ---
|
||||||
|
print("\n" + "="*50)
|
||||||
|
print(f"📊 Analysis Report for: {folder_path}")
|
||||||
|
print("="*50)
|
||||||
|
print(f"Total Source Transcripts Scanned: {total_scanned}")
|
||||||
|
print(f"Issues Found: {len(issues_found)}")
|
||||||
|
print("-" * 50)
|
||||||
|
|
||||||
|
if issues_found:
|
||||||
|
print("Detailed Issues:")
|
||||||
|
for i, issue in enumerate(issues_found, 1):
|
||||||
|
print(f"{i}. {os.path.basename(issue['source'])}")
|
||||||
|
print(f" Target: {os.path.basename(issue['translation']) if issue['translation'] != 'MISSING' else 'MISSING'}")
|
||||||
|
print(f" Error: {issue['reason']}")
|
||||||
|
print("-" * 30)
|
||||||
|
|
||||||
|
# Optional: Save to file
|
||||||
|
report_file = f"analysis_report_{socket.gethostname()}.txt"
|
||||||
|
with open(report_file, "w", encoding="utf-8") as f:
|
||||||
|
f.write(f"Analysis Report - {datetime.now().isoformat()}\n")
|
||||||
|
for issue in issues_found:
|
||||||
|
f.write(f"{issue['source']} | {issue['reason']}\n")
|
||||||
|
print(f"\nReport saved to: {report_file}")
|
||||||
|
else:
|
||||||
|
print("✅ No issues found! All translations appear healthy.")
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
from datetime import datetime
|
||||||
|
|
||||||
|
parser = argparse.ArgumentParser(description="Analyze Translations (Read-Only)")
|
||||||
|
parser.add_argument("folders", nargs='+', help="One or more paths to folders to scan")
|
||||||
|
parser.add_argument("--lang", default="English", help="Target language (default: English)")
|
||||||
|
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
for folder in args.folders:
|
||||||
|
if os.path.exists(folder):
|
||||||
|
analyze_directory(folder, args.lang)
|
||||||
|
else:
|
||||||
|
print(f"Error: Folder '{folder}' does not exist. Skipping.")
|
||||||
Binary file not shown.
File diff suppressed because it is too large
Load Diff
@@ -77,12 +77,12 @@ def process_recovery(folder_path, target_lang="English", prefer_deep=False, pref
|
|||||||
existing_translation_path = None
|
existing_translation_path = None
|
||||||
|
|
||||||
# Check if translation exists
|
# Check if translation exists
|
||||||
if os.path.exists(path_gemini):
|
if os.path.exists(path_local):
|
||||||
|
existing_translation_path = path_local
|
||||||
|
elif os.path.exists(path_gemini):
|
||||||
existing_translation_path = path_gemini
|
existing_translation_path = path_gemini
|
||||||
elif os.path.exists(path_deep):
|
elif os.path.exists(path_deep):
|
||||||
existing_translation_path = path_deep
|
existing_translation_path = path_deep
|
||||||
elif os.path.exists(path_local):
|
|
||||||
existing_translation_path = path_local
|
|
||||||
|
|
||||||
if existing_translation_path:
|
if existing_translation_path:
|
||||||
# Validate duration
|
# Validate duration
|
||||||
|
|||||||
@@ -253,22 +253,30 @@ def check_srt_duration_match(source_srt_path, target_srt_path, tolerance_seconds
|
|||||||
"""
|
"""
|
||||||
Compares the duration of two SRT files to ensure they cover roughly the same timeframe.
|
Compares the duration of two SRT files to ensure they cover roughly the same timeframe.
|
||||||
Useful for detecting partial translations.
|
Useful for detecting partial translations.
|
||||||
|
|
||||||
Args:
|
|
||||||
source_srt_path (str): Path to the original language SRT.
|
|
||||||
target_srt_path (str): Path to the translated SRT.
|
|
||||||
tolerance_seconds (float): Max allowed difference in seconds.
|
|
||||||
tolerance_percent (float): Max allowed difference as a percentage of source duration.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
tuple: (bool, str) -> (passed, message)
|
|
||||||
"""
|
"""
|
||||||
if not os.path.exists(source_srt_path) or not os.path.exists(target_srt_path):
|
if not os.path.exists(source_srt_path) or not os.path.exists(target_srt_path):
|
||||||
return False, "One or both SRT files missing."
|
return False, "One or both SRT files missing."
|
||||||
|
|
||||||
|
def load_subs_robust(path):
|
||||||
|
# Try detected encoding first
|
||||||
|
detected_enc = detect_file_encoding(path)
|
||||||
|
try:
|
||||||
|
return pysubs2.load(path, encoding=detected_enc)
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
|
# Fallback encodings
|
||||||
|
encodings = ['utf-8', 'cp1252', 'latin-1', 'utf-16', 'shift_jis']
|
||||||
|
for enc in encodings:
|
||||||
|
try:
|
||||||
|
return pysubs2.load(path, encoding=enc)
|
||||||
|
except Exception:
|
||||||
|
continue
|
||||||
|
raise Exception(f"Could not decode {os.path.basename(path)} with any standard encoding.")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
source_subs = pysubs2.load(source_srt_path)
|
source_subs = load_subs_robust(source_srt_path)
|
||||||
target_subs = pysubs2.load(target_srt_path)
|
target_subs = load_subs_robust(target_srt_path)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
return False, f"Error parsing SRTs: {e}"
|
return False, f"Error parsing SRTs: {e}"
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user