def updateAndPublishStatus(userId, orgId, sessionId, status, user=None): # Check if there is a change in the online status results = yield db.get_slice(orgId, 'presence', super_column=userId) results = utils.columnsToDict(results) oldPublishedStatus = getMostAvailablePresence(results.values()) # Update the online status if status != 'offline': yield db.insert(orgId, 'presence', status, sessionId, userId) else: yield db.remove(orgId, 'presence', sessionId, userId) # If status changed broadcast the change # XXX: Currently everyone on the network will get the presence update. # This will not scale well with big networks results[sessionId] = status newPublishedStatus = getMostAvailablePresence(results.values()) if oldPublishedStatus != newPublishedStatus: if not user: user = base.Entity(userId) yield user.fetchData() data = {"userId": userId, 'status': newPublishedStatus, 'name': user.basic['name'], 'title': user.basic['jobTitle'], 'avatar': utils.userAvatar(userId, user, 's')} yield comet.publish('/presence/' + orgId, data)
def _postChat(self, request): comment = utils.getRequestArg(request, 'message') channelId = utils.getRequestArg(request, 'room') if not comment: # Ignore empty comment return authInfo = request.getSession(IAuthInfo) myId = authInfo.username orgId = authInfo.organization timeuuid = uuid.uuid1().bytes recipientId, recipient = yield utils.getValidEntityId(request, 'to') me = base.Entity(myId) yield me.fetchData() myName = me.basic['name'] myAvatar = utils.userAvatar(myId, me, 's') chatId = utils.getUniqueKey() sessionId = request.getCookie('session') try: col = yield db.get(orgId, 'presence', sessionId, myId) except ttypes.NotFoundException: self.setResponseCodeAndWrite(request, 200, {'error': 'You are currently offline'}) return cols = yield db.get_slice(orgId, "presence", super_column=recipientId) recipientStatus = getMostAvailablePresence( utils.columnsToDict(cols).values()) if recipientStatus == PresenceStates.OFFLINE: self.setResponseCodeAndWrite(request, 200, {'error': 'Cannot send message. User is currently offline'}) return message = {"from": myName, "to": recipientId, "message": comment, "timestamp": time.time(), "avatar": myAvatar} data = {"type": "room", "from": myId, "to": recipientId, "message": message} if channelId: channelSubscribers = yield db.get_slice(channelId, 'channelSubscribers') channelSubscribers = utils.columnsToDict(channelSubscribers) channelSubscribers = set([x.split(':', 1)[0] \ for x in channelSubscribers]) if myId not in channelSubscribers: self.setResponseCodeAndWrite(request, 200, {'error': 'Access denied'}) return yield db.insert(channelId, 'channelSubscribers', '', '%s:%s'\ % (myId, sessionId)) yield db.insert("%s:%s" % (myId, sessionId), "sessionChannelsMap", '', channelId) data["room"] = channelId startKey = '%s:' % recipientId cols = yield db.get_slice(channelId, "channelSubscribers", start=startKey, count=1) count = len([col for col in cols \ if col.column.name.startswith(startKey)]) try: yield comet.publish('/chat/%s' % (channelId), message) if not count: yield comet.publish('/notify/%s' % (recipientId), data) except Exception, e: self.setResponseCodeAndWrite(request, 200, {'error': 'The message could not be sent!'}) return
start=startKey, count=1) count = len([col for col in cols \ if col.column.name.startswith(startKey)]) try: yield comet.publish('/chat/%s' % (channelId), message) if not count: yield comet.publish('/notify/%s' % (recipientId), data) except Exception, e: self.setResponseCodeAndWrite(request, 200, {'error': 'The message could not be sent!'}) return else: channelId = utils.getUniqueKey() data['room'] = channelId try: yield comet.publish('/notify/%s' % (myId), data) yield comet.publish('/notify/%s' % (recipientId), data) except Exception, e: self.setResponseCodeAndWrite(request, 200, {'error': 'The message could not be sent!'}) return yield db.insert(channelId, 'channelSubscribers', '', myId) yield db.insert(channelId, 'channelSubscribers', '', recipientId) channelSubscribers = set([myId, recipientId]) start = utils.uuid1(timestamp=time.time() - 3600).bytes cols = yield db.get_slice(myId, 'chatArchiveList', start=start, ) chatIds = [col.column.value for col in cols] participants = yield db.multiget_slice(chatIds, "chatParticipants") participants = utils.multiColumnsToDict(participants)