Example #1
0
def delete_post(post_id):
    """Deletes a post

    """
    post = get_post(post_id)

    # In some situations a post may be in a cursor (deleting account) but have
    # already been deleted by this function in a previous run.
    if post is not None:
        # Delete votes and subscribers from Redis
        r.delete(k.POST_VOTES.format(post.get('_id')))

        # Delete the post from MongoDB
        m.db.posts.remove({'_id': post_id})

        if 'upload' in post:
            # If there is an upload, delete it!
            delete_upload(post['upload'])

        if 'reply_to' in post:
            m.db.posts.update({'_id': post['reply_to']},
                              {'$inc': {'comment_count': -1}})
        else:
            # Trigger deletion all posts comments if this post isn't a reply
            r.delete(k.POST_SUBSCRIBERS.format(post.get('_id')))
            delete_post_replies(post_id)
Example #2
0
    def test_uploads(self):
        """Simply tests the backend functions in `lib.uploads`.

        Also tests `posts.get_upload` since this is only a simple wrapper
        around the backend function.

        """
        test_upload_dir = 'tests/upload_test_files/'
        test_upload_files = [
            join(test_upload_dir, f) for f in listdir(test_upload_dir)
            if isfile(join(test_upload_dir, f))
        ]

        # Create a GridFS object to test image deletion
        grid = gridfs.GridFS(m.db, collection='uploads')

        # Test each file in the upload directory
        for f in test_upload_files:
            # Don't read non image files in the directory
            _, ext = splitext(f)
            if ext not in ('.gif', '.jpg', '.jpeg', '.png'):
                continue

            image = io.BytesIO(
                open(f).read()
            )
            filename, animated = process_upload(image)

            # Get the upload these are designed for being served directly by
            # Flask. This is a Flask/Werkzeug response object
            image = get_upload(filename)
            self.assertTrue(grid.exists({'filename': filename}))
            self.assertEqual(image.headers['Content-Type'], 'image/png')

            if animated:
                image = get_upload(animated)
                self.assertTrue(grid.exists({'filename': animated}))
                self.assertEqual(image.headers['Content-Type'], 'image/gif')

            # Test deletion
            # Ensure file is present (it will be)
            self.assertTrue(grid.exists({'filename': filename}))
            # Delete the file and ensure it is not there through GridFS
            delete_upload(filename)
            # Ensure the file has gone
            self.assertFalse(grid.exists({'filename': filename}))

        # Ensure that if we load a non-image file a None value is returned
        image = io.BytesIO()
        self.assertEqual(process_upload(image), (None, None))
Example #3
0
def update_profile_settings(user_id,
                            about="",
                            hide_feed_images=False,
                            feed_size=25,
                            replies_size=25,
                            alerts_size=50,
                            reply_sort_order=-1,
                            homepage='',
                            location='',
                            upload=None,
                            permission=0):
    """Update all options on a users profile settings in MongoDB."""
    # Ensure the homepage URL is as valid as it can be
    if homepage != '':
        homepage = fix_url(homepage)

    avatar = None
    if upload:
        filename = process_upload(upload, image_size=(96, 96), thumbnail=False)
        if filename is not None:  # pragma: no cover
            avatar = filename

    update_dict = {
        'about': about,
        'hide_feed_images': hide_feed_images,
        'feed_pagination_size': int(feed_size),
        'replies_pagination_size': int(replies_size),
        'alerts_pagination_size': int(alerts_size),
        'reply_sort_order': reply_sort_order,
        'homepage': homepage,
        'location': location,
        'default_permission': int(permission)
    }

    if avatar is not None:
        update_dict['avatar'] = avatar

        user = get_user(user_id)

        if user.get('avatar'):
            # Clean up any old avatars
            # There is no update in GridFS
            delete_upload(user.get('avatar'))

    # Update the users profile
    m.db.users.update({'_id': user_id}, {'$set': update_dict})

    # Return the user object. We can update the current_user from this
    return get_user(user_id)
