From 46515020cfce9f0909e997e80c83d4d7605cdd1e Mon Sep 17 00:00:00 2001 From: Fabio Manganiello Date: Thu, 2 Jul 2020 02:07:57 +0200 Subject: [PATCH] Added Google Translate plugin --- platypush/message/response/translate.py | 18 +++++ platypush/plugins/google/__init__.py | 5 +- platypush/plugins/google/translate.py | 99 +++++++++++++++++++++++++ requirements.txt | 3 + setup.py | 2 + 5 files changed, 123 insertions(+), 4 deletions(-) create mode 100644 platypush/message/response/translate.py create mode 100644 platypush/plugins/google/translate.py diff --git a/platypush/message/response/translate.py b/platypush/message/response/translate.py new file mode 100644 index 000000000..8a272f556 --- /dev/null +++ b/platypush/message/response/translate.py @@ -0,0 +1,18 @@ +from platypush.message.response import Response + + +class TranslateResponse(Response): + def __init__(self, + translated_text: str, + source_text: str, + detected_source_language: str, + *args, + **kwargs): + super().__init__(*args, output={ + 'translated_text': translated_text, + 'source_text': source_text, + 'detected_source_language': detected_source_language, + }, **kwargs) + + +# vim:sw=4:ts=4:et: diff --git a/platypush/plugins/google/__init__.py b/platypush/plugins/google/__init__.py index 0475d9721..7c5e0a71e 100644 --- a/platypush/plugins/google/__init__.py +++ b/platypush/plugins/google/__init__.py @@ -2,8 +2,6 @@ .. moduleauthor:: Fabio Manganiello """ -import os - from platypush.plugins import Plugin @@ -43,7 +41,7 @@ class GooglePlugin(Plugin): """ from platypush.plugins.google.credentials import get_credentials - super().__init__(*args, **kwargs) + super().__init__(**kwargs) self._scopes = scopes or [] if self._scopes: @@ -54,7 +52,6 @@ class GooglePlugin(Plugin): else: self.credentials = {} - def get_service(self, service, version, scopes=None): import httplib2 from apiclient import discovery diff --git a/platypush/plugins/google/translate.py b/platypush/plugins/google/translate.py new file mode 100644 index 000000000..34832cd5f --- /dev/null +++ b/platypush/plugins/google/translate.py @@ -0,0 +1,99 @@ +import os +from typing import Optional + +# noinspection PyPackageRequirements +from google.auth import jwt +# noinspection PyPackageRequirements +from google.cloud import translate_v2 as translate + +from platypush.message.response.translate import TranslateResponse +from platypush.plugins import action, Plugin + + +class GoogleTranslatePlugin(Plugin): + """ + Plugin to interact with the Google Translate API. + You'll need a Google Cloud active project and a set of credentials to use this plugin: + + 1. Create a project on the `Google Cloud console `_ if + you don't have one already. + + 2. In the menu navigate to the _Artificial Intelligence_ section and select _Translations_ and enable the API. + + 3. From the menu select _APIs & Services_ and create a service account. You can leave role and permissions + empty. + + 4. Create a new private JSON key for the service account and download it. By default platypush will look for the + credentials file under ~/.credentials/platypush/google/translate.json. + + Requires: + + * **google-cloud-translate** (``pip install google-cloud-translate``) + + """ + + default_credentials_file = os.path.join(os.path.expanduser('~'), '.credentials', 'platypush', 'google', + 'translate.json') + + def __init__(self, target_language: str = 'en', credentials_file: Optional[str] = None, **kwargs): + """ + :param target_language: Default target language (default: 'en'). + :param credentials_file: Google service account JSON credentials file. If none is specified then the plugin will + search for the credentials file in the following order: + + 1. ``~/.credentials/platypush/google/translate.json`` + 2. Context from the ``GOOGLE_APPLICATION_CREDENTIALS`` environment variable. + """ + super().__init__(**kwargs) + self.target_language = target_language + self.credentials_file = None + + if credentials_file: + self.credentials_file = os.path.abspath(os.path.expanduser(credentials_file)) + elif os.path.isfile(self.default_credentials_file): + self.credentials_file = self.default_credentials_file + + def _get_credentials(self): + if self.credentials_file: + return jwt.Credentials.from_service_account_file( + self.credentials_file) + + # noinspection PyShadowingBuiltins + @action + def translate(self, text: str, target_language: Optional[str] = None, source_language: Optional[str] = None, + format: Optional[str] = None) -> TranslateResponse: + """ + Translate a piece of text or HTML. + + :param text: Input text. + :param target_language: target_language override. + :param source_language: source_language (default: auto-detect). + :param format: Input format (available formats: ``text``, ``html``). + :return: :class:`platypush.message.response.translate.TranslateResponse`. + """ + target_language = target_language or self.target_language + credentials = self._get_credentials() + args = {} + + if target_language: + args['target_language'] = target_language + if credentials: + args['credentials'] = credentials + + client = translate.Client(**args) + + if credentials: + del args['credentials'] + if source_language: + args['source_language'] = source_language + + result = client.translate(text, format_=format, **args) + # noinspection PyUnresolvedReferences + return TranslateResponse( + translated_text=result.get('translatedText'), + source_text=result.get('input'), + detected_source_language=result.get('detectedSourceLanguage'), + ) + + +# vim:sw=4:ts=4:et: diff --git a/requirements.txt b/requirements.txt index 26bf93462..b1e2ae1b9 100644 --- a/requirements.txt +++ b/requirements.txt @@ -267,3 +267,6 @@ croniter # Support for clipboard integration # pyperclip + +# Support for Google Translate +# google-cloud-translate diff --git a/setup.py b/setup.py index 6923708c9..fd740d092 100755 --- a/setup.py +++ b/setup.py @@ -274,6 +274,8 @@ setup( 'trello': ['py-trello'], # Support for Google Pub/Sub 'google-pubsub': ['google-cloud-pubsub'], + # Support for Google Translate + 'google-translate': ['google-cloud-translate'], # Support for keyboard/mouse plugin 'inputs': ['pyuserinput'], # Support for Buienradar weather forecast