forked from zulip/zulip
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathirc-mirror.py
executable file
·142 lines (116 loc) · 4.67 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
129
130
131
132
133
134
135
136
137
138
139
140
141
142
#!/usr/bin/env python
#
# EXPERIMENTAL
# IRC <=> Zulip mirroring bot
#
# Setup: First, you need to install python-irc version 8.5.3
# (https://github.com/jaraco/irc)
from __future__ import print_function
import irc.bot
import irc.strings
from irc.client import ip_numstr_to_quad, ip_quad_to_numstr, Event, ServerConnection
import zulip
import optparse
if False:
from typing import Any, Dict
IRC_DOMAIN = "irc.example.com"
def zulip_sender(sender_string):
# type: (str) -> str
nick = sender_string.split("!")[0]
return nick + "@" + IRC_DOMAIN
class IRCBot(irc.bot.SingleServerIRCBot):
def __init__(self, channel, nickname, server, port=6667):
# type: (irc.bot.Channel, str, str, int) -> None
irc.bot.SingleServerIRCBot.__init__(self, [(server, port)], nickname, nickname)
self.channel = channel # type: irc.bot.Channel
def on_nicknameinuse(self, c, e):
# type: (ServerConnection, Event) -> None
c.nick(c.get_nickname().replace("_zulip", "__zulip"))
def on_welcome(self, c, e):
# type: (ServerConnection, Event) -> None
c.join(self.channel)
def forward_to_irc(msg):
# type: (Dict[str, Any]) -> None
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):
# type: (ServerConnection, Event) -> None
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):
# type: (ServerConnection, Event) -> None
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):
# type: (ServerConnection, Event) -> None
c.privmsg("You said: " + e.arguments[0])
def on_dccchat(self, c, e):
# type: (ServerConnection, Event) -> None
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 = """./irc-mirror.py --server=IRC_SERVER --channel=<CHANNEL> --nick-prefix=<NICK> [optional args]
Example:
./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()