Krishna086 commited on
Commit
b5c7107
Β·
verified Β·
1 Parent(s): 8f10e97

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +77 -81
app.py CHANGED
@@ -5,100 +5,89 @@ import docx
5
  from PyPDF2 import PdfReader
6
  import time
7
 
 
8
  st.set_page_config(page_title="Multilingual Translator", page_icon="🌐", layout="wide")
9
 
10
- # Import LANGUAGES from translation.py
11
  try:
12
  from translation import LANGUAGES
13
  except ImportError as e:
14
  st.error(f"Failed to import translation module: {e}")
15
  st.stop()
16
 
17
- # Function to extract text from uploaded files (PDF, DOCX, TXT)
18
  def extract_text_from_file(uploaded_file):
19
  try:
20
  if uploaded_file.type == "application/pdf":
21
  pdf_reader = PdfReader(uploaded_file)
22
- text = ""
23
- for page in pdf_reader.pages:
24
- text += page.extract_text() or ""
25
- return text.encode().decode('utf-8', errors='ignore').strip()
26
  elif uploaded_file.type == "application/vnd.openxmlformats-officedocument.wordprocessingml.document":
27
  doc = docx.Document(uploaded_file)
28
- text = "\n".join([para.text for para in doc.paragraphs])
29
- return text.encode().decode('utf-8', errors='ignore').strip()
30
  elif uploaded_file.type == "text/plain":
31
- return uploaded_file.read().decode('utf-8', errors='ignore').strip()
32
  return ""
33
- except Exception:
 
34
  return ""
35
 
36
- # Callback to update input text when file is uploaded
37
  def on_file_upload():
38
- uploaded_file = st.session_state.file_input
39
- if uploaded_file and uploaded_file.size < 1024*1024:
40
- st.session_state.user_input_text = extract_text_from_file(uploaded_file)
41
- st.success(f"File '{uploaded_file.name}' uploaded successfully!")
42
- elif uploaded_file and uploaded_file.size >= 1024*1024:
43
- st.error("File size must be less than 1 MB")
 
 
 
44
 
45
  # Main application function
46
  def main():
47
  try:
 
48
  translation_module = importlib.import_module("translation")
49
  language_detector = importlib.import_module("lang_detect")
50
  audio_processor_module = importlib.import_module("audio_processor")
51
 
52
- # Header
53
  st.markdown("<h1 style='text-align: center; color: #4285F4;'>Multilingual Translator</h1>", unsafe_allow_html=True)
54
  st.markdown("<p style='text-align: center; color: #666;'>Effortless Multilingual Translation</p>", unsafe_allow_html=True)
55
 
56
- # Custom CSS to hide size limit and white box, reduce spacing
57
  st.markdown(
58
  """
59
  <style>
60
- .stFileUploader > div > div > div[role="button"] {
61
- display: none !important;
62
- }
63
- .stFileUploader label {
64
- display: none !important;
65
- }
66
  .stFileUploader [data-testid="stFileUploaderDropzone"] {
67
- border: 2px dashed #ccc !important;
68
- padding: 10px !important;
69
- text-align: center !important;
70
- font-size: 0 !important;
71
  }
72
  .stFileUploader [data-testid="stFileUploaderDropzone"]::after {
73
  content: 'Drag and drop TXT, DOCX, or PDF here or ' !important;
74
- font-size: 1em !important;
75
- color: #666 !important;
76
  }
77
  .stFileUploader [data-testid="stFileUploaderButton"] {
78
- font-size: 1em !important;
79
- color: #1E90FF !important;
80
- background: none !important;
81
- border: none !important;
82
- padding: 0 !important;
83
- }
84
- .stFileUploader [data-testid="stFileUploader"] {
85
- background: none !important;
86
- }
87
- .stRadio > div {
88
- margin-bottom: 0 !important;
89
- }
90
- .stTextArea {
91
- margin-top: 0 !important;
92
  }
 
 
 
93
  </style>
94
  """,
95
  unsafe_allow_html=True
96
  )
97
 
98
- # Language and Input/Output Layout with symmetric columns
99
- left_col, right_col = st.columns([1, 1]) # Equal width for symmetric layout
100
  with left_col:
101
- 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")]
 