Example #4
0
File: backend.py Project: pjuu/pjuu
def update_profile_settings(user_id, about="", hide_feed_images=False,
                            feed_size=25, replies_size=25, alerts_size=50,
                            reply_sort_order=-1, homepage='', location='',
                            upload=None, permission=0):
    """Update all options on a users profile settings in MongoDB."""
    # Ensure the homepage URL is as valid as it can be
    if homepage != '':
        homepage = fix_url(homepage)

    avatar = None
    if upload:
        filename, _ = process_upload(upload, image_size=(96, 96),
                                     thumbnail=False)
        if filename is not None:  # pragma: no cover
            avatar = filename

    update_dict = {
        'about': about,
        'hide_feed_images': hide_feed_images,
        'feed_pagination_size': int(feed_size),
        'replies_pagination_size': int(replies_size),
        'alerts_pagination_size': int(alerts_size),
        'reply_sort_order': reply_sort_order,
        'homepage': homepage,
        'location': location,
        'default_permission': int(permission)
    }

    if avatar is not None:
        update_dict['avatar'] = avatar

        user = get_user(user_id)

        if user.get('avatar'):
            # Clean up any old avatars
            # There is no update in GridFS
            delete_upload(user.get('avatar'))

    # Update the users profile
    m.db.users.update({'_id': user_id}, {'$set': update_dict})

    # Return the user object. We can update the current_user from this
    return get_user(user_id)
Example #5
0
    def test_uploads(self):
        """Simply tests the backend functions in `lib.uploads`.

        Also tests `posts.get_upload` since this is only a simple wrapper
        around the backend function.

        """
        test_upload_dir = 'tests/upload_test_files/'
        test_upload_files = [
            join(test_upload_dir, f) for f in listdir(test_upload_dir)
            if isfile(join(test_upload_dir, f))
        ]

        # Create a GridFS object to test image deletion
        grid = gridfs.GridFS(m.db, collection='uploads')

        # Test each file in the upload directory
        for f in test_upload_files:
            image = io.BytesIO(open(f).read())
            filename = process_upload(image)

            # Get the upload these are designed for being served directly by
            # Flask. This is a Flask/Werkzeug response object
            image = get_upload(filename)
            self.assertTrue(grid.exists({'filename': filename}))
            self.assertEqual(image.headers['Content-Type'], 'image/png')

            # Test deletion
            # Ensure file is present (it will be)
            self.assertTrue(grid.exists({'filename': filename}))
            # Delete the file and ensure it is not there through GridFS
            delete_upload(filename)
            # Ensure the file has gone
            self.assertFalse(grid.exists({'filename': filename}))

        # Ensure that if we load a non-image file a None value is returned
        image = io.BytesIO()
        self.assertIsNone(process_upload(image))
Example #6
0
def delete_post_replies(post_id):
    """Delete ALL comments on post with pid.

    This can't be done in one single call to Mongo because we need to remove
    the votes from Redis!

    """
    # Get a cursor for all the posts comments
    cur = m.db.posts.find({'reply_to': post_id})

    # Iterate over the cursor and delete each one
    for reply in cur:
        reply_id = reply.get('_id')

        # Delete the comment itself from MongoDB
        m.db.posts.remove({'_id': reply_id})

        # Remove any uploaded files
        if 'upload' in reply:
            delete_upload(reply['upload'])

        # Delete votes from Redis
        r.delete(k.POST_VOTES.format(reply_id))
