コード例 #1
0
ファイル: test_posts_backend.py プロジェクト: cycle-chen/pjuu
    def test_get_feed(self):
        """
        Attempt to get a users feed under certain circumstances.
        """
        # Get test user
        user1 = create_account('user1', '*****@*****.**', 'Password')
        # Ensure an empty feed is returned. Remember these are paginations
        self.assertEqual(len(get_feed(user1).items), 0)
        # Ensure a users own post is added to thier feed
        post1 = create_post(user1, 'user1', 'Test post')
        # Ensure the list is the correct length
        self.assertEqual(len(get_feed(user1).items), 1)
        self.assertEqual(get_feed(user1).total, 1)
        # Ensure the item is in Redis
        self.assertIn(post1, r.zrange(K.USER_FEED.format(user1), 0, -1))

        # Create a second user, make 1 follow them, make then post and ensure
        # that the new users post appears in user 1s feed
        user2 = create_account('user2', '*****@*****.**', 'Password')
        follow_user(user1, user2)

        post2 = create_post(user2, 'user2', 'Test post')
        # Check user 1's feed for the next item
        self.assertEqual(len(get_feed(user1).items), 2)
        self.assertEqual(get_feed(user1).total, 2)
        # Ensure the item is in Redis
        self.assertIn(post2, r.zrange(K.USER_FEED.format(user1), 0, -1))
        # Delete user 2 and ensure user 1's feed cleans itself
        delete_account(user2)
        self.assertEqual(len(get_feed(user1).items), 1)
        self.assertEqual(get_feed(user1).total, 1)
        # Ensure the item is not in Redis
        self.assertNotIn(post2, r.zrange(K.USER_FEED.format(user1), 0, -1))
コード例 #2
0
    def test_get_feed(self):
        """
        Attempt to get a users feed under certain circumstances.
        """
        # Get test user
        user1 = create_account('user1', '*****@*****.**', 'Password')
        # Ensure an empty feed is returned. Remember these are paginations
        self.assertEqual(len(get_feed(user1).items), 0)
        # Ensure a users own post is added to thier feed
        post1 = create_post(user1, 'user1', 'Test post')
        # Ensure the list is the correct length
        self.assertEqual(len(get_feed(user1).items), 1)
        self.assertEqual(get_feed(user1).total, 1)
        # Ensure the item is in Redis
        self.assertIn(post1, r.zrange(K.USER_FEED.format(user1), 0, -1))

        # Create a second user, make 1 follow them, make then post and ensure
        # that the new users post appears in user 1s feed
        user2 = create_account('user2', '*****@*****.**', 'Password')
        follow_user(user1, user2)

        post2 = create_post(user2, 'user2', 'Test post')
        # Check user 1's feed for the next item
        self.assertEqual(len(get_feed(user1).items), 2)
        self.assertEqual(get_feed(user1).total, 2)
        # Ensure the item is in Redis
        self.assertIn(post2, r.zrange(K.USER_FEED.format(user1), 0, -1))
        # Delete user 2 and ensure user 1's feed cleans itself
        delete_account(user2)
        self.assertEqual(len(get_feed(user1).items), 1)
        self.assertEqual(get_feed(user1).total, 1)
        # Ensure the item is not in Redis
        self.assertNotIn(post2, r.zrange(K.USER_FEED.format(user1), 0, -1))
コード例 #3
0
ファイル: backend.py プロジェクト: hnk/pjuu
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

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

    # 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))
コード例 #4
0
    def test_delete_account_followers_following(self):
        """Does the users social graph go on deletion of account?

        """
        user1 = create_account('user1', '*****@*****.**', 'Password')
        user2 = create_account('user2', '*****@*****.**', 'Password')

        # Friends :)
        self.assertTrue(follow_user(user1, user2))
        self.assertTrue(follow_user(user2, user1))

        # Ensure Redis's sorted sets are correct
        self.assertIn(user2, r.zrange(K.USER_FOLLOWERS.format(user1), 0, -1))
        self.assertIn(user2, r.zrange(K.USER_FOLLOWING.format(user1), 0, -1))
        self.assertIn(user1, r.zrange(K.USER_FOLLOWERS.format(user2), 0, -1))
        self.assertIn(user1, r.zrange(K.USER_FOLLOWING.format(user2), 0, -1))

        delete_account(user1)

        # Ensure sorted sets are emptied
        self.assertNotIn(user2, r.zrange(K.USER_FOLLOWERS.format(user1), 0,
                                         -1))
        self.assertNotIn(user2, r.zrange(K.USER_FOLLOWING.format(user1), 0,
                                         -1))
        self.assertNotIn(user1, r.zrange(K.USER_FOLLOWERS.format(user2), 0,
                                         -1))
        self.assertNotIn(user1, r.zrange(K.USER_FOLLOWING.format(user2), 0,
                                         -1))
