예제 #1
0
def invite(group, me, user):
    """Invite an user to join a group.
    Only group-member can invite others to the group. Ignore if invited user
    is already a member of the group.

    Keyword params:
    @me:
    @user: user object
    @group: group object
    """
    try:
        yield db.get(group.id, "groupMembers", me.id)
    except ttypes.NotFoundException as e:
        raise e

    try:
        yield db.get(group.id, "groupMembers", user.id)
    except ttypes.NotFoundException:
        try:
            yield db.get(user.id, "pendingConnections", "GO:%s" % (group.id))
        except ttypes.NotFoundException:
            cols = yield db.get_slice(user.id, "pendingConnections",
                                      ["GI:%s" % (group.id)])
            invited_by = set()
            if cols:
                invited_by.update(cols[0].column.value.split(','))
            invited_by.add(me.id)
            yield db.insert(user.id, "pendingConnections",
                            ",".join(invited_by), "GI:%s" % (group.id))
            data = {"entities": {group.id: group, user.id: user, me.id: me},
                    "groupName": group.basic["name"]}
            yield notifications.notify([user.id], ":GI:%s" % (group.id),
                                        me.id, **data)
예제 #2
0
    def _isValidToken(self, emailId, token):
        if not emailId or not token:
            defer.returnValue(None)

        try:
            yield db.get(emailId, "userAuth", "user")
            defer.returnValue(None)
        except:
            pass
        try:
            local, domain = emailId.split('@')
            sender = yield db.get(domain, "invitations", token, emailId)
            sender = sender.column.value
        except ttypes.NotFoundException, e:
            defer.returnValue(None)
예제 #3
0
    def _removeTempFile(self, request):
        (appchange, script, args, myId) = yield self._getBasicArgs(request)
        landing = not self._ajax
        myOrgId = args["orgId"]

        SKey = config.get('CloudFiles', 'SecretKey')
        AKey = config.get('CloudFiles', 'AccessKey')
        bucket = config.get('CloudFiles', 'Bucket')
        creds = AWSCredentials(AKey, SKey)

        client = s3Client.S3Client(creds)
        fileId = utils.getRequestArg(request, "id")
        key = "%s/%s/%s" % (myOrgId, myId, fileId)

        #Check if the file is not in the "files" CF. In other words, it is not
        # attached to an existing item. Also check if I am the owner of the
        # file. Finally clear the existing entry in the "temp_files" CF
        res = yield db.get_slice(fileId, "tmp_files", ["fileId"])
        if len(res) == 1:
            try:
                res = yield db.get(fileId, "files", super_column="meta")
            except ttypes.NotFoundException:
                file_info = yield client.head_object(bucket, key)
                owner = file_info['x-amz-meta-uid'][0]
                if owner == myId:
                    yield client.delete_object(bucket, key)
                    yield db.remove(fileId, "tmp_files")
                else:
                    raise errors.EntityAccessDenied("attachment", fileId)
            else:
                raise errors.InvalidRequest()
예제 #4
0
    def _changePassword(self, request):
        (appchange, script, args, myId) = yield self._getBasicArgs(request)

        currentPass = utils.getRequestArg(request, "curr_passwd", sanitize=False)
        newPass = utils.getRequestArg(request, "passwd1", sanitize=False)
        rptPass = utils.getRequestArg(request, "passwd2", sanitize=False)

        if not currentPass:
            request.write('$$.alerts.error("%s");' % _("Enter your current password"))
            defer.returnValue(None)
        if not newPass:
            request.write('$$.alerts.error("%s");' % _("Enter new password"))
            defer.returnValue(None)
        if not rptPass:
            request.write('$$.alerts.error("%s");' % _("Confirm new password"))
            defer.returnValue(None)
        if newPass != rptPass:
            request.write('$$.alerts.error("%s");' % _("Passwords do not match"))
            defer.returnValue(None)
        if currentPass == newPass:
            request.write('$$.alerts.error("%s");' % _("New password should be different from current password"))
            defer.returnValue(None)

        emailId = args["me"].basic["emailId"]
        col = yield db.get(emailId, "userAuth", "passwordHash")
        storedPass= col.column.value

        if not utils.checkpass(currentPass, storedPass):
            request.write('$$.alerts.error("%s");' % _("Incorrect Password"))
            defer.returnValue(None)

        newPasswd = utils.hashpass(newPass)
        yield db.insert(emailId, "userAuth", newPasswd, "passwordHash")
        request.write('$$.alerts.info("%s");' % _('Password changed'))
