def get_forums(cls, category_id, user): """Get the forums for the category. It returns a tuple with the category and the forums with their forumsread object are stored in a list. A return value can look like this for a category with two forums:: (<Category 1>, [(<Forum 1>, None), (<Forum 2>, None)]) :param category_id: The category id :param user: The user object is needed to check if we also need their forumsread object. """ if user.is_authenticated() and not getattr(user, "is_lockdownuser", False): # get list of user group ids forums = ( cls.query.filter(cls.id == category_id) .outerjoin(ForumsRead, db.and_(ForumsRead.user_id == user.id)) .add_entity(ForumsRead) .all() ) else: forums = cls.query.filter(cls.id == category_id).all() if not forums: abort(404) return get_forums(forums, user)
def get_topics(cls, forum_id, user, page=1, per_page=20): """Get the topics for the forum. If the user is logged in, it will perform an outerjoin for the topics with the topicsread and forumsread relation to check if it is read or unread. :param forum_id: The forum id :param user: The user object :param page: The page whom should be loaded :param per_page: How many topics per page should be shown """ if is_authenticated(user): topics = Topic.query.filter_by(forum_id=forum_id).\ outerjoin(TopicsRead, db.and_(TopicsRead.topic_id == Topic.id, TopicsRead.user_id == user.id)).\ add_entity(TopicsRead).\ order_by(Topic.important.desc(), Topic.last_updated.desc()).\ paginate(page, per_page, True) else: topics = Topic.query.filter_by(forum_id=forum_id).\ order_by(Topic.important.desc(), Topic.last_updated.desc()).\ paginate(page, per_page, True) topics.items = [(topic, None) for topic in topics.items] return topics
def get_topics(cls, forum_id, user, page=1, per_page=20): """Get the topics for the forum. If the user is logged in, it will perform an outerjoin for the topics with the topicsread and forumsread relation to check if it is read or unread. :param forum_id: The forum id :param user: The user object :param page: The page whom should be loaded :param per_page: How many topics per page should be shown """ if user.is_authenticated() and not getattr(user, "is_lockdownuser", False): topics = ( Topic.query.filter_by(forum_id=forum_id) .outerjoin(TopicsRead, db.and_(TopicsRead.topic_id == Topic.id, TopicsRead.user_id == user.id)) .add_entity(TopicsRead) .order_by(Topic.important.desc(), Topic.last_updated.desc()) .paginate(page, per_page, True) ) else: topics = ( Topic.query.filter_by(forum_id=forum_id) .order_by(Topic.important.desc(), Topic.last_updated.desc()) .paginate(page, per_page, True) ) topics.items = [(topic, None) for topic in topics.items] return topics
def topictracker(): page = request.args.get("page", 1, type=int) topics = current_user.tracked_topics.\ outerjoin(TopicsRead, db.and_(TopicsRead.topic_id == Topic.id, TopicsRead.user_id == current_user.id)).\ add_entity(TopicsRead).\ order_by(Topic.last_updated.desc()).\ paginate(page, flaskbb_config['TOPICS_PER_PAGE'], True) return render_template("forum/forum/topictracker.html", topics=topics)
def get_forum(cls, forum_id, user): """Returns the forum and forumsread object as a tuple for the user. :param forum_id: The forum id :param user: The user object is needed to check if we also need their forumsread object. """ if user.is_authenticated() and not getattr(user, "is_lockdownuser", False): forum, forumsread = ( Forum.query.filter(Forum.id == forum_id) .options(db.joinedload("category")) .outerjoin(ForumsRead, db.and_(ForumsRead.forum_id == Forum.id, ForumsRead.user_id == user.id)) .add_entity(ForumsRead) .first_or_404() ) else: forum = Forum.query.filter(Forum.id == forum_id).first_or_404() forumsread = None return forum, forumsread
def get_forum(cls, forum_id, user): """Returns the forum and forumsread object as a tuple for the user. :param forum_id: The forum id :param user: The user object is needed to check if we also need their forumsread object. """ if is_authenticated(user): forum, forumsread = Forum.query.\ filter(Forum.id == forum_id).\ options(db.joinedload("category")).\ outerjoin(ForumsRead, db.and_(ForumsRead.forum_id == Forum.id, ForumsRead.user_id == user.id)).\ add_entity(ForumsRead).\ first_or_404() else: forum = Forum.query.filter(Forum.id == forum_id).first_or_404() forumsread = None return forum, forumsread
def update_read(self, user, forumsread, topicsread): """Updates the ForumsRead status for the user. In order to work correctly, be sure that `topicsread is **not** `None`. :param user: The user for whom we should check if he has read the forum. :param forumsread: The forumsread object. It is needed to check if if the forum is unread. If `forumsread` is `None` and the forum is unread, it will create a new entry in the `ForumsRead` relation, else (and the forum is still unread) we are just going to update the entry in the `ForumsRead` relation. :param topicsread: The topicsread object is used in combination with the forumsread object to check if the forumsread relation should be updated and therefore is unread. """ if (not is_authenticated(user)) or topicsread is None: return False read_cutoff = None if flaskbb_config['TRACKER_LENGTH'] > 0: read_cutoff = datetime.utcnow() - timedelta( days=flaskbb_config['TRACKER_LENGTH']) # fetch the unread posts in the forum unread_count = Topic.query.\ outerjoin(TopicsRead, db.and_(TopicsRead.topic_id == Topic.id, TopicsRead.user_id == user.id)).\ outerjoin(ForumsRead, db.and_(ForumsRead.forum_id == Topic.forum_id, ForumsRead.user_id == user.id)).\ filter(Topic.forum_id == self.id, Topic.last_updated > read_cutoff, db.or_(TopicsRead.last_read == None, TopicsRead.last_read < Topic.last_updated)).\ count() # No unread topics available - trying to mark the forum as read if unread_count == 0: if forumsread and forumsread.last_read > topicsread.last_read: return False # ForumRead Entry exists - Updating it because a new topic/post # has been submitted and has read everything (obviously, else the # unread_count would be useless). elif forumsread: forumsread.last_read = datetime.utcnow() forumsread.save() return True # No ForumRead Entry existing - creating one. forumsread = ForumsRead() forumsread.user_id = user.id forumsread.forum_id = self.id forumsread.last_read = datetime.utcnow() forumsread.save() return True # Nothing updated, because there are still more than 0 unread # topicsread return False
def update_read(self, user, forumsread, topicsread): """Updates the ForumsRead status for the user. In order to work correctly, be sure that `topicsread is **not** `None`. :param user: The user for whom we should check if he has read the forum. :param forumsread: The forumsread object. It is needed to check if if the forum is unread. If `forumsread` is `None` and the forum is unread, it will create a new entry in the `ForumsRead` relation, else (and the forum is still unread) we are just going to update the entry in the `ForumsRead` relation. :param topicsread: The topicsread object is used in combination with the forumsread object to check if the forumsread relation should be updated and therefore is unread. """ if (not user.is_authenticated() and not getattr(user, "is_lockdownuser", False)) or topicsread is None: return False read_cutoff = None if flaskbb_config["TRACKER_LENGTH"] > 0: read_cutoff = datetime.utcnow() - timedelta(days=flaskbb_config["TRACKER_LENGTH"]) # fetch the unread posts in the forum unread_count = ( Topic.query.outerjoin(TopicsRead, db.and_(TopicsRead.topic_id == Topic.id, TopicsRead.user_id == user.id)) .outerjoin(ForumsRead, db.and_(ForumsRead.forum_id == Topic.forum_id, ForumsRead.user_id == user.id)) .filter( Topic.forum_id == self.id, Topic.last_updated > read_cutoff, db.or_(TopicsRead.last_read == None, TopicsRead.last_read < Topic.last_updated), ) .count() ) # No unread topics available - trying to mark the forum as read if unread_count == 0: if forumsread and forumsread.last_read > topicsread.last_read: return False # ForumRead Entry exists - Updating it because a new topic/post # has been submitted and has read everything (obviously, else the # unread_count would be useless). elif forumsread: forumsread.last_read = datetime.utcnow() forumsread.save() return True # No ForumRead Entry existing - creating one. forumsread = ForumsRead() forumsread.user_id = user.id forumsread.forum_id = self.id forumsread.last_read = datetime.utcnow() forumsread.save() return True # Nothing updated, because there are still more than 0 unread # topicsread return False