aboutsummaryrefslogtreecommitdiff
path: root/translate.liteonly.py
blob: 2f24418e6fb4a786b9f3fc6a522507d40241b8cf (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
r"""

Based on translate.py - Sopel Translation Plugin
Copyright 2008, Sean B. Palmer, inamidst.com
Copyright 2013-2014, Elad Alfassa <elad@fedoraproject.org>
Licensed under the Eiffel Forum License 2.
https://sopel.chat

  Eiffel Forum License, version 2

   1. Permission is hereby granted to use, copy, modify and/or
      distribute this package, provided that:
          * copyright notices are retained unchanged,
          * any distribution of this package, whether modified or not,
      includes this license text.
   2. Permission is hereby also granted to distribute binary programs
      which depend on this package. If the binary program depends on a
      modified version of this package, you are encouraged to publicly
      release the modified version of this package.

***********************

THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT WARRANTY. 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 AUTHORS BE LIABLE TO ANY PARTY FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES ARISING IN ANY WAY OUT OF THE USE OF THIS PACKAGE.

***********************
"""

import json, urllib.error, urllib.request
from urllib.parse import unquote

def translate(text, in_lang='auto', out_lang='en'):
    raw = False
    if str(out_lang).endswith('-raw'):
        out_lang = out_lang[:-4]
        raw = True

    headers = {
        'User-Agent': 'Mozilla/5.0' +
        '(X11; U; Linux i686)' +
        'Gecko/20071127 Firefox/2.0.0.11'
    }

    query = {
        "client": "gtx",
        "sl": in_lang,
        "tl": out_lang,
        "dt": "t",
        "q": text,
    }
    url = ("https://translate.googleapis.com/translate_a/single?" +
            urllib.parse.urlencode(query))
    req = urllib.request.Request(url, headers=headers)
    try:
        with urllib.request.urlopen(req) as r:
            result = r.read().decode('utf-8')
    except urllib.error.HTTPError:
        return None, None

    if result == '[,,""]':
        return None, in_lang

    while ',,' in result:
        result = result.replace(',,', ',null,')
        result = result.replace('[,', '[null,')

    try:
        data = json.loads(result)
    except ValueError:
        return None, None

    if raw:
        return str(data), 'en-raw'

    try:
        language = data[2]  # -2][0][0]
    except IndexError:
        language = '?'

    return ''.join(x[0] for x in data[0]), language


@register_command('tr', 'translate', 'üb', 'übersetzen')
def tr2(irc, hostmask, is_admin, args):
    """Translates a phrase, with an optional language hint."""
    channel, command = args

    reply = lambda msg : irc.msg(channel, f'{hostmask[0]}: {msg}')

    if not command:
        return reply('You did not give me anything to translate')

    def langcode(p):
        return p.startswith(':') and (2 < len(p) < 10) and p[1:].isalpha()

    args = ['auto', 'en']

    for i in range(2):
        if ' ' not in command:
            break
        prefix, cmd = command.split(' ', 1)
        if langcode(prefix):
            args[i] = prefix[1:]
            command = cmd
    phrase = command

    if len(phrase) > 350 and not is_admin:
        return reply('Phrase must be under 350 characters.')

    if phrase.strip() == '':
        return reply('You need to specify a string for me to translate!')

    src, dest = args
    if src != dest:
        msg, src = translate(phrase, src, dest)
        if not src:
            return reply("Translation failed, probably because of a rate-limit.")
        if msg:
            msg = msg.replace('&#39;', "'")
            msg = '"%s" (%s to %s, translate.google.com)' % (msg, src, dest)
        else:
            msg = 'The %s to %s translation failed, are you sure you specified valid language abbreviations?' % (src, dest)
        reply(msg)
    else:
        reply('Language guessing failed, so try suggesting one!')