예제 #5
0
    def _deletePresetTag(self, request):
        orgId = request.getSession(IAuthInfo).organization
        tagId = utils.getRequestArg(request, 'id')
        if not tagId:
            return

        try:
            tag = yield db.get(orgId, 'orgTags', super_column=tagId)
            tag = utils.supercolumnsToDict([tag])
            tagName = tag[tagId]['title']
            if 'isPreset' in tag[tagId]:
                yield db.remove(orgId, "orgTags", 'isPreset', tagId)
                yield db.remove(orgId, 'orgPresetTags', tagName)
            presetTags = yield db.get_slice(orgId, "orgPresetTags")
            presetTags = utils.columnsToDict(presetTags, ordered=True).values()
            if presetTags:
                tags_ = yield db.get_slice(orgId, "orgTags", presetTags)
                tags_ = utils.supercolumnsToDict(tags)
            else:
                tags_ = {}
            args = {'tagsList': presetTags, 'tags': tags_}
            request.write('$("#tag-%s").remove()' % (tagId))

        except ttypes.NotFoundException:
            return
예제 #6
0
def approveRequest(request, group, user, me):
    """accept a group-join request. Add the user to group-members.
    Only group-admin can perform this action.

    Keyword params:
    @me:
    @user: user object
    @group: group object
    @request:
    """
    if me.id not in group.admins:
        raise errors.PermissionDenied('Access Denied')

    try:
        yield db.get(group.id, "pendingConnections", "GI:%s" % (user.id))
        d1 = _removeFromPending(group, user)
        d2 = _addMember(request, group, user)

        data = {"entities": {group.id: group, user.id: user, me.id: me}}
        d3 = notifications.notify([user.id], ":GA", group.id, **data)

        yield defer.DeferredList([d1, d2, d3])
        defer.returnValue(True)

    except ttypes.NotFoundException:
        pass
    defer.returnValue(False)
예제 #7
0
def reindexItems():
    items = {}
    fetchedItems = yield db.get_range_slice('items', count=10000, reverse=True)
    for row in fetchedItems:
        items[row.key] = utils.supercolumnsToDict(row.columns)

    log.msg("Total items:", len(fetchedItems))
    for i, row in enumerate(fetchedItems):
        itemId = row.key
        item = items[itemId]
        log.msg(i+1, itemId)

        if 'meta' not in item or 'owner' not in item['meta']:
            continue

        owner = item['meta']['owner']
        try:
            col = yield db.get(owner, "entities", "org", "basic")
            ownerOrgId = col.column.value
        except:
            log.msg("Error when indexing:", itemId)
            continue

        parentId = item['meta'].get('parent', None)

        if not parentId:
            yield search.solr.updateItemIndex(itemId, item, ownerOrgId)
        else:
            yield search.solr.updateItemIndex(itemId, item, ownerOrgId, conv=items[parentId])
예제 #8
0
def block(group, user, me):
    """Block user from joining a group/ sending further group-join requests.

    Keyword params:
    @me: entity object with my info
    @user: entity object of the user
    @group: entity object of the group
    """
    if me.id not in group.admins:
        raise errors.PermissionDenied('Access Denied')

    if me.id == user.id:
        raise errors.InvalidRequest(_("An administrator cannot ban himself/herself from the group"))
    try:
        yield db.get(group.id, "pendingConnections", "GI:%s" % (user.id))
        yield _removeFromPending(group, user)
        # Add user to blocked users
        yield db.insert(group.id, "blockedUsers", '', user.id)
        defer.returnValue(True)

    except ttypes.NotFoundException:
        # If the users is already a member, remove the user from the group
        colname = _entityGroupMapColName(group)
        yield db.remove(group.id, "groupMembers", user.id)
        yield db.remove(group.id, "followers", user.id)
        yield db.remove(user.id, "entityGroupsMap", colname)
        # Add user to blocked users
        yield db.insert(group.id, "blockedUsers", '', user.id)
        defer.returnValue(False)
