From edd3d6931ddec411bf1d28143778f23a97e4d488 Mon Sep 17 00:00:00 2001 From: Piero Toffanin Date: Thu, 5 Jan 2023 13:12:35 -0500 Subject: [PATCH] Tagged all strings --- compile_locales.py | 2 +- libretranslate/app.py | 86 ++-- libretranslate/locales.py | 5 +- libretranslate/locales/.gitignore | 1 + .../locales/it/LC_MESSAGES/messages.po | 422 +++++++++++++++++- libretranslate/templates/app.js.template | 38 +- libretranslate/templates/index.html | 13 +- update_locales.py | 27 +- 8 files changed, 492 insertions(+), 102 deletions(-) diff --git a/compile_locales.py b/compile_locales.py index 300bbb0..edccc4c 100755 --- a/compile_locales.py +++ b/compile_locales.py @@ -9,7 +9,7 @@ if __name__ == "__main__": os.makedirs(locales_dir) print("Compiling locales") - sys.argv = ["", "compile", "-d", locales_dir] + sys.argv = ["", "compile", "-f", "-d", locales_dir] pybabel() diff --git a/libretranslate/app.py b/libretranslate/app.py index 65c70a3..ff33bd6 100644 --- a/libretranslate/app.py +++ b/libretranslate/app.py @@ -15,11 +15,11 @@ from flask_swagger_ui import get_swaggerui_blueprint from translatehtml import translate_html from werkzeug.utils import secure_filename from werkzeug.exceptions import HTTPException -from flask_babel import Babel, gettext as _ +from flask_babel import Babel from libretranslate import flood, remove_translated_files, security from libretranslate.language import detect_languages, improve_translation_formatting -from libretranslate.locales import get_available_locales, gettext_escaped, gettext_html +from libretranslate.locales import _, _lazy, get_available_locales, gettext_escaped, gettext_html from .api_keys import Database, RemoteDatabase from .suggestions import Database as SuggestionsDatabase @@ -188,7 +188,7 @@ def create_app(args): if args.metrics_auth_token: authorization = request.headers.get('Authorization') if authorization != "Bearer " + args.metrics_auth_token: - abort(401, description="Unauthorized") + abort(401, description=_("Unauthorized")) registry = CollectorRegistry() multiprocess.MultiProcessCollector(registry) @@ -206,7 +206,7 @@ def create_app(args): ip = get_remote_address() if flood.is_banned(ip): - abort(403, description="Too many request limits violations") + abort(403, description=_("Too many request limits violations")) if args.api_keys: ak = get_req_api_key() @@ -215,16 +215,16 @@ def create_app(args): ): abort( 403, - description="Invalid API key", + description=_("Invalid API key"), ) elif ( args.require_api_key_origin and api_keys_db.lookup(ak) is None and request.headers.get("Origin") != args.require_api_key_origin ): - description = "Please contact the server operator to get an API key" + description = _("Please contact the server operator to get an API key") if args.get_api_key_link: - description = "Visit %s to get an API key" % args.get_api_key_link + description = _("Visit %(url)s to get an API key", url=args.get_api_key_link) abort( 403, description=description, @@ -264,7 +264,7 @@ def create_app(args): @bp.errorhandler(429) def slow_down_error(e): flood.report(get_remote_address()) - return jsonify({"error": "Slowdown: " + str(e.description)}), 429 + return jsonify({"error": _("Slowdown:") + " " + str(e.description)}), 429 @bp.errorhandler(403) def denied(e): @@ -294,7 +294,8 @@ def create_app(args): if args.disable_web_ui: abort(404) - return render_template("app.js.template") + return render_template("app.js.template", + get_api_key_link=args.get_api_key_link) @bp.get("/languages") @limiter.exempt @@ -325,7 +326,7 @@ def create_app(args): type: string description: Supported target language codes """ - return jsonify([{"code": l.code, "name": l.name, "targets": language_pairs.get(l.code, [])} for l in languages]) + return jsonify([{"code": l.code, "name": _lazy(l.name), "targets": language_pairs.get(l.code, [])} for l in languages]) # Add cors @bp.after_request @@ -454,11 +455,11 @@ def create_app(args): text_format = request.values.get("format") if not q: - abort(400, description="Invalid request: missing q parameter") + abort(400, description=_("Invalid request: missing %(name)s parameter", name='q')) if not source_lang: - abort(400, description="Invalid request: missing source parameter") + abort(400, description=_("Invalid request: missing %(name)s parameter", name='source')) if not target_lang: - abort(400, description="Invalid request: missing target parameter") + abort(400, description=_("Invalid request: missing %(name)s parameter", name='target')) batch = isinstance(q, list) @@ -467,8 +468,7 @@ def create_app(args): if args.batch_limit < batch_size: abort( 400, - description="Invalid request: Request (%d) exceeds text limit (%d)" - % (batch_size, args.batch_limit), + description=_("Invalid request: request (%(size)s) exceeds text limit (%(limit)s)", size=batch_size, limit=args.batch_limit), ) if args.char_limit != -1: @@ -480,8 +480,7 @@ def create_app(args): if args.char_limit < chars: abort( 400, - description="Invalid request: Request (%d) exceeds character limit (%d)" - % (chars, args.char_limit), + description=_("Invalid request: request (%(size)s) exceeds text limit (%(limit)s)", size=chars, limit=args.char_limit), ) if source_lang == "auto": @@ -514,18 +513,18 @@ def create_app(args): for idx, lang in enumerate(src_langs): if lang is None: - abort(400, description="%s is not supported" % source_langs[idx]) + abort(400, description=_("%(lang)s is not supported", lang=source_langs[idx])) tgt_lang = next(iter([l for l in languages if l.code == target_lang]), None) if tgt_lang is None: - abort(400, description="%s is not supported" % target_lang) + abort(400, description=_("%(lang)s is not supported",lang=target_lang)) if not text_format: text_format = "text" if text_format not in ["text", "html"]: - abort(400, description="%s format is not supported" % text_format) + abort(400, description=_("%(format)s format is not supported", format=text_format)) try: if batch: @@ -533,7 +532,7 @@ def create_app(args): for idx, text in enumerate(q): translator = src_langs[idx].get_translation(tgt_lang) if translator is None: - abort(400, description="%s (%s) is not available as a target language from %s (%s)" % (tgt_lang.name, tgt_lang.code, src_langs[idx].name, src_langs[idx].code)) + abort(400, description=_("%(tname)s (%(tcode)s) is not available as a target language from %(sname)s (%(scode)s)", tname=_lazy(tgt_lang.name), tcode=tgt_lang.code, sname=_lazy(src_langs[idx].name), scode=src_langs[idx].code)) if text_format == "html": translated_text = str(translate_html(translator, text)) @@ -557,7 +556,7 @@ def create_app(args): else: translator = src_langs[0].get_translation(tgt_lang) if translator is None: - abort(400, description="%s (%s) is not available as a target language from %s (%s)" % (tgt_lang.name, tgt_lang.code, src_langs[0].name, src_langs[0].code)) + abort(400, description=_("%(tname)s (%(tcode)s) is not available as a target language from %(sname)s (%(scode)s)", tname=_lazy(tgt_lang.name), tcode=tgt_lang.code, sname=_lazy(src_langs[0].name), scode=src_langs[0].code)) if text_format == "html": translated_text = str(translate_html(translator, q)) @@ -578,7 +577,7 @@ def create_app(args): } ) except Exception as e: - abort(500, description="Cannot translate text: %s" % str(e)) + abort(500, description=_("Cannot translate text: %(text)s", text=str(e))) @bp.post("/translate_file") @access_check @@ -665,36 +664,36 @@ def create_app(args): description: Error message """ if args.disable_files_translation: - abort(403, description="Files translation are disabled on this server.") + abort(403, description=_("Files translation are disabled on this server.")) source_lang = request.form.get("source") target_lang = request.form.get("target") file = request.files['file'] if not file: - abort(400, description="Invalid request: missing file parameter") + abort(400, description=_("Invalid request: missing %(name)s parameter", name='file')) if not source_lang: - abort(400, description="Invalid request: missing source parameter") + abort(400, description=_("Invalid request: missing %(name)s parameter", name='source')) if not target_lang: - abort(400, description="Invalid request: missing target parameter") + abort(400, description=_("Invalid request: missing %(name)s parameter", name='target')) if file.filename == '': - abort(400, description="Invalid request: empty file") + abort(400, description=_("Invalid request: empty file")) if os.path.splitext(file.filename)[1] not in frontend_argos_supported_files_format: - abort(400, description="Invalid request: file format not supported") + abort(400, description=_("Invalid request: file format not supported")) source_langs = [source_lang] src_langs = [next(iter([l for l in languages if l.code == source_lang]), None) for source_lang in source_langs] for idx, lang in enumerate(src_langs): if lang is None: - abort(400, description="%s is not supported" % source_langs[idx]) + abort(400, description=_("%(lang)s is not supported", lang=source_langs[idx])) tgt_lang = next(iter([l for l in languages if l.code == target_lang]), None) if tgt_lang is None: - abort(400, description="%s is not supported" % target_lang) + abort(400, description=_("%(lang)s is not supported", lang=target_lang)) try: filename = str(uuid.uuid4()) + '.' + secure_filename(file.filename) @@ -719,7 +718,7 @@ def create_app(args): Download a translated file """ if args.disable_files_translation: - abort(400, description="Files translation are disabled on this server.") + abort(400, description=_("Files translation are disabled on this server.")) filepath = os.path.join(get_upload_dir(), filename) try: @@ -727,7 +726,7 @@ def create_app(args): if os.path.isfile(checked_filepath): filepath = checked_filepath except security.SuspiciousFileOperation: - abort(400, description="Invalid filename") + abort(400, description=_("Invalid filename")) return_data = io.BytesIO() with open(filepath, 'rb') as fo: @@ -820,9 +819,6 @@ def create_app(args): type: string description: Error message """ - if flood.is_banned(get_remote_address()): - abort(403, description="Too many request limits violations") - if request.is_json: json = get_json_dict(request) q = json.get("q") @@ -830,7 +826,7 @@ def create_app(args): q = request.values.get("q") if not q: - abort(400, description="Invalid request: missing q parameter") + abort(400, description=_("Invalid request: missing %(name)s parameter", name='q')) return jsonify(detect_languages(q)) @@ -903,11 +899,11 @@ def create_app(args): "language": { "source": { "code": frontend_argos_language_source.code, - "name": frontend_argos_language_source.name, + "name": _lazy(frontend_argos_language_source.name), }, "target": { "code": frontend_argos_language_target.code, - "name": frontend_argos_language_target.name, + "name": _lazy(frontend_argos_language_target.name), }, }, } @@ -971,7 +967,7 @@ def create_app(args): description: Error message """ if not args.suggestions: - abort(403, description="Suggestions are disabled on this server.") + abort(403, description=_("Suggestions are disabled on this server.")) q = request.values.get("q") s = request.values.get("s") @@ -979,13 +975,13 @@ def create_app(args): target_lang = request.values.get("target") if not q: - abort(400, description="Invalid request: missing q parameter") + abort(400, description=_("Invalid request: missing %(name)s parameter", name='q')) if not s: - abort(400, description="Invalid request: missing s parameter") + abort(400, description=_("Invalid request: missing %(name)s parameter", name='s')) if not source_lang: - abort(400, description="Invalid request: missing source parameter") + abort(400, description=_("Invalid request: missing %(name)s parameter", name='source')) if not target_lang: - abort(400, description="Invalid request: missing target parameter") + abort(400, description=_("Invalid request: missing %(name)s parameter", name='target')) SuggestionsDatabase().add(q, s, source_lang, target_lang) return jsonify({"success": True}) @@ -1016,8 +1012,6 @@ def create_app(args): def get_locale(): return request.accept_languages.best_match(get_available_locales()) - - app.jinja_env.globals.update(_e=gettext_escaped, _h=gettext_html) # Call factory function to create our blueprint diff --git a/libretranslate/locales.py b/libretranslate/locales.py index 759ef4b..c93adfa 100644 --- a/libretranslate/locales.py +++ b/libretranslate/locales.py @@ -1,6 +1,9 @@ import os +import json from functools import cache from flask_babel import gettext as _ +from flask_babel import lazy_gettext as _lazy + from markupsafe import escape, Markup @cache @@ -12,7 +15,7 @@ def get_available_locales(): # Javascript code should use _e instead of _ def gettext_escaped(text, **variables): - return _(text, **variables).replace("'", "\\'") + return json.dumps(_(text, **variables)) # HTML should be escaped using _h instead of _ def gettext_html(text, **variables): diff --git a/libretranslate/locales/.gitignore b/libretranslate/locales/.gitignore index d0f6ec9..7dc37f0 100644 --- a/libretranslate/locales/.gitignore +++ b/libretranslate/locales/.gitignore @@ -1 +1,2 @@ **/*.mo +.langs.py \ No newline at end of file diff --git a/libretranslate/locales/it/LC_MESSAGES/messages.po b/libretranslate/locales/it/LC_MESSAGES/messages.po index eeb23b3..85fdbbb 100644 --- a/libretranslate/locales/it/LC_MESSAGES/messages.po +++ b/libretranslate/locales/it/LC_MESSAGES/messages.po @@ -1,52 +1,309 @@ -# Italian translations for PROJECT. -# Copyright (C) 2023 ORGANIZATION -# This file is distributed under the same license as the PROJECT project. +# Italian translations for LibreTranslate. +# Copyright (C) 2023 LibreTranslate Authors +# This file is distributed under the same license as the LibreTranslate +# project. # FIRST AUTHOR , 2023. # msgid "" msgstr "" -"Project-Id-Version: PROJECT VERSION\n" +"Project-Id-Version: LibreTranslate 1.3.8\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" -"POT-Creation-Date: 2023-01-04 16:34-0500\n" -"PO-Revision-Date: 2023-01-04 12:27-0500\n" +"POT-Creation-Date: 2023-01-05 13:11-0500\n" +"PO-Revision-Date: 2023-01-05 13:11-0500\n" "Last-Translator: FULL NAME \n" -"Language: it\n" "Language-Team: it \n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"Language: it\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" "Generated-By: Babel 2.11.0\n" #: libretranslate/app.py:58 msgid "Invalid JSON format" msgstr "Formato JSON non valido" -#: libretranslate/app.py:126 +#: libretranslate/app.py:126 libretranslate/templates/app.js.template:427 msgid "Auto Detect" msgstr "Rilevamento automatico" +#: libretranslate/app.py:191 +msgid "Unauthorized" +msgstr "Non autorizzato" + +#: libretranslate/app.py:209 +msgid "Too many request limits violations" +msgstr "Troppe richieste limitano le violazioni" + +#: libretranslate/app.py:218 +msgid "Invalid API key" +msgstr "Chiave API non valida" + +#: libretranslate/app.py:225 +msgid "Please contact the server operator to get an API key" +msgstr "" +"Si prega di contattare l'operatore del server per ottenere una chiave API" + +#: libretranslate/app.py:227 +#, python-format +msgid "Visit %(url)s to get an API key" +msgstr "Visita %(url)s per ottenere una chiave API" + +#: libretranslate/app.py:267 +msgid "Slowdown:" +msgstr "Rallenta:" + +#: libretranslate/app.py:458 libretranslate/app.py:460 +#: libretranslate/app.py:462 libretranslate/app.py:674 +#: libretranslate/app.py:676 libretranslate/app.py:678 +#: libretranslate/app.py:829 libretranslate/app.py:978 +#: libretranslate/app.py:980 libretranslate/app.py:982 +#: libretranslate/app.py:984 +#, python-format +msgid "Invalid request: missing %(name)s parameter" +msgstr "Richiesta non valida: mancante %(name)s parametro" + +#: libretranslate/app.py:471 libretranslate/app.py:483 +#, python-format +msgid "Invalid request: request (%(size)s) exceeds text limit (%(limit)s)" +msgstr "" +"Richiesta non valida: richiesta (%(size)s) supera il limite di testo " +"(%(limit)s)" + +#: libretranslate/app.py:516 libretranslate/app.py:521 +#: libretranslate/app.py:691 libretranslate/app.py:696 +#, python-format +msgid "%(lang)s is not supported" +msgstr "%(lang)s non è supportato" + +#: libretranslate/app.py:527 +#, python-format +msgid "%(format)s format is not supported" +msgstr "%(format)s formato non è supportato" + +#: libretranslate/app.py:535 libretranslate/app.py:559 +#, python-format +msgid "" +"%(tname)s (%(tcode)s) is not available as a target language from %(sname)s " +"(%(scode)s)" +msgstr "" +"%(tname)s (%(tcode)s) non è disponibile come lingua di destinazione " +"%(sname)s (%(scode)s)" + +#: libretranslate/app.py:580 +#, python-format +msgid "Cannot translate text: %(text)s" +msgstr "Non può tradurre il testo: %(text)s" + +#: libretranslate/app.py:667 libretranslate/app.py:721 +msgid "Files translation are disabled on this server." +msgstr "La traduzione dei file è disabilitata su questo server." + +#: libretranslate/app.py:681 +msgid "Invalid request: empty file" +msgstr "Richiesta non valida: file vuoto" + +#: libretranslate/app.py:684 +msgid "Invalid request: file format not supported" +msgstr "Richiesta non valida: formato file non supportato" + +#: libretranslate/app.py:729 +msgid "Invalid filename" +msgstr "Invalid filename" + +#: libretranslate/app.py:970 +msgid "Suggestions are disabled on this server." +msgstr "I suggerimenti sono disabilitati su questo server." + +#: libretranslate/locales/.langs.py:1 +msgid "English" +msgstr "Inglese" + +#: libretranslate/locales/.langs.py:2 +msgid "Arabic" +msgstr "Arabo" + +#: libretranslate/locales/.langs.py:3 +msgid "Azerbaijani" +msgstr "Azerbaigian" + +#: libretranslate/locales/.langs.py:4 +msgid "Chinese" +msgstr "Cinese" + +#: libretranslate/locales/.langs.py:5 +msgid "Czech" +msgstr "Ceco" + +#: libretranslate/locales/.langs.py:6 +msgid "Danish" +msgstr "Danese" + +#: libretranslate/locales/.langs.py:7 +msgid "Dutch" +msgstr "Paesi Bassi" + +#: libretranslate/locales/.langs.py:8 +msgid "Esperanto" +msgstr "Esperanto" + +#: libretranslate/locales/.langs.py:9 +msgid "Finnish" +msgstr "Finlandia" + +#: libretranslate/locales/.langs.py:10 +msgid "French" +msgstr "Francese" + +#: libretranslate/locales/.langs.py:11 +msgid "German" +msgstr "Germania" + +#: libretranslate/locales/.langs.py:12 +msgid "Greek" +msgstr "Greco" + +#: libretranslate/locales/.langs.py:13 +msgid "Hebrew" +msgstr "Ebraico" + +#: libretranslate/locales/.langs.py:14 +msgid "Hindi" +msgstr "Hindi" + +#: libretranslate/locales/.langs.py:15 +msgid "Hungarian" +msgstr "Ungherese" + +#: libretranslate/locales/.langs.py:16 +msgid "Indonesian" +msgstr "Indonesiano" + +#: libretranslate/locales/.langs.py:17 +msgid "Irish" +msgstr "Irlanda" + +#: libretranslate/locales/.langs.py:18 +msgid "Italian" +msgstr "Italiano" + +#: libretranslate/locales/.langs.py:19 +msgid "Japanese" +msgstr "Giappone" + +#: libretranslate/locales/.langs.py:20 +msgid "Korean" +msgstr "Coreano" + +#: libretranslate/locales/.langs.py:21 +msgid "Persian" +msgstr "Persiano" + +#: libretranslate/locales/.langs.py:22 +msgid "Polish" +msgstr "Polacco" + +#: libretranslate/locales/.langs.py:23 +msgid "Portuguese" +msgstr "Portoghese" + +#: libretranslate/locales/.langs.py:24 +msgid "Russian" +msgstr "Russo" + +#: libretranslate/locales/.langs.py:25 +msgid "Slovak" +msgstr "Slovacchia" + +#: libretranslate/locales/.langs.py:26 +msgid "Spanish" +msgstr "Spagnolo" + +#: libretranslate/locales/.langs.py:27 +msgid "Swedish" +msgstr "Svezia" + +#: libretranslate/locales/.langs.py:28 +msgid "Turkish" +msgstr "Turco" + +#: libretranslate/locales/.langs.py:29 +msgid "Ukranian" +msgstr "Ucraina" + +#: libretranslate/locales/.langs.py:30 +msgid "Vietnamese" +msgstr "Vietnamita" + #: libretranslate/templates/app.js.template:31 +#: libretranslate/templates/app.js.template:279 msgid "Copy text" msgstr "Copia testo" #: libretranslate/templates/app.js.template:72 +#: libretranslate/templates/app.js.template:78 +#: libretranslate/templates/app.js.template:83 +#: libretranslate/templates/app.js.template:262 +#: libretranslate/templates/app.js.template:332 +#: libretranslate/templates/app.js.template:402 +#: libretranslate/templates/app.js.template:447 #, python-format msgid "Cannot load %(url)s" msgstr "Non riesco a caricare %(url)s" -#: libretranslate/templates/index.html:6 libretranslate/templates/index.html:26 -msgid "LibreTranslate - Free and Open Source Machine Translation API" -msgstr "API di traduzione automatica open source < ' a" +#: libretranslate/templates/app.js.template:253 +#: libretranslate/templates/app.js.template:323 +#: libretranslate/templates/app.js.template:385 +#: libretranslate/templates/app.js.template:395 +msgid "Unknown error" +msgstr "Errore sconosciuto" -#: libretranslate/templates/index.html:8 libretranslate/templates/index.html:30 +#: libretranslate/templates/app.js.template:276 +msgid "Copied" +msgstr "Copie" + +#: libretranslate/templates/app.js.template:320 msgid "" -"Free and Open Source Machine Translation API. Self-hosted, offline " -"capable and easy to setup. Run your own API server in just a few minutes." +"Thanks for your correction. Note the suggestion will not take effect right " +"away." msgstr "" -"API di traduzione automatica gratuita e open source. Auto-hosted, offline" -" in grado e facile da configurare. Eseguire il proprio server API in " -"pochi minuti." +"Grazie per la sua correzione. Si noti che il suggerimento non avrà effetto " +"subito." + +#: libretranslate/templates/app.js.template:423 +msgid "No languages available. Did you install the models correctly?" +msgstr "Nessuna lingua disponibile. Hai installato correttamente i modelli?" + +#: libretranslate/templates/app.js.template:479 +#, python-format +msgid "Type in your API Key. If you need an API key, %(instructions)s" +msgstr "" +"Digitare nella chiave API. Se hai bisogno di una chiave API, " +"%(instructions)s" + +#: libretranslate/templates/app.js.template:479 +msgid "press the \"Get API Key\" link." +msgstr "premere il link \"Get API Key\"." + +#: libretranslate/templates/app.js.template:479 +msgid "contact the server operator." +msgstr "contattare l'operatore del server." + +#: libretranslate/templates/index.html:6 +#: libretranslate/templates/index.html:26 +#: libretranslate/templates/index.html:297 +msgid "Free and Open Source Machine Translation API" +msgstr "API di traduzione automatica gratuita e open source" + +#: libretranslate/templates/index.html:8 +#: libretranslate/templates/index.html:30 +msgid "" +"Free and Open Source Machine Translation API. Self-hosted, offline capable " +"and easy to setup. Run your own API server in just a few minutes." +msgstr "" +"API di traduzione automatica gratuita e open source. Auto-hosted, offline in" +" grado e facile da configurare. Eseguire il proprio server API in pochi " +"minuti." #: libretranslate/templates/index.html:9 msgid "translation" @@ -56,3 +313,132 @@ msgstr "traduzione" msgid "api" msgstr "api" +#: libretranslate/templates/index.html:64 +#: libretranslate/templates/index.html:75 +msgid "API Docs" +msgstr "API" + +#: libretranslate/templates/index.html:66 +#: libretranslate/templates/index.html:77 +msgid "Get API Key" +msgstr "Ottieni API Chiave" + +#: libretranslate/templates/index.html:68 +#: libretranslate/templates/index.html:79 +msgid "GitHub" +msgstr "GitHub" + +#: libretranslate/templates/index.html:81 +msgid "Set API Key" +msgstr "Set API Chiave" + +#: libretranslate/templates/index.html:118 +msgid "Dismiss" +msgstr "Oggetto" + +#: libretranslate/templates/index.html:132 +msgid "Translation API" +msgstr "API di traduzione" + +#: libretranslate/templates/index.html:136 +msgid "Translate Text" +msgstr "Traduzione" + +#: libretranslate/templates/index.html:140 +msgid "Translate Files" +msgstr "Traduci file" + +#: libretranslate/templates/index.html:146 +msgid "Translate from" +msgstr "Traduttore da" + +#: libretranslate/templates/index.html:159 +msgid "Translate into" +msgstr "Traduzione" + +#: libretranslate/templates/index.html:171 +msgid "Text to translate" +msgstr "Testo da tradurre" + +#: libretranslate/templates/index.html:183 +msgid "Translated text" +msgstr "Tradotto testo" + +#: libretranslate/templates/index.html:191 +msgid "Cancel" +msgstr "Annulla" + +#: libretranslate/templates/index.html:194 +msgid "Send" +msgstr "Invia" + +#: libretranslate/templates/index.html:210 +msgid "Supported file formats:" +msgstr "Formati di file supportati:" + +#: libretranslate/templates/index.html:214 +msgid "File" +msgstr "File" + +#: libretranslate/templates/index.html:236 +msgid "Translate" +msgstr "Traduttore" + +#: libretranslate/templates/index.html:237 +#: libretranslate/templates/index.html:281 +msgid "Download" +msgstr "Scarica" + +#: libretranslate/templates/index.html:256 +msgid "Request" +msgstr "Richiesta" + +#: libretranslate/templates/index.html:261 +msgid "Response" +msgstr "Risposta" + +#: libretranslate/templates/index.html:276 +msgid "Open Source Machine Translation API" +msgstr "API di traduzione automatica Open Source" + +#: libretranslate/templates/index.html:277 +msgid "Self-Hosted. Offline Capable. Easy to Setup." +msgstr "Ossessionato. Offline Capable. Facile da configurare." + +#: libretranslate/templates/index.html:296 +msgid "LibreTranslate" +msgstr "LibreTranslate" + +#: libretranslate/templates/index.html:298 +msgid "License:" +msgstr "Licenza:" + +#: libretranslate/templates/index.html:301 +#, python-format +msgid "" +"This public API should be used for testing, personal or infrequent use. If " +"you're going to run an application in production, please %(host_server)s or " +"%(get_api_key)s." +msgstr "" +"Questa API pubblica dovrebbe essere utilizzata per il test, uso personale o " +"infrequente. Se hai intenzione di eseguire un'applicazione in produzione, " +"per favore %(host_server)s o %(get_api_key)s." + +#: libretranslate/templates/index.html:301 +msgid "host your own server" +msgstr "host tuo server" + +#: libretranslate/templates/index.html:301 +msgid "get an API key" +msgstr "ottenere una chiave API" + +#: libretranslate/templates/index.html:309 +#, python-format +msgid "Made with %(heart)s by %(contributors)s and powered by %(engine)s" +msgstr "" +"Realizzato con %(heart)s di %(contributors)s e alimentato da %(engine)s" + +#: libretranslate/templates/index.html:309 +#, python-format +msgid "%(libretranslate)s Contributors" +msgstr "%(libretranslate)s Contributori" diff --git a/libretranslate/templates/app.js.template b/libretranslate/templates/app.js.template index 57dde04..f94bbf0 100644 --- a/libretranslate/templates/app.js.template +++ b/libretranslate/templates/app.js.template @@ -28,7 +28,7 @@ document.addEventListener('DOMContentLoaded', function(){ detectedLangText: "", - copyTextLabel: '{{ _e("Copy text") }}', + copyTextLabel: {{ _e("Copy text") }}, suggestions: false, isSuggesting: false, @@ -69,18 +69,18 @@ document.addEventListener('DOMContentLoaded', function(){ } } } else { - self.error = '{{ _e("Cannot load %(url)s", url="/frontend/settings") }}'; + self.error = {{ _e("Cannot load %(url)s", url="/frontend/settings") }}; self.loading = false; } }; settingsRequest.onerror = function() { - self.error = "Error while calling /frontend/settings"; + self.error = {{ _e("Cannot load %(url)s", url="/frontend/settings") }}; self.loading = false; }; langsRequest.onerror = function() { - self.error = "Error while calling /languages"; + self.error = {{ _e("Cannot load %(url)s", url="/languages") }}; self.loading = false; }; @@ -250,7 +250,7 @@ document.addEventListener('DOMContentLoaded', function(){ self.detectedLangText = ": " + (lang !== undefined ? lang.name : res.detectedLanguage.language) + " (" + res.detectedLanguage.confidence + "%)"; } } else{ - throw new Error(res.error || "Unknown error"); + throw new Error(res.error || {{ _e("Unknown error") }}); } } catch (e) { self.error = e.message; @@ -259,7 +259,7 @@ document.addEventListener('DOMContentLoaded', function(){ }; request.onerror = function() { - self.error = "Error while calling /translate"; + self.error = {{ _e("Cannot load %(url)s", url="/translate") }}; self.loadingTranslation = false; }; @@ -273,10 +273,10 @@ document.addEventListener('DOMContentLoaded', function(){ document.execCommand("copy"); if (this.copyTextLabel === "Copy text"){ - this.copyTextLabel = "Copied"; + this.copyTextLabel = {{ _e("Copied") }}; var self = this; setTimeout(function(){ - self.copyTextLabel = "Copy text"; + self.copyTextLabel = {{ _e("Copy text") }}; }, 1500); } }, @@ -317,10 +317,10 @@ document.addEventListener('DOMContentLoaded', function(){ try{ var res = JSON.parse(this.response); if (res.success){ - M.toast({html: 'Thanks for your correction. Note the suggestion will not take effect right away.'}) + M.toast({html: {{ _e("Thanks for your correction. Note the suggestion will not take effect right away.") }} }) self.closeSuggestTranslation(e) }else{ - throw new Error(res.error || "Unknown error"); + throw new Error(res.error || {{ _e("Unknown error") }}); } }catch(e){ self.error = e.message; @@ -329,7 +329,7 @@ document.addEventListener('DOMContentLoaded', function(){ }; request.onerror = function() { - self.error = "Error while calling /suggest"; + self.error = {{ _e("Cannot load %(url)s", url="/suggest") }}; self.loadingTranslation = false; }; @@ -382,7 +382,7 @@ document.addEventListener('DOMContentLoaded', function(){ link.href = self.translatedFileUrl; link.click(); }else{ - throw new Error(res.error || "Unknown error"); + throw new Error(res.error || {{ _e("Unknown error") }}); } }catch(e){ @@ -392,14 +392,14 @@ document.addEventListener('DOMContentLoaded', function(){ } }else{ let res = JSON.parse(this.response); - self.error = res.error || "Unknown error"; + self.error = res.error || {{ _e("Unknown error") }}; self.loadingFileTranslation = false; self.inputFile = false; } } translateFileRequest.onerror = function() { - self.error = "Error while calling /translate_file"; + self.error = {{ _e("Cannot load %(url)s", url="/translate_file") }}; self.loadingFileTranslation = false; self.inputFile = false; }; @@ -420,11 +420,11 @@ function handleLangsResponse(self, response) { if (self.langs.length === 0){ self.loading = false; - self.error = "No languages available. Did you install the models correctly?" + self.error = {{ _e("No languages available. Did you install the models correctly?") }}; return; } - self.langs.push({ name: "Auto Detect", code: "auto", targets: self.langs.map(l => l.code)}) + self.langs.push({ name: {{ _e("Auto Detect") }}, code: "auto", targets: self.langs.map(l => l.code)}) const sourceLanguage = self.langs.find(l => l.code === self.getQueryParam("source")) const targetLanguage = self.langs.find(l => l.code === self.getQueryParam("target")) @@ -444,7 +444,7 @@ function handleLangsResponse(self, response) { self.handleInput(new Event('none')) } } else { - self.error = "Cannot load /languages"; + self.error = {{ _e("Cannot load %(url)s", url="/languages") }}; } self.loading = false; @@ -476,9 +476,7 @@ function getTextWidth(text) { function setApiKey(){ var prevKey = localStorage.getItem("api_key") || ""; var newKey = ""; - var instructions = "contact the server operator."; - if (window.getApiKeyLink) instructions = "press the \"Get API Key\" link." - newKey = window.prompt("Type in your API Key. If you need an API key, " + instructions, prevKey); + newKey = window.prompt({{ _e("Type in your API Key. If you need an API key, %(instructions)s", instructions=_e("press the \"Get API Key\" link.") if get_api_key_link else _e("contact the server operator.")) }}, prevKey); if (newKey === null) newKey = ""; localStorage.setItem("api_key", newKey); diff --git a/libretranslate/templates/index.html b/libretranslate/templates/index.html index be8e993..86a70f7 100644 --- a/libretranslate/templates/index.html +++ b/libretranslate/templates/index.html @@ -3,7 +3,7 @@ - {{ _h("LibreTranslate - Free and Open Source Machine Translation API") }} + LibreTranslate - {{ _h("Free and Open Source Machine Translation API") }} @@ -23,7 +23,7 @@ - + @@ -57,14 +57,13 @@