Example #7
0
def delete_account(user_id):
    """Will delete a users account.

    This **REMOVES ALL** details, posts, replies, etc. Not votes though.

    .. note: Ensure the user has authenticated this request. This is going to
             be the most *expensive* task in Pjuu, be warned.

    :param user_id: The `user_id` of the user to delete
    :type user_id: str

    """
    # Get the user object we will need this to remove the avatar
    user = get_user(user_id)

    # Delete the user from MongoDB
    m.db.users.remove({'_id': user_id})

    # If the user has an avatar remove it
    if user.get('avatar'):
        delete_upload(user.get('avatar'))

    # Remove all posts a user has ever made. This includes all votes
    # on the posts and all comments of the posts.
    # This calls the backend function from posts to do the deed
    posts_cursor = m.db.posts.find({'user_id': user_id}, {})
    for post in posts_cursor:
        delete_post(post.get('_id'))

    # Remove all the following relationships from Redis

    # Delete all references to followers of the user.
    # This will remove the user from the other users following list

    # TODO Replace with ZSCAN
    follower_cursor = r.zrange(k.USER_FOLLOWERS.format(user_id), 0, -1)

    for follower_id in follower_cursor:
        # Clear the followers following list of the uid
        r.zrem(k.USER_FOLLOWING.format(follower_id), user_id)
    # Delete the followers list
    r.delete(k.USER_FOLLOWERS.format(user_id))

    # Delete all references to the users the user is following
    # This will remove the user from the others users followers list

    # TODO Replace with ZSCAN
    followee_cursor = r.zrange(k.USER_FOLLOWING.format(user_id), 0, -1)

    for followee_id in followee_cursor:
        # Clear the followers list of people uid is following
        r.zrem(k.USER_FOLLOWERS.format(followee_id), user_id)
    # Delete the following list
    r.delete(k.USER_FOLLOWING.format(user_id))

    # Delete the users feed, this may have been added too during this process.
    # Probably not but let's be on the safe side
    r.delete(k.USER_FEED.format(user_id))

    # Delete the users alert list
    # DO NOT DELETE ANY ALERTS AS THESE ARE GENERIC
    r.delete(k.USER_ALERTS.format(user_id))
Example #8
0
def delete_account(user_id):
    """Will delete a users account.

    This **REMOVES ALL** details, posts, replies, etc. Not votes though.

    .. note: Ensure the user has authenticated this request. This is going to
             be the most *expensive* task in Pjuu, be warned.

    :param user_id: The `user_id` of the user to delete
    :type user_id: str

    """
    # Get the user object we will need this to remove the avatar
    user = get_user(user_id)

    # Delete the user from MongoDB
    m.db.users.remove({'_id': user_id})

    # If the user has an avatar remove it
    if user.get('avatar'):
        delete_upload(user.get('avatar'))

    # Remove all posts a user has ever made. This includes all votes
    # on the posts and all comments of the posts.
    # This calls the backend function from posts to do the deed
    posts_cursor = m.db.posts.find({'user_id': user_id}, {})
    for post in posts_cursor:
        delete_post(post.get('_id'))

    # Remove all the following relationships from Redis

    # Delete all references to followers of the user.
    # This will remove the user from the other users following list

    # TODO Replace with ZSCAN
    follower_cursor = r.zrange(k.USER_FOLLOWERS.format(user_id), 0, -1)

    for follower_id in follower_cursor:
        # Clear the followers following list of the uid
        r.zrem(k.USER_FOLLOWING.format(follower_id), user_id)
    # Delete the followers list
    r.delete(k.USER_FOLLOWERS.format(user_id))

    # Delete all references to the users the user is following
    # This will remove the user from the others users followers list

    # TODO Replace with ZSCAN
    followee_cursor = r.zrange(k.USER_FOLLOWING.format(user_id), 0, -1)

    for followee_id in followee_cursor:
        # Clear the followers list of people uid is following
        r.zrem(k.USER_FOLLOWERS.format(followee_id), user_id)
    # Delete the following list
    r.delete(k.USER_FOLLOWING.format(user_id))

    # Delete the users feed, this may have been added too during this process.
    # Probably not but let's be on the safe side
    r.delete(k.USER_FEED.format(user_id))

    # Delete the users alert list
    # DO NOT DELETE ANY ALERTS AS THESE ARE GENERIC
    r.delete(k.USER_ALERTS.format(user_id))