amine_dubs commited on
Commit
a583ad7
·
1 Parent(s): b7f5097
Files changed (2) hide show
  1. backend/main.py +15 -7
  2. static/script.js +104 -128
backend/main.py CHANGED
@@ -182,14 +182,15 @@ def translate_text(text, source_lang, target_lang):
182
  return use_fallback_translation(text, source_lang, target_lang)
183
 
184
  try:
185
- # Only send the raw text to the Helsinki model
186
- text_to_translate = text
 
187
 
188
  # Use a more reliable timeout approach with concurrent.futures
189
  with concurrent.futures.ThreadPoolExecutor() as executor:
190
  future = executor.submit(
191
  lambda: translator(
192
- text_to_translate,
193
  max_length=768
194
  )[0]["translation_text"]
195
  )
@@ -198,17 +199,17 @@ def translate_text(text, source_lang, target_lang):
198
  # Set a reasonable timeout
199
  result = future.result(timeout=10)
200
 
201
- # Post-process the result for Arabic cultural adaptation
202
  if target_lang == "ar":
203
  result = culturally_adapt_arabic(result)
204
 
 
205
  return result
206
  except concurrent.futures.TimeoutError:
207
  print(f"Model inference timed out after 10 seconds, falling back to online translation")
208
  return use_fallback_translation(text, source_lang, target_lang)
209
  except Exception as e:
210
  print(f"Error during model inference: {e}")
211
-
212
  # If the model failed during inference, try to re-initialize it for next time
213
  # but use fallback for this request
214
  initialize_model()
@@ -440,27 +441,34 @@ async def translate_document_endpoint(
440
  target_lang: str = Form("ar")
441
  ):
442
  """Translates text extracted from an uploaded document."""
 
443
  try:
444
  # Extract text directly from the uploaded file
 
445
  extracted_text = await extract_text_from_file(file)
446
 
447
  if not extracted_text:
 
448
  raise HTTPException(status_code=400, detail="Could not extract any text from the document.")
449
 
450
- # Translate the extracted text
 
451
  translated_text = translate_text(extracted_text, source_lang, target_lang)
452
 
 
453
  return JSONResponse(content={
454
  "original_filename": file.filename,
455
- "detected_source_lang": source_lang,
456
  "translated_text": translated_text
457
  })
458
 
459
  except HTTPException as http_exc:
 
460
  raise http_exc
461
  except Exception as e:
462
  print(f"Document translation error: {e}")
463
  traceback.print_exc()
 
464
  raise HTTPException(status_code=500, detail=f"Document translation error: {str(e)}")
465
 
466
  # --- Run the server (for local development) ---
 
182
  return use_fallback_translation(text, source_lang, target_lang)
183
 
184
  try:
185
+ # Ensure only the raw text is sent to the Helsinki model
186
+ text_to_translate = text
187
+ print(f"Translating text (first 50 chars): {text_to_translate[:50]}...") # Log the actual text being sent
188
 
189
  # Use a more reliable timeout approach with concurrent.futures
190
  with concurrent.futures.ThreadPoolExecutor() as executor:
191
  future = executor.submit(
192
  lambda: translator(
193
+ text_to_translate, # Pass only the raw text
194
  max_length=768
195
  )[0]["translation_text"]
196
  )
 
199
  # Set a reasonable timeout
200
  result = future.result(timeout=10)
201
 
202
+ # Post-process the result for Arabic cultural adaptation if needed
203
  if target_lang == "ar":
204
  result = culturally_adapt_arabic(result)
205
 
206
+ print(f"Translation successful (first 50 chars): {result[:50]}...")
207
  return result
208
  except concurrent.futures.TimeoutError:
209
  print(f"Model inference timed out after 10 seconds, falling back to online translation")
210
  return use_fallback_translation(text, source_lang, target_lang)
211
  except Exception as e:
212
  print(f"Error during model inference: {e}")
 
213
  # If the model failed during inference, try to re-initialize it for next time
214
  # but use fallback for this request
215
  initialize_model()
 
441
  target_lang: str = Form("ar")
442
  ):
443
  """Translates text extracted from an uploaded document."""
444
+ print("[DEBUG] /translate/document endpoint called (Updated Code Check)") # Added log
445
  try:
446
  # Extract text directly from the uploaded file
447
+ print(f"[DEBUG] Processing file: {file.filename}, Source: {source_lang}, Target: {target_lang}")
448
  extracted_text = await extract_text_from_file(file)
449
 
450
  if not extracted_text:
451
+ print("[DEBUG] No text extracted from document.")
452
  raise HTTPException(status_code=400, detail="Could not extract any text from the document.")
453
 
454
+ # Translate the extracted text using the updated translate_text function
455
+ print("[DEBUG] Calling translate_text for document content...")
456
  translated_text = translate_text(extracted_text, source_lang, target_lang)
457
 
458
+ print(f"[DEBUG] Document translation successful. Returning result for {file.filename}")
459
  return JSONResponse(content={
460
  "original_filename": file.filename,
461
+ "detected_source_lang": source_lang, # Assuming source_lang is detected or provided correctly
462
  "translated_text": translated_text
463
  })
