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 _renderMore(self, request, data=None): myId = request.getSession(IAuthInfo).username group = data['id'] start = data['start'] itemType = data['type'] me = base.Entity(myId) me_d = me.fetchData() args = {'itemType': itemType, 'groupId': group.id, "me": me} isMember = yield db.get_count(group.id, "groupMembers", start=myId, finish=myId) if isMember: feedItems = yield Feed.get(request.getSession(IAuthInfo), feedId=group.id, start=start, itemType=itemType) args.update(feedItems) else: args["conversations"] = [] args["entities"] = {} yield me_d args["isMember"] = isMember args["entities"].update(group) args['entities'].update(me) onload = "(function(obj){$$.convs.load(obj);})(this);" t.renderScriptBlock(request, "group-feed.mako", "feed", False, "#next-load-wrapper", "replace", True, handlers={"onload": onload}, **args)
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))
def _subscribe(self, request, data=None): authInfo = request.getSession(IAuthInfo) myId = authInfo.username orgId = authInfo.organization myGroups = [] _pg = data['_pg'] group = data['id'] groupFollowers = {group.id: []} entities = base.EntitySet([myId, orgId]) yield entities.fetchData() entities.update(group) args = {'entities': entities, "me": entities[myId]} isNewMember, pendingRequests = yield Group.subscribe(request, group, entities[myId], entities[orgId]) if isNewMember or pendingRequests: if isNewMember: myGroups.append(group.id) groupFollowers[group.id].append(myId) args["isMember"] = isNewMember args["pendingConnections"] = pendingRequests args["groupFollowers"] = groupFollowers args["groupId"] = group.id args["myGroups"] = myGroups handlers = {} if group.basic['access'] == 'open' and _pg == '/group': onload = """ $('#group_add_invitee').autocomplete({ source: '/auto/users', minLength: 2, select: function( event, ui ) { $('#group_invitee').attr('value', ui.item.uid) } }); """ t.renderScriptBlock(request, "group-feed.mako", "groupLinks", False, "#group-links", "set", handlers={"onload": onload}, **args) onload = "$('#sharebar-attach-fileshare,"\ "#sharebar-attach-file-input,"\ "#sharebar-submit').removeAttr('disabled');" onload += "$('#group-share-block').removeClass('disabled');" onload += "$('#group-links').show();" handlers = {'onload': onload} t.renderScriptBlock(request, "group-feed.mako", "group_actions", False, "#group-actions-%s" % (group.id), "set", handlers=handlers, **args) if group.basic['access'] == 'open' and _pg == '/group': feedItems = yield Feed.get(request.getSession(IAuthInfo), feedId=group.id) args.update(feedItems) onload = "(function(obj){$$.convs.load(obj);})(this);" t.renderScriptBlock(request, "group-feed.mako", "feed", False, "#user-feed", "set", True, handlers={"onload": onload}, **args)
def removeLikeFromFeeds(result): likes = utils.columnsToDict(result) removeLikeDeferreds = [] for actorId, likeUUID in likes.items(): likeUpdateVal = "L:%s:%s:%s" % (actorId, itemId, itemOwnerId) d1 = feed.deleteUserFeed(actorId, convType, likeUUID) d2 = Feed.unpush(actorId, orgId, convId, conv, likeUpdateVal) removeLikeDeferreds.extend([d1, d2]) return defer.DeferredList(removeLikeDeferreds)
def unlike(itemId, item, myId, orgId): # Make sure that I liked this item try: cols = yield db.get(itemId, "itemLikes", myId) likeTimeUUID = cols.column.value except ttypes.NotFoundException: defer.returnValue(None) convId = item["meta"].get("parent", itemId) if convId != itemId: conv = yield db.get(convId, "items", super_column="meta") conv = utils.supercolumnsToDict([conv]) else: conv = item convOwnerId = conv["meta"]["owner"] convType = conv["meta"]["type"] convACL = conv["meta"]["acl"] # 1. remove the user from likes list. yield db.remove(itemId, "itemLikes", myId) # Update the likes count likesCount = int(item["meta"].get("likesCount", "1")) if likesCount % 5 == 0: likesCount = yield db.get_count(itemId, "itemLikes") item['meta']['likesCount'] = likesCount - 1 yield db.insert(itemId, "items", str(likesCount - 1), "likesCount", "meta") responseType = 'L' # 2. Don't remove the user from followers list # (use can also become follower by responding to item, # so user can't be removed from followers list) # Ignore if i am owner of the item if myId != item["meta"]["owner"]: # 3. delete from user's feed, feedItems, feed_* likeUpdateVal = "L:%s:%s:%s" % (myId, itemId, item['meta']['owner']) yield Feed.unpush(myId, orgId, convId, conv, likeUpdateVal) # FIX: if user updates more than one item at exactly same time, # one of the updates will overwrite the other. Fix it. yield db.remove(myId, "userItems", likeTimeUUID) if convType in plugins and plugins[convType].hasIndex: yield db.remove(myId, "userItems_" + convType, likeTimeUUID) defer.returnValue(item)
def _renderMore(self, request, entityId, start, itemType): (appchange, script, args, myId) = yield self._getBasicArgs(request) entity = base.Entity(entityId) yield entity.fetchData() if entity.basic and entity.basic.get("type", '') == "group": errors.InvalidRequest("group feed will not be fetched.") feedItems = yield Feed.get(request.getSession(IAuthInfo), feedId=entityId, start=start, itemType=itemType) args.update(feedItems) args["feedId"] = entityId args['itemType'] = itemType onload = "(function(obj){$$.convs.load(obj);})(this);" t.renderScriptBlock(request, "feed.mako", "feed", False, "#next-load-wrapper", "replace", True, handlers={"onload": onload}, **args)
def _getTagItems(self, request, tagId, start='', count=10): itemsFromFeed = {} @defer.inlineCallbacks def getter(start='', count=12): items = yield db.get_slice(tagId, "tagItems", count=count, start=start, reverse=True) items = utils.columnsToDict(items, ordered=True) itemsFromFeed.update(items) defer.returnValue(items) @defer.inlineCallbacks def cleaner(convIds): deleteKeys = [] for key, value in itemsFromFeed.items(): if value in deleted: deleteKeys.append(key) yield db.batch_remove({'tagItems': [tagId]}, names=deleteKeys) return Feed.get(request.getSession(IAuthInfo), getFn=getter, cleanFn=cleaner, start=start, count=count, getReasons=False)
def _feed(self, request, data=None): (appchange, script, args, myId) = yield self._getBasicArgs(request) landing = not self._ajax group = data['id'] start = data['start'] itemType = data['type'] #if user dont belong to this group show "Join Group" message isMember = yield db.get_count(group.id, "groupMembers", start=myId, finish=myId) isFollower = yield db.get_count(group.id, "followers", start=myId, finish=myId) columns = ["GI:%s" % (group.id), "GO:%s" % (group.id)] cols = yield db.get_slice(myId, "pendingConnections", columns) pendingConnections = utils.columnsToDict(cols) args["menuId"] = "groups" args["groupId"] = group.id args["isMember"] = isMember args['itemType'] = itemType args["entities"] = base.EntitySet(group) ##XXX: following should not be static args["pendingConnections"] = pendingConnections args["myGroups"] = [group.id] if isMember else [] args["groupFollowers"] = {group.id: [myId]} if isFollower else {group.id: []} if script and landing: t.render(request, "group-feed.mako", **args) elif script and appchange: t.renderScriptBlock(request, "group-feed.mako", "layout", landing, "#mainbar", "set", **args) if script: name = group.basic['name'] onload = "$$.acl.switchACL('sharebar-acl', 'group', '%s', '%s');" % (group.id, name.replace("'", "\\'")) onload += "$$.files.init('sharebar-attach');" onload += "$('#sharebar-acl-button').attr('disabled', 'disabled');" if not isMember: onload += "$('#sharebar-attach-fileshare').attr('disabled', 'disabled');" onload += "$('#sharebar-attach-file-input').attr('disabled', 'disabled');" onload += "$('#sharebar-submit').attr('disabled', 'disabled');" onload += "$('#group-share-block').addClass('disabled');" t.renderScriptBlock(request, "group-feed.mako", "summary", landing, "#group-summary", "set", **args) t.renderScriptBlock(request, "feed.mako", "share_block", landing, "#group-share-block", "set", handlers={"onload": onload}, **args) yield self._renderShareBlock(request, "status") if isMember: feedItems = yield Feed.get(request.getSession(IAuthInfo), feedId=group.id, start=start, itemType=itemType) args.update(feedItems) else: args["conversations"] = [] entities = base.EntitySet(group.admins.keys()) yield entities.fetchData() for entityId in entities.keys(): if entityId not in args['entities']: args['entities'][entityId] = entities[entityId] #group info fetched by feed may not have required info. overwrite it. args['entities'].update(group) if script: onload = "(function(obj){$$.convs.load(obj);})(this);" t.renderScriptBlock(request, "group-feed.mako", "feed", landing, "#user-feed", "set", True, handlers={"onload": onload}, **args) t.renderScriptBlock(request, "feed.mako", "feedFilterBar", landing, "#feed-filter-bar", "set", True, args=[itemType], **args) if isMember: onload = """ $('#group_add_invitee').autocomplete({ source: '/auto/users', minLength: 2, select: function( event, ui ) { $('#group_invitee').attr('value', ui.item.uid) } }); $('#feed-side-block-container').empty(); """ t.renderScriptBlock(request, "group-feed.mako", "groupLinks", landing, "#group-links", "set", handlers={"onload": onload}, **args) t.renderScriptBlock(request, "group-feed.mako", "groupAdmins", landing, "#group-admins", "set", True, **args) if isMember: for pluginType in plugins: plugin = plugins[pluginType] if hasattr(plugin, 'renderFeedSideBlock'): yield plugins["event"].renderFeedSideBlock(request, landing, group.id, args) else: t.render(request, "group-feed.mako", **args)
def _rsvp(self, request): (appchange, script, args, myId) = yield self._getBasicArgs(request) landing = not self._ajax orgId = args['orgId'] response = utils.getRequestArg(request, 'response') deferreds = [] prevResponse = "" if not response or response not in ('yes', 'maybe', 'no'): raise errors.InvalidRequest() convId, conv = yield utils.getValidItemId(request, "id", columns=["invitees"]) if not conv: raise errors.MissingParams([_("Event ID")]) if ("type" in conv["meta"] and conv["meta"]["type"] != "event"): raise errors.InvalidRequest("Not a valid event") #Find out if already stored response is the same as this one. Saves # quite a few queries rsvp_names = ["%s:%s" %(x, myId) for x in ['yes', 'no', 'maybe']] cols = yield db.get_slice(convId, "eventResponses", names=rsvp_names) if cols: prevResponse = cols[0].column.name.split(":", 1)[0] if prevResponse == response: defer.returnValue(0) starttime = int(conv["meta"]["event_startTime"]) endtime = int(conv["meta"]["event_endTime"]) starttimeUUID = utils.uuid1(timestamp=starttime) starttimeUUID = starttimeUUID.bytes endtimeUUID = utils.uuid1(timestamp=endtime) endtimeUUID = endtimeUUID.bytes #Now insert the event in the user's agenda list if the user has # never responded to this event or the user is not in the invited list. #In the second case the agenda was already updated when creating the # event if prevResponse == "" and myId not in conv["invitees"].keys(): d1 = db.insert(myId, "userAgenda", convId, starttimeUUID) d2 = db.insert(myId, "userAgenda", convId, endtimeUUID) d3 = db.insert("%s:%s" %(myId, convId), "userAgendaMap", "", starttimeUUID) d4 = db.insert("%s:%s" %(myId, convId), "userAgendaMap", "", endtimeUUID) deferreds.extend([d1, d3, d2, d4]) #Remove any old responses to this event by this user. yield db.batch_remove({'eventResponses': [convId]}, names=rsvp_names) #Now insert the user's new response. d = db.insert(convId, "eventResponses", "", "%s:%s" %(response, myId)) deferreds.append(d) if script: #Update the inline status of the rsvp status if response == "yes": rsp = _("You are attending") elif response == "no": rsp = _("You are not attending") elif response == "maybe": rsp = _("You may attend") request.write("$('#event-rsvp-status-%s').text('%s');" %(convId, rsp)) request.write("$('#conv-%s .event-join-decline').text('%s');" %(convId, rsp)) if deferreds: res = yield defer.DeferredList(deferreds) if script: args.update({"items":{convId:conv}, "convId":convId}) entityIds = yield event.fetchData(args, convId) entities = base.EntitySet(entityIds) yield entities.fetchData() args["entities"] = entities t.renderScriptBlock(request, "event.mako", "event_meta", landing, "#item-meta", "set", **args) # Push Feed Updates responseType = "E" convMeta = conv["meta"] convType = convMeta["type"] convOwnerId = convMeta["owner"] commentSnippet = convMeta["event_title"] itemId = convId convACL = convMeta["acl"] extraEntities = [convMeta["owner"]] # Importing social.feed at the beginning of the module leads to # a cyclic dependency as feed in turn imports plugins. from social.core import Feed if response == "yes": timeUUID = uuid.uuid1().bytes # Add user to the followers list of parent item yield db.insert(convId, "items", "", myId, "followers") # Update user's feed, feedItems, feed_* userItemValue = ":".join([responseType, itemId, convId, convType, convOwnerId, commentSnippet]) yield db.insert(myId, "userItems", userItemValue, timeUUID) yield db.insert(myId, "userItems_event", userItemValue, timeUUID) # Push to feed feedItemVal = "%s:%s:%s:%s" % (responseType, myId, itemId, ','.join(extraEntities)) yield Feed.push(myId, orgId, convId, conv, timeUUID, feedItemVal) elif prevResponse != "": rsvpTimeUUID = None cols = yield db.get_slice(myId, "userItems") cols = utils.columnsToDict(cols) for k, v in cols.iteritems(): if v.startswith("E"): rsvpTimeUUID = k if rsvpTimeUUID: # Remove update if user changes RSVP to no/maybe from yes. # Do not update if user had RSVPed to this event. feedUpdateVal = "%s:%s:%s:%s" % (responseType, myId, itemId, convOwnerId) yield Feed.unpush(myId, orgId, convId, conv, feedUpdateVal) # FIX: if user updates more than one item at exactly same time, # one of the updates will overwrite the other. Fix it. yield db.remove(myId, "userItems", rsvpTimeUUID) yield db.remove(myId, "userItems_event", rsvpTimeUUID) if myId != convOwnerId and response == "yes": timeUUID = uuid.uuid1().bytes yield _notify("EA", convId, timeUUID, convType=convType, convOwnerId=convOwnerId, myId=myId, me=args["me"])
def like(itemId, item, myId, orgId, me=None): try: cols = yield db.get(itemId, "itemLikes", myId) defer.returnValue(None) # Ignore the request if we already liked it. except ttypes.NotFoundException: pass if not me: me = base.Entity(myId) yield me.fetchData() itemOwnerId = item["meta"]["owner"] extraEntities = [itemOwnerId] convId = item["meta"].get("parent", itemId) if convId != itemId: #get parent's meta data conv = yield db.get(convId, "items", super_column="meta") conv = utils.supercolumnsToDict([conv]) commentText = item["meta"]["comment"] richText = item["meta"].get("richText", "False") == "True" commentSnippet = utils.toSnippet(commentText, 35, richText) else: conv = item commentSnippet = "" convOwnerId = conv["meta"]["owner"] convType = conv["meta"]["type"] convACL = conv["meta"]["acl"] # Update the likes count likesCount = int(item["meta"].get("likesCount", "0")) if likesCount % 5 == 3: likesCount = yield db.get_count(itemId, "itemLikes") item["meta"]["likesCount"] = str(likesCount + 1) yield db.insert(itemId, "items", item['meta']['likesCount'], "likesCount", "meta") timeUUID = uuid.uuid1().bytes # 1. add user to Likes list yield db.insert(itemId, "itemLikes", timeUUID, me.id) # Ignore adding to other's feeds if I am owner of the item if me.id != item["meta"]["owner"]: responseType = "L" # 2. add user to the followers list of parent item yield db.insert(convId, "items", "", me.id, "followers") # 3. update user's feed, feedItems, feed_* userItemValue = ":".join([responseType, itemId, convId, convType, convOwnerId, commentSnippet]) yield db.insert(me.id, "userItems", userItemValue, timeUUID) if convType in plugins and plugins[convType].hasIndex: yield db.insert(me.id, "userItems_" + convType, userItemValue, timeUUID) # 4. update feeds feedItemVal = "%s:%s:%s:%s" % (responseType, myId, itemId, ','.join(extraEntities)) yield Feed.push(myId, orgId, convId, conv, timeUUID, feedItemVal) if itemId != convId: if me.id != itemOwnerId: yield _notify("LC", convId, timeUUID, convType=convType, convOwnerId=convOwnerId, myId=me.id, itemOwnerId=itemOwnerId, me=me) else: if me.id != convOwnerId: yield _notify("L", convId, timeUUID, convType=convType, convOwnerId=convOwnerId, myId=me.id, me=me) defer.returnValue(item)
def deleteItem(itemId, userId, orgId, item=None, conv=None,): if not item: item = yield db.get_slice(itemId, "items", ["meta", "tags"]) item = utils.supercolumnsToDict(item) meta = item["meta"] convId = meta.get("parent", itemId) itemUUID = meta["uuid"] itemOwnerId = meta["owner"] timestamp = str(int(time.time())) d = db.insert(itemId, "items", "deleted", "state", "meta") deferreds = [d] if not conv: conv = yield db.get_slice(convId, "items", ['meta', 'tags']) conv = utils.supercolumnsToDict(conv) plugin = plugins[conv['meta']['type']] if convId == itemId: # Delete from tagItems. for tagId in item.get("tags", {}): d = db.remove(tagId, "tagItems", itemUUID) deferreds.append(d) # Actually, delete the conversation. d1 = db.insert(itemOwnerId, 'deletedConvs', timestamp, itemId) d1.addCallback(lambda x: search.solr.delete(itemId)) d1.addCallback(lambda x: files.deleteFileInfo(userId, orgId, itemId, item)) d2 = plugin.delete(userId, convId, conv) deferreds.extend([d1, d2]) itemResponses = yield db.get_slice(convId, "itemResponses") itemResponses = utils.columnsToDict(itemResponses) items = yield db.multiget_slice(itemResponses.values(), "items", ["meta", "attachments"]) items = utils.multiSuperColumnsToDict(items) for responseId in items: deferreds.append(files.deleteFileInfo(userId, orgId, responseId, items[responseId], conv)) else: convType = conv["meta"]["type"] convOwnerId = conv["meta"]["owner"] convACL = conv["meta"]["acl"] d1 = db.insert(convId, 'deletedConvs', timestamp, itemId) d2 = db.remove(convId, 'itemResponses', itemUUID) d2.addCallback(lambda x: db.get_count(convId, "itemResponses")) d2.addCallback(lambda x: db.insert(convId, 'items', \ str(x), 'responseCount', 'meta')) d2.addCallback(lambda x: search.solr.delete(itemId)) d3 = files.deleteFileInfo(userId, orgId, itemId, item, conv) deferreds.extend([d1, d2, d3]) # Rollback changes to feeds caused by this comment d = db.get_slice(itemId, "itemLikes") def removeLikeFromFeeds(result): likes = utils.columnsToDict(result) removeLikeDeferreds = [] for actorId, likeUUID in likes.items(): likeUpdateVal = "L:%s:%s:%s" % (actorId, itemId, itemOwnerId) d1 = feed.deleteUserFeed(actorId, convType, likeUUID) d2 = Feed.unpush(actorId, orgId, convId, conv, likeUpdateVal) removeLikeDeferreds.extend([d1, d2]) return defer.DeferredList(removeLikeDeferreds) d.addCallback(removeLikeFromFeeds) deferreds.append(d) # Delete comment from comment owner's userItems d = feed.deleteUserFeed(itemOwnerId, convType, itemUUID) deferreds.append(d) # Rollback updates done to comment owner's follower's feeds. responseUpdateVal = "Q:%s:%s" if convType == "question" else "C:%s:%s" responseUpdateVal = responseUpdateVal % (itemOwnerId, itemId) d = Feed.unpush(itemOwnerId, orgId, convId, conv, responseUpdateVal) deferreds.append(d) yield defer.DeferredList(deferreds)
def new(request, authInfo, convType, richText=False): if convType not in plugins: raise errors.BaseError('Unsupported item type', 400) myId = authInfo.username orgId = authInfo.organization entities = base.EntitySet([myId, orgId]) yield entities.fetchData(['basic', 'admins']) plugin = plugins[convType] convId = utils.getUniqueKey() conv = yield plugin.create(request, entities[myId], convId, richText) orgAdminIds = entities[orgId].admins.keys() if orgAdminIds: text = '' monitoredFields = getattr(plugin, 'monitoredFields', {}) for superColumnName in monitoredFields: for columnName in monitoredFields[superColumnName]: if columnName in conv[superColumnName]: text = " ".join([text, conv[superColumnName][columnName]]) matchedKeywords = yield utils.watchForKeywords(orgId, text) if matchedKeywords: reviewOK = utils.getRequestArg(request, "_review") == "1" if reviewOK: # Add conv to list of items that matched this keyword # and notify the administrators about it. orgAdmins = base.EntitySet(orgAdminIds) yield orgAdmins.fetchData() entities.update(orgAdmins) for keyword in matchedKeywords: yield db.insert(orgId + ":" + keyword, "keywordItems", convId, conv['meta']['uuid']) yield notifications.notify(orgAdminIds, ':KW:' + keyword, myId, entities=entities) else: # This item contains a few keywords that are being monitored # by the admin and cannot be posted unless reviewOK is set. defer.returnValue((None, None, matchedKeywords)) # # Save the new item to database and index it. # yield db.batch_insert(convId, "items", conv) yield files.pushfileinfo(myId, orgId, convId, conv) search.solr.updateItemIndex(convId, conv, orgId) # # Push item to feeds and userItems # timeUUID = conv["meta"]["uuid"] convACL = conv["meta"]["acl"] deferreds = [] responseType = 'I' # Push to feeds feedUpdateVal = "I:%s:%s" % (myId, convId) d = Feed.push(myId, orgId, convId, conv, timeUUID, feedUpdateVal, promoteActor=True) deferreds.append(d) # Save in user items. userItemValue = ":".join([responseType, convId, convId, convType, myId, '']) d = db.insert(myId, "userItems", userItemValue, timeUUID) deferreds.append(d) if plugins[convType].hasIndex: d = db.insert(myId, "userItems_%s" % (convType), userItemValue, timeUUID) deferreds.append(d) yield defer.DeferredList(deferreds) defer.returnValue((convId, conv, None))
def _comment(convId, conv, comment, snippet, myId, orgId, richText, reviewed, fids=None): convType = conv["meta"].get("type", "status") # 1. Create the new item timeUUID = uuid.uuid1().bytes meta = {"owner": myId, "parent": convId, "comment": comment, "timestamp": str(int(time.time())), "org": orgId, "uuid": timeUUID, "richText": str(richText)} item = {'meta':meta} followers = {myId: ''} itemId = utils.getUniqueKey() if snippet: meta['snippet'] = snippet # 1.5. Check if the comment matches any of the keywords entities = base.EntitySet([myId, orgId]) yield entities.fetchData(['basic', 'admins']) orgAdmins = entities[orgId].admins.keys() if orgAdmins: matchedKeywords = yield utils.watchForKeywords(orgId, comment) if matchedKeywords: if reviewed: # Add item to list of items that matched this keyword # and notify the administrators about it. for keyword in matchedKeywords: yield db.insert(orgId + ":" + keyword, "keywordItems", itemId + ":" + convId, timeUUID) yield notifications.notify(orgAdmins, ':KW:' + keyword, myId, entities=entities) else: # This item contains a few keywords that are being monitored # by the admin and cannot be posted unless reviewOK is set. defer.returnValue((None, convId, {convId: conv}, matchedKeywords)) # 1.9. Actually store the item if fids: attachments = yield utils._upload_files(myId, fids) if attachments: item['attachments'] = {} for attachmentId in attachments: fileId, name, size, ftype = attachments[attachmentId] item["attachments"][attachmentId] = "%s:%s:%s" % (name, size, ftype) yield db.batch_insert(itemId, "items", item) yield files.pushfileinfo(myId, orgId, itemId, item, conv) # 2. Update response count and add myself to the followers of conv convOwnerId = conv["meta"]["owner"] convType = conv["meta"]["type"] responseCount = int(conv["meta"].get("responseCount", "0")) if responseCount % 5 == 3: responseCount = yield db.get_count(convId, "itemResponses") responseCount += 1 conv['meta']['responseCount'] = responseCount convUpdates = {"responseCount": str(responseCount)} yield db.batch_insert(convId, "items", {"meta": convUpdates, "followers": followers}) # 3. Add item as response to parent yield db.insert(convId, "itemResponses", "%s:%s" % (myId, itemId), timeUUID) # 4. Update userItems and userItems_* responseType = "Q" if convType == "question" else 'C' commentSnippet = utils.toSnippet(comment, 35, richText) userItemValue = ":".join([responseType, itemId, convId, convType, convOwnerId, commentSnippet]) yield db.insert(myId, "userItems", userItemValue, timeUUID) if convType in plugins and plugins[convType].hasIndex: yield db.insert(myId, "userItems_" + convType, userItemValue, timeUUID) # 5. Update my feed. feedItemVal = "%s:%s:%s" % (responseType, myId, itemId) yield Feed.push(myId, orgId, convId, conv, timeUUID, feedItemVal) yield _notify("C", convId, timeUUID, convType=convType, convOwnerId=convOwnerId, myId=myId, me=entities[myId], comment=comment, richText=richText) search.solr.updateItemIndex(itemId, {'meta': meta}, orgId, conv=conv) items = {itemId: item, convId: conv} defer.returnValue((itemId, convId, items, None))
def _render(self, request, entityId, start, itemType): (appchange, script, args, myId) = yield self._getBasicArgs(request) itemType = utils.getRequestArg(request, 'type') start = utils.getRequestArg(request, "start") or '' landing = not self._ajax myOrgId = args["orgId"] feedTitle = _("News Feed") menuId = "feed" if entityId: entity = base.Entity(entityId) yield entity.fetchData(['basic', 'admins']) if not entity.basic: raise errors.InvalidEntity("feed", entityId) entityType = entity.basic['type'] orgId = entity.basic["org"] if entityType != "org" else entityId if myOrgId != orgId: raise errors.EntityAccessDenied("organization", entityId) if entityType == 'org': menuId = "org" feedTitle = _("Company Feed: %s") % entity.basic["name"] elif entityType == 'group': request.redirect("/group?id=%s"%(entityId)) defer.returnValue(None) elif entityId != myId: raise errors.EntityAccessDenied("user", entityId) feedId = entityId or myId args["feedTitle"] = feedTitle args["menuId"] = menuId args["feedId"] = feedId if script and landing: t.render(request, "feed.mako", **args) request.write('<script>$("#invite-form").html5form({messages: "en"})</script>') elif script and appchange: onload = '$("#invite-form").html5form({messages: "en"})' t.renderScriptBlock(request, "feed.mako", "layout", landing, "#mainbar", "set", handlers={'onload':onload}, **args) elif script and feedTitle: t.renderScriptBlock(request, "feed.mako", "feed_title", landing, "#title", "set", True, handlers={"onload": "$$.menu.selectItem('%s')"%(menuId)}, **args) if script: handlers = {} handlers["onload"] = handlers.get("onload", "") +\ "$$.files.init('sharebar-attach');" t.renderScriptBlock(request, "feed.mako", "share_block", landing, "#share-block", "set", handlers=handlers, **args) yield self.renderShareBlock(request, "status") feedItems = yield Feed.get(request.getSession(IAuthInfo), feedId=feedId, start=start, itemType=itemType) args.update(feedItems) args['itemType'] = itemType suggestions, entities = yield people.get_suggestions(request, SUGGESTION_PER_PAGE, mini=True) args["suggestions"] = suggestions if "entities" not in args: args["entities"] = entities else: for entity in entities.keys(): if entity not in args["entities"].keys(): args["entities"][entity] = entities[entity] if script: onload = """ (function(obj){$$.convs.load(obj);})(this); $('#feed-side-block-container').empty(); """ t.renderScriptBlock(request, "feed.mako", "feed", landing, "#user-feed", "set", True, handlers={"onload": onload}, **args) t.renderScriptBlock(request, "feed.mako", "feedFilterBar", landing, "#feed-filter-bar", "set", True, args=[itemType], **args) t.renderScriptBlock(request, "feed.mako", "_suggestions", landing, "#suggestions", "set", True, **args) for pluginType in plugins: plugin = plugins[pluginType] if hasattr(plugin, 'renderFeedSideBlock'): if not entityId: entityId = myId yield plugin.renderFeedSideBlock(request, landing, entityId, args) if script and landing: request.write("</body></html>") if not script: t.render(request, "feed.mako", **args)