Skip to content

Commit

Permalink
feat: Highlights inconsistent paragraphs between the original and tra…
Browse files Browse the repository at this point in the history
…nslation lines. resolved #82
  • Loading branch information
bookfere committed Feb 26, 2024
1 parent dbf8cf1 commit 4a8f964
Show file tree
Hide file tree
Showing 13 changed files with 131 additions and 60 deletions.
44 changes: 24 additions & 20 deletions advanced.py
Original file line number Diff line number Diff line change
Expand Up @@ -420,8 +420,30 @@ def write_progress():
progress_bar.setValue(value)
self.progress_bar.connect(write_progress)

paragraph_count = QLabel()

def get_paragraph_count(select_all=True):
item_count = char_count = 0
paragraphs = self.table.get_selected_items(select_all=select_all)
for paragraph in paragraphs:
item_count += 1
char_count += len(paragraph.original)
return (item_count, char_count)
all_item_count, all_char_count = get_paragraph_count(True)

def item_selection_changed():
item_count, char_count = get_paragraph_count(False)
total = '%s/%s' % (item_count, all_item_count)
parts = '%s/%s' % (char_count, all_char_count)
paragraph_count.setText(
_('Total items: {}').format(total) + ' · ' +
_('Character count: {}').format(parts))
item_selection_changed()
self.table.itemSelectionChanged.connect(item_selection_changed)

layout.addWidget(self.table, 1)
layout.addWidget(progress_bar)
layout.addWidget(paragraph_count)
layout.addWidget(self.layout_table_control())

def working_start():
Expand All @@ -441,8 +463,6 @@ def layout_table_control(self):
action_layout.setContentsMargins(0, 0, 0, 0)

delete_button = QPushButton(_('Delete'))
paragraph_count = QLabel()
paragraph_count.setAlignment(Qt.AlignCenter)
translate_all = QPushButton(' %s ' % _('Translate All'))
translate_selected = QPushButton(' %s ' % _('Translate Selected'))

Expand All @@ -453,30 +473,15 @@ def layout_table_control(self):
delete_button.setDisabled(True)
translate_selected.setDisabled(True)

def get_paragraph_count(select_all=True):
item_count = char_count = 0
paragraphs = self.table.get_selected_items(select_all=select_all)
for paragraph in paragraphs:
item_count += 1
char_count += len(paragraph.original)
return (item_count, char_count)
all_item_count, all_char_count = get_paragraph_count(True)

def item_selection_changed():
disabled = self.table.selected_count() < 1
delete_button.setDisabled(disabled)
translate_selected.setDisabled(disabled)
item_count, char_count = get_paragraph_count(False)
total = '%s/%s' % (item_count, all_item_count)
parts = '%s/%s' % (char_count, all_char_count)
paragraph_count.setText(
_('Total items: {}').format(total) + ' · ' +
_('Character count: {}').format(parts))
item_selection_changed()
self.table.itemSelectionChanged.connect(item_selection_changed)

action_layout.addWidget(delete_button)
action_layout.addWidget(paragraph_count, 1)
action_layout.addStretch(1)
action_layout.addWidget(translate_all)
action_layout.addWidget(translate_selected)

Expand Down Expand Up @@ -708,8 +713,7 @@ def change_selected_item():
change_selected_item()

def translation_callback(paragraph):
row = paragraph.row
self.table.row.emit(row)
self.table.row.emit(paragraph.row)
self.raw_text.emit(paragraph.raw)
self.original_text.emit(paragraph.original)
self.translation_text[str].emit(paragraph.translation)
Expand Down
27 changes: 23 additions & 4 deletions components/table.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,17 @@
from ..lib.utils import group
from ..lib.translation import get_engine_class

from .alert import AlertMessage


try:
from qt.core import (
Qt, QTableWidget, QHeaderView, QMenu, QAbstractItemView, QCursor,
QAbstractItemView, QTableWidgetItem, pyqtSignal,
QTableWidgetSelectionRange)
QBrush, QTableWidgetItem, pyqtSignal, QTableWidgetSelectionRange)
except ImportError:
from PyQt5.Qt import (
Qt, QTableWidget, QHeaderView, QMenu, QAbstractItemView, QCursor,
QAbstractItemView, QTableWidgetItem, pyqtSignal,
QTableWidgetSelectionRange)
QBrush, QTableWidgetItem, pyqtSignal, QTableWidgetSelectionRange)

load_translations()

Expand Down Expand Up @@ -42,6 +41,8 @@ def layout(self):
self.setEditTriggers(triggers)
self.setAlternatingRowColors(True)

self.setVerticalHeaderLabels(
map(str, range(1, len(self.paragraphs) + 1)))
for row, paragraph in enumerate(self.paragraphs):
original = QTableWidgetItem(paragraph.original)
original.setData(Qt.UserRole, paragraph)
Expand Down Expand Up @@ -70,6 +71,24 @@ def track_row_data(self, row):
paragraph.engine_name, paragraph.target_lang, _('Translated')]
for column, text in enumerate(items, 1):
self.item(row, column).setText(text)
if paragraph.translation:
engine_class = get_engine_class(paragraph.engine_name)
if engine_class is not None and \
not paragraph.is_alignment(engine_class.separator):
self.mark_row_as_problematic(row)