예제 #9
0
파일: item.py 프로젝트: psunkari/flocked-in
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])
예제 #10
0
파일: item.py 프로젝트: psunkari/flocked-in
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)
예제 #11
0
    def _getFileInfo(self, request):
        """Fetch the meta info on a file that is being requested to be
        downloaded. Returns the meta info of the file in question.

        Keyword Arguments:
        itemId: id of the conversation on which this file is attached.
        attachmentId: id of the file on the amazon S3 that is to be served.
        version: version of the file on the amazon S3 that the user is
            requesting.

        """
        authinfo = request.getSession(IAuthInfo)
        myId = authinfo.username
        myOrgId = authinfo.organization
        itemId = utils.getRequestArg(request, "id", sanitize=False)
        attachmentId = utils.getRequestArg(request, "fid", sanitize=False)
        version = utils.getRequestArg(request, "ver", sanitize=False) or ''
        columns = ["meta", "attachments", "participants"]

        if not (itemId and attachmentId):
            raise errors.MissingParams([])

        item = yield db.get_slice(itemId, "mConversations", columns)
        item = utils.supercolumnsToDict(item)
        if not item:
            raise errors.InvalidMessage(itemId)
        if myId not in item.get('participants', {}):
            raise errors.MessageAccessDenied(itemId)

        # Check if the attachmentId belong to item
        if attachmentId not in item['attachments'].keys():
            raise errors.InvalidAttachment(itemId, attachmentId, version)

        fileId, filetype, name = None, 'text/plain', 'file'
        if version:
            version = utils.decodeKey(version)
            try:
                cols = yield db.get(attachmentId, "attachmentVersions", version)
            except ttypes.NotFoundException:
                raise errors.InvalidAttachment(itemId, attachmentId, version)
            except ttypes.InvalidRequestException:
                raise errors.InvalidAttachment(itemId, attachmentId, version)
            cols = utils.columnsToDict([cols])
        else:
            cols = yield db.get_slice(attachmentId, "attachmentVersions", count=1, reverse=True)
            cols = utils.columnsToDict(cols)
            version = cols.keys()[0]


        fileId, name, size, filetype = cols[version].split(':')

        files = yield db.get_slice(fileId, "files", ["meta"])
        files = utils.supercolumnsToDict(files)

        url = files['meta']['uri']
        owner = files["meta"]["owner"]
        defer.returnValue([owner, url, filetype, size, name])
예제 #12
0
def unsubscribe(request, group, user):
    """Unsubscribe @user from @group.
    Remove the user from group-followers, group from user-groups,
    create a group-leave activity item and push item to group-followers
    and group feed. Remove the group from user display name indices.

    Raises an error if user is not member of group or when
    user is the only administrator of the group.

    keyword params:
    @user: entity object of user
    @group: entity object of the group
    @request:

    """
    try:
        yield db.get(group.id, "groupMembers", user.id)
    except ttypes.NotFoundException:
        raise errors.InvalidRequest(_("You are not a member of the group"))

    if len(getattr(group, 'admins', {}).keys()) == 1 \
       and user.id in group.admins:
        raise errors.InvalidRequest(_("You are the only administrator of this group"))

    colname = _entityGroupMapColName(group)
    itemType = "activity"
    responseType = "I"

    itemId = utils.getUniqueKey()
    acl = {"accept": {"groups": [group.id]}}
    _acl = pickle.dumps(acl)
    item = yield utils.createNewItem(request, itemType, user,
                                     acl, "groupLeave")
    item["meta"]["target"] = group.id

    d1 = db.remove(group.id, "followers", user.id)
    d2 = db.remove(user.id, "entityGroupsMap", colname)
    d3 = db.batch_insert(itemId, 'items', item)
    d4 = db.remove(group.id, "groupMembers", user.id)
    d5 = feed.pushToOthersFeed(user.id, user.basic['org'],
                               item["meta"]["uuid"], itemId, itemId, _acl,
                               responseType, itemType, user.id,
                               promoteActor=False)
    d6 = utils.updateDisplayNameIndex(user.id, [group.id], None,
                                      user.basic['name'])
    deferreds = [d1, d2, d3, d4, d5, d6]
    if user.id in group.admins:
        d7 = db.remove(group.id, "entities", user.id, "admins")
        d8 = db.remove(user.id, "entities", group.id, "adminOfGroups")
        deferreds.extend([d7, d8])

    yield defer.DeferredList(deferreds)