コード例 #5
0
ファイル: test_auth_backend.py プロジェクト: pjuu/pjuu
    def test_delete_account_followers_following(self):
        """Does the users social graph go on deletion of account?

        """
        user1 = create_account('user1', '*****@*****.**', 'Password')
        user2 = create_account('user2', '*****@*****.**', 'Password')

        # Friends :)
        self.assertTrue(follow_user(user1, user2))
        self.assertTrue(follow_user(user2, user1))

        # Ensure Redis's sorted sets are correct
        self.assertIn(user2, r.zrange(K.USER_FOLLOWERS.format(user1), 0, -1))
        self.assertIn(user2, r.zrange(K.USER_FOLLOWING.format(user1), 0, -1))
        self.assertIn(user1, r.zrange(K.USER_FOLLOWERS.format(user2), 0, -1))
        self.assertIn(user1, r.zrange(K.USER_FOLLOWING.format(user2), 0, -1))

        delete_account(user1)

        # Ensure sorted sets are emptied
        self.assertNotIn(user2, r.zrange(K.USER_FOLLOWERS.format(user1),
                                         0, -1))
        self.assertNotIn(user2, r.zrange(K.USER_FOLLOWING.format(user1),
                                         0, -1))
        self.assertNotIn(user1, r.zrange(K.USER_FOLLOWERS.format(user2),
                                         0, -1))
        self.assertNotIn(user1, r.zrange(K.USER_FOLLOWING.format(user2),
                                         0, -1))
コード例 #6
0
ファイル: test_auth_backend.py プロジェクト: adzilla/pjuu
    def test_delete_account_followers_following(self):
        """
        Test delete_account()

        Followers & Following: Ensures that all data related to followers is
        removed during account deletion

        Note: This is not a full test of the users system. See users/test.py
        """
        # Create test users
        user1 = create_user('user1', '*****@*****.**', 'Password')
        user2 = create_user('user2', '*****@*****.**', 'Password')
        # Make users follow each other
        self.assertTrue(follow_user(user1, user2))
        self.assertTrue(follow_user(user2, user1))
        # Ensure the uid's are in the relevant sorted sets
        self.assertIn(user2, r.zrange(K.USER_FOLLOWERS.format(user1), 0, -1))
        self.assertIn(user2, r.zrange(K.USER_FOLLOWING.format(user1), 0, -1))
        self.assertIn(user1, r.zrange(K.USER_FOLLOWERS.format(user2), 0, -1))
        self.assertIn(user1, r.zrange(K.USER_FOLLOWING.format(user2), 0, -1))

        # Delete test account 1
        delete_account(user1)

        # Ensure the lists are empty
        self.assertNotIn(user2, r.zrange(K.USER_FOLLOWERS.format(user1),
                                         0, -1))
        self.assertNotIn(user2, r.zrange(K.USER_FOLLOWING.format(user1),
                                         0, -1))
        self.assertNotIn(user1, r.zrange(K.USER_FOLLOWERS.format(user2),
                                         0, -1))
        self.assertNotIn(user1, r.zrange(K.USER_FOLLOWING.format(user2),
                                         0, -1))
