def publish_user(self, sender, userid, headers = None, msg = None, need_ack = MSG_ACK_NONE): '''Publish a message to a user, either generic or specific.''' # TODO many other checks if len(userid) != utils.USERID_LENGTH and len(userid) != utils.USERID_LENGTH_RESOURCE: log.warn("invalid userid format: %s" % userid) # TODO should we throw an exception here? return None if self.config['broker']['reject_unknown_recipients']: # check if user exists # TODO this check should be done over the whole network (?) if not self.storage.get_user_stat(userid) and not self.user_online(userid): log.warn("user %s not found" % userid) return c2s.MessagePostResponse.MessageSent.STATUS_USER_NOTFOUND # prepare message dict msg_id = self.message_id() outmsg = { 'messageid' : msg_id, 'sender' : sender, 'recipient' : userid, 'timestamp' : datetime.utcnow(), 'need_ack' : need_ack, 'headers' : headers, 'payload' : msg } # process message on the next iteration # FIXME is this safe? Check for race conditions reactor.callLater(0, self._usermsg_worker, outmsg) return msg_id
def _format_msg(self, msg): msg['content'] = base64.b64encode(msg['payload']) msg['need_ack'] = (msg['need_ack'] != broker.MSG_ACK_NONE) msg['mime'] = msg['headers']['mime'] msg['flags'] = msg['headers']['flags'] msg['timestamp'] = long(time.mktime(msg['timestamp'].timetuple())) if 'filename' in msg['headers']: msg['url'] = self.broker.config['fileserver']['download_url'] % msg['headers']['filename'] try: (filename, _mime, _md5sum) = self.broker.storage.get_extra(msg['headers']['filename'], self.userid) a.length = os.path.getsize(filename) except: log.warn("attachment not found, unable to send length out") del msg['filename'] # clean private data del msg['payload'] del msg['need_ack'] del msg['headers'] return msg
def publish_user(self, sender, userid, headers=None, msg=None, need_ack=MSG_ACK_NONE): '''Publish a message to a user, either generic or specific.''' # TODO many other checks if len(userid) != utils.USERID_LENGTH and len( userid) != utils.USERID_LENGTH_RESOURCE: log.warn("invalid userid format: %s" % userid) # TODO should we throw an exception here? return None if self.config['broker']['reject_unknown_recipients']: # check if user exists # TODO this check should be done over the whole network (?) if not self.storage.get_user_stat(userid) and not self.user_online( userid): log.warn("user %s not found" % userid) return c2s.MessagePostResponse.MessageSent.STATUS_USER_NOTFOUND # prepare message dict msg_id = self.message_id() outmsg = { 'messageid': msg_id, 'sender': sender, 'recipient': userid, 'timestamp': datetime.utcnow(), 'need_ack': need_ack, 'headers': headers, 'payload': msg } # process message on the next iteration # FIXME is this safe? Check for race conditions reactor.callLater(0, self._usermsg_worker, outmsg) return msg_id
def _incoming_box(self, data, a = None): # TODO check for missing keys # TODO avoid using c2s directly; instead create a method in C2SServerProtocol if not a: a = c2s.NewMessage() a.message_id = data['messageid'] if 'originalid' in data: a.original_id = data['originalid'] a.timestamp = data['timestamp'].strftime('%Y-%m-%d %H:%M:%S') a.sender = data['sender'] a.mime = data['headers']['mime'] a.flags.extend(data['headers']['flags']) a.content = data['payload'] a.need_ack = (data['need_ack'] != broker.MSG_ACK_NONE) if 'filename' in data['headers']: a.url = self.config['fileserver']['download_url'] % data['headers']['filename'] try: (filename, _mime, _md5sum) = self.broker.storage.get_extra(data['headers']['filename'], self.userid) a.length = os.path.getsize(filename) except: log.warn("attachment not found, unable to send length out") return a
def _format_msg(self, msg): msg['content'] = base64.b64encode(msg['payload']) msg['need_ack'] = (msg['need_ack'] != broker.MSG_ACK_NONE) msg['mime'] = msg['headers']['mime'] msg['flags'] = msg['headers']['flags'] msg['timestamp'] = long(time.mktime(msg['timestamp'].timetuple())) if 'filename' in msg['headers']: msg['url'] = self.broker.config['fileserver'][ 'download_url'] % msg['headers']['filename'] try: (filename, _mime, _md5sum) = self.broker.storage.get_extra( msg['headers']['filename'], self.userid) a.length = os.path.getsize(filename) except: log.warn("attachment not found, unable to send length out") del msg['filename'] # clean private data del msg['payload'] del msg['need_ack'] del msg['headers'] return msg
def _incoming_box(self, data, a=None): # TODO check for missing keys # TODO avoid using c2s directly; instead create a method in C2SServerProtocol if not a: a = c2s.NewMessage() a.message_id = data['messageid'] if 'originalid' in data: a.original_id = data['originalid'] a.timestamp = data['timestamp'].strftime('%Y-%m-%d %H:%M:%S') a.sender = data['sender'] a.mime = data['headers']['mime'] a.flags.extend(data['headers']['flags']) a.content = data['payload'] a.need_ack = (data['need_ack'] != broker.MSG_ACK_NONE) if 'filename' in data['headers']: a.url = self.config['fileserver']['download_url'] % data[ 'headers']['filename'] try: (filename, _mime, _md5sum) = self.broker.storage.get_extra( data['headers']['filename'], self.userid) a.length = os.path.getsize(filename) except: log.warn("attachment not found, unable to send length out") return a
def _usermsg_worker(self, msg): userid = msg['recipient'] need_ack = msg['need_ack'] #log.debug("queue data for user %s (need_ack=%s)" % (userid, need_ack)) # generic user, post to every consumer if len(userid) == utils.USERID_LENGTH: try: for resource, q in self._consumers[userid].iteritems(): outmsg = dict(msg) # branch the message :) outmsg['messageid'] = self.message_id() outmsg['originalid'] = msg['messageid'] outmsg['recipient'] += resource # store to disk (if need_ack) if need_ack: try: #log.debug("storing message %s to disk" % outmsg['messageid']) self.storage.deliver(outmsg['recipient'], outmsg) except: # TODO handle errors import traceback traceback.print_exc() # send to client listener q.put(outmsg) except KeyError: #log.debug("warning: no consumer to deliver message to %s" % userid) # store to temporary spool self.storage.store(userid, msg) # send push notifications to all matching users try: # do not push for receipts if self.push_manager and msg['headers']['mime'] != MIME_RECEIPT: self.push_manager.notify_all(userid) except: # TODO notify errors import traceback traceback.print_exc() elif len(userid) == utils.USERID_LENGTH_RESOURCE: uhash, resource = utils.split_userid(userid) # store to disk (if need_ack) if need_ack: try: #log.debug("storing message %s to disk" % msg['messageid']) if 'storage' not in msg: self.storage.store(userid, msg) except: # TODO handle errors import traceback traceback.print_exc() try: # send to client consumer #log.debug("sending message %s to consumer" % msg['messageid']) self._consumers[uhash][resource].put(msg) except: #log.debug("warning: no consumer to deliver message to %s/%s!" % (uhash, resource)) # send push notification try: # do not push for receipts if self.push_manager and msg['headers']['mime'] != MIME_RECEIPT: self.push_manager.notify(userid) except: # TODO notify errors import traceback traceback.print_exc() else: log.warn("warning: unknown userid format %s" % userid)
def _usermbox_worker(self, mbox): ''' Processes a bunch of messages to be sent massively to recipients. This takes every message and put it in different lists to be delivered to their respective channels - if available. TODO this method is used only to requeue messages on login, so we can take something for granted, e.g. userid will be the same for every message, push notifications are not needed, ... ''' outbox = {} for msg in mbox: userid = msg['recipient'] need_ack = msg['need_ack'] #log.debug("queue data for user %s (need_ack=%s)" % (userid, need_ack)) # generic user, post to every consumer if len(userid) == utils.USERID_LENGTH: try: for resource, q in self._consumers[userid].iteritems(): outmsg = dict(msg) # branch the message :) outmsg['messageid'] = self.message_id() outmsg['originalid'] = msg['messageid'] outmsg['recipient'] += resource # store to disk (if need_ack) if need_ack: try: #log.debug("storing message %s to disk" % outmsg['messageid']) self.storage.deliver(outmsg['recipient'], outmsg) except: # TODO handle errors import traceback traceback.print_exc() # keep in outbox if outmsg['recipient'] not in outbox: outbox[outmsg['recipient']] = [] outbox[outmsg['recipient']].append(outmsg) except KeyError: #log.debug("warning: no consumer to deliver message to %s" % userid) # store to temporary spool self.storage.store(userid, msg) # send push notifications to all matching users try: # do not push for receipts if self.push_manager and msg['headers']['mime'] != MIME_RECEIPT: self.push_manager.notify_all(userid) except: # TODO notify errors import traceback traceback.print_exc() elif len(userid) == utils.USERID_LENGTH_RESOURCE: uhash, resource = utils.split_userid(userid) # store to disk (if need_ack) if need_ack: try: #log.debug("storing message %s to disk" % msg['messageid']) if 'storage' not in msg: self.storage.store(userid, msg) except: # TODO handle errors import traceback traceback.print_exc() # keep in outbox if userid not in outbox: outbox[userid] = [] outbox[userid].append(msg) else: log.warn("warning: unknown userid format %s" % userid) for userid, msglist in outbox.iteritems(): uhash, resource = utils.split_userid(userid) try: # send to client consumer #log.debug("sending message %s to consumer" % msg['messageid']) self._consumers[uhash][resource].put(msglist) except: #log.debug("warning: no consumer to deliver message to %s/%s!" % (uhash, resource)) # send push notification try: # do not push for receipts receipt_found = False for msg in msglist: if msg['headers']['mime'] == MIME_RECEIPT: receipt_found = True break if self.push_manager and not receipt_found: self.push_manager.notify(userid) except: # TODO notify errors import traceback traceback.print_exc()
def _usermsg_worker(self, msg): userid = msg['recipient'] need_ack = msg['need_ack'] #log.debug("queue data for user %s (need_ack=%s)" % (userid, need_ack)) # generic user, post to every consumer if len(userid) == utils.USERID_LENGTH: try: for resource, q in self._consumers[userid].iteritems(): outmsg = dict(msg) # branch the message :) outmsg['messageid'] = self.message_id() outmsg['originalid'] = msg['messageid'] outmsg['recipient'] += resource # store to disk (if need_ack) if need_ack: try: #log.debug("storing message %s to disk" % outmsg['messageid']) self.storage.deliver(outmsg['recipient'], outmsg) except: # TODO handle errors import traceback traceback.print_exc() # send to client listener q.put(outmsg) except KeyError: #log.debug("warning: no consumer to deliver message to %s" % userid) # store to temporary spool self.storage.store(userid, msg) # send push notifications to all matching users try: # do not push for receipts if self.push_manager and msg['headers'][ 'mime'] != MIME_RECEIPT: self.push_manager.notify_all(userid) except: # TODO notify errors import traceback traceback.print_exc() elif len(userid) == utils.USERID_LENGTH_RESOURCE: uhash, resource = utils.split_userid(userid) # store to disk (if need_ack) if need_ack: try: #log.debug("storing message %s to disk" % msg['messageid']) if 'storage' not in msg: self.storage.store(userid, msg) except: # TODO handle errors import traceback traceback.print_exc() try: # send to client consumer #log.debug("sending message %s to consumer" % msg['messageid']) self._consumers[uhash][resource].put(msg) except: #log.debug("warning: no consumer to deliver message to %s/%s!" % (uhash, resource)) # send push notification try: # do not push for receipts if self.push_manager and msg['headers'][ 'mime'] != MIME_RECEIPT: self.push_manager.notify(userid) except: # TODO notify errors import traceback traceback.print_exc() else: log.warn("warning: unknown userid format %s" % userid)
def _usermbox_worker(self, mbox): ''' Processes a bunch of messages to be sent massively to recipients. This takes every message and put it in different lists to be delivered to their respective channels - if available. TODO this method is used only to requeue messages on login, so we can take something for granted, e.g. userid will be the same for every message, push notifications are not needed, ... ''' outbox = {} for msg in mbox: userid = msg['recipient'] need_ack = msg['need_ack'] #log.debug("queue data for user %s (need_ack=%s)" % (userid, need_ack)) # generic user, post to every consumer if len(userid) == utils.USERID_LENGTH: try: for resource, q in self._consumers[userid].iteritems(): outmsg = dict(msg) # branch the message :) outmsg['messageid'] = self.message_id() outmsg['originalid'] = msg['messageid'] outmsg['recipient'] += resource # store to disk (if need_ack) if need_ack: try: #log.debug("storing message %s to disk" % outmsg['messageid']) self.storage.deliver(outmsg['recipient'], outmsg) except: # TODO handle errors import traceback traceback.print_exc() # keep in outbox if outmsg['recipient'] not in outbox: outbox[outmsg['recipient']] = [] outbox[outmsg['recipient']].append(outmsg) except KeyError: #log.debug("warning: no consumer to deliver message to %s" % userid) # store to temporary spool self.storage.store(userid, msg) # send push notifications to all matching users try: # do not push for receipts if self.push_manager and msg['headers'][ 'mime'] != MIME_RECEIPT: self.push_manager.notify_all(userid) except: # TODO notify errors import traceback traceback.print_exc() elif len(userid) == utils.USERID_LENGTH_RESOURCE: uhash, resource = utils.split_userid(userid) # store to disk (if need_ack) if need_ack: try: #log.debug("storing message %s to disk" % msg['messageid']) if 'storage' not in msg: self.storage.store(userid, msg) except: # TODO handle errors import traceback traceback.print_exc() # keep in outbox if userid not in outbox: outbox[userid] = [] outbox[userid].append(msg) else: log.warn("warning: unknown userid format %s" % userid) for userid, msglist in outbox.iteritems(): uhash, resource = utils.split_userid(userid) try: # send to client consumer #log.debug("sending message %s to consumer" % msg['messageid']) self._consumers[uhash][resource].put(msglist) except: #log.debug("warning: no consumer to deliver message to %s/%s!" % (uhash, resource)) # send push notification try: # do not push for receipts receipt_found = False for msg in msglist: if msg['headers']['mime'] == MIME_RECEIPT: receipt_found = True break if self.push_manager and not receipt_found: self.push_manager.notify(userid) except: # TODO notify errors import traceback traceback.print_exc()