예제 #13
0
def follow(group, user):
    """Add @user to @group followers

    Keyword params:
    @group: entity object of group
    @user: entity object of user
    """
    try:
        yield db.get(group.id, "groupMembers", user.id)
        yield db.insert(group.id, "followers", "", user.id)
        defer.returnValue(True)
    except ttypes.NotFoundException:
        return
예제 #14
0
def unfollow(group, user):
    """Remove @user from @group followers

    Keyword params:
    @group: entity object of group
    @user: entity object of user
    """
    try:
        yield db.get(group.id, "groupMembers", user.id)
        yield db.remove(group.id, "followers", user.id)
        defer.returnValue(True)
    except ttypes.NotFoundException:
        return
예제 #15
0
파일: chat.py 프로젝트: psunkari/flocked-in
    def _getMyStatus(self, request):
        authInfo = request.getSession(IAuthInfo)
        myId = authInfo.username
        orgId = authInfo.organization
        sessionId = request.getCookie('session')

        status = ''
        try:
            row = yield db.get(orgId, 'presence', sessionId, myId)
            status = row.column.value
        except Exception as ex:
            status = PresenceStates.OFFLINE

        request.write(json.dumps({"status": status}))
예제 #16
0
    def _moveConversation(self, request, convIds, toFolder):
        """Move a conversation or conversations from one folder to another.

        Keyword Arguments:
        convIds: List of conversation ids which need to be moved.
        toFolder: The final destination of the above conversations

        CF Changes:
        mConvFolders
        mUnreadConversations
        mAllConversations
        mDeletedConversations

        """
        myId = request.getSession(IAuthInfo).username

        convs = yield db.multiget_slice(convIds, "mConversations")
        convs = utils.multiSuperColumnsToDict(convs)
        for convId in convs:
            conv = convs.get(convId, {})
            if not conv:
                raise errors.InvalidMessage(convId)
            if myId not in conv.get('participants', {}):
                raise errors.MessageAccessDenied(convId)

            timeUUID = conv['meta']['uuid']
            val = "%s:%s" % ('u' if toFolder == 'unread' else 'r', convId)

            cols = yield db.get_slice(convId, 'mConvFolders', [myId])
            cols = utils.supercolumnsToDict(cols)
            for folder in cols[myId]:
                cf = self._folders[folder] if folder in self._folders else folder
                if toFolder != 'unread':
                    if folder != 'mUnreadConversations':
                        col = yield db.get(myId, cf, timeUUID)
                        val = col.column.value
                        yield db.remove(myId, cf, timeUUID)
                        yield db.remove(convId, "mConvFolders", cf, myId)
                else:
                    yield db.insert(myId, cf, "u:%s" % (convId), timeUUID)

            if toFolder == 'unread':
                val = "u:%s" % (convId)
                yield db.insert(convId, 'mConvFolders', '', 'mUnreadConversations', myId)
                yield db.insert(myId, 'mUnreadConversations', val, timeUUID)
            else:
                folder = self._folders[toFolder]
                yield db.insert(myId, folder, val, timeUUID)
                yield db.insert(convId, 'mConvFolders', '', folder, myId)
예제 #17
0
    def _editCompanyForm(self, request):
        encodedCompanyId = utils.getRequestArg(request, 'id')
        companyId = utils.decodeKey(encodedCompanyId) if encodedCompanyId else None

        if companyId:
            try:
                myId = request.getSession(IAuthInfo).username
                companyVal = yield db.get(myId, 'entities', companyId, "companies")
                companyVal = companyVal.column.value
                yield t.renderScriptBlock(request, "settings.mako", "companyForm",
                                        False, "#"+encodedCompanyId, "replace",
                                        args=[companyId, companyVal])
                return
            except: pass

        yield t.renderScriptBlock(request, "settings.mako", "companyForm",
                                False, "#addemp-wrap", "set")
예제 #18
0
    def _editSchoolForm(self, request):
        encodedSchoolId = utils.getRequestArg(request, 'id')
        schoolId = utils.decodeKey(encodedSchoolId) if encodedSchoolId else None

        if schoolId:
            try:
                myId = request.getSession(IAuthInfo).username
                schoolVal = yield db.get(myId, 'entities', schoolId, "schools")
                schoolVal = schoolVal.column.value
                yield t.renderScriptBlock(request, "settings.mako", "schoolForm",
                                        False, "#"+encodedSchoolId, "replace",
                                        args=[schoolId, schoolVal])
                return
            except: pass

        yield t.renderScriptBlock(request, "settings.mako", "schoolForm",
                                False, "#addedu-wrap", "set")
