2017-11-12 01:39:28 -08:00

219 lines
8.0 KiB
Python

###
# Copyright (c) 2014-2015, James Lu
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# * Redistributions of source code must retain the above copyright notice,
# this list of conditions, and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions, and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# * Neither the name of the author of this software nor the name of
# contributors to this software may be used to endorse or promote products
# derived from this software without specific prior written consent.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
###
import supybot.utils as utils
from supybot.commands import *
import supybot.plugins as plugins
import supybot.ircutils as ircutils
import supybot.callbacks as callbacks
import random
import json
try: # Python 3
from urllib.parse import urlencode
except ImportError: # Python 2
raise ImportError('This plugin requires Python 3!')
try:
from supybot.i18n import PluginInternationalization
_ = PluginInternationalization('TranslateParty')
except ImportError:
# Placeholder that allows to run the plugin on a bot
# without the i18n module
_ = lambda x:x
class TranslateParty(callbacks.Plugin):
"""Translates text through multiple rounds of Google Translate to get amusing results!"""
threaded = True
def __init__(self, irc):
self.__parent = super(TranslateParty, self)
self.__parent.__init__(irc)
self.langs = {
'af': 'Afrikaans',
'sq': 'Albanian',
'ar': 'Arabic',
'hy': 'Armenian',
'az': 'Azerbaijani',
'eu': 'Basque',
'be': 'Belarusian',
'bn': 'Bengali',
'bs': 'Bosnian',
'bg': 'Bulgarian',
'ca': 'Catalan',
'ceb': 'Cebuano',
'ny': 'Chichewa',
'zh-CN': 'Chinese Simplified',
'zh-TW': 'Chinese Traditional',
'hr': 'Croatian',
'cs': 'Czech',
'da': 'Danish',
'nl': 'Dutch',
'en': 'English',
'eo': 'Esperanto',
'et': 'Estonian',
'tl': 'Filipino',
'fi': 'Finnish',
'fr': 'French',
'gl': 'Galician',
'ka': 'Georgian',
'de': 'German',
'el': 'Greek',
'gu': 'Gujarati',
'ht': 'Haitian Creole',
'ha': 'Hausa',
'iw': 'Hebrew',
'hi': 'Hindi',
'hmn': 'Hmong',
'hu': 'Hungarian',
'is': 'Icelandic',
'ig': 'Igbo',
'id': 'Indonesian',
'ga': 'Irish',
'it': 'Italian',
'ja': 'Japanese',
'jw': 'Javanese',
'kn': 'Kannada',
'kk': 'Kazakh',
'km': 'Khmer',
'ko': 'Korean',
'lo': 'Lao',
'la': 'Latin',
'lv': 'Latvian',
'lt': 'Lithuanian',
'mk': 'Macedonian',
'mg': 'Malagasy',
'ms': 'Malay',
'ml': 'Malayalam',
'mt': 'Maltese',
'mi': 'Maori',
'mr': 'Marathi',
'mn': 'Mongolian',
'my': 'Myanmar (Burmese)',
'ne': 'Nepali',
'no': 'Norwegian',
'fa': 'Persian',
'pl': 'Polish',
'pt': 'Portuguese',
'ma': 'Punjabi',
'ro': 'Romanian',
'ru': 'Russian',
'sr': 'Serbian',
'st': 'Sesotho',
'si': 'Sinhala',
'sk': 'Slovak',
'sl': 'Slovenian',
'so': 'Somali',
'es': 'Spanish',
'su': 'Sudanese',
'sw': 'Swahili',
'sv': 'Swedish',
'tg': 'Tajik',
'ta': 'Tamil',
'te': 'Telugu',
'th': 'Thai',
'tr': 'Turkish',
'uk': 'Ukrainian',
'ur': 'Urdu',
'uz': 'Uzbek',
'vi': 'Vietnamese',
'cy': 'Welsh',
'yi': 'Yiddish',
'yo': 'Yoruba',
'zu': 'Zulu',
}
def _jsonRepair(self, data):
while ',,' in data:
data = data.replace(',,', ',null,')
while '[,' in data:
data = data.replace('[,', '[')
return data
def getTranslation(self, irc, sourceLang, targetLang, text):
"""
Fetches translations from Google Translate, given the source language,
target language, and text.
"""
args = {"sl": sourceLang, "tl": targetLang, 'q': text}
url = "https://translate.googleapis.com/translate_a/single?client=gtx&dt=t&"+ \
urlencode(args)
self.log.debug("TranslateParty: Using URL %s", url)
headers = {'User-Agent': ('Mozilla/5.0 (X11; Linux i586; rv:31.0) '
'Gecko/20100101 Firefox/31.0')}
try:
data = utils.web.getUrlFd(url, headers).read().decode("utf-8")
except utils.web.Error as e:
self.log.exception("TranslateParty: getTranslation errored (probably malformed or too long text)")
return text
data = self._jsonRepair(data)
data = json.loads(data)
return ''.join(x[0] for x in data[0])
@wrap(['text'])
def tp(self, irc, msg, args, text):
"""tp <text>
Translates <text> through multiple rounds of Google Translate to get amusing results.
"""
outlang = self.registryValue('language', msg.args[0])
if outlang not in self.langs:
irc.error("Unrecognized output language. Please set "
"'config plugins.wte.language' correctly.", Raise=True)
# Randomly choose 4 to 8 languages from the list of supported languages.
# The amount can be adjusted if you really wish - 4 to 8 is reasonable
# in that it gives interesting results but doesn't spam Google's API
# (and risk getting blocked) too much.
ll = random.sample(self.langs.keys(), random.randint(4,8))
self.log.debug(format("TranslateParty: Using %i languages: %L "
"(outlang %s)", len(ll), ll, outlang))
text = ircutils.stripFormatting(text)
# For every language in this list, translate the text given from
# auto-detect into the target language, and replace the original text
# with it.
for targetlang in ll:
text = self.getTranslation(irc, "auto", targetlang, text)
text = self.getTranslation(irc, "auto", outlang, text)
text = text.strip()
if self.registryValue("verbose", msg.args[0]):
# Verbose output was requested, show the language codes AND
# names that we translated through.
languages = [ircutils.bold("%s [%s]" % (self.langs[lang], lang)) for lang in ll]
irc.reply(format("Translated through \x02%i\x02 languages: %L "
"(output language %s)", len(ll), languages, outlang))
irc.reply(text)
Class = TranslateParty
# vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79: