amine_dubs commited on
Commit
54fb2f1
·
1 Parent(s): 443ca56
Files changed (2) hide show
  1. backend/main.py +7 -17
  2. static/script.js +170 -187
backend/main.py CHANGED
@@ -182,34 +182,24 @@ def translate_text(text, source_lang, target_lang):
182
  return use_fallback_translation(text, source_lang, target_lang)
183
 
184
  try:
185
- # Get full language name for better prompt context
186
  source_lang_name = LANGUAGE_MAP.get(source_lang, source_lang)
187
 
188
- # Create a culturally-aware prompt with focus on Arabic eloquence (Balagha)
189
- if target_lang == "ar":
190
- prompt = f"""Translate the following {source_lang_name} text into Modern Standard Arabic (Fusha).
191
- Focus on conveying the meaning elegantly using proper Balagha (Arabic eloquence).
192
- Adapt any cultural references or idioms appropriately rather than translating literally.
193
- Ensure the translation reads naturally to a native Arabic speaker.
194
-
195
- Text to translate:
196
- {text}"""
197
- print("Using culturally-aware prompt for Arabic translation with Balagha focus")
198
- else:
199
- # For non-Arabic target languages, use standard approach
200
- prompt = text
201
 
202
  # Use a more reliable timeout approach with concurrent.futures
203
  with concurrent.futures.ThreadPoolExecutor() as executor:
204
  future = executor.submit(
205
  lambda: translator(
206
- prompt, # Using our enhanced prompt instead of raw text
207
- max_length=768 # Increased max_length to accommodate longer prompt
208
  )[0]["translation_text"]
209
  )
210
 
211
  try:
212
- # Set a reasonable timeout (10 seconds instead of 15)
213
  result = future.result(timeout=10)
214
 
215
  # Post-process the result for Arabic cultural adaptation
 
182
  return use_fallback_translation(text, source_lang, target_lang)
183
 
184
  try:
185
+ # Get full language name for better cultural adaptation
186
  source_lang_name = LANGUAGE_MAP.get(source_lang, source_lang)
187
 
188
+ # The Helsinki model doesn't need or work with the elaborate prompt
189
+ # Just send the text directly for translation
190
+ text_to_translate = text
 
 
 
 
 
 
 
 
 
 
191
 
192
  # Use a more reliable timeout approach with concurrent.futures
193
  with concurrent.futures.ThreadPoolExecutor() as executor:
194
  future = executor.submit(
195
  lambda: translator(
196
+ text_to_translate,
197
+ max_length=768
198
  )[0]["translation_text"]
199
  )
200
 
201
  try:
202
+ # Set a reasonable timeout
203
  result = future.result(timeout=10)
204
 
205
  # Post-process the result for Arabic cultural adaptation
static/script.js CHANGED
@@ -1,217 +1,200 @@
1
  // Wait for the DOM to be fully loaded before attaching event handlers
2
- document.addEventListener('DOMContentLoaded', function() {
3
- console.log('DOM fully loaded, initializing translation app');
4
 
5
- // Get form elements
6
- const textTranslationForm = document.getElementById('text-translation-form');
7
- const docTranslationForm = document.getElementById('doc-translation-form');
8
 
9
  // Set up text translation form
10
  if (textTranslationForm) {
11
  console.log('Text translation form found');
12
- textTranslationForm.onsubmit = handleTextTranslation;
13
- } else {
14
- console.error('Text translation form not found!');
15
- }
16
-
17
- // Set up document translation form
18
- if (docTranslationForm) {
19
- console.log('Document translation form found');
20
- docTranslationForm.onsubmit = handleDocTranslation;
21
- } else {
22
- console.error('Document translation form not found!');
23
- }
24
-
25
- // Function to handle text translation
26
- function handleTextTranslation(event) {
27
- event.preventDefault();
28
- console.log('Text translation form submitted');
29
-
30
- // Clear previous results and errors
31
- hideElement('text-result');
32
- hideElement('error-message');
33
- hideElement('debug-info');
34
-
35
- // Get form elements
36
- const textInputElement = document.getElementById('text-input');
37
- const sourceLangElement = document.getElementById('source-lang-text');
38
- const targetLangElement = document.getElementById('target-lang-text');
39
- const loadingElement = document.getElementById('text-loading');
40
- const debugElement = document.getElementById('debug-info');
41
-
42
- // Debug which elements were found
43
- let debug = 'Found elements: ';
44
- debug += textInputElement ? 'text-input ✓ ' : 'text-input ✗ ';
45
- debug += sourceLangElement ? 'source-lang-text ✓ ' : 'source-lang-text ✗ ';
46
- debug += targetLangElement ? 'target-lang-text ✓ ' : 'target-lang-text ✗ ';
47
- console.log(debug);
48
-
49
- // Show debug info
50
- if (debugElement) {
51
- debugElement.textContent = debug;
52
- debugElement.style.display = 'block';
53
- }
54
-
55
- // Check for missing elements
56
- if (!textInputElement || !sourceLangElement || !targetLangElement) {
57
- showError('One or more form elements are missing');
58
- return;
59
- }
60
-
61
- // Get text input
62
- const textInput = textInputElement.value ? textInputElement.value.trim() : '';
63
- if (!textInput) {
64
- showError('Please enter text to translate');
65
- return;
66
- }
67
-
68
- // Get language selections
69
- const sourceLang = sourceLangElement.value;
70
- const targetLang = targetLangElement.value;
71
-
72
- // Show loading indicator
73
- if (loadingElement) {
74
- loadingElement.style.display = 'block';
75
- }
76
-
77
- // Create request payload
78
- const payload = {
79
- text: textInput,
80
- source_lang: sourceLang,
81
- target_lang: targetLang
82
- };
83
 
84
- // Make the API request
85
- fetch('/translate/text', {
86
- method: 'POST',
87
- headers: {
88
- 'Content-Type': 'application/json',
89
- },
90
- body: JSON.stringify(payload)
91
- })
92
- .then(function(response) {
93
- if (!response.ok) {
94
- throw new Error(`Server returned ${response.status}: ${response.statusText}`);
95
- }
96
- return response.text();
97
- })
98
- .then(function(responseText) {
99
- // Show response in debug
 
 
 
 
 
 
 
 
 
100
  if (debugElement) {
101
- debugElement.textContent += '\n\nResponse: ' + responseText;
 
 
 
 
102
  }
103
 
104
- let data;
105
- try {
106
- data = JSON.parse(responseText);
107
- } catch (error) {
108
- throw new Error('Invalid JSON response from server');
109
  }
110
 
111
- if (!data.translated_text && !data.success) {
112
- throw new Error(data.error || 'No translation returned');
 
 
 
113
  }
114
 
115
- // Show the result
116
- const resultBox = document.getElementById('text-result');
117
- const outputElement = document.getElementById('text-output');
118
- if (resultBox && outputElement) {
119
- outputElement.textContent = data.translated_text;
120
- resultBox.style.display = 'block';
121
- }
122
- })
123
- .catch(function(error) {
124
- showError(error.message);
125
- console.error('Translation error:', error);
126
- })
127
- .finally(function() {
128
- // Hide loading indicator
129
- if (loadingElement) {
130
- loadingElement.style.display = 'none';
131
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
132
  });
 
 
133
  }
134
 
135
- // Function to handle document translation
136
- function handleDocTranslation(event) {
137
- event.preventDefault();
138
- console.log('Document translation form submitted');
139
-
140
- // Clear previous results and errors
141
- hideElement('doc-result');
142
- hideElement('error-message');
143
-
144
- // Get form elements
145
- const fileInput = document.getElementById('doc-input');
146
- const loadingIndicator = document.getElementById('doc-loading');
147
-
148
- if (!fileInput || !fileInput.files || fileInput.files.length === 0) {
149
- showError('Please select a document to upload');
150
- return;
151
- }
152
-
153
- // Show loading indicator
154
- if (loadingIndicator) {
155
- loadingIndicator.style.display = 'block';
156
- }
157
-
158
- // Create form data
159
- const formData = new FormData(docTranslationForm);
160
-
161
- // Make API request
162
- fetch('/translate/document', {
163
- method: 'POST',
164
- body: formData
165
- })
166
- .then(function(response) {
167
- if (!response.ok) {
168
- throw new Error(`Server returned ${response.status}`);
169
- }
170
- return response.json();
171
- })
172
- .then(function(data) {
173
- if (!data.translated_text) {
174
- throw new Error('No translation returned');
175
- }
176
 
177
- // Display result
178
- const resultBox = document.getElementById('doc-result');
179
- const outputEl = document.getElementById('doc-output');
180
- const filenameEl = document.getElementById('doc-filename');
181
- const sourceLangEl = document.getElementById('doc-source-lang');
182
-
183
- if (resultBox && outputEl) {
184
- if (filenameEl) filenameEl.textContent = data.original_filename || 'N/A';
185
- if (sourceLangEl) sourceLangEl.textContent = data.detected_source_lang || 'N/A';
186
- outputEl.textContent = data.translated_text;
187
- resultBox.style.display = 'block';
188
- }
189
- })
190
- .catch(function(error) {
191
- showError(error.message);
192
- })
193
- .finally(function() {
194
- if (loadingIndicator) {
195
- loadingIndicator.style.display = 'none';
196
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
197
  });
 
 
198
  }
199
 
200
  // Helper function to show errors
201
  function showError(message) {
202
- const errorDiv = document.getElementById('error-message');
203
  if (errorDiv) {
204
  errorDiv.textContent = 'Error: ' + message;
205
  errorDiv.style.display = 'block';
206
  }
207
  console.error('Error:', message);
208
  }
209
-
210
- // Helper function to hide elements
211
- function hideElement(id) {
212
- const element = document.getElementById(id);
213
- if (element) {
214
- element.style.display = 'none';
215
- }
216
- }
217
- });
 
1
  // Wait for the DOM to be fully loaded before attaching event handlers
2
+ window.onload = function() {
3
+ console.log('Window fully loaded, initializing translation app');
4
 
5
+ // Get form elements using direct form access instead of getElementById
6
+ const textTranslationForm = document.querySelector('#text-translation-form');
7
+ const docTranslationForm = document.querySelector('#doc-translation-form');
8
 
9
  // Set up text translation form
10
  if (textTranslationForm) {
11
  console.log('Text translation form found');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
12
 
13
+ // Use standard form submit event
14
+ textTranslationForm.addEventListener('submit', function(event) {
15
+ event.preventDefault();
16
+ console.log('Text translation form submitted');
17
+
18
+ // Clear previous results and errors
19
+ document.querySelectorAll('#text-result, #error-message, #debug-info').forEach(el => {
20
+ if (el) el.style.display = 'none';
21
+ });
22
+
23
+ // Get form elements directly from the form itself
24
+ const textInput = textTranslationForm.querySelector('#text-input');
25
+ const sourceLang = textTranslationForm.querySelector('#source-lang-text');
26
+ const targetLang = textTranslationForm.querySelector('#target-lang-text');
27
+ const loadingElement = document.querySelector('#text-loading');
28
+ const debugElement = document.querySelector('#debug-info');
29
+
30
+ // Log which elements were found
31
+ console.log('Elements found:', {
32
+ textInput: !!textInput,
33
+ sourceLang: !!sourceLang,
34
+ targetLang: !!targetLang
35
+ });
36
+
37
+ // Show debug info
38
  if (debugElement) {
39
+ debugElement.textContent = `Form elements found:
40
+ text-input: ${!!textInput}
41
+ source-lang-text: ${!!sourceLang}
42
+ target-lang-text: ${!!targetLang}`;
43
+ debugElement.style.display = 'block';
44
  }
45
 
46
+ // Check for missing elements
47
+ if (!textInput || !sourceLang || !targetLang) {
48
+ showError('Form elements not found. Please check the HTML structure.');
49
+ return;
 
50
  }
51
 
52
+ // Get values
53
+ const text = textInput.value ? textInput.value.trim() : '';
54
+ if (!text) {
55
+ showError('Please enter text to translate');
56
+ return;
57
  }
58
 
59
+ // Get language selections
60
+ const sourceLangValue = sourceLang.value;
61
+ const targetLangValue = targetLang.value;
62
+
63
+ // Show loading indicator
64
+ if (loadingElement) loadingElement.style.display = 'block';
65
+
66
+ // Create payload
67
+ const payload = {
68
+ text: text,
69
+ source_lang: sourceLangValue,
70
+ target_lang: targetLangValue
71
+ };
72
+
73
+ console.log('Sending payload:', payload);
74
+
75
+ // Send API request
76
+ fetch('/translate/text', {
77
+ method: 'POST',
78
+ headers: { 'Content-Type': 'application/json' },
79
+ body: JSON.stringify(payload)
80
+ })
81
+ .then(function(response) {
82
+ if (!response.ok) throw new Error('Server error: ' + response.status);
83
+ return response.text();
84
+ })
85
+ .then(function(responseText) {
86
+ console.log('Response received:', responseText);
87
+
88
+ // Try to parse JSON
89
+ let data;
90
+ try {
91
+ data = JSON.parse(responseText);
92
+ } catch (error) {
93
+ throw new Error('Invalid response from server');
94
+ }
95
+
96
+ // Check for translation
97
+ if (!data.translated_text) {
98
+ throw new Error('No translation returned');
99
+ }
100
+
101
+ // Show result
102
+ const resultBox = document.querySelector('#text-result');
103
+ const outputElement = document.querySelector('#text-output');
104
+
105
+ if (resultBox && outputElement) {
106
+ outputElement.textContent = data.translated_text;
107
+ resultBox.style.display = 'block';
108
+ }
109
+ })
110
+ .catch(function(error) {
111
+ showError(error.message || 'Translation failed');
112
+ console.error('Error:', error);
113
+ })
114
+ .finally(function() {
115
+ if (loadingElement) loadingElement.style.display = 'none';
116
+ });
117
  });
118
+ } else {
119
+ console.error('Text translation form not found in the document!');
120
  }
121
 
122
+ // Document translation handler
123
+ if (docTranslationForm) {
124
+ console.log('Document translation form found');
125
+ docTranslationForm.addEventListener('submit', function(event) {
126
+ event.preventDefault();
127
+ console.log('Document translation form submitted');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
128
 
129
+ // Clear previous results and errors
130
+ document.querySelectorAll('#doc-result, #error-message').forEach(el => {
131
+ if (el) el.style.display = 'none';
132
+ });
133
+
134
+ // Get form elements
135
+ const fileInput = docTranslationForm.querySelector('#doc-input');
136
+ const loadingIndicator = document.querySelector('#doc-loading');
137
+
138
+ if (!fileInput || !fileInput.files || fileInput.files.length === 0) {
139
+ showError('Please select a document to upload');
140
+ return;
 
 
 
 
 
 
 
141
  }
142
+
143
+ // Show loading indicator
144
+ if (loadingIndicator) loadingIndicator.style.display = 'block';
145
+
146
+ // Create form data
147
+ const formData = new FormData(docTranslationForm);
148
+
149
+ // Make API request
150
+ fetch('/translate/document', {
151
+ method: 'POST',
152
+ body: formData
153
+ })
154
+ .then(function(response) {
155
+ if (!response.ok) {
156
+ throw new Error(`Server returned ${response.status}`);
157
+ }
158
+ return response.json();
159
+ })
160
+ .then(function(data) {
161
+ if (!data.translated_text) {
162
+ throw new Error('No translation returned');
163
+ }
164
+
165
+ // Display result
166
+ const resultBox = document.querySelector('#doc-result');
167
+ const outputEl = document.querySelector('#doc-output');
168
+ const filenameEl = document.querySelector('#doc-filename');
169
+ const sourceLangEl = document.querySelector('#doc-source-lang');
170
+
171
+ if (resultBox && outputEl) {
172
+ if (filenameEl) filenameEl.textContent = data.original_filename || 'N/A';
173
+ if (sourceLangEl) sourceLangEl.textContent = data.detected_source_lang || 'N/A';
174
+ outputEl.textContent = data.translated_text;
175
+ resultBox.style.display = 'block';
176
+ }
177
+ })
178
+ .catch(function(error) {
179
+ showError(error.message);
180
+ })
181
+ .finally(function() {
182
+ if (loadingIndicator) {
183
+ loadingIndicator.style.display = 'none';
184
+ }
185
+ });
186
  });
187
+ } else {
188
+ console.error('Document translation form not found in the document!');
189
  }
190
 
191
  // Helper function to show errors
192
  function showError(message) {
193
+ const errorDiv = document.querySelector('#error-message');
194
  if (errorDiv) {
195
  errorDiv.textContent = 'Error: ' + message;
196
  errorDiv.style.display = 'block';
197
  }
198
  console.error('Error:', message);
199
  }
200
+ };