Skip to content

Commit 8fcdf3f

Browse files
Add files via upload
1 parent 27db4ed commit 8fcdf3f

File tree

2 files changed

+372
-0
lines changed

2 files changed

+372
-0
lines changed

Translator/README.md

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
# AI-Powered Translator GUI Application
2+
3+
This Python-based GUI application leverages the OpenAI API to translate text accurately while preserving the original meaning. Built with PyQt5, it offers an intuitive and feature-rich user interface designed to streamline text translation tasks.
4+
5+
## Key Features
6+
7+
### Core Functionalities:
8+
- **Text Translation:** Translate text between multiple languages using OpenAI's advanced language models.
9+
- **Batch Translation:** Efficiently translate multiple text files simultaneously.
10+
- **Auto Language Detection:** Automatically identifies the language of input text.
11+
- **Speech-to-Text:** Input text via voice using microphone support.
12+
- **Text-to-Speech:** Converts translated text into audio files (MP3).
13+
- **Translation History:** Keeps track of all previous translations.
14+
- **Cost Estimation:** Calculates and displays the approximate cost of each translation request based on token usage.
15+
- **Feedback Mechanism:** Enables users to submit feedback to improve future translations.
16+
- **Progress Visualization:** Provides real-time translation progress via a progress bar, especially useful for batch translations.
17+
18+
## Features
19+
20+
- **File Operations:** Open and save translated texts.
21+
- **Clipboard Support:** Easy copying of translated content.
22+
- **Automatic Language Detection:** Integrated language detection for convenience.
23+
24+
## Technologies Used
25+
26+
- **Python 3.x**
27+
- **PyQt5** for GUI development
28+
- **OpenAI GPT API** for translations
29+
- **SpeechRecognition** for speech-to-text
30+
- **gTTS** for text-to-speech
31+
- **langdetect** for automatic language detection
32+
33+
## Setup and Installation
34+
35+
### Prerequisites
36+
- Python 3.x installed
37+
- Install dependencies:
38+
39+
```bash
40+
pip install PyQt5 openai SpeechRecognition gTTS langdetect
41+
```
42+
43+
## Running the Application
44+
45+
```bash
46+
python translator_app.py
47+
```
48+
49+
## Usage Instructions
50+
51+
1. Open or type the text you wish to translate.
52+
2. Select the target language from the dropdown.
53+
3. Click **Translate**.
54+
4. Use advanced features such as batch translation, text-to-speech, and more via dedicated buttons.
55+
56+
## Notes
57+
- Replace the provided OpenAI API key with your own secure key.
58+
- API costs shown are estimated based on token counts and current pricing (subject to change by OpenAI).
59+
60+
## Feedback and Contributions
61+
Contributions and feedback are welcomed to enhance the application's functionality and performance.
62+

Translator/translation.py

