Skip to content

Commit

Permalink
feat: Optimized GenAI prompt and added output format options for Adva…
Browse files Browse the repository at this point in the history
…nced mode.
  • Loading branch information
bookfere authored Dec 8, 2024
2 parents 756ab9f + 8a12aae commit ba2f83d
Show file tree
Hide file tree
Showing 15 changed files with 301 additions and 190 deletions.
113 changes: 69 additions & 44 deletions advanced.py
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,7 @@ def __init__(self, parent, ebook):
layout.addWidget(self.start_button)

def layout_format(self):
engine_class = get_engine_class()
widget = QWidget()
layout = QHBoxLayout(widget)
layout.setContentsMargins(0, 0, 0, 0)
Expand All @@ -258,6 +259,13 @@ def layout_format(self):
input_layout.addWidget(input_format)
layout.addWidget(input_group)

output_group = QGroupBox(_('Output Format'))
output_layout = QGridLayout(output_group)
output_format = OutputFormat()
output_format.setFixedWidth(150)
output_layout.addWidget(output_format)
layout.addWidget(output_group)

source_group = QGroupBox(_('Source Language'))
source_layout = QVBoxLayout(source_group)
source_lang = SourceLang()
Expand All @@ -272,6 +280,35 @@ def layout_format(self):
target_layout.addWidget(target_lang)
layout.addWidget(target_group)

source_lang.refresh.emit(
engine_class.lang_codes.get('source'),
engine_class.config.get('source_lang'),
not issubclass(engine_class, CustomTranslate))

target_lang.refresh.emit(
engine_class.lang_codes.get('target'),
engine_class.config.get('target_lang'))

def change_input_format(_format):
self.ebook.set_input_format(_format)
change_input_format(input_format.currentText())
input_format.currentTextChanged.connect(change_input_format)

def change_output_format(_format):
self.ebook.set_output_format(_format)
change_output_format(output_format.currentText())
output_format.currentTextChanged.connect(change_output_format)

def change_source_lang(lang):
self.ebook.set_source_lang(lang)
change_source_lang(source_lang.currentText())
source_lang.currentTextChanged.connect(change_source_lang)

def change_target_lang(lang):
self.ebook.set_target_lang(lang)
change_target_lang(target_lang.currentText())
target_lang.currentTextChanged.connect(change_target_lang)

if self.ebook.input_format in extra_formats.keys():
encoding_group = QGroupBox(_('Encoding'))
encoding_layout = QVBoxLayout(encoding_group)
Expand All @@ -295,34 +332,17 @@ def change_encoding(encoding):
direction_layout.addWidget(direction_list)
layout.addWidget(direction_group)

def change_direction(index):
direction = direction_list.itemData(index)
self.ebook.set_target_direction(direction)
def change_direction(_index):
_direction = direction_list.itemData(_index)
self.ebook.set_target_direction(_direction)
direction_list.currentIndexChanged.connect(change_direction)

def change_input_format(format):
self.ebook.set_input_format(format)
change_input_format(input_format.currentText())
input_format.currentTextChanged.connect(change_input_format)

engine_class = get_engine_class()
source_lang.refresh.emit(
engine_class.lang_codes.get('source'),
engine_class.config.get('source_lang'),
not issubclass(engine_class, CustomTranslate))
target_lang.refresh.emit(
engine_class.lang_codes.get('target'),
engine_class.config.get('target_lang'))

def change_source_lang(lang):
self.ebook.set_source_lang(source_lang.currentText())
change_source_lang(source_lang.currentText())
source_lang.currentTextChanged.connect(change_source_lang)

def change_target_lang(lang):
self.ebook.set_target_lang(lang)
change_target_lang(target_lang.currentText())
target_lang.currentTextChanged.connect(change_target_lang)
engine_target_lange_codes = engine_class.lang_codes.get('target')
if engine_target_lange_codes is not None and self.ebook.target_lang in engine_target_lange_codes:
target_lang_code = engine_target_lange_codes[self.ebook.target_lang]
direction = engine_class.lang_codes_directionality.get(target_lang_code, 'auto')
index = direction_list.findData(direction)
direction_list.setCurrentIndex(index)

