Ejemplo n.º 1
0
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])
Ejemplo n.º 2
0
    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)
Ejemplo n.º 3
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))
Ejemplo n.º 4
0
    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)
Ejemplo n.º 5
0
 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)
Ejemplo n.º 6
0
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)
Ejemplo n.º 7
0
    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)
Ejemplo n.º 8
0
    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)
Ejemplo n.º 9
0
    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)
Ejemplo n.º 10
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"])
Ejemplo n.º 11
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)
Ejemplo n.º 12
0
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)
Ejemplo n.º 13
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))
Ejemplo n.º 14
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))
Ejemplo n.º 15
0
    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)