Lines changed: 310 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,310 @@
1+
import sys
2+
from PyQt5.QtWidgets import (
3+
QApplication, QMainWindow, QWidget, QVBoxLayout, QHBoxLayout,
4+
QPushButton, QTextEdit, QFileDialog, QLabel, QComboBox, QMessageBox, QProgressBar, QDialog, QInputDialog
5+
)
6+
from PyQt5.QtCore import Qt
7+
from openai import OpenAI
8+
9+
# Initialize the OpenAI client with your test API key.
10+
client = OpenAI(
11+
api_key="TOKEN"
12+
)
13+
14+
15+
class TranslatorApp(QMainWindow):
16+
def __init__(self):
17+
super().__init__()
18+
self.setWindowTitle("Text Translator")
19+
self.resize(1000, 700)
20+
self.translation_history = []
21+
self.feedback_list = []
22+
self.initUI()
23+
24+
def initUI(self):
25+
# Main widget and layout
26+
main_widget = QWidget()
27+
self.setCentralWidget(main_widget)
28+
main_layout = QVBoxLayout()
29+
main_widget.setLayout(main_layout)
30+
31+
# Input text field
32+
self.input_text_edit = QTextEdit()
33+
self.input_text_edit.setPlaceholderText("Enter or load text to translate...")
34+
main_layout.addWidget(QLabel("Original Text:"))
35+
main_layout.addWidget(self.input_text_edit)
36+
37+
# Target language selection
38+
self.language_combo = QComboBox()
39+
self.language_combo.addItems(["Spanish", "French", "German", "Chinese", "Japanese"])
40+
self.language_combo.currentIndexChanged.connect(self.change_target_language)
41+
language_layout = QHBoxLayout()
42+
language_layout.addWidget(QLabel("Target Language:"))
43+
language_layout.addWidget(self.language_combo)
44+
main_layout.addLayout(language_layout)
45+
46+
# Translate button
47+
self.translate_button = QPushButton("Translate")
48+
self.translate_button.clicked.connect(self.translate_and_display)
49+
main_layout.addWidget(self.translate_button)
50+
51+
# Output text field
52+
self.output_text_edit = QTextEdit()
53+
self.output_text_edit.setPlaceholderText("Translated text will appear here...")
54+
main_layout.addWidget(QLabel("Translated Text:"))
55+
main_layout.addWidget(self.output_text_edit)
56+
57+
# Buttons for file operations and clipboard
58+
button_layout = QHBoxLayout()
59+
self.open_button = QPushButton("Open File")
60+
self.open_button.clicked.connect(self.open_file)
61+
button_layout.addWidget(self.open_button)
62+
63+
self.save_button = QPushButton("Save File")
64+
self.save_button.clicked.connect(self.save_file)
65+
button_layout.addWidget(self.save_button)
66+
67+
self.clear_button = QPushButton("Clear")
68+
self.clear_button.clicked.connect(self.clear_text)
69+
button_layout.addWidget(self.clear_button)
70+
71+
self.copy_button = QPushButton("Copy to Clipboard")
72+
self.copy_button.clicked.connect(self.copy_to_clipboard)
73+
button_layout.addWidget(self.copy_button)
74+
75+
main_layout.addLayout(button_layout)
76+
77+
# Advanced functionalities layout
78+
adv_layout = QHBoxLayout()
79+
80+
self.batch_button = QPushButton("Batch Translate")
81+
self.batch_button.clicked.connect(self.batch_translate)
82+
adv_layout.addWidget(self.batch_button)
83+
84+
self.tts_button = QPushButton("Text to Speech")
85+
self.tts_button.clicked.connect(self.text_to_speech)
86+
adv_layout.addWidget(self.tts_button)
87+
88+
self.stt_button = QPushButton("Speech to Text")
89+
self.stt_button.clicked.connect(self.speech_to_text)
90+
adv_layout.addWidget(self.stt_button)
91+
92+
self.auto_detect_button = QPushButton("Auto Language Detection")
93+
self.auto_detect_button.clicked.connect(self.auto_language_detection)
94+
adv_layout.addWidget(self.auto_detect_button)
95+
96+
self.history_button = QPushButton("Translation History")
97+
self.history_button.clicked.connect(self.show_translation_history)
98+
adv_layout.addWidget(self.history_button)
99+
100+
self.cost_button = QPushButton("Show Translation Cost")
101+
self.cost_button.clicked.connect(self.show_translation_cost)
102+
adv_layout.addWidget(self.cost_button)
103+
104+
self.feedback_button = QPushButton("Feedback")
105+
self.feedback_button.clicked.connect(self.translation_quality_feedback)
106+
adv_layout.addWidget(self.feedback_button)
107+
108+
main_layout.addLayout(adv_layout)
109+
110+
# Progress bar for batch translation
111+
self.progress_bar = QProgressBar()
112+
self.progress_bar.setValue(0)
113+
main_layout.addWidget(self.progress_bar)
114+
115+
def open_file(self):
116+
options = QFileDialog.Options()
117+
file_name, _ = QFileDialog.getOpenFileName(
118+
self, "Open Text File", "", "Text Files (*.txt);;All Files (*)", options=options
119+
)
120+
if file_name:
121+
try:
122+
with open(file_name, "r", encoding="utf-8") as f:
123+
content = f.read()
124+
self.input_text_edit.setPlainText(content)
125+
except Exception as e:
126+
QMessageBox.critical(self, "Error", f"Failed to open file:\n{str(e)}")
127+
128+
def save_file(self):
129+
options = QFileDialog.Options()
130+
file_name, _ = QFileDialog.getSaveFileName(
131+
self, "Save Translated Text", "", "Text Files (*.txt);;All Files (*)", options=options
132+
)
133+
if file_name:
134+
try:
135+
with open(file_name, "w", encoding="utf-8") as f:
136+
f.write(self.output_text_edit.toPlainText())
137+
except Exception as e:
138+
QMessageBox.critical(self, "Error", f"Failed to save file:\n{str(e)}")
139+
140+
def translate_and_display(self):
141+
original_text = self.input_text_edit.toPlainText()
142+
if not original_text.strip():
143+
QMessageBox.warning(self, "Warning", "Please enter some text to translate.")
144+
return
145+
146+
target_language = self.language_combo.currentText()
147+
prompt = f"Translate the following text into {target_language} while preserving its original meaning:\n\n{original_text}"
148+
149+
try:
150+
completion = client.chat.completions.create(
151+
model="gpt-4o-mini",
152+
store=True,
153+
messages=[
154+
{"role": "system", "content": "You are a helpful translation assistant."},
155+
{"role": "user", "content": prompt}
156+
]
157+
)
158+
translated_text = completion.choices[0].message['content'].strip()
159+
self.output_text_edit.setPlainText(translated_text)
160+
# Save to translation history
161+
self.translation_history.append({
162+
"file": "Manual Input",
163+
"original": original_text,
164+
"translated": translated_text,
165+
"language": target_language
166+
})
167+
except Exception as e:
168+
QMessageBox.critical(self, "Error", f"Translation failed:\n{str(e)}")
169+
170+
def clear_text(self):
171+
self.input_text_edit.clear()
172+
self.output_text_edit.clear()
173+
174+
def copy_to_clipboard(self):
175+
clipboard = QApplication.clipboard()
176+
clipboard.setText(self.output_text_edit.toPlainText())
177+
QMessageBox.information(self, "Copied", "Translated text copied to clipboard.")
178+
179+
def change_target_language(self):
180+
selected_language = self.language_combo.currentText()
181+
print(f"Target language changed to: {selected_language}")
182+
183+
def batch_translate(self):
184+
files, _ = QFileDialog.getOpenFileNames(self, "Select Text Files", "", "Text Files (*.txt)")
185+
if not files:
186+
return
187+
# Clear existing history and progress bar
188+
self.translation_history.clear()
189+
self.progress_bar.setMaximum(len(files))
190+
self.progress_bar.setValue(0)
191+
results = ""
192+
target_language = self.language_combo.currentText()
193+
for i, file_name in enumerate(files, start=1):
194+
try:
195+
with open(file_name, "r", encoding="utf-8") as f:
196+
content = f.read()
197+
prompt = f"Translate the following text into {target_language} while preserving its original meaning:\n\n{content}"
198+
completion = client.chat.completions.create(
199+
model="gpt-4o-mini",
200+
store=True,
201+
messages=[
202+
{"role": "system", "content": "You are a helpful translation assistant."},
203+
{"role": "user", "content": prompt}
204+
]
205+
)
206+
translated_text = completion.choices[0].message['content'].strip()
207+
results += f"File: {file_name}\nOriginal:\n{content}\nTranslated:\n{translated_text}\n{'-' * 40}\n"
208+
# Save to translation history
209+
self.translation_history.append({
210+
"file": file_name,
211+
"original": content,
212+
"translated": translated_text,
213+
"language": target_language
214+
})
215+
self.progress_bar.setValue(i)
216+
except Exception as e:
217+
QMessageBox.critical(self, "Error", f"Failed to translate {file_name}:\n{str(e)}")
218+
self.output_text_edit.setPlainText(results)
219+
220+
def text_to_speech(self):
221+
from gtts import gTTS
222+
text = self.output_text_edit.toPlainText()
223+
if not text.strip():
224+
QMessageBox.warning(self, "Warning", "No translated text available for conversion.")
225+
return
226+
try:
227+
tts = gTTS(text)
228+
options = QFileDialog.Options()
229+
file_name, _ = QFileDialog.getSaveFileName(
230+
self, "Save Audio File", "", "MP3 Files (*.mp3);;All Files (*)", options=options
231+
)
232+
if file_name:
233+
tts.save(file_name)
234+
QMessageBox.information(self, "Success", f"Audio saved to {file_name}")
235+
except Exception as e:
236+
QMessageBox.critical(self, "Error", f"Text-to-speech conversion failed:\n{str(e)}")
237+
238+
def speech_to_text(self):
239+
import speech_recognition as sr
240+
r = sr.Recognizer()
241+
with sr.Microphone() as source:
242+
QMessageBox.information(self, "Info", "Please speak now...")
243+
audio = r.listen(source)
244+
try:
245+
recognized_text = r.recognize_google(audio)
246+
self.input_text_edit.setPlainText(recognized_text)
247+
except Exception as e:
248+
QMessageBox.critical(self, "Error", f"Speech recognition failed:\n{str(e)}")
249+
250+
def auto_language_detection(self):
251+
from langdetect import detect
252+
text = self.input_text_edit.toPlainText()
253+
if not text.strip():
254+
QMessageBox.warning(self, "Warning", "No text available for language detection.")
255+
return
256+
try:
257+
detected_language = detect(text)
258+
QMessageBox.information(self, "Language Detection", f"Detected language: {detected_language}")
259+
except Exception as e:
260+
QMessageBox.critical(self, "Error", f"Language detection failed:\n{str(e)}")
261+
262+
def show_translation_history(self):
263+
if not self.translation_history:
264+
QMessageBox.information(self, "History", "No translations in history yet.")
265+
return
266+
history_str = ""
267+
for entry in self.translation_history:
268+
history_str += (f"File: {entry['file']}\n"
269+
f"Language: {entry['language']}\n"
270+
f"Original:\n{entry['original']}\n"
271+
f"Translated:\n{entry['translated']}\n"
272+
+ "-" * 40 + "\n")
273+
dialog = QDialog(self)
274+
dialog.setWindowTitle("Translation History")
275+
layout = QVBoxLayout()
276+
text_edit = QTextEdit()
277+
text_edit.setReadOnly(True)
278+
text_edit.setPlainText(history_str)
279+
layout.addWidget(text_edit)
280+
dialog.setLayout(layout)
281+
dialog.exec_()
282+
283+
def show_translation_cost(self):
284+
text = self.input_text_edit.toPlainText()
285+
if not text.strip():
286+
QMessageBox.warning(self, "Warning", "No text available to calculate cost.")
287+
return
288+
# Estimate cost based on word count (as a rough proxy for tokens)
289+
estimated_tokens = len(text.split())
290+
cost_per_1000_tokens = 0.02 # Example cost rate in USD
291+
estimated_cost = (estimated_tokens / 1000) * cost_per_1000_tokens
292+
QMessageBox.information(
293+
self, "Translation Cost",
294+
f"Estimated translation cost: ${estimated_cost:.4f} USD (based on {estimated_tokens} tokens)"
295+
)
296+
297+
def translation_quality_feedback(self):
298+
feedback, ok = QInputDialog.getMultiLineText(
299+
self, "Translation Feedback", "Enter your feedback about the translation:"
300+
)
301+
if ok and feedback.strip():
302+
self.feedback_list.append(feedback)
303+
QMessageBox.information(self, "Feedback Received", "Thank you for your feedback!")
304+
305+
306+
if __name__ == "__main__":
307+
app = QApplication(sys.argv)
308+
translator_app = TranslatorApp()
309+
translator_app.show()
310+
sys.exit(app.exec_())

0 commit comments

Comments
 (0)