File size: 7,180 Bytes
737c030 e656608 da34b5e 35cccff 891f160 ec946c9 aa9d2fe ff5aa1c 8040f65 35cccff 3432325 891f160 ff5aa1c e656608 ff5aa1c 7d2b4d7 8040f65 ff5aa1c 7d2b4d7 ff5aa1c 9878bca f6b831a 538b10c 95432d5 98c76e0 3432325 f6b831a 3432325 f6b831a 95432d5 ff5aa1c 35cccff 95432d5 ff5aa1c 98c76e0 95432d5 f6b831a 35cccff 98c76e0 ff5aa1c 1549aa1 9878bca 14a91a0 538b10c 35cccff 9878bca 460acea 9878bca 35cccff bcf090f 1549aa1 538b10c 1549aa1 7d2b4d7 8040f65 891f160 |
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 |
import streamlit as st
import importlib
from io import BytesIO
import docx
from PyPDF2 import PdfReader
st.set_page_config(page_title="Multilingual Translator", page_icon="π", layout="centered")
# Import LANGUAGES from translation.py
try:
from translation import LANGUAGES
except ImportError as e:
st.error(f"Failed to import translation module: {e}")
st.stop()
def extract_text_from_file(file):
try:
if file.type == "application/pdf":
pdf_reader = PdfReader(file)
text = ""
for page in pdf_reader.pages:
text += page.extract_text() or ""
return text.encode().decode('utf-8', errors='ignore').strip()
elif file.type == "application/vnd.openxmlformats-officedocument.wordprocessingml.document":
doc = docx.Document(file)
text = "\n".join([para.text for para in doc.paragraphs])
return text.encode().decode('utf-8', errors='ignore').strip()
elif file.type == "text/plain":
return file.read().decode('utf-8', errors='ignore').strip()
return ""
except Exception:
return ""
def on_file_upload():
uploaded_file = st.session_state.file_input
if uploaded_file and uploaded_file.size < 1024*1024:
st.session_state.input_text = extract_text_from_file(uploaded_file)
elif uploaded_file and uploaded_file.size >= 1024*1024:
st.error("File size must be less than 1 MB")
def main():
try:
translation = importlib.import_module("translation")
lang_detect = importlib.import_module("lang_detect")
audio_processor = importlib.import_module("audio_processor")
# Header
st.markdown("<h1 style='text-align: center; color: #4285F4;'>Multilingual Translator</h1>", unsafe_allow_html=True)
st.markdown("<p style='text-align: center; color: #666;'>Effortless Multilingual Translation</p>", unsafe_allow_html=True)
# Custom CSS to override file uploader size limit display
st.markdown(
"""
<style>
.stFileUploader > div > div > div {
display: none;
}
.stFileUploader label {
display: block !important;
color: #666;
font-size: 0.8em;
}
.stFileUploader label::after {
content: "Limit 1MB per file β’ TXT, DOCX, PDF";
}
</style>
""",
unsafe_allow_html=True
)
# Language and Input/Output Layout
col1, col2 = st.columns([2, 1]) # Wider input column
with col1:
detected_options = lang_detect.detect_language(st.session_state.get("input_text", "")) if st.session_state.get("input_text", "").strip() else [("Auto-detect", 1.0, "Auto-detect")]
source_lang = detected_options[0][2] if detected_options[0][0] != "Auto-detect" else "Auto-detect"
source_lang_code = next((k for k, v in LANGUAGES.items() if v[1] == source_lang), "hi") if source_lang != "Auto-detect" else "auto"
source_options = ["Auto-detect"] + [f"{v[0]} ({v[1]})" for v in LANGUAGES.values()]
st.selectbox("Source Language", options=source_options, index=0 if source_lang == "Auto-detect" else source_options.index(f"{LANGUAGES[source_lang_code][0]} ({source_lang})"), key="source_lang")
input_text = st.text_area("Input Text", height=400, key="input_text", placeholder="Enter text here", label_visibility="hidden")
input_type = st.radio("Input Type", ["Text", "File"], horizontal=True, label_visibility="hidden", key="input_type")
if input_type == "File":
st.file_uploader("Upload File", type=["txt", "docx", "pdf"], key="file_input", on_change=on_file_upload, label_visibility="hidden")
if st.session_state.get("file_input") and st.session_state.get("file_input").size >= 1024*1024:
st.error("File size must be less than 1 MB")
st.button("Translate", key="translate_btn", on_click=trigger_translation, args=(translation, lang_detect, audio_processor))
with col2:
source_lang_display = st.session_state.source_lang.split(" (")[0] if " (" in st.session_state.source_lang else st.session_state.source_lang
target_options = [f"{v[0]} ({v[1]})" for v in LANGUAGES.values() if v[0] != source_lang_display and v[1] != source_lang_display]
st.selectbox("Target Language", options=target_options, index=target_options.index(f"{LANGUAGES['en'][0]} ({LANGUAGES['en'][1]})") if "English" not in source_lang_display else 0, key="target_lang")
if "translated_text" in st.session_state:
st.text_area("Output Text", value=st.session_state.translated_text, height=400, key="output_text", disabled=True, label_visibility="hidden")
if st.button("π", key="audio_btn", on_click=play_audio, args=(audio_processor,), help="Play audio", use_container_width=False):
pass
# Footer
if "translated_text" in st.session_state:
st.markdown("""
<p style="font-size: small; color: grey; text-align: center;">
Developed By: Krishna Prakash
<a href="https://www.linkedin.com/in/krishnaprakash-profile/" target="_blank">
<img src="https://img.icons8.com/ios-filled/30/0077b5/linkedin.png" alt="LinkedIn" style="vertical-align: middle; margin: 0 5px;"/>
</a>
</p>
""", unsafe_allow_html=True)
except Exception as e:
st.error(f"App error: {e}")
def trigger_translation(translation, lang_detect, audio_processor):
text = st.session_state.get("input_text", "").strip()
if text:
source_lang = st.session_state.source_lang.split(" (")[0] if " (" in st.session_state.source_lang else st.session_state.source_lang
target_lang = st.session_state.target_lang.split(" (")[0] if " (" in st.session_state.target_lang else st.session_state.target_lang
if source_lang == "Auto-detect":
detected_options = lang_detect.detect_language(text)
source_lang_code = next((k for k, v in LANGUAGES.items() if v[1] == detected_options[0][0]), "hi")
else:
source_lang_code = next((k for k, v in LANGUAGES.items() if v[0] == source_lang), "hi")
target_lang_code = next((k for k, v in LANGUAGES.items() if v[0] == target_lang), "en")
translated_text = translation.translate(text, source_lang_code, target_lang_code)
st.session_state.translated_text = translated_text or text
def play_audio(audio_processor):
if "translated_text" in st.session_state and st.session_state.translated_text:
target_lang = next((k for k, v in LANGUAGES.items() if v[0] == st.session_state.target_lang.split(" (")[0]), "en")
audio = audio_processor.text_to_speech(st.session_state.translated_text, target_lang)
if audio and audio.getbuffer().nbytes > 0:
st.audio(audio, format="audio/mp3")
if __name__ == "__main__":
main() |