Exemple #1
0
class EventDispatcher(object):
    def __init__(self, mysql, cassandra, user_server):
        self.user_server = user_server
        self.mysql = mysql
        self.cassandra = cassandra
        self.mailer = Mailer(mysql)
        logging.info('Initializing event dispatcher')

    def __call__(self, frame):
        action = frame['action']
        data = frame['data']

        if action == 'tap.new':
            self.on_new_message(action, data)
        elif action == 'tap.delete':
            self.on_delete_message(action, data)
        elif action == 'response.new':
            self.on_new_response(action, data)
        elif action == 'group.follow':
            gid, uid, status = map(int, [data['group_id'], data['user_id'], data['status']])
            self.on_group_follow(gid, uid, status)
        elif action == 'convo.follow':
            mid, uid, status = map(int, [data['message_id'], data['user_id'], data['status']])
            self.on_convo_follow(mid, uid, status)
        elif action == 'response.typing':
            self.user_server.send_to(action, data, convo = int(data['cid']))
        elif action == 'user.follow':
            uid, fid, status = map(int, [data['who'], data['whom'], data['status']])
            unrecieved = self.user_server.send_to(action, data, users = set([fid]))
            if unrecieved or not status:
                self.on_user_follow(uid, fid, status)
        elif action == 'event.delete':
            self.on_delete_event(action, data)
        elif action == 'event.delete.all':
            self.on_delete_event(action, data, all = True)
        elif action == 'mention.new':
            self.on_mention_new(action, data)
        else:
            logging.warning('Unknow event! %s: %s' (action, data))

    def on_new_message(self, action, message):
        "New message handler"
        sender, group, private, reciever = intcast(message['sender_id'], 
            message['group_id'], message['private'], message['reciever_id'])

        if reciever is not None:
            recievers = {'users': set([sender, reciever])}
        else: 
            recievers = {'users': self.group_users(group)}
            if not private:
                recievers['group'] = group

        unrecieved = self.user_server.send_to(action, message, **recievers)
        unrecieved = unrecieved if not private else recievers 
        if unrecieved:
            self.on_unrecieved_message(int(message['id']), unrecieved, data = message)

    def group_users(self, group):
        users = self.cassandra.get('group_members', group)
        return set(users) if users else set()

    def on_new_response(self, action, response):
        rid, mid, timestamp = map(int, [response['id'], response['message_id'], response['timestamp']])
        self.touch_message(mid, timestamp)

        unrecieved = self.user_server.send_to(action, response, 
                        users = self.convo_followers(mid), convo = mid)
        if unrecieved:
            self.on_unrecieved_response(mid, rid, unrecieved, data = response)
            
    def touch_message(self, mid, timestamp):
        "Update message timestamp to reply timestamp"
        sql = "UPDATE message SET modification_time = FROM_UNIXTIME(%i) WHERE id = %i" % (timestamp, mid)
        self.mysql.cursor().execute(sql)
        self.mysql.commit()

    def convo_followers(self, convo):
        return set(self.cassandra.get('convo_followers', convo))

    def on_group_follow(self, group, user, status):
        if status:
            self.cassandra.insert('group_members', group, {user: user})
            self.cassandra.insert('inverted_members', user, {group: group})
        else:
            self.cassandra.remove('group_members', group, columns=[user])
            self.cassandra.remove('inverted_members', user, columns=[group])

        if status:
            unrecieved = self.user_server.send_to('member.new', {'group_id': group, 'user_id': user, 'status': status}, 
                        users = self.group_users(group))
            if unrecieved:
                self.mailer.queue(unrecieved, 'new_member', user_id = user, group_id = group)

    def on_convo_follow(self, message, user, status):
        if status:
            self.cassandra.insert('convo_followers', message, {user: user})
        else:
            self.cassandra.remove('convo_followers', message, columns=[user])

    def on_unrecieved_message(self, message, users, data = None):
        "Adds message to events queue for each user"
        joined = (', 0, %i),(' % message).join(map(str, users))
        sql = 'INSERT IGNORE INTO events (user_id, type, related_id) VALUES (%s, 0, %i)' % (joined, message)
        self.mysql.cursor().execute(sql)
        self.mysql.commit()

        type = 'new_personal' if data['reciever_id'] is not None else 'new_message'
        self.mailer.queue(users, type, message_id = data['id'], 
            group_id = data['group_id'], user_id = data['sender_id'])

    def on_unrecieved_response(self, message, reply, users, data = None):
        "Insert new reply event or update every event to +1"
        
        joined = (', 1, %i, %i, 1),(' % (message, reply)).join(map(str, users))
        sql = 'INSERT INTO events (user_id, type, related_id, addit_id, new_replies) VALUES (%s, 1, %i, %i, 1)' % (joined, message, reply) + \
              'ON DUPLICATE KEY UPDATE new_replies = new_replies + 1, addit_id = VALUES(addit_id)'
        self.mysql.cursor().execute(sql)
        self.mysql.commit()

        self.mailer.queue(users, 'new_reply', message_id = data['message_id'], 
            user_id = data['user_id'], reply_id = data['id'])

    def on_user_follow(self, user, friend, status):
        "Updates events on user following/unfollowing"
        sql = ''
        if status:
            sql = 'INSERT IGNORE INTO events (user_id, type, related_id) VALUES (%i, 2, %i)' % (friend, user)
        else:
            sql = 'DELETE FROM events WHERE user_id = %i AND type = 2 AND related_id = %i' % (friend, user)
        self.mysql.cursor().execute(sql)
        self.mysql.commit()

        if status:
            self.mailer.queue(friend, 'new_follower', user_id = user)

    def on_delete_message(self, action, message):
        "Delete message from events queue and cassandra tables"
        cid = int(message['id'])
        sql = 'DELETE FROM events WHERE related_id = %i' % cid
        self.mysql.cursor().execute(sql)
        self.mysql.commit()

        self.cassandra.remove('convo_followers', cid)

        self.user_server.send_to(action, message, convo = cid)

    def on_delete_event(self, action, event, all = False):
        "Delete event by type"
        uid, type, id = intcast(event['user_id'], event['type'], event['event_id'])
        if uid is None:
            return

        where = 'WHERE user_id = %i' % uid
        if not all:
            where += ' AND related_id = %i' % id
            where += ' AND type IN (0, 1)' if type in (0, 1) else (' AND type = %i' % type)

        sql = 'DELETE FROM events %s' % where
        self.mysql.cursor().execute(sql)
        self.mysql.commit()

        self.user_server.send_to(action, event, users = set([uid]))

    def on_mention_new(self, action, data):
        "Add 'mention' events to queue and send emails"
        uid, mid, sid = intcast(data['uid'], data['mid'], data['sid'])

        if uid == sid:
            return

        self.user_server.send_to(action, data, users = set([sid]))

        self.mailer.queue(uid, 'mention', message_id = mid, user_id = sid)
Exemple #2
0
 def __init__(self, mysql, cassandra, user_server):
     self.user_server = user_server
     self.mysql = mysql
     self.cassandra = cassandra
     self.mailer = Mailer(mysql)
     logging.info('Initializing event dispatcher')
Exemple #3
0
import asyncio
import websockets
import threading
from Mail import Mailer

lock = threading.RLock()
mailer = Mailer()


def write_in_file(message):
    base_file = open('logs.txt', 'a')
    base_file.write(message + "\n")


async def mark(websocket, path):
    async for message in websocket:
        with lock:
            write_in_file(message)
            mailer.send_mail(message)


def main():
    start_server = websockets.serve(mark, "localhost", 8080)
    asyncio.get_event_loop().run_until_complete(start_server)
    asyncio.get_event_loop().run_forever()


if __name__ == "__main__":
    main()