Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Catalog · How the catalog works
Anything · Lazarus or Delphi
Random projectRandom project

pol-translator

View on GitHub

Member rating

No ratings yet.

Sign in to rate this project.

README

.translate command with LibreTranslate

This guide explains how to run LibreTranslate and use the .translate player command. On Windows, LibreTranslate normally runs in a Docker container; it does not provide a standalone .exe.

Package file layout

text
pkg/system/translator/
|-- include/
|   `-- translator.inc
|-- pkg.cfg
|-- README.md
|-- config/
|   `-- translator.cfg
|-- textcmd/
|   `-- player/
|       `-- translate.src
|-- translationrequest.src
`-- versioncheck.src
  • pkg.cfg: enables the package and declares its name and maintainer.
  • include/translator.inc: shared source for the TRANSLATOR_* constants and properties, version parsing/comparison and release-check helpers, and the input/result gump functions. It is included by textcmd/player/translate.src, translationrequest.src, and versioncheck.src so these scripts use the same definitions.
  • config/translator.cfg: configures the LibreTranslate endpoints, optional API key, character limit, player cooldown, and shared release-check interval.
  • textcmd/player/translate.src: implements the player .translate command, enforces the cooldown, and starts the shared version check before the translation request.
  • translationrequest.src: loads the available target languages, opens the input gump, requests automatic source detection and translation, and displays the selectable result.
  • versioncheck.src: reads the installed LibreTranslate version from /spec and compares it with the latest official release when the shared release-check cache expires.
  • README.md: installation, configuration, usage, language maintenance, and container management instructions.

1. Install Docker Desktop on Windows

  1. Download and install Docker Desktop for Windows.

  2. Start Docker Desktop and wait until Docker is running.

  3. Open a terminal and check the installation:

    text
    docker version

    If the command does not show both the client and server versions, Docker Desktop may still be starting or the installation may not be complete.

2. Clean reinstall (optional)

To remove an existing Docker installation and its downloaded models, run:

text
docker rm -f libretranslate
docker volume rm libretranslate-models

The first command removes the container. The second permanently deletes the models stored in the volume; they will need to be downloaded again. The Docker image remains in the local cache. To download the latest image as well, first run docker image rm libretranslate/libretranslate.

3. Run LibreTranslate locally

Run this command in a terminal:

text
docker run -d --name libretranslate --restart unless-stopped --label=com.centurylinklabs.watchtower.enable=true --cpus="1.0" -p 127.0.0.1:5000:5000 -v libretranslate-models:/home/libretranslate/.local libretranslate/libretranslate --load-only en,it

The command downloads the LibreTranslate image, creates the container, and starts it in the background. --load-only en,it selects which language codes the startup model installer considers. It is not a runtime language filter and does not remove packages already stored in the volume; LibreTranslate loads all installed model packages when it starts. On this clean volume, the command installs English and Italian. To add languages, install their model packages as described in Language maintenance. The libretranslate-models volume keeps models between container restarts. --restart unless-stopped restarts the container when Docker starts, unless you have stopped it manually.

The Watchtower enable label is included so this container can be managed if you later configure Watchtower with --label-enable. The label is harmless when Watchtower is not used.

--cpus="1.0" sets a hard ceiling of one CPU core's worth of processing time for LibreTranslate. Docker throttles the container when it reaches that ceiling, leaving CPU capacity available to other work on the machine. Use --cpus="0.5" to cap it at half a core; translations and model loading may then take longer. This is a maximum, not a CPU reservation or a guarantee that the host will never become busy.

To apply a limit to a container that is already running, without removing it or downloading the models again, run:

text
docker update --cpus="1.0" libretranslate

Change 1.0 to 0.5 for a lower ceiling. Check current usage with docker stats --no-stream libretranslate.

Binding the port to 127.0.0.1 restricts access to the computer running the service. This is suitable when POL and LibreTranslate run on the same machine.

Check the container status and logs:

text
docker ps
docker logs -f libretranslate

Wait for the Listening at: http://[::]:5000 line in the logs. Before it appears, the model may still be downloading or loading, and HTTP requests may fail with Empty reply from server. Once the service is ready, open [http://127.0.0.1:5000](http://127.0.0.1:5000) in a browser to confirm that it responds.

To test automatic language detection from Command Prompt (CMD), run these commands. The first translates English to Italian; the second translates Italian to English:

text
curl.exe -X POST "http://127.0.0.1:5000/translate" -H "Content-Type: application/json" -d "{\"q\":\"Hello, how are you?\",\"source\":\"auto\",\"target\":\"it\",\"format\":\"text\"}"
curl.exe -X POST "http://127.0.0.1:5000/translate" -H "Content-Type: application/json" -d "{\"q\":\"Ciao, come stai?\",\"source\":\"auto\",\"target\":\"en\",\"format\":\"text\"}"

In Windows PowerShell, use these equivalent commands:

powershell
$body = @{
    q = 'Hello, how are you?'
    source = 'auto'
    target = 'it'
    format = 'text'
} | ConvertTo-Json -Compress
Invoke-RestMethod -Uri 'http://127.0.0.1:5000/translate' -Method Post -ContentType 'application/json; charset=utf-8' -Body $body

$body = @{
    q = 'Ciao, come stai?'
    source = 'auto'
    target = 'en'
    format = 'text'
} | ConvertTo-Json -Compress
Invoke-RestMethod -Uri 'http://127.0.0.1:5000/translate' -Method Post -ContentType 'application/json; charset=utf-8' -Body $body

The expected response is JSON containing the translatedText field.

4. Use the .translate command

The configuration is in pkg/system/translator/config/translator.cfg:

cfg
Elem Translator
{
  Endpoint http://127.0.0.1:5000/translate
  LanguagesEndpoint http://127.0.0.1:5000/languages
  VersionEndpoint http://127.0.0.1:5000/spec
  LatestVersionEndpoint https://api.github.com/repos/LibreTranslate/LibreTranslate/releases/latest
  VersionCheckInterval 3600
  ApiKey
  // Maximum submitted input length; the translated result is not limited by this value.
  Maximum 400
  // Minimum seconds between translation attempts by the same character; set to 0 to disable.
  Cooldown 5
}
  • Endpoint: full URL of the /translate endpoint.
  • LanguagesEndpoint: full URL of the /languages endpoint. The gump builds its destination options from the target languages reported by the service each time .translate is opened.
  • VersionEndpoint: URL of LibreTranslate's machine-readable /spec endpoint. The package reads the installed version from info.version; the web UI does not need to be enabled.
  • LatestVersionEndpoint: official GitHub API URL used to find the latest stable release. The game server needs outbound HTTPS access to GitHub.
  • VersionCheckInterval: minimum number of seconds between GitHub release checks. The latest version, check time, and check outcome are cached in server-wide global properties shared by all players. Both successful and failed release checks are cached for this interval. The installed version is read from /spec whenever anyone runs .translate.
  • ApiKey: leave blank for a local service that does not require a key; fill it in only if the service requires one.
  • Maximum: maximum input length accepted by the gump and checked again by the server. The package configuration is set to 400; change this value to adjust the limit. If the setting is missing or invalid, the script falls back to 400. A translated result longer than this value remains available in full in the result field; submitting it again as input still applies Maximum.
  • Cooldown: minimum number of seconds between requests from the same character.

With the translator package enabled, in game:

  1. Type .translate to open the translator gump. The input field accepts typed or pasted text; .translate text to translate opens it with the supplied text prefilled.
  2. Select the destination language from the options shown above the text field, then press Translate. Up to five languages are shown on each page; Next and Previous navigate the list when more are available. The list comes from LibreTranslate's /languages response, so installing additional models makes their supported target languages available automatically.
  3. LibreTranslate detects the source language automatically and translates the text to the selected destination. The result appears in the same gump layout; you can edit it, select another destination and press Translate again as long as the submitted text is within Maximum, or select and copy the text using your client's features.

Both gumps use the LibreTranslate title and matching layout. When anyone runs .translate, the installed version appears at the lower left of each gump, aligned to the left on the same row as the Translate button at the lower right. It is green when the installed version matches or is newer than the latest release, and red when an update is available or the GitHub release check fails. The footer still shows only the version, so red alone does not tell which of those two conditions occurred; a failed check is never treated as an available update. If /spec cannot provide a valid version, no version is shown. The release-check outcome is shared and cached, and a failed check does not block translation. This check does not update Docker automatically.

POL's documented HTTPRequest script API has no per-request timeout option; its request options cover POST data and headers. The gump waits for the local /spec request and, when the shared cache expires, the GitHub request to return. A network connection that does not respond may therefore delay opening the gump according to POL's underlying network timeout. The package handles returned connection errors and HTTP error statuses, but cannot set a shorter timeout in eScript.

The destination list is built from /languages and includes only target codes reported as supported from every language that LibreTranslate may detect as the source. This avoids offering a target that works for only some detected source languages. With asymmetric model sets, this can be a shorter list than the union of all target codes.

Temporary diagnostics are enabled with TRANSLATOR_DEBUG := 1 in include/translator.inc; set it to 0 to disable them. Debug logs include HTTP response bodies, which can contain translated text.

5. Language maintenance

LibreTranslate stores language models in the libretranslate-models Docker volume mounted at /home/libretranslate/.local. The --load-only option specifies which language codes LibreTranslate considers when installing or updating models. It does not remove model packages that are already in the volume.

Model update options

There are two separate things you can update:

  • Language models can be updated manually with install_models.py (see Add languages) or automatically at startup with --update-models.
  • The LibreTranslate application itself is the Docker image. Update it separately with docker pull and recreate the container (see Manage the container). --update-models does not update the Docker image.

--update-models refreshes the model index at startup, downloads missing selected model pairs and MiniSBD data, and updates installed pairs only when a newer model version is available. --force-update-models installs or reinstalls the selected model pairs at startup without the normal version check, so already-installed models may be downloaded again. Both options run during every container startup and can lengthen startup while the index or model files are downloaded. They update language models, not the LibreTranslate Docker image.

To have LibreTranslate check and update models each time the container starts, add --update-models after the image name and keep the full language list in --load-only. For example, recreate the container with:

If you use Watchtower with --label-enable, keep the enable label on the recreated LibreTranslate container. The example includes it; omit the label if you do not use Watchtower.

text
docker stop libretranslate
docker rm libretranslate
docker run -d --name libretranslate --restart unless-stopped --label=com.centurylinklabs.watchtower.enable=true --cpus="1.0" -p 127.0.0.1:5000:5000 -v libretranslate-models:/home/libretranslate/.local libretranslate/libretranslate --load-only en,it,fr --update-models

--update-models runs the model update step during every container startup. This can require network access and make startup take longer. To perform a one-time update instead, use the manual model installer below and then restart the container. Do not add --force-update-models to this routine command; it reinstalls selected models at every startup.

After installing or removing model packages manually, always restart LibreTranslate so the running service reloads them:

text
docker restart libretranslate

Wait for the container logs to show that the service is listening before sending translation requests. If you change startup arguments such as --load-only or --update-models, docker restart alone is not enough: Docker retains the command used when the container was created. Stop and remove the container, then create it again with the updated arguments and the same named volumes. The language models remain in libretranslate-models.

Add languages

Run LibreTranslate's model installer with all language codes you want to support. For example, to add French to an English/Italian setup, use Windows Command Prompt:

text
docker exec -it libretranslate /app/venv/bin/python /app/scripts/install_models.py --load_only_lang_codes en,it,fr --update
docker restart libretranslate

The installer downloads missing model pairs and MiniSBD data into the existing libretranslate-models volume, and updates installed pairs when newer versions are available. Keep every language you want to retain in the comma-separated list. A simple container restart is enough to load manually installed packages: --load-only filters the installer, not the packages LibreTranslate loads into /languages. If you also want startup --update-models to maintain the new language automatically, recreate the container with the expanded --load-only list. The restart after installation is shown in the command; check docker logs -f libretranslate and wait for the service to finish loading before sending requests.

Remove a language

Model packages are directional. First list the installed packages:

text
docker exec -it libretranslate /app/venv/bin/argospm list

Remove every installed package whose source or target code is the language being removed. Package names use the translate-_<target> format. The exact pairs depend on the models available for those languages. For example, if you are removing French (fr), first check argospm list, then run a removal command only for each listed package containing fr in its pair name. These are example package names; skip any pair that is not shown by argospm list:

text
docker exec -it libretranslate /app/venv/bin/argospm remove translate-en_fr
docker exec -it libretranslate /app/venv/bin/argospm remove translate-fr_en

Do not send translation requests while removing packages. Use the exact package names shown by argospm list; if a pair is absent, do not run its remove command because Argos reports Package not found and exits with an error. Removing a package deletes its Argos model files from the volume. If startup uses --update-models or --force-update-models, remove the language from the container's --load-only list and recreate the container with the updated arguments and the same volume before it starts again; otherwise the updater can install its pairs again. If startup does not run either updater, restart the container after removing packages:

text
docker restart libretranslate

The volume also contains LibreTranslate's .local/cache data; use the full cleanup below if you want to purge all model and cache storage. After removal and restart, the /languages response and in-game destination list reflect the remaining models.

Clear the model storage

To guarantee that all persisted language-model files and caches are removed, delete the entire libretranslate-models volume. This deletes models for every language, including languages you intend to keep. They will be downloaded again when you start LibreTranslate. Stop and remove the container first so Docker can remove the volume:

text
docker stop libretranslate
docker rm libretranslate
docker volume rm libretranslate-models

Then recreate the container with only the language codes you want to keep. Preserve the other options from your existing command, such as API key settings, port bindings, resource limits, Watchtower labels, and the libretranslate-db volume if you use it. For a local setup, for example:

text
docker run -d --name libretranslate --restart unless-stopped --label=com.centurylinklabs.watchtower.enable=true --cpus="1.0" -p 127.0.0.1:5000:5000 -v libretranslate-models:/home/libretranslate/.local libretranslate/libretranslate --load-only en,it --update-models

This cleanup removes every model and cache from libretranslate-models; it does not remove the Docker image. If you also use the separate libretranslate-db volume for API keys, leave it in place unless you intend to delete that database too.

6. Run LibreTranslate on another computer

If LibreTranslate runs on a different machine from POL, 127.0.0.1 points to the POL machine, not to the LibreTranslate host. On the machine running LibreTranslate, start the container with the port exposed to the network:

text
docker run -d --name libretranslate --restart unless-stopped --label=com.centurylinklabs.watchtower.enable=true --cpus="1.0" -p 192.168.1.50:5000:5000 -v libretranslate-models:/home/libretranslate/.local -v libretranslate-db:/app/db libretranslate/libretranslate --load-only en,it --api-keys --req-limit 0

Replace 192.168.1.50 with the LAN IP assigned to the LibreTranslate host. Binding -p 5000:5000 without a host IP publishes the port on all host interfaces; use that only when intentional and protected by a restrictive firewall. Allow port 5000 only from the POL server's address and do not expose it directly to the Internet. This setup requires an API key. With --api-keys and --req-limit 0, requests without a valid key are rejected.

The image uses /app as its working directory and stores the default API-key database at /app/db/api_keys.db. The named libretranslate-db volume therefore preserves the key database when the container is removed and recreated, including by Watchtower. Keep both named volumes when replacing the container.

Create a key in the container:

text
docker exec -it libretranslate ltmanage keys add 120 --char-limit 1000

Keep the generated key and set both endpoints to addresses reachable from POL, for example:

cfg
Endpoint http://192.168.1.50:5000/translate
  LanguagesEndpoint http://192.168.1.50:5000/languages
  VersionEndpoint http://192.168.1.50:5000/spec
ApiKey INSERT_THE_GENERATED_KEY

Replace the example address with the actual address of the machine running LibreTranslate. An API key sent over plain HTTP can be read by anyone who can observe that network path; do not use it over an untrusted network. If the connection between the two servers must be encrypted, put the API behind an HTTPS reverse proxy and use HTTPS URLs for Endpoint, LanguagesEndpoint, and VersionEndpoint.

7. Manage the container

text
docker stop libretranslate
docker start libretranslate
docker logs -f libretranslate

To update the image, download the latest version with docker pull libretranslate/libretranslate, then recreate the container using the same parameters and volumes as the startup command, including the Watchtower enable label if you use it. A docker restart only restarts the existing container; it does not use a newly pulled image or change the container's startup arguments. The models and API database are stored in Docker volumes, not in the container.

8. Optional: automatic image updates with Watchtower

Watchtower can check for a newer LibreTranslate image every 24 hours and recreate the container when one is available. This is optional; without it, follow the manual update steps above. The original containrrr/watchtower repository is archived, so these instructions use the maintained nickfedor/watchtower fork.

Watchtower must be able to access the Docker daemon. These are two distinct settings: --label-enable belongs on the Watchtower command, while --label=com.centurylinklabs.watchtower.enable=true belongs on LibreTranslate's docker run command. Both are required for Watchtower to manage LibreTranslate in this label-filtered setup. If the existing container was created without the LibreTranslate label, recreate it with the command below. Removing the container does not delete named volumes. Watchtower recreates an updated container with the options used when it was originally deployed, so its CPU limit, port binding, startup arguments, labels, and named volumes remain in effect; translation requests may fail briefly while the service restarts.

text
docker stop libretranslate
docker rm libretranslate
docker run -d --name libretranslate --restart unless-stopped --label=com.centurylinklabs.watchtower.enable=true --cpus="1.0" -p 127.0.0.1:5000:5000 -v libretranslate-models:/home/libretranslate/.local libretranslate/libretranslate --load-only en,it

Start Watchtower:

text
docker run -d --name watchtower --restart unless-stopped -v /var/run/docker.sock:/var/run/docker.sock nickfedor/watchtower --label-enable --interval 86400 --cleanup

--interval 86400 checks once per day. --label-enable restricts updates to containers with the com.centurylinklabs.watchtower.enable=true label, so other containers are left alone. --cleanup removes the old image after an update. Watchtower pulls the new image and recreates LibreTranslate with the options used when it was originally deployed, including its CPU limit, port binding, startup arguments, labels, and named model/API-key volumes. Translation requests may fail briefly while the service restarts. --cleanup removes images, not named volumes. Read the Watchtower documentation for other scheduling and update options.

Mounting /var/run/docker.sock gives Watchtower control of the Docker daemon. Use only a Watchtower image you trust. To stop automatic checks, stop the Watchtower container:

text
docker stop watchtower

References