File size: 8,143 Bytes
737c030
e656608
da34b5e
35cccff
 
f3041d7
891f160
b5c7107
c55f7e1
aa9d2fe
0787c83
ff5aa1c
 
 
 
 
8040f65
0787c83
40d3704
35cccff
40d3704
 
b5c7107
0787c83
40d3704
 
b5c7107
0787c83
40d3704
0787c83
35cccff
b5c7107
0787c83
35cccff
 
b5c7107
3432325
0787c83
 
 
b5c7107
 
0787c83
b5c7107
3432325
40d3704
891f160
ff5aa1c
b5c7107
40d3704
 
 
e656608
0787c83
ff5aa1c
7d2b4d7
 
b5c7107
 
40d3704
0787c83
 
40d3704
c55f7e1
538b10c
40d3704
63de0ad
3432325
f6b831a
3432325
54945d2
0787c83
40d3704
0787c83
35cccff
 
95432d5
ff5aa1c
63de0ad
6c6d6f8
 
0787c83
 
c55f7e1
 
 
 
 
 
 
 
0787c83
ff5aa1c
b5c7107
0787c83
1549aa1
b5c7107
40d3704
0787c83
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
a640cbd
 
 
0787c83
 
8f879af
a640cbd
 
8f879af
1549aa1
0787c83
40d3704
0787c83
 
 
b5c7107
0787c83
 
 
 
 
 
b5c7107
0787c83
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
138
139
140
141
142
import streamlit as st
import importlib
from io import BytesIO
import docx
from PyPDF2 import PdfReader
import time

# Configure Streamlit page settings
st.set_page_config(page_title="Multilingual Translator", page_icon="🌐", layout="wide")

# Import LANGUAGES from translation.py with error handling
try:
    from translation import LANGUAGES
except ImportError as e:
    st.error(f"Failed to import translation module: {e}")
    st.stop()

# Extract text from uploaded files (PDF, DOCX, TXT) with error handling
def extract_text_from_file(uploaded_file):
    try:
        if uploaded_file.type == "application/pdf":
            pdf_reader = PdfReader(uploaded_file)
            text = "".join(page.extract_text() or "" for page in pdf_reader.pages)
            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 as e:
        st.error(f"Error processing file: {e}")
        return ""

# Update input text when a file is uploaded
def on_file_upload():
    uploaded_file = st.session_state.get("file_input")
    if uploaded_file:
        if uploaded_file.size < 1024 * 1024:  # Check file size limit (1MB)
            st.session_state.user_input_text = extract_text_from_file(uploaded_file)
            st.success(f"File '{uploaded_file.name}' uploaded successfully!")
        else:
            st.error("File size must be less than 1 MB")

# Main application function
def main():
    try:
        # Import required modules dynamically
        translation_module = importlib.import_module("translation")
        language_detector = importlib.import_module("lang_detect")
        audio_processor_module = importlib.import_module("audio_processor")

        # Display 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)

        # Create symmetric layout with two columns
        left_col, right_col = st.columns([1, 1])
        with left_col:
            # Detect language of input text
            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), "en") 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=200, 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")
            st.button("Translate", key="translate_btn", on_click=trigger_translation, args=(translation_module, language_detector, audio_processor_module))

        with right_col:
            # Set target language options
            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=200, key="output_text", disabled=True, label_visibility="hidden")
                if st.button("πŸ”Š", key="audio_btn", on_click=play_audio, args=(audio_processor_module,), help="Play audio", use_container_width=False):
                    pass

        # Display footer
        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"Application error occurred: {e}")
        raise  # Re-raise exception for further handling if needed

# Trigger translation process with timeout handling
def trigger_translation(translation_module, language_detector, audio_processor_module):
    user_input_text = st.session_state.get("user_input_text", "").strip()
    if not user_input_text:
        st.error("No input text provided")
        return
    with st.spinner("Translating..."):
        start_time = time.time()
        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]), "en")
        else:
            source_lang_code = next((k for k, v in LANGUAGES.items() if v[0] == source_lang), "en")
        target_lang_code = next((k for k, v in LANGUAGES.items() if v[0] == target_lang), "en")
        try:
            translated_text = translation_module.translate(user_input_text, source_lang_code, target_lang_code)
            if time.time() - start_time > 20:  # Timeout after 20 seconds
                st.error("Translation took too long, reverting to input.")
                translated_text = user_input_text
            if translated_text and len(translated_text.split()) > 2:
                st.session_state.translated_text = translated_text
            else:
                st.session_state.translated_text = user_input_text
        except Exception as e:
            st.error(f"Translation failed: {e}")
            st.session_state.translated_text = user_input_text

# Handle audio playback with error handling
def play_audio(audio_processor_module):
    if "translated_text" not in st.session_state or not st.session_state.translated_text:
        st.error("No translated text available for audio")
        return
    try:
        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")
        else:
            st.error("Failed to generate audio")
    except Exception as e:
        st.error(f"Audio playback error: {e}")

if __name__ == "__main__":
    main()