-
-
Notifications
You must be signed in to change notification settings - Fork 114
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[BUGS#1238] fix: check cache before asking engine when visit translat… (
#884) * [BUGS#1238] fix: check cache before asking engine when visit translated segment Signed-off-by: Hiroshi Miura <[email protected]> * fix: unused imports Signed-off-by: Hiroshi Miura <[email protected]> * docs: developer manual for MT engine connector Signed-off-by: Hiroshi Miura <[email protected]> * docs: update developer manual and comment Signed-off-by: Hiroshi Miura <[email protected]> * feat: add fake MT connector for test and devel_docs for it Signed-off-by: Hiroshi Miura <[email protected]> --------- Signed-off-by: Hiroshi Miura <[email protected]>
- Loading branch information
Showing
7 changed files
with
263 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,153 @@ | ||
# How to make Machine Translation connector plugin | ||
|
||
## What is MT connector | ||
|
||
OmegaT can be extended with plugin. One of the popular categories of plugin is a Machine Translation (MT) connector. | ||
There are many translation web services, thanks to the innovation of AI technologies. | ||
OmegaT bundles some MT connectors that support popular services, such as Google, DeepL and IBM Watson. | ||
There are also genuine and third party plugins for services; | ||
|
||
- [Azure translate](https://github.com/omegat-org/azure-translate-plugin/releases) | ||
- [Moses](https://github.com/omegat-org/moses-plugin/releases) | ||
- [Autshumato MT](https://sourceforge.net/projects/autshumatoite/files/OmegaT-plugins-AutshumatoMT/) | ||
- [Mirai translator](https://codeberg.org/miurahr/omegat-mirai/releases) | ||
- [NICT TexTra](https://codeberg.org/miurahr/omegat-textra-plugin/releases) | ||
- [Tencent translation](https://github.com/yoyicue/omegat-tencent-plugin) | ||
|
||
## Getting started the project | ||
|
||
OmegaT project provides a plugin project skeleton repository. You can start your project from | ||
a skeleton project. Please go to the URL https://github.com/omegat-org/plugin-skeleton and | ||
click "Use this template" button to start your project in GitHub. | ||
When you use codeberg.org forge site, there is also a skeleton at https://codeberg.org/miurahr/omegat-plugin-skeleton | ||
|
||
The skeleton project uses Gradle for a build system. | ||
You can select Groovy DSL or Kotlin DSL for the configuration. | ||
When you choose a Groovy DSL, please rename `build.gradle.disabled` to `build.gradle` and remove `build.gradle.kts`. | ||
|
||
You should also modify a file | ||
- Project.name in settings.gradle | ||
- Properties: description, title, website and category | ||
- Plugin Main class name in build.gradle(.kts). | ||
|
||
Implementation should be placed at | ||
- Source code: src/main/<lang>/* | ||
- Test code: src/test/<lang>/* and src/test/resources/* | ||
|
||
## OmegaT MT API | ||
|
||
There is a main API that is `org.omegat.gui.exttrans.IMachineTranslation`. | ||
All MT connectors should implement the API. | ||
|
||
### `String getTranslation(Language sLang, Language tLang, String text) throws Exception` | ||
|
||
It is a main method to override in your plugin project. The method receives a source text, translation from sLang to | ||
tLang language, and return translation text. | ||
|
||
### String getCachedTranslation(Language sLang, Language tLang, String text); | ||
|
||
It is another method that you should override. If your plugin has a caching mechanism, and there is entry for the text, | ||
return translation without accessing MT engine. Otherwise, return null. | ||
|
||
> **_NOTE:_** You should not call the engine in the method, because OmegaT will call it even when the target | ||
> segment has already translated, but configured as `MT only untranslated segment` is on or `automatically translate` is off. | ||
### getName() | ||
|
||
Human and machine-readable name of MT engine. OmegaT uses it for the index of results, and as a property value, and | ||
logging purpose. | ||
|
||
### `isEnabled()`/`setEnabled(boolean b)` | ||
|
||
return and set an enabled status. | ||
|
||
### `boolean isConfigurable()` / `void showConfigurationUI(Window parent)` | ||
|
||
When the plugin return true for the method, `isConfigurable()` OmegaT will call `showConfigurationUI` when user | ||
clicks a configuration UI button on `Tools > Preferences > MachineTranslation`. | ||
|
||
## Convenience abstract class for plugins | ||
|
||
There are two convenience class for plugins. You are recommended to use `org.omegat.core. | ||
machinetranslators.BaseCachedTranslate`. It implements many necessary things, and you can concentrate into a logic to | ||
access your MT engine API. There are only three methods you should override. | ||
|
||
### `getName()` | ||
|
||
Name of the engine as same as `IMachineTranslate`. | ||
|
||
### `protected abstract String getPreferenceName()` | ||
|
||
A preference key used in a user's configuration file. It will be like a "allow_<ENGINE NAME>_translate". | ||
|
||
### `protected abstract String translate(Language sLang, Language tLang, String text) throws Exception` | ||
|
||
Main method to return translation from source text. | ||
|
||
|
||
## Common way to register your plugin | ||
|
||
You can register your plugin through a Core method like as follows; | ||
|
||
```java | ||
public class ExamplePlugin { | ||
public static void loadPlugins() { | ||
Core.registerMachineTranslationClass(ExamplePlugin.class); | ||
} | ||
|
||
public static void unloadPlugins() { | ||
} | ||
|
||
public ExamplePlugin() { | ||
// You can initialize internal resources here. | ||
// Because the class will be instantiated in a dynamic way through | ||
// Core.registerMachineTranslationClass API, only a default constructor | ||
// can be used, and unable to expect static initialization of the class. | ||
} | ||
} | ||
``` | ||
|
||
## Utility functions | ||
|
||
You can use several utility functions to implement a feature. | ||
|
||
### JSON and XML Parser | ||
|
||
OmegaT 6.0 and later bundles Jackson JSON parser. You can use Jackson to create query JSON data and parse a response. | ||
You can check details at Jackson document page; https://github.com/FasterXML/jackson-docs | ||
|
||
> **_NOTE:_** There was `org.omegat.util.JsonParser#parse` utility method, but it is deprecated in OmegaT 5.8 and later. | ||
OmegaT 6.1 and later bundles Jackson XML parser. You can use Jackson to create query XML data and parse a response XML. | ||
|
||
> **_NOTE:_** `org.omegat.util.xml.XMLReader` is deprecated in OmegaT 6.1 and later | ||
### HttpConnectionUtils | ||
|
||
You can use `org.omegat.util.HttpConnectionUtils` to access your MT engine. | ||
You may interested `get`, `post` and `postJSON` methods. | ||
|
||
## Writing tests | ||
|
||
### Unit test | ||
|
||
When you write a connector, you will also want to write unit tests to check a parser of responses from MT engine. | ||
At first, you will need to prepare examples of responses in XML or JSON file, and store it as test data. | ||
It is better to test not only for a response of success case, but also for a response with error or an empty content. | ||
|
||
### Connection test | ||
|
||
You may want to use WireMock for test for http query and response. | ||
You can learn about usage of the library to see a bundled connector test. | ||
|
||
You can see an MT connector source code in the OmegaT project, | ||
`machinetranslators/aperitium/src/test/java/org/omegat/machinetranslators.aperitium/ApertiumTranslateTest` | ||
|
||
You can also see a plugin project Azure-translate-plugin to learn how to write a test. | ||
`TestMicrosoftTranslatorAzure.java` implement a case to test http request and response. | ||
|
||
## Publish | ||
|
||
If you are willing to merge your connector into OmegaT genuine bundles, it is challenging for maintainers to test it | ||
with actual MT engines, because we need to learn a target service, pay costs and conformance to its license. | ||
You are recommended to publish your plugin and share its download link in OmegaT users mail list. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
# Test a specific features | ||
|
||
Sometimes there are challenging targets to test when want to see the behavior of specific features in OmegaT. | ||
There are several features that require resources, whether connecting to external services, or test data that is not | ||
freely available in categories of machine translation, and dictionary. | ||
|
||
## check the behavior of Machine Translation | ||
|
||
We have a fake MT connector project in `machinetranslator/dummy` folder. | ||
You can build the fake connector by running `./gradlew machinetranslators:dummy:jar` and copy `dummy.jar` from | ||
`machinetranslator/dummy/build/libs/` to `.omegat/plugins` folder. It always produces a translation text such as | ||
"Translated result from dummy engine.". You can check OmegaT core calls engine or not by looking on the MT pane. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
plugins { | ||
id 'java-library' | ||
} | ||
|
||
dependencies { | ||
compileOnly(project.rootProject) | ||
} | ||
|
||
jar { | ||
manifest { | ||
attributes('License': 'GNU Public License version 3 or later', | ||
'Implementation-Version': '1.0', | ||
'OmegaT-Plugins': 'org.omegat.machinetranslators.dummy.Dummy', | ||
'Plugin-Category': 'machinetranslator', | ||
'Automatic-Module-Name': 'org.omegat.machinetranslators.dummy' | ||
) | ||
} | ||
} |
71 changes: 71 additions & 0 deletions
71
machinetranslators/dummy/src/main/java/org/omegat/machinetranslators/dummy/Dummy.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
/* | ||
* OmegaT - Computer Assisted Translation (CAT) tool | ||
* with fuzzy matching, translation memory, keyword search, | ||
* glossaries, and translation leveraging into updated projects. | ||
* | ||
* Copyright (C) 2024 Hiroshi Miura | ||
* Home page: https://www.omegat.org/ | ||
* Support center: https://omegat.org/support | ||
* | ||
* This file is part of OmegaT. | ||
* | ||
* OmegaT is free software: you can redistribute it and/or modify | ||
* it under the terms of the GNU General Public License as published by | ||
* the Free Software Foundation, either version 3 of the License, or | ||
* (at your option) any later version. | ||
* | ||
* OmegaT is distributed in the hope that it will be useful, | ||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
* GNU General Public License for more details. | ||
* | ||
* You should have received a copy of the GNU General Public License | ||
* along with this program. If not, see <https://www.gnu.org/licenses/>. | ||
*/ | ||
|
||
package org.omegat.machinetranslators.dummy; | ||
|
||
import org.omegat.core.Core; | ||
import org.omegat.core.machinetranslators.BaseCachedTranslate; | ||
import org.omegat.util.Language; | ||
|
||
public class Dummy extends BaseCachedTranslate { | ||
|
||
private static final String ENGINE_NAME = "dummy"; | ||
private static final String ALLOW_TRANSLATE = "allow_dummy_translate"; | ||
private static final String TRANSLATION = "Translated result from dummy engine."; | ||
|
||
/** | ||
* Register plugins into OmegaT. | ||
*/ | ||
public static void loadPlugins() { | ||
Core.registerMachineTranslationClass(Dummy.class); | ||
} | ||
|
||
public static void unloadPlugins() { | ||
} | ||
|
||
public Dummy() { | ||
super(); | ||
} | ||
|
||
@Override | ||
public String getName() { | ||
return ENGINE_NAME; | ||
} | ||
|
||
@Override | ||
public String getPreferenceName() { | ||
return ALLOW_TRANSLATE; | ||
} | ||
|
||
@Override | ||
protected String translate(Language sLang, Language tLang, String text) { | ||
return TRANSLATION; | ||
} | ||
|
||
@Override | ||
public boolean isConfigurable() { | ||
return false; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters