Beispiel #1
0
    def process(self, username=None, recipe_slug=None, brew_slug=None):
        publicuser = UserPrefs.all()\
                              .filter('name =', username)\
                              .get()

        if not publicuser:
            return [None, None, None]

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

        if not recipe:
            return [publicuser, None, None]

        if brew_slug is not None:
            brew = Brew.all()\
                       .filter('owner =', publicuser)\
                       .filter('recipe =', recipe)\
                       .filter('slug =', brew_slug)\
                       .get()

            if not brew:
                return [publicuser, recipe, None]
        else:
            brew = Brew()
            brew.owner = self.user
            brew.recipe = recipe

        return [publicuser, recipe, brew]
Beispiel #2
0
    def process(self, username=None, recipe_slug=None, brew_slug=None):
        publicuser = UserPrefs.all()\
                              .filter('name =', username)\
                              .get()

        if not publicuser:
            return [None, None, None]

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

        if not recipe:
            return [publicuser, None, None]

        if brew_slug is not None:
            brew = Brew.all()\
                       .filter('owner =', publicuser)\
                       .filter('recipe =', recipe)\
                       .filter('slug =', brew_slug)\
                       .get()

            if not brew:
                return [publicuser, recipe, None]
        else:
            brew = Brew()
            brew.owner = self.user
            brew.recipe = recipe

        return [publicuser, recipe, brew]
Beispiel #3
0
def generate_usable_slug(brew):
    """
    Generate a usable slug for a given brew. This method will try to slugify
    the brew date + owner and then append an integer if needed, increasing this
    integer until no existing brew would be overwritten.
    """
    base = brew.started.strftime('%d-%b-%Y') + '-' + brew.owner.name
    slug = slugify(base)

    # Reuse existing slug if we can
    if brew.slug and brew.slug == slug:
        return brew.slug

    append = 0
    while True:
        count = Brew.all()\
                    .filter('owner =', brew.owner)\
                    .filter('recipe =', brew.recipe)\
                    .filter('slug =', slug)\
                    .count()

        if not count:
            break

        append += 1
        slug = slugify(base) + str(append)

    return slug
Beispiel #4
0
def generate_usable_slug(brew):
    """
    Generate a usable slug for a given brew. This method will try to slugify
    the brew date + owner and then append an integer if needed, increasing this
    integer until no existing brew would be overwritten.
    """
    base = brew.started.strftime('%d-%b-%Y') + '-' + brew.owner.name
    slug = slugify(base)

    # Reuse existing slug if we can
    if brew.slug and brew.slug == slug:
        return brew.slug

    append = 0
    while True:
        count = Brew.all()\
                    .filter('owner =', brew.owner)\
                    .filter('recipe =', brew.recipe)\
                    .filter('slug =', slug)\
                    .count()

        if not count:
            break

        append += 1
        slug = slugify(base) + str(append)

    return slug
Beispiel #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
            })
Beispiel #6
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
        })
Beispiel #7
0
 def object(self):
     if self.type in [self.TYPE_USER_FOLLOWED]:
         return UserPrefs.get_by_id(self.object_id)
     elif self.type in [
             self.TYPE_RECIPE_CREATED, self.TYPE_RECIPE_EDITED,
             self.TYPE_RECIPE_CLONED, self.TYPE_RECIPE_LIKED
     ]:
         from models.recipe import Recipe
         return Recipe.get_by_id(self.object_id)
     elif self.type in [self.TYPE_BREW_CREATED, self.TYPE_BREW_UPDATED]:
         from models.brew import Brew
         return Brew.get_by_id(self.object_id)
Beispiel #8
0
 def object(self):
     if self.type in [self.TYPE_USER_FOLLOWED]:
         return UserPrefs.get_by_id(self.object_id)
     elif self.type in [self.TYPE_RECIPE_CREATED,
                        self.TYPE_RECIPE_EDITED,
                        self.TYPE_RECIPE_CLONED,
                        self.TYPE_RECIPE_LIKED]:
         from models.recipe import Recipe
         return Recipe.get_by_id(self.object_id)
     elif self.type in [self.TYPE_BREW_CREATED,
                        self.TYPE_BREW_UPDATED]:
         from models.brew import Brew
         return Brew.get_by_id(self.object_id)
