def _compute_weights(userIds, myGroups, type): followers = yield db.multiget_slice(userIds, "followers", count=50) subscriptions = yield db.multiget_slice(userIds, "subscriptions", count=50) groups = yield db.multiget_slice(userIds, "entityGroupsMap") followers = utils.multiColumnsToDict(followers) subscriptions = utils.multiColumnsToDict(subscriptions) groups = utils.multiColumnsToDict(groups) for userId in followers: for follower in followers[userId]: people[follower] = people.setdefault(follower, defaultWeight) + weights[type]['follower'] for userId in subscriptions: for subscription in subscriptions[userId]: people[subscription] = people.setdefault(subscription, defaultWeight) + weights[type]['subscription'] for userId in groups: groupIds = [x.split(':', 1)[1] for x in groups[userId]] for groupId in groupIds: if groupId in myGroups: people[userId] = people.setdefault(userId, defaultWeight) + weights[type]['group']
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 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 responses(myId, itemId, item, start=''): toFetchEntities = set() itemResponses = yield db.get_slice(itemId, "itemResponses", start=start, reverse=True, count=constants.COMMENTS_PER_PAGE + 1) nextPageStart = itemResponses[-1].column.name\ if len(itemResponses) > constants.COMMENTS_PER_PAGE\ else None itemResponses = itemResponses[:-1] \ if len(itemResponses) > constants.COMMENTS_PER_PAGE\ else itemResponses responseKeys = [] for response in itemResponses: userKey, responseKey = response.column.value.split(":") responseKeys.append(responseKey) toFetchEntities.add(userKey) responseKeys.reverse() entities = base.EntitySet(toFetchEntities) d3 = db.multiget_slice(responseKeys + [itemId], "itemLikes", [myId]) d2 = db.multiget_slice(responseKeys + [itemId], "items", ["meta", "attachments"]) d1 = entities.fetchData() fetchedItems = yield d2 myLikes = yield d3 yield d1 fetchedItems = utils.multiSuperColumnsToDict(fetchedItems) fetchedLikes = utils.multiColumnsToDict(myLikes) # Do some error correction/consistency checking to ensure that the # response items actually exist. I don't know of any reason why these # items may not exist. missingIds = [x for x, y in fetchedItems.items() if not y] if missingIds: yield _cleanupMissingComments(itemId, missingIds, itemResponses) ret = {'items': fetchedItems, 'entities': entities, 'myLikes': myLikes, 'responses': {itemId: responseKeys}} if nextPageStart: ret['oldest'] = utils.encodeKey(nextPageStart) defer.returnValue(ret)
def _getUserItems(self, request, userId, start='', count=10): authinfo = request.getSession(IAuthInfo) myId = authinfo.username myOrgId = authinfo.organization toFetchItems = set() toFetchEntities = set() toFetchTags = set() toFetchResponses = set() toFetchCount = count + 1 toFetchStart = utils.decodeKey(start) if start else '' fetchedUserItem = [] responses = {} convs = [] userItemsRaw = [] userItems = [] reasonStr = {} timestamps = {} items = {} nextPageStart = None args = {'myId': myId} relation = Relation(myId, []) yield relation.initGroupsList() toFetchEntities.add(userId) while len(convs) < toFetchCount: cols = yield db.get_slice(userId, "userItems", start=toFetchStart, reverse=True, count=toFetchCount) tmpIds = [] for col in cols: convId = col.column.value.split(":")[2] if convId not in tmpIds and convId not in convs: tmpIds.append(convId) (filteredConvs, deletedConvs) = yield utils.fetchAndFilterConvs\ (tmpIds, relation, items, myId, myOrgId) for col in cols[0:count]: convId = col.column.value.split(":")[2] if len(convs) == count or len(fetchedUserItem) == count*2: nextPageStart = col.column.name break if convId not in filteredConvs and convId not in convs: continue fetchedUserItem.append(col) if convId not in convs: convs.append(convId) if len(cols) < toFetchCount or nextPageStart: break if cols: toFetchStart = cols[-1].column.name if nextPageStart: nextPageStart = utils.encodeKey(nextPageStart) for col in fetchedUserItem: value = tuple(col.column.value.split(":")) timestamps[value] = col.column.timestamp/1e6 rtype, itemId, convId, convType, convOwnerId, commentSnippet = value commentSnippet = """<span class="snippet">"%s"</span>""" %(_(commentSnippet)) toFetchEntities.add(convOwnerId) if rtype == 'I': toFetchItems.add(convId) toFetchResponses.add(convId) userItems.append(value) elif rtype == "L" and itemId == convId and convOwnerId != userId: reasonStr[value] = _("liked %s's %s") userItems.append(value) elif rtype == "L" and convOwnerId != userId: r = "answer" if convType == 'question' else 'comment' reasonStr[value] = _("liked") + " %s " %(commentSnippet) + _("%s "%r) + _("on %s's %s") userItems.append(value) elif rtype in ["C", 'Q'] and convOwnerId != userId: reasonStr[value] = "%s"%(commentSnippet) + _(" on %s's %s") userItems.append(value) itemResponses = yield db.multiget_slice(toFetchResponses, "itemResponses", count=2, reverse=True) for convId, comments in itemResponses.items(): responses[convId] = [] for comment in comments: userId_, itemKey = comment.column.value.split(':') if itemKey not in toFetchItems: responses[convId].insert(0,itemKey) toFetchItems.add(itemKey) toFetchEntities.add(userId_) items = yield db.multiget_slice(toFetchItems, "items", ["meta", "tags", "attachments"]) items = utils.multiSuperColumnsToDict(items) args["items"] = items extraDataDeferreds = [] for convId in convs: if convId not in items: continue meta = items[convId]["meta"] itemType = meta["type"] toFetchEntities.add(meta["owner"]) if "target" in meta: toFetchEntities.update(meta["target"].split(',')) toFetchTags.update(items[convId].get("tags", {}).keys()) if itemType in plugins: d = plugins[itemType].fetchData(args, convId) extraDataDeferreds.append(d) result = yield defer.DeferredList(extraDataDeferreds) for success, ret in result: if success: toFetchEntities.update(ret) entities = base.EntitySet(toFetchEntities) yield entities.fetchData() tags = {} if toFetchTags: userOrgId = entities[userId].basic["org"] fetchedTags = yield db.get_slice(userOrgId, "orgTags", toFetchTags) tags = utils.supercolumnsToDict(fetchedTags) fetchedLikes = yield db.multiget(toFetchItems, "itemLikes", myId) myLikes = utils.multiColumnsToDict(fetchedLikes) data = {"entities": entities, "reasonStr": reasonStr, "tags": tags, "myLikes": myLikes, "userItems": userItems, "responses": responses, "nextPageStart": nextPageStart, "timestamps": timestamps } del args['myId'] args.update(data) defer.returnValue(args)
def _renderChatArchives(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 = constants.CHATS_PER_PAGE if script and landing: t.render(request, "chat.mako", **args) if appchange and script: t.renderScriptBlock(request, "chat.mako", "layout", landing, "#mainbar", "set", **args) chats = {} chatParticipants = {} prevPageStart = '' nextPageStart = '' cols = yield db.get_slice(myId, "chatArchiveList", start=start, count=count + 1, reverse=True) chatIds = [col.column.value for col in cols] if len(cols) == count + 1: chatIds = chatIds[:count] nextPageStart = utils.encodeKey(cols[-1].column.name) cols = yield db.get_slice(myId, "chatArchiveList", start=start, count=count + 1) if len(cols) > 1 and start: prevPageStart = utils.encodeKey(cols[-1].column.name) if chatIds: cols = yield db.multiget_slice(chatIds, "chatLogs", reverse=False) chats = OrderedDict() for chatId in cols: chats[chatId] = [] for col in cols[chatId]: entityId, comment = col.column.value.split(':', 1) chats[chatId] = (entityId, comment, col.column.timestamp / 1e6) participants = yield db.multiget_slice(chatIds, "chatParticipants") participants = utils.multiColumnsToDict(participants) entityIds = set([]) for chatId in participants: entityIds.update(participants[chatId]) entities = base.EntitySet(entityIds) yield entities.fetchData() entities.update(args['me']) args.update({'chatParticipants': participants, 'entities': entities, 'chats': chats, 'chatIds': chatIds, 'nextPageStart': nextPageStart, 'prevPageStart': prevPageStart, 'view': 'list', 'menuId': 'chats'}) if script: onload = """ $$.menu.selectItem('chats'); """ t.renderScriptBlock(request, "chat.mako", "chatList", landing, '.center-contents', "set", True, handlers={"onload": onload}, **args) else: t.render(request, "chat.mako", **args)
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) oldTimeuuid = None chatId = None timeuuid = uuid.uuid1().bytes for col in cols: _participants = participants[col.column.value].keys() if not set(_participants).difference(channelSubscribers): chatId = col.column.value oldTimeuuid = col.column.name if not chatId: chatId = utils.getUniqueKey() for userId in channelSubscribers: yield db.insert(chatId, "chatParticipants", '', userId) for userId in channelSubscribers: yield db.insert(chatId, "chatLogs", '%s:%s' % (myId, comment), timeuuid)
def _listGroups(self, request): appchange, script, args, myId = yield self._getBasicArgs(request) landing = not self._ajax me = args['me'] viewType = utils.getRequestArg(request, 'type') or 'myGroups' start = utils.getRequestArg(request, 'start') or '' start = utils.decodeKey(start) viewTypes = ['myGroups', 'allGroups', 'adminGroups', 'pendingRequests', 'invitations'] viewType = 'myGroups' if viewType not in viewTypes else viewType args["menuId"] = "groups" args['viewType'] = viewType cols = yield db.get_slice(myId, "entities", super_column='adminOfGroups') managedGroupIds = [col.column.name for col in cols] ##TODO: can we use getLatestCounts instead of fetching pendingConnections? cols = yield db.multiget_slice(managedGroupIds, "pendingConnections", count=1) cols = utils.multiColumnsToDict(cols) showPendingRequestsTab = sum([len(cols[groupId]) for groupId in cols]) > 0 args["showPendingRequestsTab"] = showPendingRequestsTab if viewType == 'pendingRequests' and not showPendingRequestsTab: viewType = 'myGroups' args["viewType"] = viewType cols = yield db.get_slice(myId, "pendingConnections", start="GI:", count=1) args["showInvitationsTab"] = bool(len([col for col in cols if col.column.name.startswith('GI:')])) if viewType == 'invitations' and not args["showInvitationsTab"]: viewType = 'myGroups' args['viewType'] = viewType counts = yield utils.getLatestCounts(request, False) groupRequestCount = args["groupRequestCount"] = counts["groups"] if script and landing: t.render(request, "groups.mako", **args) if script and appchange: t.renderScriptBlock(request, "groups.mako", "layout", landing, "#mainbar", "set", **args) if viewType not in ['pendingRequests', 'invitations']: if viewType == 'myGroups': data = yield Group.getGroups(me, me, start) elif viewType == 'allGroups': data = yield Group.getGroups(me, args['org'], start) else: data = yield Group.getManagedGroups(me, start) args.update(data) elif viewType == 'pendingRequests': data = yield Group.getGroupRequests(me, start) args.update(data) args['tab'] = 'pending' elif viewType == 'invitations': data = yield Group.getAllInvitations(me, start) args.update(data) if script: t.renderScriptBlock(request, "groups.mako", "titlebar", landing, "#titlebar", "set", **args) t.renderScriptBlock(request, "groups.mako", "viewOptions", landing, "#groups-view", "set", args=[viewType], showPendingRequestsTab=showPendingRequestsTab, showInvitationsTab=args['showInvitationsTab'], groupRequestCount=groupRequestCount) if viewType == "pendingRequests": t.renderScriptBlock(request, "groups.mako", "allPendingRequests", landing, "#groups-wrapper", "set", **args) else: t.renderScriptBlock(request, "groups.mako", "listGroups", landing, "#groups-wrapper", "set", **args) t.renderScriptBlock(request, "groups.mako", "paging", landing, "#groups-paging", "set", **args) if not script: t.render(request, "groups.mako", **args)
entities_d = entities.fetchData() # Results of previously initiated fetches (items, tags, entities, likes) fetchedItems = yield items_d items.update(utils.multiSuperColumnsToDict(fetchedItems)) # Filter out any deleted comments from the fetched items. for itemId, itemVal in items.items(): if itemVal.get('meta', {}).get('state', None) == 'deleted': del items[itemId] fetchedTags = yield tags_d tags.update(utils.supercolumnsToDict(fetchedTags)) fetchedMyLikes = yield myLikes_d myLikes.update(utils.multiColumnsToDict(fetchedMyLikes)) #fetchedEntities = yield entities_d #entities.update(utils.multiSuperColumnsToDict(fetchedEntities)) yield entities_d data['entities'].update(entities) # Time to build reason strings (and reason userIds) if getReasons: reasonStr = {} reasonUserIds = {} for convId in convReasonUpdates.keys(): if convId not in convIds: continue
def postFeedback(self, request): """creates a feedback item with feedback, feedback-{mood} tags. Push item to feeback, feedback-{mood} tag followers. Note: Item is owned by feedback-domain/synovel.com, not user sending the feedback. Only users of feedback-domain/synovel.com can access the item. """ comment = utils.getRequestArg(request, 'comment') mood = utils.getRequestArg(request, 'mood') if not mood or not comment: raise errors.MissingParams([_("Feedback")]) authInfo = request.getSession(IAuthInfo) myId = authInfo.username orgId = authInfo.organization tagName = 'feedback' moodTagName = 'feedback-' + mood feedbackDomain = config.get('Feedback', 'Domain') or 'synovel.com' cols = yield db.get_slice(feedbackDomain, 'domainOrgMap') if not cols: raise errors.ConfigurationError("feedbackDomain is invalid!") # Only one org exists per domain synovelOrgId = cols[0].column.name tagId, tag = yield tags.ensureTag(request, tagName, synovelOrgId) moodTagId, moodTag = yield tags.ensureTag(request, moodTagName, synovelOrgId) # Anyone in synovel can receive feedback. acl = {'accept': {'orgs': [synovelOrgId]}} acl = json.dumps(acl) synovelOrg = base.Entity(synovelOrgId) yield synovelOrg.fetchData() # createNewItem expects an entity object with has org in basic info. # organizations wont have 'org' set. synovelOrg.basic['org'] = synovelOrgId item = yield utils.createNewItem(request, 'feedback', synovelOrg, acl, subType=mood) item['meta']['org'] = synovelOrgId item['meta']['userId'] = myId item['meta']['userOrgId'] = orgId item['meta']['comment'] = comment item['tags'] = {tagId: synovelOrgId, moodTagId: synovelOrgId} itemId = utils.getUniqueKey() tagItemCount = int(tag['itemsCount']) moodTagItemCount = int(moodTag['itemsCount']) if tagItemCount % 10 == 7: tagItemCount = yield db.get_count(tagId, "tagItems") if moodTagItemCount % 10 == 7: moodTagItemCount = yield db.get_count(moodTagId, "tagItems") tagItemCount += 1 moodTagItemCount += 1 # Finally save the feedback yield db.batch_insert(itemId, "items", item) yield db.insert(tagId, "tagItems", itemId, item["meta"]["uuid"]) yield db.insert(moodTagId, "tagItems", itemId, item["meta"]["uuid"]) yield db.insert(synovelOrgId, "orgTags", str(tagItemCount), "itemsCount", tagId) yield db.insert(synovelOrgId, "orgTags", str(moodTagItemCount), "itemsCount", moodTagId) cols = yield db.multiget_slice([tagId, moodTagId], "tagFollowers") followers = utils.multiColumnsToDict(cols) followers = set(followers[tagId].keys() + followers[moodTagId].keys()) value = {"feed": {item['meta']['uuid']: itemId}} muts = dict([(x, value) for x in followers]) if muts: yield db.batch_mutate(muts)
def _update_suggestions(request, relation=None): authinfo = request.getSession(IAuthInfo) myId = authinfo.username orgId = authinfo.organization weights = {'group': {'follower': 15, 'subscription': 40, 'group': 30}, 'follower': {'follower': 9, 'subscription': 24, 'group': 15}, 'subscription': {'follower': 24, 'subscription': 64, 'group': 40}} defaultWeight = 1 people = {} @defer.inlineCallbacks def _compute_weights(userIds, myGroups, type): followers = yield db.multiget_slice(userIds, "followers", count=50) subscriptions = yield db.multiget_slice(userIds, "subscriptions", count=50) groups = yield db.multiget_slice(userIds, "entityGroupsMap") followers = utils.multiColumnsToDict(followers) subscriptions = utils.multiColumnsToDict(subscriptions) groups = utils.multiColumnsToDict(groups) for userId in followers: for follower in followers[userId]: people[follower] = people.setdefault(follower, defaultWeight) + weights[type]['follower'] for userId in subscriptions: for subscription in subscriptions[userId]: people[subscription] = people.setdefault(subscription, defaultWeight) + weights[type]['subscription'] for userId in groups: groupIds = [x.split(':', 1)[1] for x in groups[userId]] for groupId in groupIds: if groupId in myGroups: people[userId] = people.setdefault(userId, defaultWeight) + weights[type]['group'] if not relation: relation = Relation(myId, []) yield defer.DeferredList([relation.initSubscriptionsList(), relation.initFollowersList(), relation.initGroupsList()]) if relation.followers: yield _compute_weights(relation.followers, relation.groups, 'follower') if relation.subscriptions: yield _compute_weights(relation.subscriptions, relation.groups, 'subscription') if relation.groups: groupMembers = yield db.multiget_slice(relation.groups, "groupMembers", count=20) groupMembers = utils.multiColumnsToDict(groupMembers) for groupId in groupMembers: yield _compute_weights(groupMembers[groupId], relation.groups, 'group') cols = yield db.get_slice(orgId, "orgUsers", count=100) for col in cols: userId = col.column.name if userId not in people: people[userId] = people.setdefault(userId, 0) + defaultWeight suggestions = {} for userId in people: if isValidSuggestion(myId, userId, relation): suggestions.setdefault(people[userId], []).append(userId) yield db.remove(myId, "suggestions") weights_userIds_map = {} format = '>l' for weight in suggestions: key = struct.pack(format, weight) weights_userIds_map[key] = ' '.join(suggestions[weight]) if weights_userIds_map: yield db.batch_insert(myId, "suggestions", weights_userIds_map)
def _sendInvitations(myOrgUsers, otherOrgUsers, me, myId, myOrg): rootUrl = config.get('General', 'URL') brandName = config.get('Branding', 'Name') senderName = me.basic["name"] senderOrgName = myOrg.basic["name"] senderAvatarUrl = utils.userAvatar(myId, me, "medium") sentUsers = [] blockedUsers = [] existingUsers = [] myOrgSubject = "%s invited you to %s" % (senderName, brandName) myOrgBody = "Hi,\n\n"\ "%(senderName)s has invited you to %(senderOrgName)s network on %(brandName)s.\n"\ "To activate your account please visit: %(activationUrl)s.\n\n" otherOrgSubject = "%s invited you to %s" % (senderName, brandName) otherOrgBody = "Hi,\n\n"\ "%(senderName)s has invited you to try %(brandName)s.\n"\ "To activate your account please visit: %(activationUrl)s.\n\n" signature = "Flocked.in Team.\n\n\n\n"\ "--\n"\ "To block invitations from %(senderName)s visit %(blockSenderUrl)s\n"\ "To block all invitations from %(brandName)s visit %(blockAllUrl)s" blockSenderTmpl = "%(rootUrl)s/signup/blockSender?email=%(emailId)s&token=%(token)s" blockAllTmpl = "%(rootUrl)s/signup/blockAll?email=%(emailId)s&token=%(token)s" activationTmpl = "%(rootUrl)s/signup?email=%(emailId)s&token=%(token)s" # Combine all users. myOrgUsers.extend(otherOrgUsers) # Ensure that the users do not already exist and that the users are # not in the doNotSpam list (for this sender or globally) d1 = db.multiget(myOrgUsers, "userAuth", "user") d2 = db.multiget_slice(myOrgUsers, "doNotSpam", [myId, '*']) existing = yield d1 existing = utils.multiColumnsToDict(existing) doNotSpam = yield d2 doNotSpam = utils.multiColumnsToDict(doNotSpam) deferreds = [] for emailId in myOrgUsers: if emailId in existing and existing[emailId]: existingUsers.append(emailId) continue token = utils.getRandomKey() # Add invitation to the database localpart, domainpart = emailId.split('@') deferreds.append(db.insert(domainpart, "invitations", myId, token, emailId)) deferreds.append(db.insert(myId, "invitationsSent", '', emailId)) # Mail the invitation if everything is ok. if emailId in doNotSpam and doNotSpam[emailId]: blockedUsers.append(emailId) continue activationUrl = activationTmpl % locals() blockAllUrl = blockAllTmpl % locals() blockSenderUrl = blockSenderTmpl % locals() sameOrg = False if emailId in otherOrgUsers else True if not sameOrg: subject = otherOrgSubject textBody = (otherOrgBody + signature) % locals() else: subject = myOrgSubject textBody = (myOrgBody + signature) % locals() # XXX: getBlock blocks the application for disk reads when reading template htmlBody = t.getBlock("emails.mako", "invite", **locals()) deferreds.append(utils.sendmail(emailId, subject, textBody, htmlBody)) sentUsers.append(emailId) yield defer.DeferredList(deferreds) defer.returnValue((sentUsers, blockedUsers, existingUsers))
def renderItem(self, request, toFeed=False): (appchange, script, args, myId) = yield self._getBasicArgs(request) landing = not self._ajax myOrgId = args["orgId"] convId, conv = yield utils.getValidItemId(request, "id", columns=['tags']) itemType = conv["meta"].get("type", None) if 'parent' in conv['meta']: raise errors.InvalidItem('conversation', convId) start = utils.getRequestArg(request, "start") or '' start = utils.decodeKey(start) args['convId'] = convId args['isItemView'] = True args['items'] = {convId: conv} meta = conv["meta"] owner = meta["owner"] relation = Relation(myId, []) yield defer.DeferredList([relation.initGroupsList(), relation.initSubscriptionsList()]) args["relations"] = relation if script and landing: t.render(request, "item.mako", **args) if script and appchange: t.renderScriptBlock(request, "item.mako", "layout", landing, "#mainbar", "set", **args) args["entities"] = {} toFetchEntities = set() toFetchTags = set(conv.get("tags", {}).keys()) plugin = plugins[itemType] if itemType in plugins else None if plugin: entityIds = yield plugin.fetchData(args) toFetchEntities.update(entityIds) toFetchEntities.add(conv['meta']['owner']) if "target" in conv["meta"]: toFetchEntities.update(conv['meta']['target'].split(',')) if conv['meta']['owner'] not in toFetchEntities: toFetchEntities.add(conv['meta']['owner']) entities = base.EntitySet(toFetchEntities) yield entities.fetchData() args["entities"] = entities renderers = [] if script: t.renderScriptBlock(request, "item.mako", "conv_root", landing, "#conv-root-%s > .conv-summary" % (convId), "set", **args) convOwner = args["items"][convId]["meta"]["owner"] args["ownerId"] = convOwner if script: if itemType != "feedback": t.renderScriptBlock(request, "item.mako", "conv_owner", landing, "#conv-avatar-%s" % convId, "set", **args) else: feedbackType = conv['meta']['subType'] t.renderScriptBlock(request, "item.mako", "feedback_icon", landing, "#conv-avatar-%s" % convId, "set", args=[feedbackType]) # A copy of this code for fetching comments is present in _responses # Most changes here may need to be done there too. itemResponses = yield db.get_slice(convId, "itemResponses", start=start, reverse=True, count=constants.COMMENTS_PER_PAGE + 1) nextPageStart = itemResponses[-1].column.name\ if len(itemResponses) > constants.COMMENTS_PER_PAGE\ else None itemResponses = itemResponses[:-1] \ if len(itemResponses) > constants.COMMENTS_PER_PAGE\ else itemResponses responseKeys = [] for response in itemResponses: userKey, responseKey = response.column.value.split(":") responseKeys.append(responseKey) toFetchEntities.add(userKey) responseKeys.reverse() subscriptions = list(relation.subscriptions) likes = yield db.get_slice(convId, "itemLikes", subscriptions) \ if subscriptions else defer.succeed([]) toFetchEntities.update([x.column.name for x in likes]) entities = base.EntitySet(toFetchEntities) d1 = entities.fetchData() d2 = db.multiget_slice(responseKeys, "items", ["meta", "attachments"]) d3 = db.multiget_slice(responseKeys + [convId], "itemLikes", [myId]) d4 = db.get_slice(myOrgId, "orgTags", toFetchTags)\ if toFetchTags else defer.succeed([]) yield d1 fetchedItems = yield d2 myLikes = yield d3 fetchedTags = yield d4 fetchedItems = utils.multiSuperColumnsToDict(fetchedItems) myLikes = utils.multiColumnsToDict(myLikes) fetchedTags = utils.supercolumnsToDict(fetchedTags) # Do some error correction/consistency checking to ensure that the # response items actually exist. I don't know of any reason why these # items may not exist. missingIds = [x for x, y in fetchedItems.items() if not y] if missingIds: yield self._cleanupMissingComments(convId, missingIds, itemResponses) args["items"].update(fetchedItems) args["entities"].update(entities) args["myLikes"] = myLikes args["tags"] = fetchedTags args["responses"] = {convId: responseKeys} if nextPageStart: args["oldest"] = utils.encodeKey(nextPageStart) if script: t.renderScriptBlock(request, "item.mako", 'conv_footer', landing, '#item-footer-%s' % convId, 'set', **args) t.renderScriptBlock(request, "item.mako", 'conv_tags', landing, '#conv-tags-wrapper-%s' % convId, 'set', handlers={"onload": "$('#conv-meta-wrapper-%s').removeClass('no-tags')" % convId} if toFetchTags else None, **args) t.renderScriptBlock(request, "item.mako", 'conv_comments', landing, '#conv-comments-wrapper-%s' % convId, 'set', **args) t.renderScriptBlock(request, "item.mako", 'conv_comment_form', landing, '#comment-form-wrapper-%s' % convId, 'set', True, handlers={"onload": "(function(obj){$$.convs.load(obj);})(this);"}, **args) numLikes = int(conv["meta"].get("likesCount", "0")) if numLikes: numLikes = int(conv["meta"].get("likesCount", "0")) iLike = myId in args["myLikes"].get(convId, []) t.renderScriptBlock(request, "item.mako", 'conv_likes', landing, '#conv-likes-wrapper-%s' % convId, 'set', args=[convId, numLikes, iLike, [x.column.name for x in likes]], entities=args['entities']) if plugin and hasattr(plugin, 'renderItemSideBlock'): plugin.renderItemSideBlock(request, landing, args) if script and landing: request.write("</body></html>") if not script: t.render(request, "item.mako", **args)