def _listPresetTags(self, request): (appchange, script, args, myId) = yield self._getBasicArgs(request) orgId = args["orgId"] landing = not self._ajax args['title'] = 'Preset Tags' args['menuId'] = 'tags' args["viewType"] = "tags" if script and landing: t.render(request, "admin.mako", **args) if script and appchange: t.renderScriptBlock(request, "admin.mako", "layout", landing, "#mainbar", "set", **args) presetTags = yield db.get_slice(orgId, "orgPresetTags", count=100) presetTags = utils.columnsToDict(presetTags, ordered=True).values() if presetTags: tags_ = yield db.get_slice(orgId, "orgTags", presetTags) tags_ = utils.supercolumnsToDict(tags_) else: tags_ = {} args['tagsList'] = presetTags args['tags'] = tags_ if script: t.renderScriptBlock(request, "admin.mako", "list_tags", landing, "#content", "set", **args) if not script: t.render(request, "admin.mako", **args)
def getLatestCounts(request, asJSON=True): authinfo = yield defer.maybeDeferred(request.getSession, IAuthInfo) myId = authinfo.username myOrgId = authinfo.organization latest = yield db.get_slice(myId, "latest") latest = supercolumnsToDict(latest) counts = dict([(key, len(latest[key])) for key in latest]) # Default keys for which counts should be set defaultKeys = ["notifications", "messages", "groups", "tags"] for key in defaultKeys: counts[key] = counts[key] if key in counts else 0 groups = yield db.get_slice(myId, "entities", ["adminOfGroups"]) groups = supercolumnsToDict(groups).get("adminOfGroups", {}).keys() if groups: counts.setdefault("groups", 0) cols = yield db.multiget_slice(groups, "latest") cols = multiSuperColumnsToDict(cols) for groupId in cols: for key in cols[groupId]: counts["groups"] += len(cols[groupId][key]) if asJSON: defer.returnValue(json.dumps(counts)) else: defer.returnValue(counts)
def _addPresetTag(self, request): orgId = request.getSession(IAuthInfo).organization tagNames = utils.getRequestArg(request, 'tag') if not tagNames: return invalidTags = [] tagNames = [x.strip().decode('utf-8', 'replace') for x in tagNames.split(',')] for tagName in tagNames: if len(tagName) < 50 and regex.match('^[\w-]*$', tagName): yield tags.ensureTag(request, tagName, orgId, True) else: invalidTags.append(tagName) presetTags = yield db.get_slice(orgId, "orgPresetTags") presetTags = utils.columnsToDict(presetTags, ordered=True).values() tags_ = yield db.get_slice(orgId, "orgTags", presetTags) tags_ = utils.supercolumnsToDict(tags_) args = {'tags': tags_, 'tagsList': presetTags} handlers = {} if invalidTags: if len(invalidTags) == 1: message = " %s is invalid tag." % (invalidTags[0]) else: message = " %s are invalid tags. " % (",".join(invalidTags)) errorMsg = "%s <br/>Tag can contain alpha-numeric characters or hyphen only. It cannot be more than 50 characters" % (message) handlers = {'onload': "$$.alerts.error('%s')" % (errorMsg)} t.renderScriptBlock(request, "admin.mako", "list_tags", False, "#content", "set", True, handlers=handlers, **args)
def deleteFileInfo(myId, orgId, itemId, item, conv=None): if 'parent' in item['meta']: if not conv: conv = yield db.get_slice(item['meta']['parent'], 'items', ['meta']) conv = utils.supercolumnsToDict(conv) convId = item['meta']['parent'] else: conv = item convId = itemId acl = pickle.loads(conv['meta']['acl']) allowedGroups = acl.get('accept', {}).get('groups', []) deniedGroups = acl.get('deny', {}).get('groups', []) groups = [x for x in allowedGroups if x not in deniedGroups] allowedOrgs = acl.get('accept', {}).get('orgs', []) ownerId = conv['meta']['owner'] entityIds = [myId] entityIds.extend(groups) entityIds.extend(allowedOrgs) entityIds_ = yield utils.expandAcl(myId, orgId, conv['meta']['acl'], convId, ownerId, True) entityIds.extend(entityIds_) deferreds = [] for attachmentId in item.get('attachments', {}): col = yield db.get_slice(attachmentId, 'attachmentVersions', count=1) tuuid = col[0].column.name deferreds.append(db.remove(myId, "user_files", tuuid)) #TODO: use batch remove/batch mutate for entityId in entityIds: deferreds.append(db.remove(entityId, "entityFeed_files", tuuid)) if deferreds: yield defer.DeferredList(deferreds)
def _deletePresetTag(self, request): orgId = request.getSession(IAuthInfo).organization tagId = utils.getRequestArg(request, 'id') if not tagId: return try: tag = yield db.get(orgId, 'orgTags', super_column=tagId) tag = utils.supercolumnsToDict([tag]) tagName = tag[tagId]['title'] if 'isPreset' in tag[tagId]: yield db.remove(orgId, "orgTags", 'isPreset', tagId) yield db.remove(orgId, 'orgPresetTags', tagName) presetTags = yield db.get_slice(orgId, "orgPresetTags") presetTags = utils.columnsToDict(presetTags, ordered=True).values() if presetTags: tags_ = yield db.get_slice(orgId, "orgTags", presetTags) tags_ = utils.supercolumnsToDict(tags) else: tags_ = {} args = {'tagsList': presetTags, 'tags': tags_} request.write('$("#tag-%s").remove()' % (tagId)) except ttypes.NotFoundException: return
def pushfileinfo(myId, orgId, itemId, item, conv=None): if 'parent' in item['meta']: if not conv: conv = yield db.get_slice(item['meta']['parent'], "items", ["meta"]) conv = utils.supercolumnsToDict(conv) convId = item['meta']['parent'] else: convId = itemId conv = item acl = pickle.loads(conv['meta']['acl']) allowedGroups = acl.get('accept', {}).get('groups', []) deniedGroups = acl.get('deny', {}).get('groups', []) groups = [x for x in allowedGroups if x not in deniedGroups] allowedOrgs = acl.get('accept', {}).get('orgs', []) ownerId = conv['meta']['owner'] entityIds = [myId] entityIds.extend(groups) entityIds.extend(allowedOrgs) entityIds_ = yield utils.expandAcl(myId, orgId, conv['meta']['acl'], convId, ownerId, True) entityIds.extend(entityIds_) for attachmentId in item.get('attachments', {}): name, size, ftype = item['attachments'][attachmentId].split(':') cols = yield db.get_slice(attachmentId, "attachmentVersions", count=1) tuuid = cols[0].column.name value = '%s:%s:%s:%s' % (attachmentId, name, itemId, ownerId) #TODO: use batch remove/batch mutate yield db.insert(myId, "user_files", value, tuuid) for entityId in entityIds: yield db.insert(entityId, "entityFeed_files", value, tuuid)
def getPendingRequests(group, me, start='', count=PEOPLE_PER_PAGE): """get the list of users who want to join the group. Only admin can view pending group requests. Keyword params: @me: @group: group object @start: start fetching from @start @count: no.of pending requests to fetch. """ toFetchCount = count + 1 nextPageStart = None prevPageStart = None if me.id not in group.admins: raise errors.PermissionDenied('Access Denied') cols = yield db.get_slice(group.id, "pendingConnections", start=start, count=toFetchCount) userIds = [x.column.name.split(':')[1] for x in cols if len(x.column.name.split(':')) == 2] if len(userIds) == toFetchCount: nextPageStart = userIds[-1] userIds = userIds[0:count] entities = base.EntitySet(userIds) yield entities.fetchData() if start: cols = yield db.get_slice(group.id, "pendingConnections", start=start, count=toFetchCount, reverse=True) if len(cols) > 1: prevPageStart = cols[-1].column.name data = {'userIds': userIds, "entities": entities, "prevPageStart": prevPageStart, "nextPageStart": nextPageStart} defer.returnValue(data)
def _getPresence(self, request): authInfo = request.getSession(IAuthInfo) orgId = authInfo.organization myId = authInfo.username data = [] cols = yield db.get_slice(orgId, "presence") cols = utils.supercolumnsToDict(cols) if myId not in cols: myPresence = yield db.get_slice(orgId, "presence", super_column=myId) cols[myId] = utils.columnsToDict(myPresence) presence = {} for userId in cols: presence[userId] = getMostAvailablePresence(cols[userId].values()) if presence[myId] == PresenceStates.OFFLINE: request.write(json.dumps(data)) return userIds = cols.keys() entities = base.EntitySet(userIds) yield entities.fetchData() for entityId in entities.keys(): entity = entities[entityId] _data = {"userId": entityId, "name": entity.basic['name'], "status": presence.get(entityId, PresenceStates.OFFLINE), "title": entity.basic["jobTitle"], "avatar": utils.userAvatar(entityId, entity, 's')} data.append(_data) request.write(json.dumps(data))
def fetchData(self, args, convId=None, userId=None, columns=[]): convId = convId or args["convId"] myId = userId or args.get("myId", None) conv = yield db.get_slice(convId, "items", ['options', 'counts'].extend(columns)) conv = utils.supercolumnsToDict(conv, True) conv.update(args.get("items", {}).get(convId, {})) options = conv["options"] if "options" in conv else None if not options: raise errors.InvalidRequest("The poll does not have any options") myVote = yield db.get_slice(myId, "userVotes", [convId]) myVote = myVote[0].column.value if myVote else None startTime = conv['meta'].get('start', None) endTime = conv['meta'].get('end', None) showResults = conv['meta'].get('showResults', 'True') == True if not showResults: # FIX: endTime is String. convert to time if not endTime or time.gmtime() > endTime: showResults = "True" args.setdefault("items", {})[convId] = conv args.setdefault("myVotes", {})[convId] = myVote args.setdefault("showResults", {})[convId] = showResults defer.returnValue(set())
def _tags(self, request, term): if len(term) < 2: request.write("[]") return orgId = request.getSession(IAuthInfo).organization finish = _getFinishTerm(term) itemId = utils.getRequestArg(request, "itemId") if not itemId: request.write("[]") return toFetchTags = set() d1 = db.get_slice(orgId, "orgTagsByName", start=term, finish=finish, count=10) tags = [] matchedTags = yield d1 matchedTags = [match.column.value for match in matchedTags] if matchedTags: matchedTags = yield db.get_slice(orgId, "orgTags", matchedTags) matchedTags = utils.supercolumnsToDict(matchedTags) for tagId in matchedTags: tags.append({"title": matchedTags[tagId]["title"], "id": tagId}) tags.sort(key=itemgetter("title")) output = [] template = self._singleLineTemplate for tag in tags: data = {"title": tag["title"], "meta": ""} output.append({"value": tag["title"], "label": template % data, "href": "/tags?id=%s" % tag["id"]}) request.write(json.dumps(output))
def _revoke(self, request): authinfo = request.getSession(IAuthInfo) myId = authinfo.username myOrgId = authinfo.organization clientId = utils.getRequestArg(request, "id", sanitize=False) client = yield db.get_slice(clientId, "apps") client = utils.supercolumnsToDict(client) if not client: raise errors.InvalidApp(clientId) me = yield db.get_slice(myId, "entities", ["apikeys", "apps"]) me = utils.supercolumnsToDict(me) # Remove the client in case of API Key if client["meta"]["category"] == "apikey": if client["meta"]["author"] != myId: raise errors.AppAccessDenied(clientId) d1 = db.remove(clientId, "apps") d2 = db.remove(myId, "appsByOwner", clientId) d3 = db.remove(myId, "entities", clientId, "apikeys") d4 = db.remove(myOrgId, "appsByOwner", clientId) yield defer.DeferredList([d1, d2, d3, d4]) # Remove the refresh token # XXX: Valid access tokens could still exist else: authorization = me["apps"][clientId] d1 = db.remove(myId, "entities", clientId, "apps") d2 = db.remove(authorization, "oAuthData") yield defer.DeferredList([d1, d2])
def _myCollection(self, request, term): authInfo = request.getSession(IAuthInfo) myId = authInfo.username orgId = authInfo.organization finish = _getFinishTerm(term) # Fetch list of tags and names that match the given term d2 = db.get_slice(orgId, "nameIndex", start=term, finish=finish, count=10) toFetchEntities = set() users = [] # List of users that match the given term matchedUsers = yield d2 for user in matchedUsers: name, uid = user.column.name.rsplit(":") if uid not in toFetchEntities: users.append(uid) toFetchEntities.add(uid) # Fetch the required entities entities = {} if toFetchEntities: entities = base.EntitySet(toFetchEntities) yield entities.fetchData() output = [] template = self._dlgLinetemplate avatar = utils.userAvatar for uid in users: if uid in entities: name = entities[uid].basic["name"] data = { "icon": avatar(uid, entities[uid], "s"), "title": name, "meta": entities[uid].basic.get("jobTitle", ""), } output.append({"label": template % data, "type": "user", "value": uid}) cols = yield db.get_slice(myId, "entityGroupsMap", start=term.lower(), finish=finish.lower(), count=10) groupIds = [x.column.name.split(":", 1)[1] for x in cols] avatar = utils.groupAvatar groups = {} if groupIds: groups = base.EntitySet(groupIds) yield groups.fetchData() for groupId in groupIds: data = { "icon": avatar(groupId, groups[groupId], "s"), "title": groups[groupId].basic["name"], "meta": groups[groupId].basic.get("desc", " "), } obj = {"value": groupId, "label": template % data, "type": "group"} output.append(obj) request.write(json.dumps(output))
def _unlike(self, request, data=None): (appchange, script, args, myId) = yield self._getBasicArgs(request) orgId = args['orgId'] itemId, item = data['id'] item = yield Item.unlike(itemId, item, myId, orgId) if not item: return args["items"] = {itemId: item} args["myLikes"] = {itemId: []} likesCount = int(item["meta"]["likesCount"]) convId = item["meta"].get('parent', itemId) if itemId != convId: t.renderScriptBlock(request, "item.mako", "item_footer", False, "#item-footer-%s" % (itemId), "set", args=[itemId], **args) else: relation = Relation(myId, []) yield relation.initSubscriptionsList() toFetchEntities = set() likes = [] subscriptions = list(relation.subscriptions) if subscriptions: likes = yield db.get_slice(convId, "itemLikes", subscriptions) likes = [x.column.name for x in likes] toFetchEntities = set(likes) feedItems = yield db.get_slice(myId, "feedItems", [convId]) feedItems = utils.supercolumnsToDict(feedItems) isFeed = (utils.getRequestArg(request, "_pg") != "/item") hasComments = False if not isFeed: hasComments = True else: feedItems = yield db.get_slice(myId, "feedItems", [convId]) feedItems = utils.supercolumnsToDict(feedItems) for tuuid in feedItems.get(convId, {}): val = feedItems[convId][tuuid] rtype = val.split(":")[0] if rtype == "C": hasComments = True entities = base.EntitySet(toFetchEntities) if toFetchEntities: yield entities.fetchData() args["entities"] = entities handler = {"onload": "(function(){$$.convs.showHideComponent('%s', 'likes', false)})();" % (convId)} if not likes else None t.renderScriptBlock(request, "item.mako", "conv_footer", False, "#item-footer-%s" % (itemId), "set", args=[itemId, hasComments, likes], **args) t.renderScriptBlock(request, "item.mako", 'conv_likes', False, '#conv-likes-wrapper-%s' % convId, 'set', True, args=[itemId, likesCount, False, likes], handlers=handler, **args)
def fetchData(self, columns=None): if columns == None: columns = ['basic'] if columns == []: data = yield db.get_slice(self.id, "entities") else: data = yield db.get_slice(self.id, "entities", columns) data = utils.supercolumnsToDict(data) self._data = data
def _getFileInfo(self, request): """Fetch the meta info on a file that is being requested to be downloaded. Returns the meta info of the file in question. Keyword Arguments: itemId: id of the conversation on which this file is attached. attachmentId: id of the file on the amazon S3 that is to be served. version: version of the file on the amazon S3 that the user is requesting. """ authinfo = request.getSession(IAuthInfo) myId = authinfo.username myOrgId = authinfo.organization itemId = utils.getRequestArg(request, "id", sanitize=False) attachmentId = utils.getRequestArg(request, "fid", sanitize=False) version = utils.getRequestArg(request, "ver", sanitize=False) or '' columns = ["meta", "attachments", "participants"] if not (itemId and attachmentId): raise errors.MissingParams([]) item = yield db.get_slice(itemId, "mConversations", columns) item = utils.supercolumnsToDict(item) if not item: raise errors.InvalidMessage(itemId) if myId not in item.get('participants', {}): raise errors.MessageAccessDenied(itemId) # Check if the attachmentId belong to item if attachmentId not in item['attachments'].keys(): raise errors.InvalidAttachment(itemId, attachmentId, version) fileId, filetype, name = None, 'text/plain', 'file' if version: version = utils.decodeKey(version) try: cols = yield db.get(attachmentId, "attachmentVersions", version) except ttypes.NotFoundException: raise errors.InvalidAttachment(itemId, attachmentId, version) except ttypes.InvalidRequestException: raise errors.InvalidAttachment(itemId, attachmentId, version) cols = utils.columnsToDict([cols]) else: cols = yield db.get_slice(attachmentId, "attachmentVersions", count=1, reverse=True) cols = utils.columnsToDict(cols) version = cols.keys()[0] fileId, name, size, filetype = cols[version].split(':') files = yield db.get_slice(fileId, "files", ["meta"]) files = utils.supercolumnsToDict(files) url = files['meta']['uri'] owner = files["meta"]["owner"] defer.returnValue([owner, url, filetype, size, name])
def delete(self, myId, convId, conv): log.debug("plugin:delete", convId) user_tuids = {} # Get the list of every user who responded to this event res = yield db.get_slice(convId, "eventResponses") attendees = [x.column.name.split(":", 1)[1] for x in res] # Add all the invited people of the item res = yield db.get_slice(convId, "items", ['invitees']) res = utils.supercolumnsToDict(res) attendees.extend(res["invitees"].keys()) invitedPeople = res["invitees"].keys() log.debug("Maps", ["%s:%s"%(uId, convId) for \ uId in attendees]) # Get the Org and GroupIds if any. convMeta = conv["meta"] groupIds = convMeta["target"].split(",") if "target" in convMeta else [] attendees.extend(groupIds+[convMeta["org"]]) log.debug("Attendees", attendees) # Get the timeuuids that were inserted for this user res = yield db.multiget_slice(["%s:%s"%(uId, convId) for \ uId in attendees], "userAgendaMap") res = utils.multiColumnsToDict(res) for k, v in res.iteritems(): uid = k.split(":", 1)[0] tuids = v.keys() if tuids: user_tuids[uid] = tuids log.debug("userAgenda Removal", user_tuids) # Delete their entries in the user's list of event entries for attendee in user_tuids: yield db.batch_remove({'userAgenda': [attendee]}, names=user_tuids[attendee]) # Delete invitation entries for invited people invited_tuids = dict([[x, user_tuids[x]] for x in invitedPeople]) log.debug("userAgenda Invitation Removal", invited_tuids) for attendee in invited_tuids: yield db.batch_remove({'userAgenda': ['%s:%s' %(attendee, 'I')]}, names=invited_tuids[attendee]) log.debug("eventResponses Removal", convId) # Delete the event's entry in eventResponses yield db.remove(convId, "eventResponses") log.debug("userAgendaMap Removal", user_tuids) # Delete their entries in userAgendaMap for attendee in user_tuids: yield db.batch_remove({'userAgendaMap': ["%s:%s"%(attendee, convId)]}, names=user_tuids[attendee])
def getGroups(me, entity, start='', count=PEOPLE_PER_PAGE): """get the groups of entity. (either groups of an organization or groups of an user) keyword params: @me: @entity: org/user start: fetch group from @start count: no.of groups to fetch. """ toFetchCount = count + 1 groups = {} groupIds = [] myGroupsIds = [] groupFollowers = {} pendingConnections = {} toFetchGroups = set() nextPageStart = '' prevPageStart = '' #TODO: list the groups in sorted order. cols = yield db.get_slice(entity.id, 'entityGroupsMap', start=start, count=toFetchCount) groupIds = [x.column.name for x in cols] if len(groupIds) > count: nextPageStart = utils.encodeKey(groupIds[-1]) groupIds = groupIds[0:count] toFetchGroups.update(set([y.split(':', 1)[1] for y in groupIds])) if entity.id == me.id: myGroupsIds = [x.split(':', 1)[1] for x in groupIds] elif groupIds: cols = yield db.get_slice(me.id, "entityGroupsMap", groupIds) myGroupsIds = [x.column.name.split(':', 1)[1] for x in cols] groupIds = [x.split(':', 1)[1] for x in groupIds] if start: cols = yield db.get_slice(entity.id, 'entityGroupsMap', start=start, count=toFetchCount, reverse=True) if len(cols) > 1: prevPageStart = utils.encodeKey(cols[-1].column.name) if toFetchGroups: groups = base.EntitySet(toFetchGroups) yield groups.fetchData() groupFollowers = yield db.multiget_slice(toFetchGroups, "followers", names=[me.id]) groupFollowers = utils.multiColumnsToDict(groupFollowers) columns = reduce(lambda x, y: x + y, [["GO:%s" % (x), "GI:%s" % (x)] for x in toFetchGroups]) cols = yield db.get_slice(me.id, 'pendingConnections', columns) pendingConnections = utils.columnsToDict(cols) data = {"entities": groups, "groupIds": groupIds, "pendingConnections": pendingConnections, "myGroups": myGroupsIds, "groupFollowers": groupFollowers, "nextPageStart": nextPageStart, "prevPageStart": prevPageStart} defer.returnValue(data)
def edit(me, group, name, access, desc, displayPic): """update group meta info. Only group-admin can edit group meta info. Keyword params: @me: @group: @name: name of the group. @access: group access type (open/closed). @desc: description of the group. @displayPic: profile pic of the group. """ if me.id not in group.admins: raise errors.PermissionDenied('Only administrator can edit group meta data') if name: start = name.lower() + ':' cols = yield db.get_slice(me.basic['org'], "entityGroupsMap", start=start, count=1) for col in cols: name_, groupId_ = col.column.name.split(':') if name_ == name.lower() and groupId_ != group.id: raise errors.InvalidGroupName(name) meta = {'basic': {}} if name and name != group.basic['name']: meta['basic']['name'] = name if desc and desc != group.basic.get('desc', ''): meta['basic']['desc'] = desc if access in ['closed', 'open'] and access != group.basic['access']: meta['basic']['access'] = access if displayPic: avatar = yield saveAvatarItem(group.id, me.basic['org'], displayPic) meta['basic']['avatar'] = avatar if name and name != group.basic["name"]: members = yield db.get_slice(group.id, "groupMembers") members = utils.columnsToDict(members).keys() entities = members + [me.basic['org']] oldColName = "%s:%s" % (group.basic["name"].lower(), group.id) colname = '%s:%s' % (name.lower(), group.id) mutations = {} for entity in entities: mutations[entity] = {'entityGroupsMap': {colname: '', oldColName: None}} #XXX:notify group-members about the change in name yield db.batch_mutate(mutations) if meta['basic']: yield db.batch_insert(group.id, 'entities', meta) if not desc and group.basic.get('desc', ''): yield db.remove(group.id, "entities", 'desc', 'basic') if (not desc and group.basic.get('desc', '')) or meta['basic']: defer.returnValue(True)
def getManagedGroups(me, start, count=PEOPLE_PER_PAGE): """get all groups managed by me Keyword params: @me: @start: get groups from @start. @count: no.of groups to be fetched. """ groups = {} groupIds = [] myGroupsIds = [] nextPageStart = '' prevPageStart = '' toFetchCount = count + 1 toFetchGroups = set() groupFollowers = {} pendingConnections = {} try: cols = yield db.get_slice(me.id, "entities", super_column='adminOfGroups', start=start, count=toFetchCount) groupIds = [x.column.name for x in cols] toFetchGroups.update(set(groupIds)) myGroupsIds = groupIds if len(groupIds) > count: nextPageStart = utils.encodeKey(groupIds[-1]) groupIds = groupIds[0:count] except ttypes.NotFoundException: pass if start: cols = yield db.get_slice(me.id, "entities", super_column='adminOfGroups', start=start, count=toFetchCount, reverse=True) if len(cols) > 1: prevPageStart = utils.encodeKey(cols[-1].column.name) if toFetchGroups: groups = base.EntitySet(toFetchGroups) yield groups.fetchData() groupFollowers = yield db.multiget_slice(toFetchGroups, "followers", names=[me.id]) groupFollowers = utils.multiColumnsToDict(groupFollowers) columns = reduce(lambda x, y: x + y, [["GO:%s" % (x), "GI:%s" % (x)] for x in toFetchGroups]) cols = yield db.get_slice(me.id, 'pendingConnections', columns) pendingConnections = utils.columnsToDict(cols) data = {"entities": groups, "groupIds": groupIds, "pendingConnections": pendingConnections, "myGroups": myGroupsIds, "groupFollowers": groupFollowers, "nextPageStart": nextPageStart, "prevPageStart": prevPageStart} defer.returnValue(data)
def _listBlockedUsers(self, request): (appchange, script, args, myId) = yield self._getBasicArgs(request) orgId = args["orgId"] landing = not self._ajax start = utils.getRequestArg(request, 'start') or '' start = utils.decodeKey(start) count = PEOPLE_PER_PAGE toFetchCount = count + 1 nextPageStart = '' prevPageStart = '' args["title"] = "Manage Users" args["menuId"] = "users" args["viewType"] = "blocked" if script and landing: t.render(request, "admin.mako", **args) if script and appchange: t.renderScriptBlock(request, "admin.mako", "layout", landing, "#mainbar", "set", **args) args["heading"] = "Admin Console - Blocked Users" cols = yield db.get_slice(orgId, "blockedUsers", start=start, count=toFetchCount) blockedUsers = [col.column.name for col in cols] if len(blockedUsers) > count: nextPageStart = utils.encodeKey(blockedUsers[-1]) blockedUsers = blockedUsers[:count] if start: cols = yield db.get_slice(orgId, "blockedUsers", start=start, count=toFetchCount, reverse=True) if len(cols) > 1: prevPageStart = utils.decodeKey(cols[-1].column.name) entities = base.EntitySet(blockedUsers) yield entities.fetchData() args["entities"] = entities args['nextPageStart'] = nextPageStart args['prevPageStart'] = prevPageStart if script: t.renderScriptBlock(request, "admin.mako", "viewOptions", landing, "#users-view", "set", **args) t.renderScriptBlock(request, "admin.mako", "list_users", landing, "#content", "set", **args) if script and landing: request.write("</body></html>") if not script: t.render(request, "admin.mako", **args)
def untag(itemId, item, tagId, tag, myId, orgId): if "parent" in item: raise errors.InvalidRequest(_("Tags cannot be applied or removed from comments")) if tagId not in item.get("tags", {}): raise errors.InvalidRequest(_("No such tag on the item")) # No such tag on item d1 = db.remove(itemId, "items", tagId, "tags") d2 = db.remove(tagId, "tagItems", item["meta"]["uuid"]) d3 = db.get_slice(tagId, "tagFollowers") try: itemsCountCol = yield db.get(orgId, "orgTags", "itemsCount", tagId) tagItemsCount = int(itemsCountCol.column.value) - 1 if tagItemsCount % 10 == 7: tagItemsCount = yield db.get_count(tagId, "tagItems") tagItemsCount = tagItemsCount - 1 db.insert(orgId, "orgTags", "%s" % tagItemsCount, "itemsCount", tagId) except ttypes.NotFoundException: pass result = yield defer.DeferredList([d1, d2, d3]) followers = utils.columnsToDict(result[2][1]).keys() feedUpdateVal = "T:%s:%s::%s" % (myId, itemId, tagId) yield Feed.unpush(myId, orgId, itemId, item, feedUpdateVal, followers + [myId])
def _vote(self, request): convId, conv = yield utils.getValidItemId(request, 'id', 'poll', ['options']) vote = utils.getRequestArg(request, 'option') if not vote or vote not in conv.get("options", {}): raise errors.MissingParams(["Option"]) optionCounts = {} myId = request.getSession(IAuthInfo).username prevVote = yield db.get_slice(myId, "userVotes", [convId]) prevVote = prevVote[0].column.value if prevVote else False if prevVote == vote: yield self._results(request) return if prevVote: yield db.remove(convId, "votes", myId, prevVote) prevOptionCount = yield db.get_count(convId, "votes", prevVote) optionCounts[prevVote] = str(prevOptionCount) yield db.insert(myId, "userVotes", vote, convId) yield db.insert(convId, "votes", '', myId, vote) voteCount = yield db.get_count(convId, "votes", vote) optionCounts[vote] = str(voteCount) yield db.batch_insert(convId, "items", {"counts": optionCounts}) yield self._results(request)
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 clearChannels(userId, sessionId): key = "%s:%s" % (userId, sessionId) cols = yield db.get_slice(key, "sessionChannelsMap") channels = utils.columnsToDict(cols).keys() for channelId in channels: yield db.remove(channelId, "channelSubscribers", key) yield db.remove(key, "sessionChannelsMap")
def render_POST(self, request): try: username = request.args['u'][0] password = request.args['p'][0] remember = request.args['r'][0] if 'r' in request.args else None if not username or not password: raise KeyError except KeyError: self._renderSigninForm(request, self.MISSING_FIELDS) return server.NOT_DONE_YET d = db.get_slice(username, "userAuth") def callback(result): cols = utils.columnsToDict(result) if not utils.checkpass(password, cols.get("passwordHash", "XXX")): return self._renderSigninForm(request, self.AUTHENTICATION_FAILED) if cols.has_key("isBlocked"): return self._renderSigninForm(request, self.USER_BLOCKED) if cols.has_key("isFlagged"): return self._renderSigninForm(request, self.USER_FLAGGED) self._saveSessionAndRedirect(request, cols, remember) def errback(error): return self._renderSigninForm(request, self.UNKNOWN_ERROR) d.addCallback(callback) d.addErrback(errback) return server.NOT_DONE_YET
def _attendance(self, request): itemId, item = yield utils.getValidItemId(request, "id", columns=["invitees"]) list_type = utils.getRequestArg(request, 'type') or "yes" user_list = [] if itemId and list_type in ["yes", "no", "maybe"]: cols = yield db.get_slice(itemId, "eventResponses") res = utils.columnsToDict(cols) for rsvp in res.keys(): resp = rsvp.split(":")[0] uid = rsvp.split(":")[1] if resp == list_type: if uid in item["invitees"] and \ item["invitees"][uid] == list_type: user_list.insert(0, uid) else: user_list.append(uid) invited = user_list owner = item["meta"].get("owner") entities = base.EntitySet(invited+[owner]) yield entities.fetchData() args = {"users": invited, "entities": entities} args['title'] = {"yes":_("People attending this event"), "no": _("People not attending this event"), "maybe": _("People who may attend this event") }[list_type] t.renderScriptBlock(request, "item.mako", "userListDialog", False, "#invitee-dlg-%s"%(itemId), "set", **args)
def _removeTempFile(self, request): (appchange, script, args, myId) = yield self._getBasicArgs(request) landing = not self._ajax myOrgId = args["orgId"] SKey = config.get('CloudFiles', 'SecretKey') AKey = config.get('CloudFiles', 'AccessKey') bucket = config.get('CloudFiles', 'Bucket') creds = AWSCredentials(AKey, SKey) client = s3Client.S3Client(creds) fileId = utils.getRequestArg(request, "id") key = "%s/%s/%s" % (myOrgId, myId, fileId) #Check if the file is not in the "files" CF. In other words, it is not # attached to an existing item. Also check if I am the owner of the # file. Finally clear the existing entry in the "temp_files" CF res = yield db.get_slice(fileId, "tmp_files", ["fileId"]) if len(res) == 1: try: res = yield db.get(fileId, "files", super_column="meta") except ttypes.NotFoundException: file_info = yield client.head_object(bucket, key) owner = file_info['x-amz-meta-uid'][0] if owner == myId: yield client.delete_object(bucket, key) yield db.remove(fileId, "tmp_files") else: raise errors.EntityAccessDenied("attachment", fileId) else: raise errors.InvalidRequest()
def getValidEntityId(request, arg, type="user", columns=None): entityId = getRequestArg(request, arg, sanitize=False) if not entityId: raise errors.MissingParams([_("%s id") % _(type).capitalize()]) if not columns: columns = [] columns.extend(["basic"]) entity = yield db.get_slice(entityId, "entities", columns) if not entity: raise errors.InvalidEntity(type, entityId) entity = supercolumnsToDict(entity) basic = entity["basic"] if type != basic["type"]: raise errors.InvalidEntity(type, entityId) authinfo = request.getSession(IAuthInfo) myOrgId = authinfo.organization org = basic["org"] if basic["type"] != "org" else entityId if myOrgId != org: raise errors.EntityAccessDenied(type, entityId) defer.returnValue((entityId, entity))
def delete(itemId, item, myId, orgId): convId = item["meta"].get("parent", itemId) itemOwnerId = item["meta"]["owner"] if itemId == convId: conv = item convOwnerId = itemOwnerId else: conv = yield db.get_slice(convId, "items", ["meta", "tags"]) conv = utils.supercolumnsToDict(conv) if not conv: raise errors.InvalidRequest(_('Conversation does not exist!')) convOwnerId = conv["meta"]["owner"] # TODO: Admin actions. # Do I have permission to delete the comment if (itemOwnerId != myId and convOwnerId != myId): raise errors.PermissionDenied(_("You must either own the comment or the conversation to delete this comment")) deferreds = [] convType = conv["meta"].get('type', 'status') convACL = conv["meta"]["acl"] timestamp = str(int(time.time())) itemUUID = item["meta"]["uuid"] # The conversation is lazy deleted. # If it is the comment being deleted, rollback all feed updates # that were made due to this comment and likes on this comment. d = deleteItem(itemId, myId, orgId, item, conv) deferreds.append(d) yield defer.DeferredList(deferreds) defer.returnValue(conv)
def tag(itemId, item, tagName, myId, orgId): if "parent" in item["meta"]: raise errors.InvalidRequest(_("Tag cannot be applied on a comment")) (tagId, tag) = yield tags._ensureTag(tagName, myId, orgId) if tagId in item.get("tags", {}): raise errors.InvalidRequest(_("Tag already exists on the choosen item")) d1 = db.insert(itemId, "items", myId, tagId, "tags") d2 = db.insert(tagId, "tagItems", itemId, item["meta"]["uuid"]) d3 = db.get_slice(tagId, "tagFollowers") tagItemsCount = int(tag.get("itemsCount", "0")) + 1 if tagItemsCount % 10 == 7: tagItemsCount = yield db.get_count(tagId, "tagItems") tagItemsCount += 1 db.insert(orgId, "orgTags", "%s" % tagItemsCount, "itemsCount", tagId) result = yield defer.DeferredList([d1, d2, d3]) followers = utils.columnsToDict(result[2][1]).keys() if followers: timeUUID = uuid.uuid1().bytes feedUpdateVal = "T:%s:%s::%s" % (myId, itemId, tagId) yield Feed.push(myId, orgId, itemId, item, timeUUID, feedUpdateVal, feeds=followers) defer.returnValue((tagId, tag))