return widget

Expand Down Expand Up @@ -356,7 +376,7 @@ def __init__(self, parent, icon, worker, ebook):
self.cache = None
self.merge_enabled = False

self.prgress_step = 0
self.progress_step = 0
self.translate_all = False

self.editor_worker = EditorWorker()
Expand Down Expand Up @@ -612,7 +632,7 @@ def layout_table(self):
progress_bar.setVisible(False)

def write_progress():
value = progress_bar.value() + self.prgress_step
value = progress_bar.value() + self.progress_step
if value > progress_bar.maximum():
value = progress_bar.maximum()
progress_bar.setValue(value)
Expand Down Expand Up @@ -941,9 +961,12 @@ def layout_review(self):
translation_text.ensureCursorVisible)

def refresh_translation(paragraph):
raw_text.setPlainText(paragraph.raw.strip())
original_text.setPlainText(paragraph.original.strip())
translation_text.setPlainText(paragraph.translation)
# TODO: how can this happen and what should we do in case it does?
if paragraph is not None:
raw_text.setPlainText(paragraph.raw.strip())
original_text.setPlainText(paragraph.original.strip())
translation_text.setPlainText(paragraph.translation)

self.paragraph_sig.connect(refresh_translation)

self.trans_worker.start.connect(
Expand Down Expand Up @@ -1060,17 +1083,19 @@ def modify_translation():
self.editor_worker.show.connect(save_status.setText)

def save_translation():
save_button.setDisabled(True)
paragraph = self.table.current_paragraph()
translation = translation_text.toPlainText()
paragraph.translation = translation
paragraph.engine_name = self.current_engine.name
paragraph.target_lang = self.ebook.target_lang
self.table.row.emit(paragraph.row)
self.cache.update_paragraph(paragraph)
translation_text.setFocus(Qt.OtherFocusReason)
self.editor_worker.start[str].emit(
_('Your changes have been saved.'))
# TODO: how can this happen and what should we do in case it does?
if paragraph is not None:
save_button.setDisabled(True)
paragraph = self.table.current_paragraph()
translation = translation_text.toPlainText()
paragraph.translation = translation
paragraph.engine_name = self.current_engine.name
paragraph.target_lang = self.ebook.target_lang
self.table.row.emit(paragraph.row)
self.cache.update_paragraph(paragraph)
translation_text.setFocus(Qt.OtherFocusReason)
self.editor_worker.start[str].emit(_('Your changes have been saved.'))

save_button.clicked.connect(save_translation)
set_shortcut(save_button, 'save', save_translation, save_button.text())

Expand Down Expand Up @@ -1109,7 +1134,7 @@ def translate_all_paragraphs(self):
is_fresh = len(paragraphs) < 1
if is_fresh:
paragraphs = self.table.get_selected_paragraphs(False, True)
self.prgress_step = self.get_progress_step(len(paragraphs))
self.progress_step = self.get_progress_step(len(paragraphs))
if not self.translate_all:
message = _(
'Are you sure you want to translate all {:n} paragraphs?')
Expand All @@ -1124,7 +1149,7 @@ def translate_selected_paragraph(self):
if len(paragraphs) == self.table.rowCount():
self.translate_all_paragraphs()
else:
self.prgress_step = self.get_progress_step(len(paragraphs))
self.progress_step = self.get_progress_step(len(paragraphs))
self.trans_worker.translate.emit(paragraphs, True)

def install_widget_event(
Expand Down
74 changes: 42 additions & 32 deletions batch.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from .lib.translation import get_engine_class
from .lib.conversion import extra_formats
from .lib.encodings import encoding_list
from .lib.ebook import Ebooks, Ebook
from .engines.custom import CustomTranslate
from .components import (
Footer, AlertMessage, SourceLang, TargetLang, InputFormat,
Expand All @@ -24,7 +25,7 @@


class BatchTranslation(QDialog):
def __init__(self, parent, worker, ebooks):
def __init__(self, parent, worker, ebooks: Ebooks):
QDialog.__init__(self, parent)

self.gui = parent
Expand Down Expand Up @@ -82,40 +83,10 @@ def layout_translate(self):

translation_engine = get_engine_class()
for row, ebook in enumerate(self.ebooks):
ebook: Ebook
ebook_title = QTableWidgetItem(ebook.title)
table.setItem(row, 0, ebook_title)

if ebook.input_format in extra_formats.keys():
input_encoding = QComboBox()
input_encoding.wheelEvent = lambda event: None
table.setCellWidget(row, 1, self._cell_widget(input_encoding))
input_encoding.addItems(encoding_list)
input_encoding.currentTextChanged.connect(
lambda encoding, row=row: self.ebooks[row]
.set_encoding(encoding))
input_encoding.currentTextChanged.connect(
lambda encoding: input_encoding.setToolTip(encoding))
# Target directionality
target_direction = QTableWidgetItem(_('Default'))
target_direction.setTextAlignment(Qt.AlignCenter)
table.setItem(row, 6, target_direction)
else:
input_encoding = QTableWidgetItem(_('Default'))
input_encoding.setTextAlignment(Qt.AlignCenter)
table.setItem(row, 1, input_encoding)
# Target directionality
direction_list = QComboBox()
direction_list.wheelEvent = lambda event: None
direction_list.addItem(_('Auto'), 'auto')
direction_list.addItem(_('Left to Right'), 'ltr')
direction_list.addItem(_('Right to Left'), 'rtl')
direction_list.currentIndexChanged.connect(
lambda index, row=row: self.ebooks[row]
.set_target_direction(direction_list.itemData(index)))
direction_list.currentTextChanged.connect(
lambda direction: direction_list.setToolTip(direction))
table.setCellWidget(row, 6, self._cell_widget(direction_list))

input_fmt = InputFormat(ebook.files.keys())
table.setCellWidget(row, 2, self._cell_widget(input_fmt))

Expand Down Expand Up @@ -175,6 +146,45 @@ def change_target_lang(lang, row=row):
translation_engine.lang_codes.get('target'),
translation_engine.config.get('target_lang'))

if ebook.input_format in extra_formats.keys():
input_encoding = QComboBox()
input_encoding.wheelEvent = lambda event: None
table.setCellWidget(row, 1, self._cell_widget(input_encoding))
input_encoding.addItems(encoding_list)
input_encoding.currentTextChanged.connect(
lambda encoding, row=row: self.ebooks[row]
.set_encoding(encoding))
input_encoding.currentTextChanged.connect(
lambda encoding: input_encoding.setToolTip(encoding))
# Target directionality
target_direction = QTableWidgetItem(_('Default'))
target_direction.setTextAlignment(Qt.AlignCenter)
table.setItem(row, 6, target_direction)
else:
input_encoding = QTableWidgetItem(_('Default'))
input_encoding.setTextAlignment(Qt.AlignCenter)
table.setItem(row, 1, input_encoding)
# Target directionality
direction_list = QComboBox()
direction_list.wheelEvent = lambda event: None
direction_list.addItem(_('Auto'), 'auto')
direction_list.addItem(_('Left to Right'), 'ltr')
direction_list.addItem(_('Right to Left'), 'rtl')
direction_list.currentIndexChanged.connect(
lambda index, row=row: self.ebooks[row]
.set_target_direction(direction_list.itemData(index)))
direction_list.currentTextChanged.connect(
lambda direction: direction_list.setToolTip(direction))

engine_target_lange_codes = translation_engine.lang_codes.get('target')
if engine_target_lange_codes is not None and ebook.target_lang in engine_target_lange_codes:
target_lang_code = engine_target_lange_codes[ebook.target_lang]
direction = translation_engine.lang_codes_directionality.get(target_lang_code, 'auto')
index = direction_list.findData(direction)
direction_list.setCurrentIndex(index)

table.setCellWidget(row, 6, self._cell_widget(direction_list))

table.resizeRowsToContents()
table.resizeColumnsToContents()

Expand Down
14 changes: 8 additions & 6 deletions engines/anthropic.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
from mechanize._response import response_seek_wrapper as Response

from .base import Base
from .languages import anthropic as anthropic_languages
from .languages import lang_directionality
from .languages import anthropic
from .prompt_extensions import anthropic as anthropic_prompt_extension

try:
Expand All @@ -19,7 +20,8 @@
class ClaudeTranslate(Base):
name = 'Claude'
alias = 'Claude (Anthropic)'
lang_codes = Base.load_lang_codes(anthropic_languages)
lang_codes = Base.load_lang_codes(anthropic)
lang_codes_directionality = Base.load_lang_codes_directionality(lang_directionality)
endpoint = 'https://api.anthropic.com/v1/messages'
api_version = '2023-06-01'
api_key_hint = 'sk-ant-xxxx'
Expand All @@ -35,10 +37,10 @@ class ClaudeTranslate(Base):
'Translate the given content from <slang> to <tlang> only. Do not '
'explain any term or answer any question-like content. Your answer '
'should be solely the translation of the given content. In your answer '
'do not add any prefix or suffix to the translated content.')

# https://docs.anthropic.com/en/docs/about-claude/models#model-names
models = [
'do not add any prefix or suffix to the translated content. Websites\' '
'URLs/addresses should be preserved as is in the translation\'s output. ')

models = [ # https://docs.anthropic.com/en/docs/about-claude/models#model-names
'claude-3-5-sonnet-latest',
'claude-3-5-sonnet-20241022',
'claude-3-5-sonnet-20240620',
Expand Down
2 changes: 2 additions & 0 deletions engines/baidu.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from ..lib.exception import BadApiKeyFormat

from .base import Base
from .languages import lang_directionality
from .languages import baidu


Expand All @@ -17,6 +18,7 @@ class BaiduTranslate(Base):
name = 'Baidu'
alias = _z('Baidu')
lang_codes = Base.load_lang_codes(baidu)
lang_codes_directionality = Base.load_lang_codes_directionality(lang_directionality)
endpoint = 'https://fanyi-api.baidu.com/api/trans/vip/translate'
api_key_hint = 'appid|appkey'
api_key_pattern = r'^[^\s:\|]+?[:\|][^\s:\|]+$'
Expand Down
4 changes: 4 additions & 0 deletions engines/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,10 @@ def load_lang_codes(cls, codes):
codes = {'source': codes, 'target': codes}
return codes

@classmethod
def load_lang_codes_directionality(cls, codes):
return codes

@classmethod
def get_source_code(cls, lang):
source_codes = cls.lang_codes.get('source')
Expand Down
3 changes: 3 additions & 0 deletions engines/deepl.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from ..lib.utils import request

from .base import Base
from .languages import lang_directionality
from .languages import deepl


Expand All @@ -15,6 +16,7 @@ class DeeplTranslate(Base):
name = 'DeepL'
alias = 'DeepL'
lang_codes = Base.load_lang_codes(deepl)
lang_codes_directionality = Base.load_lang_codes_directionality(lang_directionality)
endpoint = 'https://api-free.deepl.com/v2/translate'
usage_endpoint = 'https://api-free.deepl.com/v2/usage'
# api_key_hint = 'xxx-xxx-xxx:fx'
Expand Down Expand Up @@ -64,6 +66,7 @@ class DeeplFreeTranslate(Base):
alias = 'DeepL (Free)'
free = True
lang_codes = Base.load_lang_codes(deepl)
lang_codes_directionality = Base.load_lang_codes_directionality(lang_directionality)
endpoint = 'https://www2.deepl.com/jsonrpc?client=chrome-extension,1.5.1'
need_api_key = False
placeholder = DeeplTranslate.placeholder
Expand Down
Loading

0 comments on commit ba2f83d

Please sign in to comment.