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 _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 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))