Esempio n. 1
0
    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)
Esempio n. 2
0
    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
Esempio n. 3
0
    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
Esempio n. 4
0
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)
Esempio n. 5
0
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)
Esempio n. 6
0
    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
Esempio n. 7
0
    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
Esempio n. 8
0
    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
Esempio n. 9
0
    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