コード例 #7
0
ファイル: test_posts_backend.py プロジェクト: pjuu/pjuu
    def test_create_post(self):
        """Tests creating and getting a post

        """
        # Create a user to test creating post
        user1 = create_account('user1', '*****@*****.**', 'Password')
        # Create post
        post1 = create_post(user1, 'user1', 'Test post')
        # Check the post actually exists
        self.assertIsNotNone(post1)

        # Check that all the hash members are what we expect
        post = get_post(post1)
        self.assertIsNotNone(post)
        self.assertEqual(post.get('_id'), post1)
        self.assertEqual(post.get('user_id'), user1)
        self.assertEqual(post.get('body'), 'Test post')
        self.assertEqual(post.get('score'), 0)
        self.assertEqual(post.get('comment_count'), 0)
        # Check the memebers we don't know the answer to
        self.assertIsNotNone(post.get('created'))
        self.assertNotIn('upload', post)

        # Ensure this post is the users feed (populate_feed)
        self.assertIn(post1, r.zrange(K.USER_FEED.format(user1), 0, -1))

        # Testing getting post with invalid arguments
        # Test getting a post that does not exist
        self.assertIsNone(get_post(K.NIL_VALUE))

        # Create a post with an image
        image = io.BytesIO(open('tests/upload_test_files/otter.jpg').read())
        post2 = create_post(user1, 'user1', 'Test post #2', upload=image)

        self.assertIsNotNone(post2)

        post = get_post(post2)
        self.assertIn('upload', post)
        self.assertIsNotNone(post.get('upload'))

        image = io.BytesIO(open('tests/upload_test_files/otter.gif').read())
        post3 = create_post(user1, 'user1', 'Test post #2', upload=image)

        self.assertIsNotNone(post3)

        post = get_post(post3)
        self.assertIn('upload', post)
        self.assertIn('upload_animated', post)
        self.assertIsNotNone(post.get('upload'))
        self.assertIsNotNone(post.get('upload_animated'))

        # Create a post with a broken image, ensure it's handled correctly
        image = io.BytesIO()
        post4 = create_post(user1, 'user1', 'Test post #3', upload=image)
        self.assertIsNone(post4)
        post4 = get_post(post4)
        self.assertIsNone(post4)
コード例 #8
0
ファイル: backend.py プロジェクト: sydneyjd/pjuu
def populate_approved_followers_feeds(user_id, post_id, timestamp):
    """Fan out a post_id to all the users approved followers."""
    # Get a list of ALL users who are following a user
    followers = r.zrange(k.USER_APPROVED.format(user_id), 0, -1)
    # This is not transactional as to not hold Redis up.
    for follower_id in followers:
        # Add the pid to the list
        r.zadd(k.USER_FEED.format(follower_id), timestamp, post_id)
        # Stop followers feeds from growing to large, doesn't matter if it
        # doesn't exist
        r.zremrangebyrank(k.USER_FEED.format(follower_id), 0, -1000)
コード例 #9
0
ファイル: backend.py プロジェクト: adzilla/pjuu
def populate_feeds(uid, pid):
    """Fan out a pid to all the users with uid's followers

    """
    # Get a list of ALL users who are following a user
    followers = r.zrange(K.USER_FOLLOWERS.format(uid), 0, -1)
    # This is not transactional as to not hold Redis up.
    for fid in followers:
        # Add the pid to the list
        r.lpush(K.USER_FEED.format(fid), pid)
        # Stop followers feeds from growing to large, doesn't matter if it
        # doesn't exist
        r.ltrim(K.USER_FEED.format(fid), 0, 999)
コード例 #10
0
ファイル: test_alerts.py プロジェクト: hnk/pjuu
    def test_alertmanager(self):
        """
        Test the alert manager.

        Similar to the above a very simple test. Will check that it can alert
        users and one can be created.
        """
        # Create our alert manager
        am = AlertManager()

        # Try and load a non-existant alert
        self.assertIsNone(am.get(k.NIL_VALUE))

        # Try and alert on something which is not an alert
        self.assertRaises(ValueError, lambda: am.alert('ALERT', k.NIL_VALUE))

        # Test that alerting a single users does not work, they need to be
        # iterable
        # Create an alert
        alert = BaseAlert(k.NIL_VALUE)
        self.assertRaises(TypeError, lambda: am.alert(alert, 1))

        # Create a couple of users
        user1 = create_account('user1', '*****@*****.**', 'Password')
        user2 = create_account('user2', '*****@*****.**', 'Password')

        # Ensure the length of user1's alert feed is 0
        self.assertEqual(r.zcard(k.USER_ALERTS.format(user1)), 0)

        # Create an alert from user2
        alert = BaseAlert(user2)
        # Alert user1
        am.alert(alert, [user1])

        # Ensure the length of user1's alert feed is 1
        self.assertEqual(r.zcard(k.USER_ALERTS.format(user1)), 1)

        # Get alerts for user1, user Redis directly
        alerts = r.zrange(k.USER_ALERTS.format(user1), 0, 0)
        # Get the alert from alerts
        alert = am.get(alerts[0])
        self.assertIsNotNone(alert)
        self.assertEqual(alert.user.get('username'), 'user2')
        self.assertEqual(alert.user.get('email'), '*****@*****.**')

        # Delete test2 and ensure getting the alert returns None
        delete_account(user2)
        alert = am.get(alerts[0])
        self.assertIsNone(alert)
