Skip to content

Commit

Permalink
jabber_mirror: Dynamically join and leave MUCs
Browse files Browse the repository at this point in the history
For personal mirrors, this means that the mirror should join all Jabber rooms
corresponding to their Zulip subscriptions.  For the public mirror, this means
that the mirror should join all Jabber rooms corresponding to Zulip streams that
end in "/xmpp".

(imported from commit 16ed9e3deee7e02b2ae0dd79925f0ed5c4acd044)
  • Loading branch information
zbenjamin committed Mar 3, 2014
1 parent 814aed7 commit 9634fcc
Showing 1 changed file with 70 additions and 23 deletions.
93 changes: 70 additions & 23 deletions bots/jabber_mirror.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ def room_to_stream(room):
return str(room).rpartition("@")[0] + "/xmpp"

def stream_to_room(stream):
return stream.rpartition("/xmpp")[0]
return stream.lower().rpartition("/xmpp")[0]

def jid_to_zulip(jid):
return "%s@%s" % (str(jid).rpartition("@")[0], options.zulip_domain)
Expand All @@ -64,7 +64,8 @@ def __init__(self, nick, domain, password, rooms, openfire=False):
jid = "%s@%s/jabber_mirror" % (nick, domain)
ClientXMPP.__init__(self, jid, password)
self.password = password
self.rooms = rooms
self.rooms = set()
self.rooms_to_join = rooms
self.add_event_handler("session_start", self.session_start)
self.add_event_handler("message", self.message)
self.password = password
Expand All @@ -85,9 +86,24 @@ def set_zulip_client(self, client):
def session_start(self, event):
self.get_roster()
self.send_presence()
for room in self.rooms:
muc_jid = room + "@" + options.conference_domain
self.plugin['xep_0045'].joinMUC(muc_jid, self.nick)
for room in self.rooms_to_join:
self.join_muc(room)

def join_muc(self, room):
if room in self.rooms:
return
logging.debug("Joining " + room)
self.rooms.add(room)
muc_jid = room + "@" + options.conference_domain
self.plugin['xep_0045'].joinMUC(muc_jid, self.nick)

def leave_muc(self, room):
if room not in self.rooms:
return
logging.debug("Leaving " + room)
self.rooms.remove(room)
muc_jid = room + "@" + options.conference_domain
self.plugin['xep_0045'].leaveMUC(muc_jid, self.nick)

def message(self, msg):
try:
Expand Down Expand Up @@ -154,19 +170,23 @@ def __init__(self, zulip_client):
def set_jabber_client(self, client):
self.jabber = client

def process_message(self, event):
try:
if event['type'] != 'message':
return
def process_event(self, event):
if event['type'] == 'message':
message = event["message"]
if message['sender_email'] != self.client.email:
return
if message['type'] == 'stream':
self.stream_message(message)
elif message['type'] == 'private':
self.private_message(message)
except:
logging.exception("Exception forwarding Zulip => Jabber")

try:
if message['type'] == 'stream':
self.stream_message(message)
elif message['type'] == 'private':
self.private_message(message)
except:
logging.exception("Exception forwarding Zulip => Jabber")
elif event['type'] == 'subscription':
self.process_subscription(event)
elif event['type'] == 'stream':
self.process_stream(event)

def stream_message(self, msg):
stream = msg['display_recipient']
Expand Down Expand Up @@ -196,6 +216,30 @@ def private_message(self, msg):
outgoing['thread'] = u'\u1B80'
outgoing.send()

def process_subscription(self, event):
if event['op'] == 'add':
streams = [s['name'].lower() for s in event['subscriptions']]
streams = [s for s in streams if s.endswith("/xmpp")]
for stream in streams:
self.jabber.join_muc(stream_to_room(stream))
if event['op'] == 'remove':
streams = [s['name'].lower() for s in event['subscriptions']]
streams = [s for s in streams if s.endswith("/xmpp")]
for stream in streams:
self.jabber.leave_muc(stream_to_room(stream))

def process_stream(self, event):
if event['op'] == 'occupy':
streams = [s['name'].lower() for s in event['streams']]
streams = [s for s in streams if s.endswith("/xmpp")]
for stream in streams:
self.jabber.join_muc(stream_to_room(stream))
if event['op'] == 'vacate':
streams = [s['name'].lower() for s in event['streams']]
streams = [s for s in streams if s.endswith("/xmpp")]
for stream in streams:
self.jabber.leave_muc(stream_to_room(stream))

def get_rooms(zulip):
if options.mode == 'public':
stream_infos = zulip.client.get_streams()['streams']
Expand Down Expand Up @@ -286,13 +330,16 @@ def get_rooms(zulip):
xmpp.set_zulip_client(zulip)
zulip.set_jabber_client(xmpp)

xmpp.process(block=False)
if options.mode == 'public':
xmpp.process(block=True)
event_types = ['stream']
else:
xmpp.process(block=False)
try:
logging.info("Connecting to Zulip.")
zulip.client.call_on_each_event(zulip.process_message)
except BaseException as e:
logging.exception("Exception in main loop")
xmpp.abort()
event_types = ['message', 'subscription']

try:
logging.info("Connecting to Zulip.")
zulip.client.call_on_each_event(zulip.process_event,
event_types=event_types)
except BaseException as e:
logging.exception("Exception in main loop")
xmpp.abort()

0 comments on commit 9634fcc

Please sign in to comment.