def _edit_tags(self): tags_str = self.request.get('tags') self.edited = True helper = TagHelper(self.user) if tags_str: # remove duplication src = tags_str.split(' ') tags_arr = [] for t in src: if t and t not in tags_arr: tags_arr.append(t) tags = elements.Tags.get_by_user_isbn(self.user, self.isbn) if tags: for name in tags.names: helper.remove(name, tags.isbn) for name in tags_arr: helper.add(name, tags.isbn) tags.names = tags_arr else: tags = elements.Tags(user=self.user, isbn=self.isbn, parent=utils.get_key_private('Tags', self.user), names=tags_arr) for name in tags_arr: helper.add(name, self.isbn) tags.put() else: # to delete any tags t = elements.Tags.get_by_user_isbn(self.user, self.isbn) if t: t.delete() for name in t.names: helper.remove(name, t.isbn)
def _is_tag(self, text, user): """ Determine whether the user's input is a valid isbn number. """ if not text: # there must be something return False if ' ' in text: # can not be multiple tags return False helper = TagHelper(user) if helper.isbns(text): return True else: return False
def _being_praised(self, user): """ Filtering by calculating scores of each book. """ def _rating_weight(rating_score): """ Return the relative weight of a rating score. @param rating_score: In 10 points scale. """ if rating_score < 6.0: base = -2 elif rating_score < 7.0: base = -1 elif rating_score < 7.5: base = 0 elif rating_score < 7.8: base = 0.3 elif rating_score < 8.0: base = 0.6 elif rating_score < 8.3: base = 0.9 elif rating_score < 8.5: base = 1.2 elif rating_score < 8.8: base = 1.5 elif rating_score < 9.0: base = 1.8 else: base = 2 return base + random.random() def _voted_weight(amount): """ @returns: the relative weight of rated_amount. Generally, the larger it is, the more it's rating can present. """ if amount <= 0: base = -2 elif amount < 64: base = -1 else: # too many is also useless amount = max(amount, 10000) base = log10(amount) return base + random.random() def _pages_weight(pages): """ @returns: the relative weight of pages of a book. Generally, if pages is larger than a threshhold, it become bad. """ if pages > self.PAGE_THRESHHOLD: return -1 else: return 1 helper = SortHelper(user) now = datetime.datetime.now() dt = datetime.timedelta(days=30) one_month_ago = now - dt datas = helper.all(booklist.LIST_DONE) consider_pages = False for d in sorted(datas, key=lambda sd: sd.updated_time, reverse=True): if d.updated_time < one_month_ago: break if d.pages > self.PAGE_THRESHHOLD: consider_pages = True break tag_helper = TagHelper(user) week_goals = tag_helper.isbns('thisweek') month_goals = tag_helper.isbns('thismonth') def _calculate(data): """ Calculate the score of that data. @param consider_pages: whether to take pages into account. Default is False. """ r = _rating_weight(data.public_rating) v = _voted_weight(data.rated_amount) score = r * v if consider_pages: score += _pages_weight(data.pages) if data.isbn in week_goals or data.isbn in month_goals: score += 16 * random.random() return score datas = helper.all(booklist.LIST_INTERESTED) sorted_datas = sorted(datas, key=_calculate, reverse=True) return [d.isbn for d in sorted_datas[:self.NEXT_LIMIT]]