コード例 #11
0
ファイル: test_alerts.py プロジェクト: sydneyjd/pjuu
    def test_alertmanager(self):
        """
        Test the alert manager.

        Similar to the above a very simple test. Will check that it can alert
        users and one can be created.
        """
        # Create our alert manager
        am = AlertManager()

        # Try and load a non-existant alert
        self.assertIsNone(am.get(k.NIL_VALUE))

        # Try and alert on something which is not an alert
        self.assertRaises(ValueError, lambda: am.alert('ALERT', k.NIL_VALUE))

        # Test that alerting a single users does not work, they need to be
        # iterable
        # Create an alert
        alert = BaseAlert(k.NIL_VALUE)
        self.assertRaises(TypeError, lambda: am.alert(alert, 1))

        # Create a couple of users
        user1 = create_account('user1', '*****@*****.**', 'Password')
        user2 = create_account('user2', '*****@*****.**', 'Password')

        # Ensure the length of user1's alert feed is 0
        self.assertEqual(r.zcard(k.USER_ALERTS.format(user1)), 0)

        # Create an alert from user2
        alert = BaseAlert(user2)
        # Alert user1
        am.alert(alert, [user1])

        # Ensure the length of user1's alert feed is 1
        self.assertEqual(r.zcard(k.USER_ALERTS.format(user1)), 1)

        # Get alerts for user1, user Redis directly
        alerts = r.zrange(k.USER_ALERTS.format(user1), 0, 0)
        # Get the alert from alerts
        alert = am.get(alerts[0])
        self.assertIsNotNone(alert)
        self.assertEqual(alert.user.get('username'), 'user2')
        self.assertEqual(alert.user.get('email'), '*****@*****.**')

        # Delete test2 and ensure getting the alert returns None
        delete_account(user2)
        alert = am.get(alerts[0])
        self.assertIsNone(alert)
コード例 #12
0
    def test_create_post(self):
        """Tests creating and getting a post

        """
        # Create a user to test creating post
        user1 = create_account('user1', '*****@*****.**', 'Password')
        # Create post
        post1 = create_post(user1, 'user1', 'Test post')
        # Check the post actually exists
        self.assertIsNotNone(post1)

        # Check that all the hash members are what we expect
        post = get_post(post1)
        self.assertIsNotNone(post)
        self.assertEqual(post.get('_id'), post1)
        self.assertEqual(post.get('user_id'), user1)
        self.assertEqual(post.get('body'), 'Test post')
        self.assertEqual(post.get('score'), 0)
        self.assertEqual(post.get('comment_count'), 0)
        # Check the memebers we don't know the answer to
        self.assertIsNotNone(post.get('created'))
        self.assertNotIn('upload', post)

        # Ensure this post is the users feed (populate_feed)
        self.assertIn(post1, r.zrange(K.USER_FEED.format(user1), 0, -1))

        # Testing getting post with invalid arguments
        # Test getting a post that does not exist
        self.assertIsNone(get_post(K.NIL_VALUE))

        # Create a post with an image
        image = io.BytesIO(open('tests/upload_test_files/otter.jpg').read())
        post2 = create_post(user1, 'user1', 'Test post #2', upload=image)

        self.assertIsNotNone(post2)

        post = get_post(post2)
        self.assertIn('upload', post)
        self.assertIsNotNone(post.get('upload'))

        # Create a post with a broken image, ensure it's handled correctly
        image = io.BytesIO()
        post3 = create_post(user1, 'user1', 'Test post #3', upload=image)
        self.assertIsNone(post3)
        post3 = get_post(post3)
        self.assertIsNone(post3)
