Example #1
0
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))
Example #2
0
    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"])
Example #3
0
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)
Example #4
0
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))
Example #5
0
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))