Beispiel #9
0
    def update_grade(self):
        """
        Grade a recipe based on several factors:

          * Recipe completeness (title, description, ingredients)
          * Average brew rating weighted inverse temporally
          * Average completeness of brews (measurements, rating, notes)
          * Total number of clones, brews and unique brewers

        The calculated grade is used to rank recipes - those with the highest
        grade will move toward the front of the list. This should hopefully
        mean that recipes that are very popular, that many people like, that
        have many clones or reviews, and that have many positive reviews
        should be shown before others.

        What actions can someone take to increase the grade of a recipe?
        The owner can make sure it has a proper title, description, and at
        least one of each type of ingredient. A normal user can clone and/or
        brew the recipe, making sure to fill in as much as possible for the
        brew.
        """
        from models.brew import Brew

        grade = 0.0

        clone_count = Recipe.all().filter('cloned_from =', self).count()
        logging.info('clone count ' + str(clone_count))
        brew_count = Brew.all().filter('recipe =', self).count()
        brews = Brew.all().filter('recipe =', self).order('-started').fetch(25)

        # Grade completeness
        if self.name.lower() not in [
                '', 'untitled', 'untitled brew', 'no name'
        ]:
            grade += 1.0

        if self.description.lower() not in ['', 'no description', 'none']:
            grade += 1.0

        if len(self.ingredients['fermentables']) and len(
                self.ingredients['spices']) and len(self.ingredients['yeast']):
            grade += 1.0

        if clone_count and brew_count:
            grade += 1.0

        # Grade average weighted reviews
        count = 0
        brewers = set()
        avg_review = 0.0
        for i, brew in enumerate(brews):
            brew_grade = 0.0

            brewers.add(brew.owner_key)

            # Completeness of brew
            if brew.started:
                brew_grade += 1.0

            if brew.og and brew.fg:
                brew_grade += 1.0

            if brew.notes:
                brew_grade += 1.0

            # Brew rating
            if brew.rating:
                brew_grade += brew.rating
                avg_review += brew.rating
                count += 1

            # Weighted average (0.5, 0.25, 0.125, ...)
            grade += brew_grade * (0.5 / (i + 1))

        # Total unique brewers
        grade += math.ceil(math.log(len(brewers) + 1, 3))

        # Total clones and brews
        grade += math.ceil(math.log(clone_count + 1, 3))
        grade += math.ceil(math.log(brew_count + 1, 3))

        # Update values on this recipe
        self.grade = grade

        self.review_count = brew_count
        if count:
            self.avg_review = avg_review / count
        else:
            self.avg_review = 0.0
Beispiel #10
0
    def update_grade(self):
        """
        Grade a recipe based on several factors:

          * Recipe completeness (title, description, ingredients)
          * Average brew rating weighted inverse temporally
          * Average completeness of brews (measurements, rating, notes)
          * Total number of clones, brews and unique brewers

        The calculated grade is used to rank recipes - those with the highest
        grade will move toward the front of the list. This should hopefully
        mean that recipes that are very popular, that many people like, that
        have many clones or reviews, and that have many positive reviews
        should be shown before others.

        What actions can someone take to increase the grade of a recipe?
        The owner can make sure it has a proper title, description, and at
        least one of each type of ingredient. A normal user can clone and/or
        brew the recipe, making sure to fill in as much as possible for the
        brew.
        """
        from models.brew import Brew

        grade = 0.0

        clone_count = Recipe.all().filter('cloned_from =', self).count()
        logging.info('clone count ' + str(clone_count))
        brew_count = Brew.all().filter('recipe =', self).count()
        brews = Brew.all().filter('recipe =', self).order('-started').fetch(25)

        # Grade completeness
        if self.name.lower() not in ['', 'untitled', 'untitled brew', 'no name']:
            grade += 1.0

        if self.description.lower() not in ['', 'no description', 'none']:
            grade += 1.0

        if len(self.ingredients['fermentables']) and len(self.ingredients['spices']) and len(self.ingredients['yeast']):
            grade += 1.0

        if clone_count and brew_count:
            grade += 1.0

        # Grade average weighted reviews
        count = 0
        brewers = set()
        avg_review = 0.0
        for i, brew in enumerate(brews):
            brew_grade = 0.0

            brewers.add(brew.owner_key)

            # Completeness of brew
            if brew.started:
                brew_grade += 1.0

            if brew.og and brew.fg:
                brew_grade += 1.0

            if brew.notes:
                brew_grade += 1.0

            # Brew rating
            if brew.rating:
                brew_grade += brew.rating
                avg_review += brew.rating
                count += 1

            # Weighted average (0.5, 0.25, 0.125, ...)
            grade += brew_grade * (0.5 / (i + 1))

        # Total unique brewers
        grade += math.ceil(math.log(len(brewers) + 1, 3))

        # Total clones and brews
        grade += math.ceil(math.log(clone_count + 1, 3))
        grade += math.ceil(math.log(brew_count + 1, 3))

        # Update values on this recipe
        self.grade = grade

        self.review_count = brew_count
        if count:
            self.avg_review = avg_review / count
        else:
            self.avg_review = 0.0