コード例 #13
0
ファイル: backend.py プロジェクト: sydneyjd/pjuu
def get_subscribers(post_id):
    """Return a list of subscribers 'user_id's for a given post

    """
    return r.zrange(k.POST_SUBSCRIBERS.format(post_id), 0, -1)
コード例 #14
0
ファイル: test_users_backend.py プロジェクト: buskirka/pjuu
    def test_follow_unfollow_get_followers_following_is_following(self):
        """
        Test everything about following. There is not that much to it to
        deserve 3 seperate methods.
        """
        # Create two test users
        user1 = create_account('user1', '*****@*****.**', 'Password')
        user2 = create_account('user2', '*****@*****.**', 'Password')
        # Ensure is_following() is false atm
        self.assertFalse(is_following(user1, user2))
        self.assertFalse(is_following(user2, user1))
        # Ensure user 1 can follow user 2
        self.assertTrue(follow_user(user1, user2))
        # Ensure the user can't follow them again
        self.assertFalse(follow_user(user1, user2))
        # And visa-versa
        self.assertTrue(follow_user(user2, user1))
        # Ensre the user can't follow them again
        self.assertFalse(follow_user(user2, user1))
        # Ensure the id's are in the Redis sorted sets, followers and following
        self.assertIn(user2, r.zrange(k.USER_FOLLOWING.format(user1), 0, -1))
        self.assertIn(user2, r.zrange(k.USER_FOLLOWERS.format(user1), 0, -1))
        self.assertIn(user1, r.zrange(k.USER_FOLLOWING.format(user2), 0, -1))
        self.assertIn(user1, r.zrange(k.USER_FOLLOWERS.format(user2), 0, -1))
        # Ensure the get_followers and get_following functions return
        # the correct data
        self.assertEqual(len(get_following(user1).items), 1)
        self.assertEqual(len(get_following(user1).items), 1)
        self.assertEqual(len(get_following(user2).items), 1)
        self.assertEqual(len(get_following(user2).items), 1)
        # Ensure the totals are correct
        self.assertEqual(get_following(user1).total, 1)
        self.assertEqual(get_followers(user1).total, 1)
        self.assertEqual(get_following(user2).total, 1)
        self.assertEqual(get_followers(user2).total, 1)

        # Make sure is_following() returns correctly
        self.assertTrue(is_following(user1, user2))
        self.assertTrue(is_following(user2, user1))

        # User 1 unfollow user 2 and ensure the sorted sets are updated
        self.assertTrue(unfollow_user(user1, user2))
        self.assertNotIn(user2,
                         r.zrange(k.USER_FOLLOWING.format(user1), 0, -1))
        self.assertNotIn(user1,
                         r.zrange(k.USER_FOLLOWERS.format(user2), 0, -1))

        # Ensure the user can't unfollow the user again
        self.assertFalse(unfollow_user(user1, user2))
        # Ensure is_following shows correctly
        self.assertFalse(is_following(user1, user2))

        # Test what happens when we delete an account.

        # Ensure user 2 is still following user1
        self.assertTrue(is_following(user2, user1))

        # This should clean
        delete_account(user1)

        # Ensure this has cleaned user2 following list
        self.assertFalse(is_following(user2, user1))

        # Ensure get_followers and get_following return the correct value for
        # user2
        self.assertEqual(len(get_following(user2).items), 0)
        # Ensure the totals are correct
        self.assertEqual(get_following(user2).total, 0)
        self.assertEqual(get_followers(user2).total, 0)
        # Make sure is_following() returns correctly
        self.assertFalse(is_following(user1, user2))
        self.assertFalse(is_following(user2, user1))

        # I don't want to play with the above testing to much. I am adding
        # in a test for self cleaning lists. I am going to reset this test
        # case by manually flushing the Redis database :)
        r.flushdb()
        # Back to normal, I don't like artificially uping the number of tests.

        # Test the self cleaning lists in case there is an issue with Redis
        # during an account deletion. We need 2 new users.
        user1 = create_account('user1', '*****@*****.**', 'Password')
        user2 = create_account('user2', '*****@*****.**', 'Password')

        # Follow each other.
        self.assertTrue(follow_user(user1, user2))
        self.assertTrue(follow_user(user2, user1))

        # Manually delete user1
        m.db.users.remove({'_id': user1})

        # Ensure user1 appears in both user2's followers and following lists
        self.assertIn(user1, r.zrange(k.USER_FOLLOWERS.format(user2), 0, -1))
        self.assertIn(user1, r.zrange(k.USER_FOLLOWING.format(user2), 0, -1))

        # Ensure if we actuallt get the lists from the backend functions user1
        # is not there
        self.assertEqual(get_followers(user2).total, 0)
        self.assertEqual(get_following(user2).total, 0)
