#!/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"]