From 7d0b1c5270e5792b96f5cc53a5e2a3f097047cfe Mon Sep 17 00:00:00 2001 From: dece Date: Wed, 4 Nov 2020 17:21:52 +0100 Subject: [PATCH] translate: add plugin --- README.md | 2 +- config.json.example | 6 +++ edmond/plugins/requirements.txt | 3 ++ edmond/plugins/tests/test_sleep.py | 2 +- edmond/plugins/tests/test_translate.py | 35 +++++++++++++++++ edmond/plugins/translate.py | 54 ++++++++++++++++++++++++++ 6 files changed, 100 insertions(+), 2 deletions(-) create mode 100644 edmond/plugins/tests/test_translate.py create mode 100644 edmond/plugins/translate.py diff --git a/README.md b/README.md index 18788dd..9045d21 100644 --- a/README.md +++ b/README.md @@ -37,7 +37,7 @@ Missing features - [ ] Mug - [ ] Music - [x] Opinions -- [ ] Translate +- [x] Translate - [x] Wikipedia: find definition, get random page - [ ] Wolframalpha - [x] Youtube: parsing for title, requests for channel or video diff --git a/config.json.example b/config.json.example index 211250e..ddf9e82 100644 --- a/config.json.example +++ b/config.json.example @@ -77,6 +77,12 @@ "wakeup_messages": ["/me wakes up"], "snore_rate": 1.0 }, + "translate": { + "commands": ["translate"], + "default_dest": "en", + "param_source": "from", + "param_dest": "to" + }, "wikipedia": { "commands": ["science", "define"], "lang": "en", diff --git a/edmond/plugins/requirements.txt b/edmond/plugins/requirements.txt index 66fecac..5daa7ad 100644 --- a/edmond/plugins/requirements.txt +++ b/edmond/plugins/requirements.txt @@ -6,3 +6,6 @@ beautifulsoup4 # Google API (i.e. Youtube) google-api-python-client + +# Translator +translate diff --git a/edmond/plugins/tests/test_sleep.py b/edmond/plugins/tests/test_sleep.py index 1ea309c..35dcd8f 100644 --- a/edmond/plugins/tests/test_sleep.py +++ b/edmond/plugins/tests/test_sleep.py @@ -2,8 +2,8 @@ import unittest from datetime import datetime, timedelta from unittest.mock import Mock, patch -from ..sleep import SleepPlugin from edmond.tests.test_plugin import get_plugin_patcher +from ..sleep import SleepPlugin class TestSleepPlugin(unittest.TestCase): diff --git a/edmond/plugins/tests/test_translate.py b/edmond/plugins/tests/test_translate.py new file mode 100644 index 0000000..aa8ef8e --- /dev/null +++ b/edmond/plugins/tests/test_translate.py @@ -0,0 +1,35 @@ +import unittest + +from edmond.tests.test_plugin import get_plugin_patcher +from ..translate import TranslatePlugin + + +class TestTranslatePlugin(unittest.TestCase): + + def test_parse_words(self): + with get_plugin_patcher(TranslatePlugin): + plugin = TranslatePlugin() + plugin.config = { + "default_dest": "en", + "param_source": "from", + "param_dest": "to", + } + + # No params. + result = plugin.parse_words(["test"]) + self.assertEqual(result, ("autodetect", "en", "test")) + # Source param. + result = plugin.parse_words(["!from:fr", "test"]) + self.assertEqual(result, ("fr", "en", "test")) + # Destination param. + result = plugin.parse_words(["!to:fr", "test"]) + self.assertEqual(result, ("autodetect", "fr", "test")) + # Both source and dest params. + result = plugin.parse_words(["!from:it", "!to:fr", "test"]) + self.assertEqual(result, ("it", "fr", "test")) + # Badly placed param. + result = plugin.parse_words(["!from:it", "test", "!to:fr"]) + self.assertEqual(result, ("it", "en", "test !to:fr")) + # Unknown param. + result = plugin.parse_words(["!zzz", "test"]) + self.assertEqual(result, ("autodetect", "en", "test")) diff --git a/edmond/plugins/translate.py b/edmond/plugins/translate.py new file mode 100644 index 0000000..b08d0d3 --- /dev/null +++ b/edmond/plugins/translate.py @@ -0,0 +1,54 @@ +try: + from translate import Translator + DEPENDENCIES_FOUND = True +except ImportError: + DEPENDENCIES_FOUND = False + +from edmond.plugin import Plugin + + +class TranslatePlugin(Plugin): + + REQUIRED_CONFIGS = [ + "commands", "default_dest", "param_source", "param_dest", + ] + + def __init__(self, bot): + super().__init__(bot) + + def on_pubmsg(self, event): + if not self.should_handle_command(event.arguments[0]): + return False + + text = self.command.content + if not text: + return False + words = text.split() + if len(words) == 0: + return False + + from_lang, to_lang, text = self.parse_words(words) + self.bot.log_d(f"Translating '{text}' from {from_lang} to {to_lang}.") + translator = Translator(to_lang=to_lang, from_lang=from_lang) + translation = translator.translate(text) + self.bot.say(event.target, translation) + return True + + def parse_words(self, words): + """Parse given words for parameters and return (from, to, text).""" + from_lang = "autodetect" + to_lang = self.config["default_dest"] + num_param_found = 0 + for word in words: + if not word.startswith("!"): + break + num_param_found += 1 + param_word = word.lstrip("!") + if not ":" in param_word: + continue + param_name, param_value = param_word.split(":") + if param_name == self.config["param_source"]: + from_lang = param_value + elif param_name == self.config["param_dest"]: + to_lang = param_value + return from_lang, to_lang, " ".join(words[num_param_found:])