102
  source_language = detected_options[0][2] if detected_options[0][0] != "Auto-detect" else "Auto-detect"
103
  source_lang_code = next((k for k, v in LANGUAGES.items() if v[1] == source_language), "en") if source_language != "Auto-detect" else "auto"
104
  source_options = ["Auto-detect"] + [f"{v[0]} ({v[1]})" for v in LANGUAGES.values()]
@@ -109,15 +98,16 @@ def main():
109
  st.file_uploader("Upload File", type=["txt", "docx", "pdf"], key="file_input", on_change=on_file_upload, label_visibility="hidden")
110
  st.button("Translate", key="translate_btn", on_click=trigger_translation, args=(translation_module, language_detector, audio_processor_module))
111
  with right_col:
 
112
  source_lang_display = st.session_state.source_lang.split(" (")[0] if " (" in st.session_state.source_lang else st.session_state.source_lang
113
  target_options = [f"{v[0]} ({v[1]})" for v in LANGUAGES.values() if v[0] != source_lang_display and v[1] != source_lang_display]
114
  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")
115
  if "translated_text" in st.session_state:
116
  st.text_area("Output Text", value=st.session_state.translated_text, height=200, key="output_text", disabled=True, label_visibility="hidden")
117
- # Play audio button and playback below output
118
  if st.button("πŸ”Š", key="audio_btn", on_click=play_audio, args=(audio_processor_module,), help="Play audio", use_container_width=False):
119
  pass
120
- # Footer
121
  st.markdown("""
122
  <p style="font-size: small; color: grey; text-align: center;">
123
  Developed By: Krishna Prakash
@@ -126,42 +116,48 @@ def main():
126
  </a>
127
  </p>
128
  """, unsafe_allow_html=True)
129
-
130
  except Exception as e:
131
- st.error(f"App error: {e}")
132
 
133
- # Function to trigger translation process with progress indicator and adjusted timeout
134
  def trigger_translation(translation_module, language_detector, audio_processor_module):
135
- user_input_text = st.session_state.get("user_input_text", "").strip()
136
- if user_input_text:
137
- with st.spinner("Translating..."):
138
- start_time = time.time()
139
- source_lang = st.session_state.source_lang.split(" (")[0] if " (" in st.session_state.source_lang else st.session_state.source_lang
140
- target_lang = st.session_state.target_lang.split(" (")[0] if " (" in st.session_state.target_lang else st.session_state.target_lang
141
- if source_lang == "Auto-detect":
142
- detected_options = language_detector.detect_language(user_input_text)
143
- source_lang_code = next((k for k, v in LANGUAGES.items() if v[1] == detected_options[0][0]), "en")
144
- else:
145
- source_lang_code = next((k for k, v in LANGUAGES.items() if v[0] == source_lang), "en")
146
- target_lang_code = next((k for k, v in LANGUAGES.items() if v[0] == target_lang), "en")
147
- translated_text = translation_module.translate(user_input_text, source_lang_code, target_lang_code)
148
- if time.time() - start_time > 20: # Increased timeout to 20 seconds
149
- st.error("Translation took too long, reverting to input.")
150
- translated_text = user_input_text
151
- if translated_text and len(translated_text.split()) > 2: # Basic validation
152
- st.session_state.translated_text = translated_text
153
- else:
154
- st.session_state.translated_text = user_input_text
 
 
 
 
155
 
156
- # Function to handle audio playback with error handling
157
  def play_audio(audio_processor_module):
158
- if "translated_text" in st.session_state and st.session_state.translated_text:
159
- target_lang = next((k for k, v in LANGUAGES.items() if v[0] == st.session_state.target_lang.split(" (")[0]), "en")
160
- audio_data = audio_processor_module.text_to_speech(st.session_state.translated_text, target_lang)
161
- if audio_data and audio_data.getbuffer().nbytes > 0:
162
- st.audio(audio_data, format="audio/mp3")
163
- else:
164
- st.error("Failed to generate audio. Please try again.")
 
 
 
165
 
166
  if __name__ == "__main__":
167
  main()
 
5
  from PyPDF2 import PdfReader
6
  import time
7
 
8
+ # Configure Streamlit page settings
9
  st.set_page_config(page_title="Multilingual Translator", page_icon="🌐", layout="wide")