def mark_row_as_problematic(self, row):
tip = _('The translation line count does not match the original.')
item = self.verticalHeaderItem(row)
if item is None:
return
item.setBackground(QBrush(Qt.yellow))
item.setForeground(QBrush(Qt.white))
item.setToolTip(tip)
for column in range(self.columnCount()):
item = self.item(row, column)
item.setBackground(QBrush(Qt.yellow))
item.setToolTip(tip)

def contextMenuEvent(self, event):
if self.parent.on_working:
Expand Down
7 changes: 7 additions & 0 deletions lib/cache.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import os
import re
import json
import shutil
import sqlite3
Expand Down Expand Up @@ -36,6 +37,12 @@ def get_attributes(self):
return json.loads(self.attributes)
return {}

def is_alignment(self, seperator):
pattern = re.compile(seperator)
count_original = len(pattern.split(self.original.strip()))
count_translation = len(pattern.split(self.translation.strip()))
return count_original == count_translation


def default_cache_path():
path = os.path.join(
Expand Down
1 change: 1 addition & 0 deletions lib/translation.py
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,7 @@ def translate_paragraph(self, paragraph):
paragraph.translation = translation.strip()
paragraph.engine_name = self.translator.name
paragraph.target_lang = self.translator.get_target_lang()
paragraph.seperator = self.translator.separator
paragraph.is_cache = False

def process_translation(self, paragraph):
Expand Down
11 changes: 6 additions & 5 deletions test.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import sys
import unittest
from pkgutil import iter_modules
from importlib import import_module

# from calibre.utils.run_tests import run_cli
from calibre_plugins.ebook_translator.tests import (
test_utils, test_config, test_engine, test_element, test_translation)


def get_tests(module):
Expand All @@ -12,9 +12,10 @@ def get_tests(module):

def get_test_suite():
suite = unittest.TestSuite()
klasses = [
test_utils, test_config, test_engine, test_element, test_translation]
suite.addTests(get_tests(klass) for klass in klasses)
for module in iter_modules(['tests']):
module = import_module(
'calibre_plugins.ebook_translator.tests.%s' % module.name)
suite.addTests(get_tests(module))
return suite


Expand Down
20 changes: 20 additions & 0 deletions tests/test_cache.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import unittest

from ..lib.cache import Paragraph


class TestParagraph(unittest.TestCase):
def setUp(self):
self.paragraph = Paragraph(
1, 'TEST', 'a\n\nb\n\nc', 'a\n\nb\n\nc\n\n',
translation='A\n\nB\n\nC', attributes='{"class": "test"}')

def test_get_attributes(self):
self.assertEqual({'class': 'test'}, self.paragraph.get_attributes())

def test_check_translation(self):
self.assertTrue(self.paragraph.is_alignment('\n\n'))

self.paragraph.original = 'a\n\nb\n\nc'
self.paragraph.translation = 'A\n\nB\nC\n\n'
self.assertFalse(self.paragraph.is_alignment('\n\n'))
5 changes: 4 additions & 1 deletion translations/es.po
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Ebook Translator Calibre Plugin\n"
"Report-Msgid-Bugs-To: [email protected]\n"
"POT-Creation-Date: 2024-02-17 16:48+0800\n"
"POT-Creation-Date: 2024-02-26 22:51+0800\n"
"PO-Revision-Date: 2023-04-17 14:17+0800\n"
"Last-Translator: Automatically generated\n"
"Language-Team: none\n"
Expand Down Expand Up @@ -276,6 +276,9 @@ msgstr ""
msgid "Untranslated"
msgstr ""

msgid "The translation line count does not match the original."
msgstr ""

msgid "Select the whole chapter"
msgstr ""

Expand Down
5 changes: 4 additions & 1 deletion translations/fr.po
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Ebook Translator Calibre Plugin\n"
"Report-Msgid-Bugs-To: [email protected]\n"
"POT-Creation-Date: 2024-02-17 16:48+0800\n"
"POT-Creation-Date: 2024-02-26 22:51+0800\n"
"PO-Revision-Date: 2023-10-01 15:35-0400\n"
"Last-Translator: <a href=\"https://www.mobileread.com/forums/member.php?"
"u=90932\">PoP</a>\n"
Expand Down Expand Up @@ -284,6 +284,9 @@ msgstr "Statut"
msgid "Untranslated"
msgstr "Non-traduit"

msgid "The translation line count does not match the original."
msgstr ""

msgid "Select the whole chapter"
msgstr "Choisissez le chapitre en entier"

Expand Down
Loading

0 comments on commit 4a8f964

Please sign in to comment.