예제 #1
0
파일: users.py 프로젝트: jensyt/malt.io
    def process(self, username, action):
        """
        Follow the given user.
        """
        user = UserPrefs.get()
        publicuser = UserPrefs.all().filter('name =', username).get()

        if not user or not publicuser:
            return self.render_json({
                'status': 'error',
                'error': 'User not found'
            })

        if action == 'post':
            if publicuser.user_id in user.following:
                return self.render_json({
                    'status': 'error',
                    'error': 'Already following user'
                })

            user.following.append(publicuser.user_id)

            existing = UserAction.all()\
                                 .filter('owner =', user)\
                                 .filter('type =', UserAction.TYPE_USER_FOLLOWED)\
                                 .filter('object_id =', publicuser.key().id())\
                                 .count()

            if not existing:
                user_action = UserAction()
                user_action.owner = user
                user_action.type = user_action.TYPE_USER_FOLLOWED
                user_action.object_id = publicuser.key().id()
                user_action.put()
        else:
            if publicuser.user_id not in user.following:
                return self.render_json({
                    'status': 'error',
                    'error': 'User not being followed'
                })

            user.following.remove(publicuser.user_id)

            existing = UserAction.all()\
                                 .filter('owner =', user)\
                                 .filter('type =', UserAction.TYPE_USER_FOLLOWED)\
                                 .filter('object_id =', publicuser.key().id())\
                                 .get()

            if existing:
                existing.delete()

        # Save updated following list
        user.put()

        self.render_json({
            'status': 'ok'
        })
예제 #2
0
    def process(self, username, action):
        """
        Follow the given user.
        """
        user = self.user
        publicuser = UserPrefs.all().filter('name =', username).get()

        if not user or not publicuser:
            return self.render_json({
                'status': 'error',
                'error': 'User not found'
            })

        if action == 'post':
            if publicuser.user_id in user.following:
                return self.render_json({
                    'status': 'error',
                    'error': 'Already following user'
                })

            user.following.append(publicuser.user_id)

            existing = UserAction.all()\
                                 .filter('owner =', user)\
                                 .filter('type =', UserAction.TYPE_USER_FOLLOWED)\
                                 .filter('object_id =', publicuser.key().id())\
                                 .count()

            if not existing:
                user_action = UserAction()
                user_action.owner = user
                user_action.type = user_action.TYPE_USER_FOLLOWED
                user_action.object_id = publicuser.key().id()
                user_action.put()
        else:
            if publicuser.user_id not in user.following:
                return self.render_json({
                    'status': 'error',
                    'error': 'User not being followed'
                })

            user.following.remove(publicuser.user_id)

            existing = UserAction.all()\
                                 .filter('owner =', user)\
                                 .filter('type =', UserAction.TYPE_USER_FOLLOWED)\
                                 .filter('object_id =', publicuser.key().id())\
                                 .get()

            if existing:
                existing.delete()

        # Save updated following list
        user.put()

        self.render_json({
            'status': 'ok'
        })
예제 #3
0
    def process(self, action, username=None, recipe_slug=None):
        """
        Process a request to add or remove a user from the liked list.
        """
        user = UserPrefs.get()
        publicuser = UserPrefs.all()\
                              .filter('name = ', username)\
                              .get()

        if not publicuser:
            self.render_json({'status': 'error', 'error': 'User not found'})
            return

        recipe = Recipe.all()\
                       .filter('owner =', publicuser)\
                       .filter('slug =', recipe_slug)\
                       .get()

        if not recipe:
            self.render_json({'status': 'error', 'error': 'Recipe not found'})
            return

        if action == 'post':
            if user.user_id not in recipe.likes:
                recipe.likes.append(user.user_id)
                recipe.put()

                existing = UserAction.all()\
                                     .filter('owner =', user)\
                                     .filter('type =', UserAction.TYPE_RECIPE_LIKED)\
                                     .filter('object_id =', recipe.key().id())\
                                     .count()

                if not existing:
                    user_action = UserAction()
                    user_action.owner = user
                    user_action.type = user_action.TYPE_RECIPE_LIKED
                    user_action.object_id = recipe.key().id()
                    user_action.put()

        elif action == 'delete':
            if user.user_id in recipe.likes:
                recipe.likes.remove(user.user_id)
                recipe.put()

                existing = UserAction.all()\
                                     .filter('owner =', user)\
                                     .filter('type =', UserAction.TYPE_RECIPE_LIKED)\
                                     .filter('object_id =', recipe.key().id())\
                                     .get()

                if existing:
                    existing.delete()

        return self.render_json({'status': 'ok', 'likes': len(recipe.likes)})