コード例 #15
0
ファイル: backend.py プロジェクト: sydneyjd/pjuu
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))
コード例 #16
0
ファイル: backend.py プロジェクト: adzilla/pjuu
def delete_account(uid):
    """Will delete a users account.

    This _MUST_ _REMOVE_ _ALL_ details, comments, posts, etc.

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

    """
    # Get some information from the hashes to delete lookup keys
    username = r.hget(K.USER.format(uid), 'username')
    email = r.hget(K.USER.format(uid), 'email')

    # Clear the users lookup keys and user account. These are not needed
    pipe = r.pipeline()
    # Delete lookup keys. This will stop the user being found or logging in
    pipe.set(K.UID_USERNAME.format(username), K.NIL_VALUE)
    pipe.expire(K.UID_USERNAME.format(username), K.EXPIRE_SECONDS)
    pipe.set(K.UID_EMAIL.format(email), K.NIL_VALUE)
    pipe.expire(K.UID_EMAIL.format(email), K.EXPIRE_SECONDS)

    # Delete user account
    pipe.delete(K.USER.format(uid))
    pipe.execute()

    # Remove all posts a user has ever made. This includes all votes
    # on that post and all comments.
    pids = r.lrange(K.USER_POSTS.format(uid), 0, -1)
    for pid in pids:
        # Delete post
        r.delete(K.POST.format(pid))
        # Delete all the votes made on the post
        r.delete(K.POST_VOTES.format(pid))
        # Delete posts subscribers list
        r.delete(K.POST_SUBSCRIBERS.format(pid))

        cids = r.lrange(K.POST_COMMENTS.format(pid), 0, -1)
        for cid in cids:
            # Get author, ensure uid is an int
            cid_author = r.hget(K.COMMENT.format(cid), 'uid')
            # Delete comment
            r.delete(K.COMMENT.format(cid))
            # Delete comment votes
            r.delete(K.COMMENT_VOTES.format(cid))
            # Remove the cid from users comment list
            # This may remove some of ours. This will just make deleting
            # a bit quicker
            r.lrem(K.USER_COMMENTS.format(cid_author), 0, cid)
        # Delete the comments list
        r.delete(K.POST_COMMENTS.format(pid))
    # Delete the users post list
    r.delete(K.USER_POSTS.format(uid))

    # Delete all comments the user has every made. Including all votes on
    # those comments
    # This is a stripped down version of above for post comments.
    # We are not going to clean the lists related to the posts, they will
    # self clean. We also do not need to clear the comments from the users
    # comments list as it will be getting deleted straight after

    cids = r.lrange(K.USER_COMMENTS.format(uid), 0, -1)
    for cid in cids:
        # Get author, ensure uid is an int
        cid_author = r.hget(K.COMMENT.format(cid), 'uid')
        # Delete comment
        r.delete(K.COMMENT.format(cid))
        # Delete comment votes
        r.delete(K.COMMENT_VOTES.format(cid))
    # Delete the comments list
    r.delete(K.USER_COMMENTS.format(uid))

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

    fids = r.zrange(K.USER_FOLLOWERS.format(uid), 0, -1)

    for fid in fids:
        # Clear the followers following list of the uid
        r.zrem(K.USER_FOLLOWING.format(fid), uid)
    # Delete the followers list
    r.delete(K.USER_FOLLOWERS.format(uid))

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

    fids = r.zrange(K.USER_FOLLOWING.format(uid), 0, -1)

    for fid in fids:
        # Clear the followers list of people uid is following
        r.zrem(K.USER_FOLLOWERS.format(fid), uid)
    # Delete the following list
    r.delete(K.USER_FOLLOWING.format(uid))

    # Finally 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(uid))

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