464
 
465
  except HTTPException as http_exc:
466
+ # Re-raise HTTPExceptions directly
467
  raise http_exc
468
  except Exception as e:
469
  print(f"Document translation error: {e}")
470
  traceback.print_exc()
471
+ # Return a generic error response
472
  raise HTTPException(status_code=500, detail=f"Document translation error: {str(e)}")
473
 
474
  # --- Run the server (for local development) ---
static/script.js CHANGED
@@ -2,142 +2,119 @@
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
- // Debugging: Log the form element itself
24
- console.log('Form element context (this):', this);
25
-
26
- // Always select elements from the form context
27
- const textInput = this.querySelector('#text-input');
28
- // Debugging: Log the result of the querySelector
29
- console.log('Result of this.querySelector(\'#text-input\'):', textInput);
30
-
31
- const sourceLang = this.querySelector('#source-lang-text');
32
- console.log('Result of this.querySelector(\'#source-lang-text\'):', sourceLang);
33
-
34
- const targetLang = this.querySelector('#target-lang-text');
35
- console.log('Result of this.querySelector(\'#target-lang-text\'):', targetLang);
36
-
37
- const loadingElement = document.querySelector('#text-loading');
38
- const debugElement = document.querySelector('#debug-info');
39
-
40
- // Log which elements were found
41
- console.log('Elements found:', {
42
- textInput: !!textInput,
43
- sourceLang: !!sourceLang,
44
- targetLang: !!targetLang
45
- });
46
-
47
- // Show debug info
48
- if (debugElement) {
49
- debugElement.textContent = `Form elements found:
50
- text-input: ${!!textInput}
51
- source-lang-text: ${!!sourceLang}
52
- target-lang-text: ${!!targetLang}`;
53
- debugElement.style.display = 'block';
 
 
 
 
 
 
 
 
 
 
 
54
  }
55
 
56
- // Check for missing elements
57
- if (!textInput || !sourceLang || !targetLang) {
58
- // Debugging: Log which specific elements are missing
59
- console.error('Missing elements:', {
60
- textInput: textInput,
61
- sourceLang: sourceLang,
62
- targetLang: targetLang
63
- });
64
- showError('Form elements not found. Please check the HTML structure and console logs.');
65
- return;
66
  }
67
 
68
- // Get values
69
- const text = textInput.value ? textInput.value.trim() : '';
70
- if (!text) {
71
- showError('Please enter text to translate');
72
- return;
73
  }
74
-
75
- // Get language selections
76
- const sourceLangValue = sourceLang.value;
77
- const targetLangValue = targetLang.value;
78
-
79
- // Show loading indicator
80
- if (loadingElement) loadingElement.style.display = 'block';
81
-
82
- // Create payload
83
- const payload = {
84
- text: text,
85
- source_lang: sourceLangValue,
86
- target_lang: targetLangValue
87
- };
88
-
89
- console.log('Sending payload:', payload);
90
-
91
- // Send API request
92
- fetch('/translate/text', {
93
- method: 'POST',
94
- headers: { 'Content-Type': 'application/json' },
95
- body: JSON.stringify(payload)
96
- })
97
- .then(function(response) {
98
- if (!response.ok) throw new Error('Server error: ' + response.status);
99
- return response.text();
100
- })
101
- .then(function(responseText) {
102
- console.log('Response received:', responseText);
103
-
104
- // Try to parse JSON
105
- let data;
106
- try {
107
- data = JSON.parse(responseText);
108
- } catch (error) {
109
- throw new Error('Invalid response from server');
110
- }
111
-
112
- // Check for translation
113
- if (!data.translated_text) {
114
- throw new Error('No translation returned');
115
- }
116
-
117
- // Show result
118
- const resultBox = document.querySelector('#text-result');
119
- const outputElement = document.querySelector('#text-output');
120
-
121
- if (resultBox && outputElement) {
122
- outputElement.textContent = data.translated_text;
123
- resultBox.style.display = 'block';
124
- }
125
- })
126
- .catch(function(error) {
127
- showError(error.message || 'Translation failed');
128
- console.error('Error:', error);
129
- })
130
- .finally(function() {
131
- if (loadingElement) loadingElement.style.display = 'none';
132
- });
133
  });
134
- } else {
135
- console.error('Text translation form not found in the document!');
136
- }
137
 
138
  // Document translation handler
139
  if (docTranslationForm) {
140
- console.log('Document translation form found');
141
  docTranslationForm.addEventListener('submit', function(event) {
142
  event.preventDefault();
143
  console.log('Document translation form submitted');
@@ -201,16 +178,15 @@ window.onload = function() {
201
  });
202
  });
203
  } else {
204
- console.error('Document translation form not found in the document!');
205
  }
206
 
207
  // Helper function to show errors
208
  function showError(message) {
209
- const errorDiv = document.querySelector('#error-message');
210
- if (errorDiv) {
211
- errorDiv.textContent = 'Error: ' + message;
212
- errorDiv.style.display = 'block';
213
  }
214
- console.error('Error:', message);
215
  }
216
  };
 
