forked from zulip/zulip
-
Notifications
You must be signed in to change notification settings - Fork 0
/
irc-mirror.py
128 lines (104 loc) · 4.19 KB
/
irc-mirror.py
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
#! /usr/bin/env python
#
# EXPERIMENTAL
# IRC <=> Zulip mirroring bot
#
# Setup: First, you need to install python-irc version 8.5.3
# (https://bitbucket.org/jaraco/irc)
import irc.bot
import irc.strings
from irc.client import ip_numstr_to_quad, ip_quad_to_numstr
import zulip
import optparse
IRC_DOMAIN = "irc.example.com"
def zulip_sender(sender_string):
nick = sender_string.split("!")[0]
return nick + "@" + IRC_DOMAIN
class IRCBot(irc.bot.SingleServerIRCBot):
def __init__(self, channel, nickname, server, port=6667):
irc.bot.SingleServerIRCBot.__init__(self, [(server, port)], nickname, nickname)
self.channel = channel
def on_nicknameinuse(self, c, e):
c.nick(c.get_nickname().replace("_zulip", "__zulip"))
def on_welcome(self, c, e):
c.join(self.channel)
def forward_to_irc(msg):
if msg["type"] == "stream":
send = lambda x: c.privmsg(msg["display_recipient"], x)
else:
recipients = [u["short_name"] for u in msg["display_recipient"] if
u["email"] != msg["sender_email"]]
if len(recipients) == 1:
send = lambda x: c.privmsg(recipients[0], x)
else:
send = lambda x: c.privmsg_many(recipients, x)
for line in msg["content"].split("\n"):
send(line)
## Forwarding from Zulip => IRC is disabled; uncomment the next
## line to make this bot forward in that direction instead.
#
# zulip_client.call_on_each_message(forward_to_irc)
def on_privmsg(self, c, e):
content = e.arguments[0]
sender = zulip_sender(e.source)
if sender.endswith("_zulip@" + IRC_DOMAIN):
return
# Forward the PM to Zulip
print zulip_client.send_message({
"sender": sender,
"type": "private",
"to": "[email protected]",
"content": content,
})
def on_pubmsg(self, c, e):
content = e.arguments[0]
stream = e.target
sender = zulip_sender(e.source)
if sender.endswith("_zulip@" + IRC_DOMAIN):
return
# Forward the stream message to Zulip
print zulip_client.send_message({
"forged": "yes",
"sender": sender,
"type": "stream",
"to": stream,
"subject": "IRC",
"content": content,
})
def on_dccmsg(self, c, e):
c.privmsg("You said: " + e.arguments[0])
def on_dccchat(self, c, e):
if len(e.arguments) != 2:
return
args = e.arguments[1].split()
if len(args) == 4:
try:
address = ip_numstr_to_quad(args[2])
port = int(args[3])
except ValueError:
return
self.dcc_connect(address, port)
usage = """python irc-mirror.py --server=IRC_SERVER --channel=<CHANNEL> --nick-prefix=<NICK> [optional args]
Example:
python irc-mirror.py --irc-server=127.0.0.1 --channel='#test' --nick-prefix=username
--site=https://zulip.example.com [email protected]
--api-key=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Note that "_zulip" will be automatically appended to the IRC nick provided
Also note that at present you need to edit this code to do the Zulip => IRC side
"""
if __name__ == "__main__":
parser = optparse.OptionParser(usage=usage)
parser.add_option('--irc-server', default=None)
parser.add_option('--port', default=6667)
parser.add_option('--nick-prefix', default=None)
parser.add_option('--channel', default=None)
parser.add_option_group(zulip.generate_option_group(parser))
(options, args) = parser.parse_args()
if options.irc_server is None or options.nick_prefix is None or options.channel is None:
parser.error("Missing required argument")
# Setting the client to irc_mirror is critical for this to work
options.client = "irc_mirror"
zulip_client = zulip.init_from_options(options)
nickname = options.nick_prefix + "_zulip"
bot = IRCBot(options.channel, nickname, options.irc_server, options.port)
bot.start()