예제 #19
0
def rejectRequest(group, user, me):
    """reject user's group-join request.
    Only group-admin can perform this action.

    Keyword params:
    @me:
    @user: user object
    @group: group object
    """
    if me.id not in group.admins:
        raise errors.PermissionDenied('Access Denied')

    try:
        yield db.get(group.id, "pendingConnections", "GI:%s" % (user.id))
        yield _removeFromPending(group, user)
        defer.returnValue(True)
    except ttypes.NotFoundException:
        pass
    defer.returnValue(False)
예제 #20
0
파일: tags.py 프로젝트: psunkari/flocked-in
    def _render(self, request):
        (appchange, script, args, myId) = yield self._getBasicArgs(request)
        landing = not self._ajax

        (tagId, tagInfo) = yield utils.getValidTagId(request, 'id')
        args["tags"] = tagInfo
        args["tagId"] = tagId
        args["tagFollowing"] = False
        args["menuId"] = "tags"

        if script and landing:
            t.render(request, "tags.mako", **args)

        if script and appchange:
            t.renderScriptBlock(request, "tags.mako", "layout",
                                landing, "#mainbar", "set", **args)

        try:
            yield db.get(tagId, "tagFollowers", myId)
            args["tagFollowing"] = True
        except ttypes.NotFoundException:
            pass

        if script:
            t.renderScriptBlock(request, "tags.mako", "header",
                                landing, "#tags-header", "set", **args)
        start = utils.getRequestArg(request, "start") or ''

        tagItems = yield self._getTagItems(request, tagId, start=start)
        args.update(tagItems)

        if script:
            onload = """
                        (function(obj){$$.convs.load(obj);})(this);
                        $('form').html5form({messages: 'en'});
                     """
            t.renderScriptBlock(request, "tags.mako", "itemsLayout",
                                landing, "#content", "set", True,
                                handlers={"onload": onload}, **args)

        if not script:
            t.render(request, "tags.mako", **args)
예제 #21
0
def subscribe(request, group, user, org):
    """Open group: add user to the group.
    Closed group: add a pending request, send a notification to group-admins.
    Raise an exception if user is blocked from joining the group.

    Keyword params:
    @org: org object
    @user: user object
    @group: group object
    @request:

    """
    cols = yield db.get_slice(group.id, "blockedUsers", [user.id])
    if cols:
        raise errors.PermissionDenied(_("You are banned from joining the group."))

    isNewMember = False
    pendingRequests = {}
    try:
        cols = yield db.get(group.id, "groupMembers", user.id)
    except ttypes.NotFoundException:
        if group.basic['access'] == "open":
            yield _addMember(request, group, user)
            yield _removeFromPending(group, user)
            isNewMember = True
        else:
            # Add to pending connections
            yield db.insert(user.id, "pendingConnections",
                            '', "GO:%s" % (group.id))
            yield db.insert(group.id, "pendingConnections",
                            '', "GI:%s" % (user.id))

            yield _notify(group, user)
            pendingRequests["GO:%s" % (group.id)] = user.id

            entities = base.EntitySet(group.admins.keys())
            yield entities.fetchData()

            entities.update({group.id: group, org.id: org, user.id: user})
            data = {"entities": entities, "groupName": group.basic['name']}
            yield notifications.notify(group.admins, ":GR", user.id, **data)
    defer.returnValue((isNewMember, pendingRequests))