2
  window.onload = function() {
3
  console.log('Window fully loaded, initializing translation app');
4
 
5
+ // Get form elements ONCE after load
6
  const textTranslationForm = document.querySelector('#text-translation-form');
7
  const docTranslationForm = document.querySelector('#doc-translation-form');
8
 
9
+ // Get text form INPUT elements ONCE
10
+ const textInput = document.getElementById('text-input');
11
+ const sourceLangText = document.getElementById('source-lang-text');
12
+ const targetLangText = document.getElementById('target-lang-text');
13
+ const textLoadingElement = document.getElementById('text-loading');
14
+ const debugElement = document.getElementById('debug-info');
15
+ const errorElement = document.getElementById('error-message');
16
+ const textResultBox = document.getElementById('text-result');
17
+ const textOutputElement = document.getElementById('text-output');
18
+
19
+ // Check if essential text elements were found on load
20
+ if (!textTranslationForm || !textInput || !sourceLangText || !targetLangText) {
21
+ console.error('CRITICAL: Essential text form elements not found on window load!', {
22
+ form: !!textTranslationForm,
23
+ input: !!textInput,
24
+ source: !!sourceLangText,
25
+ target: !!targetLangText
26
+ });
27
+ if (errorElement) {
28
+ errorElement.textContent = 'Error: Could not find essential text translation form elements. Check HTML IDs.';
29
+ errorElement.style.display = 'block';
30
+ }
31
+ // Optionally disable the form if elements are missing
32
+ if (textTranslationForm) textTranslationForm.style.opacity = '0.5';
33
+ return; // Stop further initialization if critical elements missing
34
+ }
35
+
36
  // Set up text translation form
37
+ console.log('Text translation form and elements found on load');
38
+ textTranslationForm.addEventListener('submit', function(event) {
39
+ event.preventDefault();
40
+ console.log('Text translation form submitted');
41
 
42
+ // Hide previous results/errors
43
+ if (textResultBox) textResultBox.style.display = 'none';
44
+ if (errorElement) errorElement.style.display = 'none';
45
+ if (debugElement) debugElement.style.display = 'none';
46
+
47
+ // **Crucial Check:** Verify elements still exist before use
48
+ if (!textInput || !sourceLangText || !targetLangText) {
49
+ console.error('ERROR: Text form elements became null before accessing value!');
50
+ showError('Internal error: Form elements missing unexpectedly.');
51
+ return;
52
+ }
53
+
54
+ // Get values
55
+ const text = textInput.value ? textInput.value.trim() : '';
56
+ if (!text) {
57
+ showError('Please enter text to translate');
58
+ return;
59
+ }
60
+
61
+ const sourceLangValue = sourceLangText.value;
62
+ const targetLangValue = targetLangText.value;
63
+
64
+ // Show loading indicator
65
+ if (textLoadingElement) textLoadingElement.style.display = 'block';
66
+
67
+ // Create payload
68
+ const payload = {
69
+ text: text,
70
+ source_lang: sourceLangValue,
71
+ target_lang: targetLangValue
72
+ };
73
+
74
+ console.log('Sending payload:', payload);
75
+
76
+ // Send API request
77
+ fetch('/translate/text', {
78
+ method: 'POST',
79
+ headers: { 'Content-Type': 'application/json' },
80
+ body: JSON.stringify(payload)
81
+ })
82
+ .then(response => {
83
+ if (!response.ok) throw new Error('Server error: ' + response.status);
84
+ return response.text(); // Get raw text first
85
+ })
86
+ .then(responseText => {
87
+ console.log('Response received:', responseText);
88
+ let data;
89
+ try {
90
+ data = JSON.parse(responseText);
91
+ } catch (error) {
92
+ console.error("Failed to parse JSON:", responseText);
93
+ throw new Error('Invalid response format from server');
94
  }
95
 
96
+ if (!data.success || !data.translated_text) {
97
+ throw new Error(data.error || 'No translation returned or success flag false');
 
 
 
 
 
 
 
 
98
  }
99
 
100
+ // Show result
101
+ if (textResultBox && textOutputElement) {
102
+ textOutputElement.textContent = data.translated_text;
103
+ textResultBox.style.display = 'block';
 
104
  }
105
+ })
106
+ .catch(error => {
107
+ showError(error.message || 'Translation failed');
108
+ console.error('Error:', error);
109
+ })
110
+ .finally(() => {
111
+ if (textLoadingElement) textLoadingElement.style.display = 'none';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
112
  });
113
+ });
 
 
114
 
115
  // Document translation handler
116
  if (docTranslationForm) {
117
+ console.log('Document translation form found on load');
118
  docTranslationForm.addEventListener('submit', function(event) {
119
  event.preventDefault();
120
  console.log('Document translation form submitted');
 
178
  });
179
  });
180
  } else {
181
+ console.error('Document translation form not found on load!');
182
  }
183
 
184
  // Helper function to show errors
185
  function showError(message) {
186
+ if (errorElement) {
187
+ errorElement.textContent = 'Error: ' + message;
188
+ errorElement.style.display = 'block';
 
189
  }
190
+ console.error('Error displayed:', message);
191
  }
192
  };