예제 #4
0
    def get(self, username):
        """
        Render a user page.
        """
        publicuser = UserPrefs.all().filter('name =', username).get()

        if not publicuser:
            self.abort(404)

        recipes = Recipe.all()\
                        .filter('owner =', publicuser)\
                        .order('name')\
                        .run(limit=25)

        actions = UserAction.all()\
                            .filter('owner =', publicuser)\
                            .order('-created')\
                            .fetch(15)

        object_ids = UserAction.gather_object_ids(actions)

        user_map = {publicuser.key().id(): publicuser}

        for user in UserPrefs.get_by_id(object_ids['users']):
            user_map[user.key().id()] = user

        recipes = [r for r in recipes]
        recipe_ids = [recipe.key().id() for recipe in recipes]
        object_ids['recipes'] = [
            id for id in object_ids['recipes'] if id not in recipe_ids
        ]

        recipe_map = {}

        for recipe in recipes:
            recipe.owner = publicuser
            recipe_map[recipe.key().id()] = recipe

        for recipe in Recipe.get_by_id(object_ids['recipes']):
            recipe_map[recipe.key().id()] = recipe

        brew_map = {}

        for brew in Brew.get_by_id(object_ids['brews']):
            brew_map[brew.key().id()] = brew

        self.render(
            'user.html', {
                'publicuser': publicuser,
                'recipes': recipes,
                'actions': actions,
                'user_map': user_map,
                'recipe_map': recipe_map,
                'brew_map': brew_map
            })
예제 #5
0
    def get(self, username):
        """
        Render a user page.
        """
        publicuser = UserPrefs.all().filter('name =', username).get()

        if not publicuser:
            self.abort(404)

        recipes = Recipe.all()\
                        .filter('owner =', publicuser)\
                        .order('name')\
                        .run(limit=25)

        actions = UserAction.all()\
                            .filter('owner =', publicuser)\
                            .order('-created')\
                            .fetch(15)

        object_ids = UserAction.gather_object_ids(actions)

        user_map = {
            publicuser.key().id(): publicuser
        }

        for user in UserPrefs.get_by_id(object_ids['users']):
            user_map[user.key().id()] = user

        recipes = [r for r in recipes]
        recipe_ids = [recipe.key().id() for recipe in recipes]
        object_ids['recipes'] = [id for id in object_ids['recipes'] if id not in recipe_ids]

        recipe_map = {}

        for recipe in recipes:
            recipe.owner = publicuser
            recipe_map[recipe.key().id()] = recipe

        for recipe in Recipe.get_by_id(object_ids['recipes']):
            recipe_map[recipe.key().id()] = recipe

        brew_map = {}

        for brew in Brew.get_by_id(object_ids['brews']):
            brew_map[brew.key().id()] = brew

        self.render('user.html', {
            'publicuser': publicuser,
            'recipes': recipes,
            'actions': actions,
            'user_map': user_map,
            'recipe_map': recipe_map,
            'brew_map': brew_map
        })
예제 #6
0
    def top_interesting_events(self):
        """
        Get a list of interesting events ordered by date from most
        recent to least. Interesting events are events that either belong
        to this user or any user she is following.
        """
        from models.useraction import UserAction

        following = self.following_users.run(batch_size=100)

        return UserAction.all()\
                         .filter('owner IN', [self] + list(following))\
                         .order('-created')\
                         .fetch(25)
예제 #7
0
    def delete(self, username=None, recipe_slug=None):
        """
        Handle recipe delete. This will remove a recipe and return success
        or failure.
        """
        user = self.user

        if not user:
            self.render_json({
                'status': 'error',
                'error': 'User not logged in'
            })

        recipe = Recipe.all()\
                       .filter('slug = ', recipe_slug)\
                       .filter('owner =', user)\
                       .get()

        if recipe:
            # Delete all actions pointing to this recipe
            actions = UserAction.all()\
                                .filter('type IN', [UserAction.TYPE_RECIPE_CREATED,
                                                    UserAction.TYPE_RECIPE_EDITED,
                                                    UserAction.TYPE_RECIPE_CLONED,
                                                    UserAction.TYPE_RECIPE_LIKED])\
                                .filter('object_id =', recipe.key().id())\
                                .fetch(1000)

            for action in actions:
                action.delete()

            # Delete the actual recipe itself
            recipe.delete()

            self.render_json({
                'status': 'ok',
                'redirect': '/users/%(username)s/recipes' % {
                    'username': user.name
                }
            })
        else:
            self.render_json({
                'status': 'error',
                'error': 'Unable to delete recipe'
            })
