def render_POST(self, request): segmentCount = len(request.postpath) if segmentCount != 1: return self._epilogue(request, defer.fail(errors.NotFoundError())) action = request.postpath[0] requestDeferred = utils.getValidEntityId(request, "id", "user") myId = request.getSession(IAuthInfo).username def callback((targetId, target)): actionDeferred = None if action == "follow": actionDeferred = self._follow(myId, targetId) elif action == "unfollow": actionDeferred = self._unfollow(myId, targetId) elif action == "report": actionDeferred = self._reportUser(request, myId, targetId) else: raise errors.NotFoundError() relation = Relation(myId, [targetId]) data = {"relations": relation} def fetchRelations(ign): return relation.initSubscriptionsList() isProfile = (utils.getRequestArg(request, "_pg") == "/profile") isFeed = utils.getRequestArg(request, "_pg").startswith("/feed/") isPeople = (utils.getRequestArg(request, "_pg") == "/people") def renderActions(ign): if isFeed: d = people.get_suggestions(request, constants.SUGGESTION_PER_PAGE, mini=True) def renderSuggestion(res): suggestions, entities = res t.renderScriptBlock(request, "feed.mako", "_suggestions", False, "#suggestions", "set", True, relations = relation, suggestions = suggestions, entities=entities) d.addCallback(renderSuggestion) return d else: t.renderScriptBlock(request, "profile.mako", "user_actions", False, "#user-actions-%s"%targetId, "set", args=[targetId, True], **data) return defer.succeed([]) actionDeferred.addCallback(fetchRelations) actionDeferred.addCallback(renderActions) return actionDeferred requestDeferred.addCallback(callback) return self._epilogue(request, requestDeferred)
def _events(self, request): (appchange, script, args, myId) = yield self._getBasicArgs(request) landing = not self._ajax page = utils.getRequestArg(request, 'page') or '1' entityId = utils.getRequestArg(request, 'id') or myId view = utils.getRequestArg(request, 'view') or "agenda" authinfo = request.getSession(IAuthInfo) myOrgId = authinfo.organization start = utils.getRequestArg(request, 'start') or "" #Check if entity Id is my Org or a group that I have access to. if entityId != myId and entityId != myOrgId: yield utils.getValidEntityId(request, "id", "group") if view == "invitations": entityId = "%s:%s" %(myId, "I") if page.isdigit(): page = int(page) else: page = 1 count = constants.EVENTS_PER_PAGE try: start = datetime.datetime.strptime(start, "%Y-%m-%d") except ValueError: start = None args.update({'view':view, 'menuId': 'events'}) args.update({'page':page, 'entityId': entityId}) if script and landing: t.render(request, "event.mako", **args) if script and appchange: t.renderScriptBlock(request, "event.mako", "layout", landing, "#mainbar", "set", **args) yield event.fetchMatchingEvents(request, args, entityId, count=count, start=start) if script: onload = """ $$.menu.selectItem('events'); $$.events.prepareAgendaDatePicker('%s') """ % (args["start"]) t.renderScriptBlock(request, 'event.mako', "render_events", landing, ".center-contents", "set", True, handlers={"onload": onload}, **args) else: t.render(request, "event.mako", **args)
def _render(self, request): (appchange, script, args, myId) = yield self._getBasicArgs(request) # We are setting an empty value to 'cu' here just to make sure that # any errors when looking validating the entity should not leave us # in a bad state. request.addCookie('cu', '', path="/ajax/profile") if request.args.get("id", None): userId, ign = yield utils.getValidEntityId(request, "id", "user") else: userId = myId # XXX: We should use getValidEntityId to fetch the entire user # info instead of another call to the database. request.addCookie('cu', userId, path="/ajax/profile") user = base.Entity(userId) yield user.fetchData([]) if user._data: args['user'] = user detail = utils.getRequestArg(request, "dt") or "activity" args["detail"] = detail args["userId"] = userId args["menuId"] = "people" args["entities"] = base.EntitySet({myId:args['me'], userId:user}) # When scripts are enabled, updates are sent to the page as # and when we get the required data from the database. # When we are the landing page, we also render the page header # and all updates are wrapped in <script> blocks. landing = not self._ajax # User entered the URL directly # Render the header. Other things will follow. if script and landing: t.render(request, "profile.mako", **args) # Start with displaying the template and navigation menu if script and appchange: t.renderScriptBlock(request, "profile.mako", "layout", landing, "#mainbar", "set", **args) # Prefetch some data about how I am related to the user. # This is required in order to reliably filter our profile details # that I don't have access to. relation = Relation(myId, [userId]) args["relations"] = relation yield defer.DeferredList([relation.initSubscriptionsList(), relation.initGroupsList()]) # Reload all user-depended blocks if the currently displayed user is # not the same as the user for which new data is being requested. if script: t.renderScriptBlock(request, "profile.mako", "summary", landing, "#profile-summary", "set", **args) t.renderScriptBlock(request, "profile.mako", "user_subactions", landing, "#user-subactions", "set", **args) fetchedEntities = set() start = utils.getRequestArg(request, "start") or '' fromFetchMore = ((not landing) and (not appchange) and start) if detail == "activity": userItems = yield self._getUserItems(request, userId, start=start) args.update(userItems) elif detail == 'files': end = utils.getRequestArg(request, "end") or '' end = utils.decodeKey(end) start = utils.decodeKey(start) userFiles = yield files.userFiles(myId, userId, args['orgId'], start, end, fromFeed=False) args['userfiles'] = userFiles args['fromProfile'] = True if script: t.renderScriptBlock(request, "profile.mako", "tabs", landing, "#profile-tabs", "set", **args) handlers = {} if detail != "activity" \ else {"onload": "(function(obj){$$.convs.load(obj);})(this);"} if fromFetchMore and detail == "activity": t.renderScriptBlock(request, "profile.mako", "content", landing, "#next-load-wrapper", "replace", True, handlers=handlers, **args) else: t.renderScriptBlock(request, "profile.mako", "content", landing, "#profile-content", "set", True, handlers=handlers, **args) # List the user's subscriptions cols = yield db.get_slice(userId, "subscriptions", count=11) subscriptions = set(utils.columnsToDict(cols).keys()) args["subscriptions"] = subscriptions # List the user's followers cols = yield db.get_slice(userId, "followers", count=11) followers = set(utils.columnsToDict(cols).keys()) args["followers"] = followers # Fetch item data (name and avatar) for subscriptions, followers, # user groups and common items. entitiesToFetch = followers.union(subscriptions)\ .difference(fetchedEntities) # List the user's groups (and look for groups common with me) cols = yield db.multiget_slice([myId, userId], "entityGroupsMap") myGroups = set([x.column.name.split(':', 1)[1] for x in cols[myId]]) userGroups = set([x.column.name.split(':', 1)[1] for x in cols[userId]]) commonGroups = myGroups.intersection(userGroups) if len(userGroups) > 10: userGroups = sample(userGroups, 10) args["userGroups"] = userGroups args["commonGroups"] = commonGroups groupsToFetch = commonGroups.union(userGroups) entitiesToFetch = entitiesToFetch.union(groupsToFetch) entities = base.EntitySet(entitiesToFetch) yield entities.fetchData() for entityId, entity in entities.items(): if not entity._data: del entities[entityId] args["entities"].update(entities) if script: t.renderScriptBlock(request, "profile.mako", "user_subscriptions", landing, "#user-subscriptions", "set", **args) t.renderScriptBlock(request, "profile.mako", "user_followers", landing, "#user-followers", "set", **args) t.renderScriptBlock(request, "profile.mako", "user_me", landing, "#user-me", "set", **args) t.renderScriptBlock(request, "profile.mako", "user_groups", landing, "#user-groups", "set", **args) if script and landing: request.write("</body></html>") if not script: t.render(request, "profile.mako", **args)
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