예제 #22
0
def removeUser(group, user, me):
    """Remove user from the group.
    Only group-admin can perform this action.

    Keyword params
    @me:
    @user: user object
    @group: group object
    """
    if me.id not in group.admins:
        raise errors.PermissionDenied('Access Denied')

    if len(getattr(group, 'admins', {})) == 1 and me.id == user.id:
        raise errors.InvalidRequest(_("You are currently the only administrator of this group"))

    try:
        cols = yield db.get(group.id, "groupMembers", user.id)
        itemId = cols.column.value
        username = user.basic['name']
        colName = _entityGroupMapColName(group)
        d1 = db.remove(itemId, "items")
        d2 = db.remove(group.id, "followers", user.id)

        d3 = db.remove(user.id, "entityGroupsMap", colName)
        d4 = db.remove(group.id, "groupMembers", user.id)
        d5 = utils.updateDisplayNameIndex(user.id, [group.id], '', username)
        deferreds = [d1, d2, d3, d4, d5]

        if user.id in group.admins:
            d6 = db.remove(group.id, 'entities', user.id, 'admins')
            d7 = db.remove(user.id, 'entities', group.id, 'adminOfGroups')
            deferreds.extend([d6, d7])

        #XXX: remove item from feed?
        yield defer.DeferredList(deferreds)
        defer.returnValue(True)

    except ttypes.NotFoundException:
        pass
예제 #23
0
파일: tags.py 프로젝트: psunkari/flocked-in
def _ensureTag(tagName, myId, orgId, presetTag=False):
    try:
        tagName = tagName.lower()
        c = yield db.get(orgId, "orgTagsByName", tagName)
        tagId = c.column.value
        c = yield db.get_slice(orgId, "orgTags", super_column=tagId)
        tag = utils.columnsToDict(c)
        if presetTag and not tag.get('isPreset', '') == 'True':
            yield db.insert(orgId, "orgPresetTags", tagId, tagName)

            yield db.insert(orgId, "orgTags", 'True', 'isPreset', tagId)
            tag['isPreset'] = 'True'
    except ttypes.NotFoundException:
        tagId = utils.getUniqueKey()
        tag = {"title": tagName, 'createdBy': myId}
        if presetTag:
            tag['isPreset'] = 'True'
        tagName = tagName.lower()
        yield db.batch_insert(orgId, "orgTags", {tagId: tag})
        yield db.insert(orgId, "orgTagsByName", tagId, tagName)
        if presetTag:
            yield db.insert(orgId, "orgPresetTags", tagId, tagName)

    defer.returnValue((tagId, tag))
예제 #24
0
    def _getFileInfo(self, request):
        authinfo = request.getSession(IAuthInfo)
        myId = authinfo.username
        myOrgId = authinfo.organization

        itemId, item = yield utils.getValidItemId(request, 'id')
        attachmentId = utils.getRequestArg(request, "fid", sanitize=False)
        version = utils.getRequestArg(request, "ver", sanitize=False)

        if not attachmentId:
            raise errors.MissingParams()

        # Check if the attachmentId belong to item
        if attachmentId not in item['attachments'].keys():
            raise errors.EntityAccessDenied("attachment", attachmentId)
        if version:
            version = utils.decodeKey(version)
            cols = yield db.get(attachmentId, "attachmentVersions", version)
            cols = utils.columnsToDict([cols])
        else:
            cols = yield db.get_slice(attachmentId, 'attachmentVersions', count=1, reverse=True)
            cols = utils.columnsToDict(cols)
            version = cols.keys()[0]

        if not cols:
            raise errors.InvalidRequest()

        fileId, fileType, name = None, 'text/plain', 'file'
        fileId, name, size, fileType = cols[version].split(':')

        files = yield db.get_slice(fileId, "files", ["meta"])
        files = utils.supercolumnsToDict(files)

        url = files['meta']['uri']
        owner = files["meta"]["owner"]
        defer.returnValue([owner, url, fileType, size, name])
