File size: 7,951 Bytes
737c030 e656608 da34b5e 35cccff 891f160 ec946c9 aa9d2fe ff5aa1c 8040f65 40d3704 35cccff 40d3704 35cccff 40d3704 35cccff 40d3704 35cccff 40d3704 3432325 40d3704 3432325 40d3704 891f160 ff5aa1c 40d3704 e656608 ff5aa1c 7d2b4d7 6c6d6f8 7d2b4d7 cff3443 7d2b4d7 cff3443 7d2b4d7 6c6d6f8 7d2b4d7 8040f65 40d3704 538b10c 40d3704 3432325 f6b831a 3432325 f6b831a 40d3704 35cccff 95432d5 ff5aa1c 98c76e0 6c6d6f8 35cccff 98c76e0 ff5aa1c 1549aa1 cff3443 40d3704 cff3443 1549aa1 40d3704 1549aa1 538b10c 40d3704 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 131 132 133 134 135 136 137 |
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()
# Function to extract text from uploaded files (PDF, DOCX, TXT)
def extract_text_from_file(uploaded_file):
try:
if uploaded_file.type == "application/pdf":
pdf_reader = PdfReader(uploaded_file)
text = ""
for page in pdf_reader.pages:
text += page.extract_text() or ""
return text.encode().decode('utf-8', errors='ignore').strip()
elif uploaded_file.type == "application/vnd.openxmlformats-officedocument.wordprocessingml.document":
doc = docx.Document(uploaded_file)
text = "\n".join([para.text for para in doc.paragraphs])
return text.encode().decode('utf-8', errors='ignore').strip()
elif uploaded_file.type == "text/plain":
return uploaded_file.read().decode('utf-8', errors='ignore').strip()
return ""
except Exception:
return ""
# Callback to update input text when file is uploaded
def on_file_upload():
uploaded_file = st.session_state.file_input
if uploaded_file and uploaded_file.size < 1024*1024:
st.session_state.user_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")
# Main application function
def main():
try:
translation_module = importlib.import_module("translation")
language_detector = importlib.import_module("lang_detect")
audio_processor_module = 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 hide size limit and show only file types
st.markdown(
"""
<style>
.stFileUploader > div > div > div[role="button"] {
display: none !important;
}
.stFileUploader label {
display: block !important;
color: #666 !important;
font-size: 0.8em !important;
}
.stFileUploader label::after {
content: 'TXT, DOCX, PDF' !important;
}
</style>
""",
unsafe_allow_html=True
)
# Language and Input/Output Layout with symmetric columns
left_col, right_col = st.columns([1, 1]) # Equal width for symmetric layout
with left_col:
detected_options = language_detector.detect_language(st.session_state.get("user_input_text", "")) if st.session_state.get("user_input_text", "").strip() else [("Auto-detect", 1.0, "Auto-detect")]
source_language = 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_language), "hi") if source_language != "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_language == "Auto-detect" else source_options.index(f"{LANGUAGES[source_lang_code][0]} ({source_language})"), key="source_lang")
user_input_text = st.text_area("Input Text", height=400, key="user_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_module, language_detector, audio_processor_module))
with right_col:
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")
# Play audio button and playback below output
if st.button("π", key="audio_btn", on_click=play_audio, args=(audio_processor_module,), 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}")
# Function to trigger translation process with progress indicator
def trigger_translation(translation_module, language_detector, audio_processor_module):
user_input_text = st.session_state.get("user_input_text", "").strip()
if user_input_text:
with st.spinner("Translating..."):
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 = language_detector.detect_language(user_input_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_module.translate(user_input_text, source_lang_code, target_lang_code)
st.session_state.translated_text = translated_text or user_input_text
# Function to handle audio playback
def play_audio(audio_processor_module):
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_data = audio_processor_module.text_to_speech(st.session_state.translated_text, target_lang)
if audio_data and audio_data.getbuffer().nbytes > 0:
st.audio(audio_data, format="audio/mp3")
if __name__ == "__main__":
main() |