LibreTranslatePlus/Python/Drivers/LibreTranslatePlus.Drivers.LibreTranslate.py

310 lines
12 KiB
Python

#!/usr/bin/env python
# -*- coding: utf-8 -*-
from os import popen as execute_command
from urllib.parse import quote_plus as uri_encode
from re import compile as re_compile
if "LibreTranslatePlus" not in globals():
class LibreTranslatePlus:pass
class Anonymous(LibreTranslatePlus.Abstracts.Drivers): # LibreTranslatePlus.Drivers.LibreTranslate
re_url = re_compile(r'^https?\:\/{2}')
def __init__(self, ltp, _input = None):
super().__init__(ltp, _input)
self.__url = self.settings(("drivers_libre_translate_default_url", "url"), _input)
self._print_variables["url"] = self.__url
self._print("info", "ltp_drivers_libre_translate_building", self._print_variables)
self.__api_key = self.settings(("drivers_libre_translate_default_api_key", "api_key"), _input)
self.__default_format = self.settings(("drivers_libre_translate_default_format", "default_format", "format"), _input)
self.__variables_format = self.settings("drivers_libre_translate_variables_format")
self.__query_format = self.settings("drivers_libre_translate_query_format")
self.__forced_languages = self.settings(("drivers_libre_translate_forced_languages", "forced_languages"), _input)
self.__show_build_error = self.settings(("drivers_libre_translate_show_build_error_message", "show_error_message"))
self.__show_build_ok = self.settings(("drivers_libre_translate_show_build_ok_message", "show_ok_message"))
self.__show_query_error = self.settings(("drivers_libre_translate_show_query_error_message", "show_error_message"))
self.__show_query_ok = self.settings(("drivers_libre_translate_show_query_ok_message", "show_ok_message"))
self.__show_query_exception = self.settings(("drivers_libre_translate_show_query_exception_message", "show_exception_message"))
self.__show_translate_error = self.settings(("drivers_libre_translate_show_translate_error_message", "show_error_message"))
self.__show_translate_ok = self.settings(("drivers_libre_translate_show_translate_ok_message", "show_ok_message"))
self.__languages = None
self.__languages_error = None
self.__code_index = {}
self.__key_index = {}
self.__error = (
((
1 << 0 if self.__key == None else
1 << 1 if not isinstance(self.__key, str) else
1 << 2 if not self.__key else
0) << 0) |
((
1 << 0 if self.__url == None else
1 << 1 if not isinstance(self.__url, str) else
1 << 2 if not self.__url else
1 << 3 if not LibreTranslatePlus.Drivers.LibreTranslate.re_url.match(self.__url) else
0) << 3) |
((
0 if self.__api_key == None else
1 << 1 if not isinstance(self.__api_key, str) else
1 << 2 if not self.__api_key else
0) << 7) |
0)
self.__ok = self.validate(
self.__error,
(
"key_null",
"key_not_string",
"key_empty",
"url_null",
"url_not_string",
"url_empty",
"url_bad_protocol",
"api_key_null",
"api_key_not_string",
"api_key_empty"
),
self._print_variables,
self.__show_build_error and "ltp_drivers_libre_translate_build_error",
self.__show_build_ok and "ltp_drivers_libre_translate_build_ok"
)
if isinstance(self.__forced_languages, str):
self.__forced_languages = (self.__forced_languages,)
elif isinstance(self.__forced_languages, list):
self.__forced_languages = tuple(self.__forced_languages)
if not isinstance(self.__forced_languages, tuple) or not len(self.__forced_languages):
self.__forced_languages = None
self.__ok and self.settings(("drivers_libre_translate_autoload", "autoload"), _input) and self.languages()
def __validate_query(self, error, request, show_errors = None):
has_show_errors = isinstance(show_errors, bool)
return self.validate(
error,
(
"exception",
"connection_with_errors",
"request_null",
"request_not_string",
"request_empty",
"request_invalid",
"variables_null",
"variables_not_dictionary",
"response_null",
"response_not_string",
"response_empty",
"response_json_null",
"response_not_list"
),
{
"request" : request,
**self._print_variables
},
(show_errors if has_show_errors else self.__show_query_error) and "ltp_drivers_libre_translate_query_error",
(show_errors if has_show_errors else True) and self.__show_query_ok and "ltp_drivers_libre_translate_query_ok"
)
def query(self, request, variables = None, show_errors = None):
error = (
(0 if self.__ok else 1 << 0) |
((
1 << 0 if request == None else
1 << 1 if not isinstance(request, str) else
1 << 2 if not request else
1 << 3 if request[0] != "/" else
0) << 1) |
((
0 if variables == None else
1 << 1 if not isinstance(variables, dict) else
0) << 5) |
0) << 1
response = None
try:
uri_variables = ""
if variables:
for key, value in variables.items():
uri_variables += ("&" if uri_variables else "") + uri_encode(key) + "=" + uri_encode(str(value))
if uri_variables:
uri_variables = LibreTranslatePlus.string_variables(self.__variables_format, {
"uri_variables" : uri_variables
})
response = execute_command(LibreTranslatePlus.string_variables(self.__query_format, {
"url" : self.__url,
"variables" : uri_variables,
"method" : "POST" if variables else "GET",
"request" : request
})).read()
error |= (
1 << 0 if response == None else
1 << 1 if not isinstance(response, str) else
1 << 2 if not response else
0) << 8
if not error:
response = self.ltp.json_decode(response)[0]
error |= 1 << 11 if response == None else 0
except Exception as exception:
error |= 1 << 0
self.exception(exception, self.__show_query_exception and "ltp_drivers_libre_translate_query_exception")
self.__validate_query(error, request, show_errors)
return (response, error)
def languages(self, show_errors = None):
if self.__languages_error == None:
(response, self.__languages_error) = self.query("/languages", None, show_errors)
if not self.__languages_error:
self.__languages_error |= (0 if isinstance(response, (list, tuple)) else 1 << 12)
if self.__validate_query(self.__languages_error & (1 << 12), "/languages", show_errors):
self.__languages = []
for language in response:
key = self.ltp.i18n.get_key(language["code"])[0]
if self.__forced_languages and key not in self.__forced_languages:
continue
l = len(self.__languages)
if key:
self.__key_index[key] = l
self.__code_index[language["code"]] = l
self.__languages.append({
"code" : language["code"],
"name" : language["name"].lower(),
"key" : key
})
else:
self.__validate_query(self.__languages_error, "/languages", show_errors)
return (self.__languages, self.__languages_error)
def translate(self, text, _from, to, format = None, show_errors = None):
if format == None:
format = self.__default_format
response = None
error = (
((
1 << 0 if text == None else
1 << 1 if not isinstance(text, str) else
# 1 << 2 if not text else
0) << 0) |
((
1 << 0 if _from == None else
1 << 1 if not isinstance(_from, str) else
1 << 2 if not _from else
1 << 3 if len(_from) != 2 else
0) << 3) |
((
1 << 0 if to == None else
1 << 1 if not isinstance(to, str) else
1 << 2 if not to else
1 << 3 if len(to) != 2 else
0) << 7) |
((
1 << 0 if format == None else
1 << 1 if not isinstance(format, str) else
1 << 2 if not format else
1 << 3 if format not in ("text", "html") else
0) << 11) |
0)
has_show_errors = isinstance(show_errors, bool)
if not error:
if not text:
response = text
else:
(response, suberror) = self.query("/translate", {
"q" : text,
"source" : _from,
"target" : to,
"format" : format,
**({"api_key" : self.__api_key} if self.__api_key else {})
}, False)
error |= suberror << 16
if not error:
error |= (
1 << 0 if "translatedText" not in response else
1 << 1 if response["translatedText"] == None else
1 << 2 if not isinstance(response["translatedText"], str) else
# 1 << 3 if not response["translatedText"] else
0)
response = None if error else response["translatedText"]
self.validate(
error,
(
"text_null",
"text_not_string",
"text_empty",
"from_language_null",
"from_language_not_string",
"from_language_empty",
"from_language_invalid",
"to_language_null",
"to_language_not_string",
"to_language_empty",
"to_language_invalid",
"format_null",
"format_not_string",
"format_empty",
"format_unknown",
"exception",
"connection_with_errors",
"request_null",
"request_not_string",
"request_empty",
"request_invalid",
"variables_null",
"variables_not_dictionary",
"response_null",
"response_not_string",
"response_empty",
"response_json_null",
"translated_not_exists",
"translated_null",
"translated_not_string",
"translated_empty"
),
{
"text" : text,
"length" : len(text),
"from" : _from,
"to" : to,
"format" : format,
**self._print_variables
},
(show_errors if has_show_errors else self.__show_translate_error) and "ltp_drivers_libre_translate_translate_error",
(show_errors if has_show_errors else True) and self.__show_translate_ok and "ltp_drivers_libre_translate_translate_ok"
)
return (response, error)
if not hasattr(LibreTranslatePlus, "Drivers"):
class Subanonymous:pass
LibreTranslatePlus.Drivers = Subanonymous
del globals()["Subanonymous"]
LibreTranslatePlus.Drivers.LibreTranslate = Anonymous
del globals()["Anonymous"]