Spaces:
Configuration error
Configuration error
File size: 6,847 Bytes
a1258b5 029ef5b fa7018d a1258b5 ec27e8c 6bbdef7 52d2425 a1258b5 029ef5b 52d2425 1a471fb 1826c30 029ef5b 91c078f 029ef5b 1a471fb a1258b5 029ef5b 1a471fb a1258b5 1a471fb 91c078f 52d2425 fa7018d a1258b5 91c078f 1a471fb 91c078f 52d2425 1a471fb 52d2425 a1258b5 1a471fb 52d2425 a1258b5 1a471fb dd0a059 1a471fb dd0a059 1a471fb 91c078f 1a471fb 029ef5b 91c078f 029ef5b 91c078f 029ef5b 91c078f 029ef5b 91c078f 029ef5b 91c078f a1258b5 029ef5b 52d2425 a1258b5 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 |
from fasthtml.common import *
from fasthtml.xtend import CheckboxX
from translator import languages as VALID_LANGUAGES, translate_to_languages
import tempfile
from starlette.requests import Request
from typing import List
from starlette.responses import FileResponse, PlainTextResponse
import os
import mimetypes
import zipfile
import io
css = Style(':root {--pico-font-size:90%,--pico-font-family: Pacifico, cursive;}')
app = FastHTML(hdrs=(picolink, css))
TEMP_FILES = {}
# Extract form generation to a separate function
def generate_language_form():
return Form(
Input(type='file', name='sbv_file', accept='.sbv', required=True),
H3('Select languages for translation'),
Fieldset(
Legend("Languages"),
Div(
*[CheckboxX(
label=lang,
value=lang,
id=f'lang_{lang}',
name='languages'
) for lang in VALID_LANGUAGES],
class_='grid'
)
),
Button('Translate', class_="primary"),
action="/upload", method='post', enctype='multipart/form-data'
)
@app.get('/')
def home():
return Container(
Article(
H1("SBV File Translator"),
P("Upload an SBV File and select languages for translation:"),
generate_language_form(),
)
)
# Extract file processing logic to a separate function
def translate_and_process_sbv(content: bytes, filename: str, languages: List[str]) -> dict:
"""
Translate and process an SBV file for the given languages.
Args:
content (bytes): The content of the uploaded SBV file.
filename (str): The name of the uploaded file.
languages (List[str]): List of target languages for translation.
Returns:
dict: A dictionary containing translation results, file paths, and zip filename.
"""
try:
temp_dir = tempfile.mkdtemp()
input_file = os.path.join(temp_dir, filename)
# Ensure the directory exists
os.makedirs(os.path.dirname(input_file), exist_ok=True)
with open(input_file, 'wb') as f:
f.write(content)
selected_languages = [lang for lang in languages if lang in VALID_LANGUAGES]
output_dir = os.path.join(temp_dir, "translations")
os.makedirs(output_dir, exist_ok=True)
translate_to_languages(input_file, output_dir, selected_languages)
return create_translation_files(temp_dir, output_dir, filename, selected_languages)
except Exception as e:
print(f"Error in translate_and_process_sbv: {str(e)}")
raise # Re-raise the exception after logging
# Extract translation file creation logic to a separate function
def create_translation_files(temp_dir: str, output_dir: str, filename: str, languages: List[str]) -> dict:
"""
Create translation files and organize them for download.
This function processes the translated SBV files, organizes them in a temporary directory,
creates a zip file containing all translations, and prepares the data for the response.
Args:
temp_dir (str): Path to the temporary directory for storing files.
output_dir (str): Path to the directory containing the translated SBV files.
filename (str): Name of the original uploaded file.
languages (List[str]): List of languages for which translations were created.
Returns:
dict: A dictionary containing:
- 'translations': Dict of language codes to translated content.
- 'file_paths': Dict of language codes to paths of individual translation files.
- 'zip_filename': Name of the zip file containing all translations.
"""
translations = {}
file_paths = {}
base_filename = os.path.splitext(filename)[0]
for lang in languages:
translated_file = os.path.join(output_dir, f"{base_filename}_{lang}.sbv")
with open(translated_file, 'r', encoding='utf-8') as f:
translations[lang] = f.read()
new_filename = f"{base_filename}_{lang}.sbv"
new_path = os.path.join(temp_dir, new_filename)
os.rename(translated_file, new_path)
file_paths[lang] = new_path
TEMP_FILES[new_filename] = new_path
zip_filename = f"{base_filename}_{'_'.join(languages)}.zip"
zip_path = os.path.join(temp_dir, zip_filename)
with zipfile.ZipFile(zip_path, 'w') as zip_file:
for lang, file_path in file_paths.items():
zip_file.write(file_path, os.path.basename(file_path))
TEMP_FILES[zip_filename] = zip_path
return {
'translations': translations,
'file_paths': file_paths,
'zip_filename': zip_filename
}
@app.post('/upload')
async def upload_file(request: Request, sbv_file: UploadFile):
content = await sbv_file.read()
# Get form data
form = await request.form()
languages = form.getlist('languages')
# Ensure languages is always a list
if not languages:
return PlainTextResponse("Please select at least one language for translation.", status_code=400)
result = translate_and_process_sbv(content, sbv_file.filename, languages)
return Container(
Article(
H1('Translations'),
A("Download All Translations",
href=f"/download/{result['zip_filename']}",
download=True,
class_="primary",
role="button"
),
*[Card(
H3(f'{lang.capitalize()} Translation'),
Pre(
'\n'.join(result['translations'][lang].split('\n')[:9]) + '\n...',
),
Footer(
A(f"Download {lang.capitalize()} Translation",
href=f"/download/{os.path.basename(result['file_paths'][lang])}",
download=True,
class_="secondary outline",
role="button"
)
)
) for lang in result['translations']],
class_="container-fluid" # Add this class for full-width content
)
)
@app.get("/download/{filename}")
def get(filename: str):
file_path = TEMP_FILES.get(filename)
if file_path and os.path.exists(file_path):
mime_type, _ = mimetypes.guess_type(file_path)
return FileResponse(
file_path,
filename=filename,
media_type=mime_type or "application/octet-stream",
headers={
"Content-Disposition": f"attachment; filename={filename}",
"X-Content-Type-Options": "nosniff",
}
)
else:
return PlainTextResponse("File not found", status_code=404)
serve() |