예제 #25
0
파일: chat.py 프로젝트: psunkari/flocked-in
    def _postChat(self, request):
        comment = utils.getRequestArg(request, 'message')
        channelId = utils.getRequestArg(request, 'room')

        if not comment:  # Ignore empty comment
            return

        authInfo = request.getSession(IAuthInfo)
        myId = authInfo.username
        orgId = authInfo.organization
        timeuuid = uuid.uuid1().bytes

        recipientId, recipient = yield utils.getValidEntityId(request, 'to')
        me = base.Entity(myId)
        yield me.fetchData()
        myName = me.basic['name']
        myAvatar = utils.userAvatar(myId, me, 's')

        chatId = utils.getUniqueKey()
        sessionId = request.getCookie('session')
        try:
            col = yield db.get(orgId, 'presence', sessionId, myId)
        except ttypes.NotFoundException:
            self.setResponseCodeAndWrite(request, 200, {'error': 'You are currently offline'})
            return

        cols = yield db.get_slice(orgId, "presence", super_column=recipientId)
        recipientStatus = getMostAvailablePresence(
                                utils.columnsToDict(cols).values())
        if recipientStatus == PresenceStates.OFFLINE:
            self.setResponseCodeAndWrite(request, 200, {'error': 'Cannot send message. User is currently offline'})
            return

        message = {"from": myName, "to": recipientId, "message": comment,
                   "timestamp": time.time(), "avatar": myAvatar}
        data = {"type": "room", "from": myId, "to": recipientId,
                "message": message}
        if channelId:
            channelSubscribers = yield db.get_slice(channelId,
                                                    'channelSubscribers')
            channelSubscribers = utils.columnsToDict(channelSubscribers)
            channelSubscribers = set([x.split(':', 1)[0] \
                                      for x in channelSubscribers])

            if myId not in channelSubscribers:
                self.setResponseCodeAndWrite(request, 200, {'error': 'Access denied'})
                return
            yield db.insert(channelId, 'channelSubscribers', '', '%s:%s'\
                            % (myId, sessionId))
            yield db.insert("%s:%s" % (myId, sessionId), "sessionChannelsMap",
                            '', channelId)

            data["room"] = channelId

            startKey = '%s:' % recipientId
            cols = yield db.get_slice(channelId, "channelSubscribers",
                                      start=startKey, count=1)
            count = len([col for col in cols \
                         if col.column.name.startswith(startKey)])
            try:
                yield comet.publish('/chat/%s' % (channelId), message)
                if not count:
                    yield comet.publish('/notify/%s' % (recipientId), data)
            except Exception, e:
                self.setResponseCodeAndWrite(request, 200, {'error': 'The message could not be sent!'})
                return
