Source

openju / openju / message_bus.py

Full commit
#!/usr/bin/python
# -*- coding: utf-8 -*-

import xmpp
from mongoengine.queryset import DoesNotExist

# from openju.util import none_or_int
from openju import g
from openju import current_app as app
from openju.validators import UserAlertError
from openju.routes import *

def error_handler(f):
    def new_f(conn, *args, **kw):
        try:
            f(conn, *args, **kw)
        except UserAlertError, e:
            conn.send(xmpp.Message(g.xmpp_user, unicode(e)))
    return new_f

def auth_user(user_jid):
    from openju.model import User
    try:
        return User.objects.get(jid=user_jid)
    except DoesNotExist:
        return  None

@error_handler
def message_bus(conn, mess):
    """ kind a routing thing """
    
    text = mess.getBody()
    xmpp_user = mess.getFrom()
    user_jid = u'%(node)s@%(domain)s' % dict(
        node=xmpp_user.getNode(),
        domain=xmpp_user.getDomain())
    if text is not None: # don't know why, but sometimes it's None. TODO: debug it
        def dispatch(xmpp_user):
            def call_list(*f_list):
                for f in f_list:
                    res = f(text)
                    if isinstance(res, unicode):
                        conn.send(xmpp.Message(xmpp_user, res))
                    if res is not None:
                        return
            
            call_list(
                cmd_register,
                cmd_last_messages,
                cmd_last_messages_from_friends,
                cmd_read_message,
                cmd_read_message_with_replies,
                cmd_post_reply,
                cmd_user_info,
                cmd_user_messages,
                cmd_subscribe,
                cmd_post_message,
                )
        
        # should be only place to put some g-stuff
        g.xmpp_user = xmpp_user
        g.text = text
        g.user_jid = user_jid
        
        g.auth_user = auth_user(user_jid)
        dispatch(xmpp_user)
        notify_logic(xmpp_user)
        g.auth_user = None
        g.user_jid = None

def presence_bus(conn, mess):
    xmpp_user = mess.getFrom()
    user_jid = u'%(node)s@%(domain)s' % dict(
        node=xmpp_user.getNode(),
        domain=xmpp_user.getDomain())
    g.auth_user = auth_user(user_jid)
    if mess.getType() == 'subscribe':
        g.xmpp_cli.Roster.Authorize(user_jid)
    
    # ask for subscription
    if xmpp_user not in g.xmpp_cli.Roster.getItems():
        g.xmpp_cli.Roster.Subscribe(user_jid)

    if mess.getName() == 'presence' and \
       g.auth_user is not None:
        notify_logic(xmpp_user)
    g.auth_user = None

def notify_logic(xmpp_user):
    from openju import bl
    
    def filter_empty(l):
        return (x for x in l if x is not None)
    
    def process_notification(notification):
        from openju.controllers import notify
        action = getattr(notify, notification.action, None)
        if action is not None:
            res = action(notification.user, notification.info)
            notification.delete()
            if res is not None:
                return res
        else:
            app.logger.exception(
                Exception(u'Notification action %s not found (not implemented, eh?)' % action))
    
    notifications = bl.notify.get_notifications()
    for notification in notifications:
        msg = process_notification(notification)
        if msg:
            g.xmpp_cli.send(
                xmpp.Message(
                    xmpp.JID(notification.user.jid),
                    msg))
    
    # def process_notifications(notifications):
    #     def process_notification(notification):
    #         from openju.controllers import notify
    #         action = getattr(notify, notification.action, None)
    #         if action is not None:
    #             res = action(notification.user, notification.info)
    #             notification.delete()
    #             if res is not None:
    #                 return res
    #         else:
    #             app.logger.exception(
    #                 Exception(u'Notification action %s not found' % action))

    #     return (process_notification(x) for x in notifications)

    # if g.auth_user is not None:
    #     notify_text = (
    #         u"\n\n"
    #         .join(
    #             filter_empty(
    #                 process_notifications(
    #                     g.auth_user.get_notifications()))))
    #     if notify_text:
    #         import ipdb; ipdb.set_trace()
    #         g.xmpp_cli.send(xmpp.Message(xmpp_user, unicode(notify_text)))