예제 #8
0
파일: recipes.py 프로젝트: pheezer/malt.io
    def delete(self, username=None, recipe_slug=None):
        """
        Handle recipe delete. This will remove a recipe and return success
        or failure.
        """
        user = self.user

        if not user:
            self.render_json({
                'status': 'error',
                'error': 'User not logged in'
            })

        recipe = Recipe.all()\
                       .filter('slug = ', recipe_slug)\
                       .filter('owner =', user)\
                       .get()

        if recipe:
            # Delete all actions pointing to this recipe
            actions = UserAction.all()\
                                .filter('type IN', [UserAction.TYPE_RECIPE_CREATED,
                                                    UserAction.TYPE_RECIPE_EDITED,
                                                    UserAction.TYPE_RECIPE_CLONED,
                                                    UserAction.TYPE_RECIPE_LIKED])\
                                .filter('object_id =', recipe.key().id())\
                                .fetch(1000)

            for action in actions:
                action.delete()

            # Delete the actual recipe itself
            recipe.delete()

            self.render_json({
                'status': 'ok',
                'redirect': '/users/%(username)s/recipes' % {
                    'username': user.name
                }
            })
        else:
            self.render_json({
                'status': 'error',
                'error': 'Unable to delete recipe'
            })
예제 #9
0
파일: index.py 프로젝트: pheezer/malt.io
    def get(self):
        user = self.user

        # Try to get rendered output from memcache
        rendered = memcache.get('dashboard-' + user.user_id)
        if rendered and not settings.DEBUG:
            return self.response.out.write(rendered)

        # Fetch following users
        following = user.following_users\
                        .order('name')\
                        .fetch(100)

        user_keys = [user.key()] + [u.key() for u in following]

        # Start async fetch of top recipes
        top_recipes = Recipe.all()\
                            .filter('owner IN', user_keys)\
                            .order('-grade')\
                            .run(limit=15)

        # Get and process interesting events
        interesting_events = UserAction.all()\
                                       .filter('owner IN', user_keys)\
                                       .order('-created')\
                                       .fetch(15)

        object_ids = UserAction.gather_object_ids(interesting_events)
        object_ids['users'] = [
            id for id in object_ids['users']
            if id not in [user.key().id()] + user.following
        ]

        # Start async fetch of relevant recipes
        recipes = db.get_async(
            [Key.from_path('Recipe', id) for id in object_ids['recipes']])

        # Start async fetch of relevant brews
        brews = db.get_async(
            [Key.from_path('Brew', id) for id in object_ids['brews']])

        # Convert iterators to  lists of items in memory and setup a map
        # of user id -> user for easy lookups
        following = list(following)
        top_recipes = list(top_recipes)

        user_map = {user.key().id(): user}

        for u in following:
            user_map[u.key().id()] = u

        if object_ids['users']:
            for u in UserPrefs.get_by_id(object_ids['users']):
                user_map[u.key().id()] = u

        # Setup a map of brew id -> brew for easy lookups
        brew_map = {}
        brew_recipe_ids = set()

        for b in brews.get_result():
            brew_recipe_ids.add(b.recipe_key.id())
            brew_map[b.key().id()] = b

        # Async fetch of any recipes brews reference that weren't
        # included in the recipe fetch above...
        brew_recipes = db.get_async([
            Key.from_path('Recipe', id) for id in brew_recipe_ids
            if id not in object_ids['recipes']
        ])

        # Setup a map of recipe id -> recipe for easy lookups
        recipe_map = {}

        for r in recipes.get_result():
            recipe_map[r.key().id()] = r

        for r in brew_recipes.get_result():
            recipe_map[r.key().id()] = r

        # Render and cache for 1 minute
        memcache.set(
            'dashboard-' + user.user_id,
            self.render(
                'dashboard.html', {
                    'following': following,
                    'user_map': user_map,
                    'recipe_map': recipe_map,
                    'brew_map': brew_map,
                    'top_recipes': top_recipes,
                    'interesting_events': interesting_events
                }), self.CACHE_TIME)