예제 #26
0
def updateData():
    yield db.truncate('user_files')
    try:
        yield db.get('asdf', 'entityFeed_files', uuid.uuid1().bytes)
    except ttypes.InvalidRequestException as exception:
        log.msg(exception)
        raise Exception('entityFeed_files CF missing, create the CF')
    except ttypes.NotFoundException:
        pass
    entities = {}
    items = {}

    rows = yield db.get_range_slice('items', count=10000, reverse=True)
    for row in rows:
        itemId = row.key
        item = utils.supercolumnsToDict(row.columns)
        items[itemId]=item

    for itemId in items:
        item =  items[itemId]
        log.msg(itemId)
        if 'meta' not in item:
            continue

        # Add org to all items
        try:
            owner = item['meta']['owner']
            col = yield db.get(owner, "entities", 'org', 'basic')
            ownerOrgId = col.column.value
            yield db.insert(itemId, 'items', ownerOrgId, 'org', 'meta')
        except Exception as e:
            if item['meta'].get('type', '') == 'feedback':
                yield db.insert(itemId, 'items', owner, 'org', 'meta')

        # Fix ACLs
        if 'parent' not in item['meta']:
            acl = item['meta']['acl']
            convOwner = item['meta']['owner']
            convId = itemId

            if acl == 'company':
                col = yield db.get(convOwner, "entities", "org", "basic")
                ownerOrgId = col.column.value
                acl = pickle.dumps({"accept":{"orgs":[ownerOrgId]}})
                yield db.insert(convId, 'items', acl, 'acl', 'meta')
            else:
                try:
                    acl = pickle.loads(acl)
                    if 'accept' in acl and 'friends' in acl['accept'] and isinstance(acl['accept']['friends'], bool):
                        del acl['accept']['friends']
                        acl = pickle.dumps(acl)
                        yield db.insert(convId, 'items', acl, 'acl', 'meta')
                except :
                    log.msg('cannot unpack acl', acl)

        # Migrate files
        #    truncate user_files
        #    update user_files and entityFeed_files
        if 'owner' in item['meta'] and 'attachments' in item:
            ownerId = item['meta']['owner']
            if ownerId not in entities:
                cols = yield db.get_slice(ownerId, 'entities', ['basic'])
                entities.update({ownerId: utils.supercolumnsToDict(cols)})
            for attachmentId in item['attachments']:
                orgId = entities[ownerId]['basic']['org']
                timeuuid, name = item['attachments'][attachmentId].split(':')[:2]
                timeuuid = utils.decodeKey(timeuuid)
                val = '%s:%s:%s:%s' % (attachmentId, name, itemId, ownerId)
                yield db.insert(ownerId, "user_files", val, timeuuid)
                if 'parent' not in item['meta'] and item['meta'].get('acl', ''):
                    _entities = yield utils.expandAcl(ownerId, orgId, item['meta']['acl'],
                                                      itemId, ownerId, True)
                    for entityId in _entities:
                        yield db.insert(entityId, "entityFeed_files", val, timeuuid)

        # Migrate items
        # Meta fields in "link", "event" and "poll"
        if item['meta'].get('type', None) in ['link', 'poll', 'event']:
            itemMeta = item['meta']
            itemType = itemMeta['type']
            updated = {}

            if itemType == "link":
                if 'url' in itemMeta:
                    updated['link_url'] = itemMeta['url']
                if 'title' in itemMeta:
                    updated['link_title'] = itemMeta['title']
                if 'summary' in itemMeta:
                    updated['link_summary'] = itemMeta['summary']
                if 'imgSrc' in itemMeta:
                    updated['link_imgSrc'] = itemMeta['imgSrc']
                if 'embedType' in itemMeta:
                    updated['link_embedType'] = itemMeta['embedType']
                if 'embedSrc' in itemMeta:
                    updated['link_embedSrc'] = itemMeta['embedSrc']
                if 'embedHeight' in itemMeta:
                    updated['link_embedHeight'] = itemMeta['embedHeight']
                if 'embedWidth' in itemMeta:
                    updated['link_embedWidth'] = itemMeta['embedWidth']
            elif itemType == 'poll':
                if 'question' in itemMeta:
                    updated['comment'] = itemMeta['question']
            else:
                print 'Found an event:', itemId

            if updated:
                yield db.batch_insert(itemId, 'items', {'meta': updated})


    #
    # Create poll indexes for feed and userItems
    #
    rows = yield db.get_range_slice('entities', count=10000, reverse=True)
    mutations = {}
    for row in rows:
        entityId = row.key
        entity = utils.supercolumnsToDict(row.columns)

        if entity['basic']['type'] != 'user':
            continue

        d1 = db.get_slice(entityId, 'feed', count=10000)
        d2 = db.get_slice(entityId, 'userItems', count=10000)

        results = yield d1
        for col in results:
            value = col.column.value
            if value in items:
                if items.get(value, {}).get('meta', {}).get('type', '') == 'poll':
                    mutations.setdefault(entityId, {}).setdefault('feed_poll', {}).update({col.column.name: value})

        results = yield d2
        for col in results:
            value = col.column.value
            responseType, itemId, convId, convType, others = value.split(':', 4)
            if convType == 'poll':
                mutations.setdefault(entityId, {}).setdefault('userItems_poll', {}).update({col.column.name: value})
    yield db.batch_mutate(mutations)

    #Group type changed from public-private to open-closed.
    rows = yield db.get_range_slice('entityGroupsMap', count=1000)
    groupIds = set()
    for row in rows:
        for col in row.columns:
            name_, groupId = col.column.name.split(':')
            groupIds.add(groupId)

    cols = yield db.multiget_slice(groupIds, "entities")
    groups = utils.multiSuperColumnsToDict(cols)
    for groupId in groups:
        access = groups[groupId]['basic']['access'].lower()
        if access == 'public':
            yield db.insert(groupId, 'entities', 'open', 'access', 'basic')
        elif access.lower() == 'private':
            yield db.insert(groupId, 'entities', 'closed', 'access', 'basic')

    #Fix entityGroupsMap
    rows = yield db.get_range_slice('entityGroupsMap', count=1000)
    for row in rows:
        entityId = row.key
        for col in row.columns:
            name_, groupId = col.column.name.split(':')
            if col.column.name != '%s:%s'%(groups[groupId]['basic']['name'].lower(), groupId):
                yield db.remove(entityId, 'entityGroupsMap', col.column.name)
                yield db.insert(entityId, 'entityGroupsMap', '', '%s:%s' %(groups[groupId]['basic']['name'].lower(), groupId))
예제 #27
0
 def getSession(self, uid):
     result = yield db.get(uid, "sessions", "auth")
     serialized = result.column.value
     defer.returnValue(pickle.loads(serialized))
예제 #28
0
파일: item.py 프로젝트: psunkari/flocked-in
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)