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]
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
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
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