예제 #10
0
    def get(self):
        user = self.user

        # Try to get rendered output from memcache
        rendered = memcache.get('dashboard-' + user.user_id)
        if rendered and not settings.DEBUG:
            return self.response.out.write(rendered)

        # Fetch following users
        following = user.following_users\
                        .order('name')\
                        .fetch(100)

        user_keys = [user.key()] + [u.key() for u in following]

        # Start async fetch of top recipes
        top_recipes = Recipe.all()\
                            .filter('owner IN', user_keys)\
                            .order('-grade')\
                            .run(limit=15)

        # Get and process interesting events
        interesting_events = UserAction.all()\
                                       .filter('owner IN', user_keys)\
                                       .order('-created')\
                                       .fetch(15)

        object_ids = UserAction.gather_object_ids(interesting_events)
        object_ids['users'] = [id for id in object_ids['users'] if id not in [user.key().id()] + user.following]

        # Start async fetch of relevant recipes
        recipes = db.get_async([Key.from_path('Recipe', id) for id in object_ids['recipes']])

        # Start async fetch of relevant brews
        brews = db.get_async([Key.from_path('Brew', id) for id in object_ids['brews']])

        # Convert iterators to  lists of items in memory and setup a map
        # of user id -> user for easy lookups
        following = list(following)
        top_recipes = list(top_recipes)

        user_map = {
            user.key().id(): user
        }

        for u in following:
            user_map[u.key().id()] = u

        if object_ids['users']:
            for u in UserPrefs.get_by_id(object_ids['users']):
                user_map[u.key().id()] = u

        # Setup a map of brew id -> brew for easy lookups
        brew_map = {}
        brew_recipe_ids = set()

        for b in brews.get_result():
            brew_recipe_ids.add(b.recipe_key.id())
            brew_map[b.key().id()] = b

        # Async fetch of any recipes brews reference that weren't
        # included in the recipe fetch above...
        brew_recipes = db.get_async([Key.from_path('Recipe', id) for id in brew_recipe_ids if id not in object_ids['recipes']])

        # Setup a map of recipe id -> recipe for easy lookups
        recipe_map = {}

        for r in recipes.get_result():
            recipe_map[r.key().id()] = r

        for r in brew_recipes.get_result():
            recipe_map[r.key().id()] = r

        # Render and cache for 1 minute
        memcache.set('dashboard-' + user.user_id, self.render('dashboard.html', {
            'following': following,
            'user_map': user_map,
            'recipe_map': recipe_map,
            'brew_map': brew_map,
            'top_recipes': top_recipes,
            'interesting_events': interesting_events
        }), self.CACHE_TIME)
예제 #11
0
    def get(self):
        """
        Render the index page. Currently this renders a 'Coming soon' landing
        page that will eventually be replaced with a proper home page.
        """
        user = self.user

        if user:
            # Try to get rendered output from memcache
            rendered = memcache.get('dashboard-' + user.user_id)
            if rendered and not settings.DEBUG:
                return self.response.out.write(rendered)

            # Fetch following users
            following = user.following_users\
                            .order('name')\
                            .fetch(100)

            user_keys = [user.key()] + [u.key() for u in following]

            # Start async fetch of top recipes
            top_recipes = Recipe.all()\
                                .filter('owner IN', user_keys)\
                                .order('-likes_count')\
                                .run(limit=15)

            # Get and process interesting events
            interesting_events = UserAction.all()\
                                           .filter('owner IN', user_keys)\
                                           .order('-created')\
                                           .fetch(15)

            object_ids = UserAction.gather_object_ids(interesting_events)
            object_ids['users'] = [
                id for id in object_ids['users']
                if id not in [user.key().id()] + user.following
            ]

            # Start async fetch of relevant recipes
            recipes = db.get_async(
                [Key.from_path('Recipe', id) for id in object_ids['recipes']])

            # Convert iterators to  lists of items in memory and setup a map
            # of user id -> user for easy lookups
            following = list(following)
            top_recipes = list(top_recipes)

            user_map = {user.key().id(): user}

            for u in following:
                user_map[u.key().id()] = u

            if object_ids['users']:
                for u in UserPrefs.get_by_id(object_ids['users']):
                    user_map[u.key().id()] = u

            # Setup a map of recipe id -> recipe for easy lookups
            recipe_map = {}

            for r in recipes.get_result():
                recipe_map[r.key().id()] = r

            # Render and cache for 1 minute
            memcache.set(
                'dashboard-' + user.user_id,
                self.render(
                    'dashboard.html', {
                        'following': following,
                        'user_map': user_map,
                        'recipe_map': recipe_map,
                        'top_recipes': top_recipes,
                        'interesting_events': interesting_events
                    }), 60)
        else:
            # Try to get rendered output from memcache
            rendered = memcache.get('index')
            if rendered and not settings.DEBUG:
                return self.response.out.write(rendered)

            recipes = Recipe.all()\
                            .order('-likes_count')\
                            .run(limit=15)

            # Render and cache for 15 minutes
            memcache.set('index',
                         self.render('index.html', {'recipes': recipes}), 900)
