Adding a bit
[apertium.git] / apertium-tools / xchat-modules / translate.py
blobab285827575a0f5d69f4b917c053848c7ec89d21
1 __module_name__ = "translate"
2 __module_version__ = "0.1"
3 __module_description__ = "Uses Apertium to translate users' text"
4 __module_author__ = "Wynand Winterbach <wynand.winterbach@gmail.com"
6 import xchat
7 import dbus
9 active_pairs = set()
11 translator = dbus.Interface(dbus.SessionBus().get_object("org.apertium.mode", "/"), "org.apertium.Translate")
12 info = dbus.Interface(dbus.SessionBus().get_object("org.apertium.info", "/"), "org.apertium.Info")
15 def no_reenter(f):
16 """While the function f is running, it can't be invoked again.
17 Any attempt to invoke it during this period will only return
18 xchat.EAT_NONE.
20 This is used to annotate other functions. We need this if f
21 is triggered by an event x and f itself will trigger event x.
22 Without this protection, and infinite loop will occur.
24 The Beacon class variable set states whether we are busy executing
25 f. If a function wants to execute f, it checks whether the beacon
26 is set. If not, it set it and executes f. Otherwise
27 xchat.EAT_NONE is returned.
28 """
30 class Beacon:
31 set = False
33 def new_func(*args, **kwargs):
34 if not Beacon.set:
35 Beacon.set = True
36 try:
37 ret = f(*args, **kwargs)
38 return ret
40 finally:
41 Beacon.set = False
43 else:
44 return xchat.EAT_NONE
46 return new_func
49 def add_code(num, text):
50 """Add MIRC ^C style 'tags' to a string. A 'tag' is
51 identified by a number (num in this function)."""
52 escape = "\x03"
53 return "".join([escape, str(num), text, escape])
55 def grey(text):
56 return add_code(15, text)
58 def dark_grey(text):
59 return add_code(14, text)
61 @no_reenter
62 def translate(word, word_eol, userdata):
63 """This must be non-reentrable, because it is triggered by the 'Channel Message' event,
64 but will itself trigger this event."""
66 nick, text = word[0:2]
68 xchat.emit_print("Channel Message", nick, text)
70 for pair in active_pairs:
71 #print dark_grey("[%s]" % pair), grey(translator.translate(pair, {}, text))
72 xchat.emit_print("Channel Message", grey("[%s] %s" % (pair, nick)), grey(translator.translate(pair, {}, text)))
74 return xchat.EAT_XCHAT
77 def add_pair(word, word_eol, userdata):
78 if len(word) != 2:
79 print "usage: /add_pair <language_pair"
80 return xchat.EAT_NONE
82 _, pair = word
84 if pair not in info.modes():
85 print "invalid language pair"
86 return xchat.EAT_NONE
88 print "Adding %s" % pair
89 active_pairs.add(pair)
90 return xchat.EAT_NONE
93 def remove_pair(word, word_eol, userdata):
94 try:
95 active_pairs.remove(word[1])
96 print "Removing %s" % word[1]
98 except KeyError:
99 print "No such pair is active"
101 return xchat.EAT_NONE
104 xchat.hook_print("Channel Message", translate)
105 xchat.hook_command("add_pair", add_pair, help="/add_pair <pair> will start using the language pair to translate IRC text")
106 xchat.hook_command("remove_pair", remove_pair, help="/remove_pair <pair> will stop using the language pair to translate IRC text")
108 print "Plugin translate loaded!"