10
 
11
+ # Import language definitions from translation module
12
  try:
13
  from translation import LANGUAGES
14
  except ImportError as e:
15
  st.error(f"Failed to import translation module: {e}")
16
  st.stop()
17
 
18
+ # Extract text from uploaded files (PDF, DOCX, TXT)
19
  def extract_text_from_file(uploaded_file):
20
  try:
21
  if uploaded_file.type == "application/pdf":
22
  pdf_reader = PdfReader(uploaded_file)
23
+ text = "".join(page.extract_text() or "" for page in pdf_reader.pages)
24
+ return text.encode().decode("utf-8", errors="ignore").strip()
 
 
25
  elif uploaded_file.type == "application/vnd.openxmlformats-officedocument.wordprocessingml.document":
26
  doc = docx.Document(uploaded_file)
27
+ text = "\n".join(para.text for para in doc.paragraphs)
28
+ return text.encode().decode("utf-8", errors="ignore").strip()
29
  elif uploaded_file.type == "text/plain":
30
+ return uploaded_file.read().decode("utf-8", errors="ignore").strip()
31
  return ""
32
+ except Exception as e:
33
+ st.error(f"Error extracting text from file: {e}")
34
  return ""
35
 
36
+ # Update input text when a file is uploaded
37
  def on_file_upload():
38
+ try:
39
+ uploaded_file = st.session_state.get("file_input")
40
+ if uploaded_file and uploaded_file.size < 1024 * 1024:
41
+ st.session_state.user_input_text = extract_text_from_file(uploaded_file)
42
+ st.success(f"File '{uploaded_file.name}' uploaded successfully!")
43
+ elif uploaded_file and uploaded_file.size >= 1024 * 1024:
44
+ st.error("File size must be less than 1 MB")
45
+ except Exception as e:
46
+ st.error(f"Error processing file upload: {e}")
47
 
48
  # Main application function
49
  def main():
50
  try:
51
+ # Import required modules dynamically
52
  translation_module = importlib.import_module("translation")
53
  language_detector = importlib.import_module("lang_detect")
54
  audio_processor_module = importlib.import_module("audio_processor")
55
 
56
+ # Display application header
57
  st.markdown("<h1 style='text-align: center; color: #4285F4;'>Multilingual Translator</h1>", unsafe_allow_html=True)
58
  st.markdown("<p style='text-align: center; color: #666;'>Effortless Multilingual Translation</p>", unsafe_allow_html=True)
59
 
60
+ # Apply custom CSS for UI enhancements
61
  st.markdown(
62
  """
63
  <style>
64
+ .stFileUploader > div > div > div[role="button"] { display: none !important; }
65
+ .stFileUploader label { display: none !important; }
 
 
 
 
66
  .stFileUploader [data-testid="stFileUploaderDropzone"] {
67
+ border: 2px dashed #ccc !important; padding: 10px !important;
68
+ text-align: center !important; font-size: 0 !important;
 
 
69
  }
70
  .stFileUploader [data-testid="stFileUploaderDropzone"]::after {
71
  content: 'Drag and drop TXT, DOCX, or PDF here or ' !important;
72
+ font-size: 1em !important; color: #666 !important;
 
73
  }
74
  .stFileUploader [data-testid="stFileUploaderButton"] {
75
+ font-size: 1em !important; color: #1E90FF !important;
76
+ background: none !important; border: none !important; padding: 0 !important;
 
 
 
 
 
 
 
 
 
 
 
 
77
  }
78
+ .stFileUploader [data-testid="stFileUploader"] { background: none !important; }
79
+ .stRadio > div { margin-bottom: 0 !important; }
80
+ .stTextArea { margin-top: 0 !important; }
81
  </style>
82
  """,
83
  unsafe_allow_html=True
84
  )
85
 
86
+ # Create symmetric layout with two columns
87
+ left_col, right_col = st.columns([1, 1])
88
  with left_col:
89
+ # Detect language of input text if available
90
+ detected_options = language_detector.detect_language(st.session_state.get("user_input_text", "").strip()) if st.session_state.get("user_input_text", "").strip() else [("Auto-detect", 1.0, "Auto-detect")]
91
  source_language = detected_options[0][2] if detected_options[0][0] != "Auto-detect" else "Auto-detect"
92
  source_lang_code = next((k for k, v in LANGUAGES.items() if v[1] == source_language), "en") if source_language != "Auto-detect" else "auto"
93
  source_options = ["Auto-detect"] + [f"{v[0]} ({v[1]})" for v in LANGUAGES.values()]
 
98
  st.file_uploader("Upload File", type=["txt", "docx", "pdf"], key="file_input", on_change=on_file_upload, label_visibility="hidden")
99
  st.button("Translate", key="translate_btn", on_click=trigger_translation, args=(translation_module, language_detector, audio_processor_module))
100
  with right_col:
101
+ # Set target language options based on source language
102
  source_lang_display = st.session_state.source_lang.split(" (")[0] if " (" in st.session_state.source_lang else st.session_state.source_lang
103
  target_options = [f"{v[0]} ({v[1]})" for v in LANGUAGES.values() if v[0] != source_lang_display and v[1] != source_lang_display]
104
  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")
105
  if "translated_text" in st.session_state:
106
  st.text_area("Output Text", value=st.session_state.translated_text, height=200, key="output_text", disabled=True, label_visibility="hidden")
107
+ # Trigger audio playback on button click
108
  if st.button("πŸ”Š", key="audio_btn", on_click=play_audio, args=(audio_processor_module,), help="Play audio", use_container_width=False):
109
  pass
110
+ # Display application footer
111
  st.markdown("""
112
  <p style="font-size: small; color: grey; text-align: center;">
113
  Developed By: Krishna Prakash
 
116
  </a>
117
  </p>
118
  """, unsafe_allow_html=True)
 
119
  except Exception as e:
120
+ st.error(f"Application error occurred: {e}")
121
 
122
+ # Trigger translation process with timeout handling
123
  def trigger_translation(translation_module, language_detector, audio_processor_module):
124
+ try:
125
+ user_input_text = st.session_state.get("user_input_text", "").strip()
126
+ if user_input_text:
127
+ with st.spinner("Translating..."):
128
+ start_time = time.time()
129
+ source_lang = st.session_state.source_lang.split(" (")[0] if " (" in st.session_state.source_lang else st.session_state.source_lang
130
+ target_lang = st.session_state.target_lang.split(" (")[0] if " (" in st.session_state.target_lang else st.session_state.target_lang
131
+ if source_lang == "Auto-detect":
132
+ detected_options = language_detector.detect_language(user_input_text)
133
+ source_lang_code = next((k for k, v in LANGUAGES.items() if v[1] == detected_options[0][0]), "en")
134
+ else:
135
+ source_lang_code = next((k for k, v in LANGUAGES.items() if v[0] == source_lang), "en")
136
+ target_lang_code = next((k for k, v in LANGUAGES.items() if v[0] == target_lang), "en")
137
+ translated_text = translation_module.translate(user_input_text, source_lang_code, target_lang_code)
138
+ if time.time() - start_time > 20: # Check if translation exceeds 20-second timeout
139
+ st.error("Translation took too long, reverting to input.")
140
+ translated_text = user_input_text
141
+ if translated_text and len(translated_text.split()) > 2: # Validate translation result
142
+ st.session_state.translated_text = translated_text
143
+ else:
144
+ st.session_state.translated_text = user_input_text
145
+ except Exception as e:
146
+ st.error(f"Translation process failed: {e}")
147
+ st.session_state.translated_text = user_input_text
148
 
149
+ # Handle audio playback with error checking
150
  def play_audio(audio_processor_module):
151
+ try:
152
+ if "translated_text" in st.session_state and st.session_state.translated_text:
153
+ target_lang = next((k for k, v in LANGUAGES.items() if v[0] == st.session_state.target_lang.split(" (")[0]), "en")
154
+ audio_data = audio_processor_module.text_to_speech(st.session_state.translated_text, target_lang)
155
+ if audio_data and audio_data.getbuffer().nbytes > 0:
156
+ st.audio(audio_data, format="audio/mp3")
157
+ else:
158
+ st.error("Failed to generate audio. Please try again.")
159
+ except Exception as e:
160
+ st.error(f"Audio playback failed: {e}")
161
 
162
  if __name__ == "__main__":
163
  main()