예제 #12
0
파일: recipes.py 프로젝트: jensyt/malt.io
    def process(self, action, username=None, recipe_slug=None):
        """
        Process a request to add or remove a user from the liked list.
        """
        user = UserPrefs.get()
        publicuser = UserPrefs.all()\
                              .filter('name = ', username)\
                              .get()

        if not publicuser:
            self.render_json({
                'status': 'error',
                'error': 'User not found'
            })
            return

        recipe = Recipe.all()\
                       .filter('owner =', publicuser)\
                       .filter('slug =', recipe_slug)\
                       .get()

        if not recipe:
            self.render_json({
                'status': 'error',
                'error': 'Recipe not found'
            })
            return

        if action == 'post':
            if user.user_id not in recipe.likes:
                recipe.likes.append(user.user_id)
                recipe.put()

                existing = UserAction.all()\
                                     .filter('owner =', user)\
                                     .filter('type =', UserAction.TYPE_RECIPE_LIKED)\
                                     .filter('object_id =', recipe.key().id())\
                                     .count()

                if not existing:
                    user_action = UserAction()
                    user_action.owner = user
                    user_action.type = user_action.TYPE_RECIPE_LIKED
                    user_action.object_id = recipe.key().id()
                    user_action.put()

        elif action == 'delete':
            if user.user_id in recipe.likes:
                recipe.likes.remove(user.user_id)
                recipe.put()

                existing = UserAction.all()\
                                     .filter('owner =', user)\
                                     .filter('type =', UserAction.TYPE_RECIPE_LIKED)\
                                     .filter('object_id =', recipe.key().id())\
                                     .get()

                if existing:
                    existing.delete()

        return self.render_json({
            'status': 'ok',
            'likes': len(recipe.likes)
        })
예제 #13
0
파일: index.py 프로젝트: jensyt/malt.io
    def get(self):
        """
        Render the index page. Currently this renders a 'Coming soon' landing
        page that will eventually be replaced with a proper home page.
        """
        user = self.user

        if user:
            # Try to get rendered output from memcache
            rendered = memcache.get('dashboard-' + user.user_id)
            if rendered and not settings.DEBUG:
                return self.response.out.write(rendered)

            # Fetch following users
            following = user.following_users\
                            .order('name')\
                            .fetch(100)

            user_keys = [user.key()] + [u.key() for u in following]

            # Start async fetch of top recipes
            top_recipes = Recipe.all()\
                                .filter('owner IN', user_keys)\
                                .order('-likes_count')\
                                .run(limit=15)

            # Get and process interesting events
            interesting_events = UserAction.all()\
                                           .filter('owner IN', user_keys)\
                                           .order('-created')\
                                           .fetch(15)

            object_ids = UserAction.gather_object_ids(interesting_events)
            object_ids['users'] = [id for id in object_ids['users'] if id not in [user.key().id()] + user.following]

            # Start async fetch of relevant recipes
            recipes = db.get_async([Key.from_path('Recipe', id) for id in object_ids['recipes']])

            # Convert iterators to  lists of items in memory and setup a map
            # of user id -> user for easy lookups
            following = list(following)
            top_recipes = list(top_recipes)

            user_map = {
                user.key().id(): user
            }

            for u in following:
                user_map[u.key().id()] = u

            if object_ids['users']:
                for u in UserPrefs.get_by_id(object_ids['users']):
                    user_map[u.key().id()] = u

            # Setup a map of recipe id -> recipe for easy lookups
            recipe_map = {}

            for r in recipes.get_result():
                recipe_map[r.key().id()] = r

            # Render and cache for 1 minute
            memcache.set('dashboard-' + user.user_id, self.render('dashboard.html', {
                'following': following,
                'user_map': user_map,
                'recipe_map': recipe_map,
                'top_recipes': top_recipes,
                'interesting_events': interesting_events
            }), 60)
        else:
            # Try to get rendered output from memcache
            rendered = memcache.get('index')
            if rendered and not settings.DEBUG:
                return self.response.out.write(rendered)

            recipes = Recipe.all()\
                            .order('-likes_count')\
                            .run(limit=15)

            # Render and cache for 15 minutes
            memcache.set('index', self.render('index.html', {
                'recipes': recipes
            }), 900)