|
@@ -15,7 +15,9 @@ from sqlalchemy.orm import aliased
|
|
|
|
|
|
from flaskbb.extensions import db
|
|
from flaskbb.extensions import db
|
|
from flaskbb.utils.decorators import can_access_forum, can_access_topic
|
|
from flaskbb.utils.decorators import can_access_forum, can_access_topic
|
|
-from flaskbb.utils.helpers import slugify, get_categories_and_forums, get_forums
|
|
|
|
|
|
+from flaskbb.utils.helpers import slugify, get_categories_and_forums, \
|
|
|
|
+ get_forums
|
|
|
|
+from flaskbb.utils.database import CRUDMixin
|
|
from flaskbb.utils.settings import flaskbb_config
|
|
from flaskbb.utils.settings import flaskbb_config
|
|
|
|
|
|
|
|
|
|
@@ -37,6 +39,7 @@ topictracker = db.Table(
|
|
use_alter=True, name="fk_tracker_topic_id"),
|
|
use_alter=True, name="fk_tracker_topic_id"),
|
|
nullable=False))
|
|
nullable=False))
|
|
|
|
|
|
|
|
+
|
|
# m2m table for group-forum permission mapping
|
|
# m2m table for group-forum permission mapping
|
|
forumgroups = db.Table(
|
|
forumgroups = db.Table(
|
|
'forumgroups',
|
|
'forumgroups',
|
|
@@ -54,7 +57,8 @@ forumgroups = db.Table(
|
|
)
|
|
)
|
|
)
|
|
)
|
|
|
|
|
|
-class TopicsRead(db.Model):
|
|
|
|
|
|
+
|
|
|
|
+class TopicsRead(db.Model, CRUDMixin):
|
|
__tablename__ = "topicsread"
|
|
__tablename__ = "topicsread"
|
|
|
|
|
|
user_id = db.Column(db.Integer, db.ForeignKey("users.id"),
|
|
user_id = db.Column(db.Integer, db.ForeignKey("users.id"),
|
|
@@ -69,23 +73,8 @@ class TopicsRead(db.Model):
|
|
primary_key=True)
|
|
primary_key=True)
|
|
last_read = db.Column(db.DateTime, default=datetime.utcnow())
|
|
last_read = db.Column(db.DateTime, default=datetime.utcnow())
|
|
|
|
|
|
- def __repr__(self):
|
|
|
|
- return "<{}>".format(self.__class__.__name__)
|
|
|
|
-
|
|
|
|
- def save(self):
|
|
|
|
- """Saves a TopicsRead entry."""
|
|
|
|
- db.session.add(self)
|
|
|
|
- db.session.commit()
|
|
|
|
- return self
|
|
|
|
|
|
|
|
- def delete(self):
|
|
|
|
- """Deletes a TopicsRead entry."""
|
|
|
|
- db.session.delete(self)
|
|
|
|
- db.session.commit()
|
|
|
|
- return self
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-class ForumsRead(db.Model):
|
|
|
|
|
|
+class ForumsRead(db.Model, CRUDMixin):
|
|
__tablename__ = "forumsread"
|
|
__tablename__ = "forumsread"
|
|
|
|
|
|
user_id = db.Column(db.Integer, db.ForeignKey("users.id"),
|
|
user_id = db.Column(db.Integer, db.ForeignKey("users.id"),
|
|
@@ -97,23 +86,8 @@ class ForumsRead(db.Model):
|
|
last_read = db.Column(db.DateTime, default=datetime.utcnow())
|
|
last_read = db.Column(db.DateTime, default=datetime.utcnow())
|
|
cleared = db.Column(db.DateTime)
|
|
cleared = db.Column(db.DateTime)
|
|
|
|
|
|
- def __repr__(self):
|
|
|
|
- return "<{}>".format(self.__class__.__name__)
|
|
|
|
|
|
|
|
- def save(self):
|
|
|
|
- """Saves a ForumsRead entry."""
|
|
|
|
- db.session.add(self)
|
|
|
|
- db.session.commit()
|
|
|
|
- return self
|
|
|
|
-
|
|
|
|
- def delete(self):
|
|
|
|
- """Deletes a ForumsRead entry."""
|
|
|
|
- db.session.delete(self)
|
|
|
|
- db.session.commit()
|
|
|
|
- return self
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-class Report(db.Model):
|
|
|
|
|
|
+class Report(db.Model, CRUDMixin):
|
|
__tablename__ = "reports"
|
|
__tablename__ = "reports"
|
|
|
|
|
|
id = db.Column(db.Integer, primary_key=True)
|
|
id = db.Column(db.Integer, primary_key=True)
|
|
@@ -137,9 +111,7 @@ class Report(db.Model):
|
|
"""Saves a report.
|
|
"""Saves a report.
|
|
|
|
|
|
:param post: The post that should be reported
|
|
:param post: The post that should be reported
|
|
-
|
|
|
|
:param user: The user who has reported the post
|
|
:param user: The user who has reported the post
|
|
-
|
|
|
|
:param reason: The reason why the user has reported the post
|
|
:param reason: The reason why the user has reported the post
|
|
"""
|
|
"""
|
|
|
|
|
|
@@ -157,14 +129,8 @@ class Report(db.Model):
|
|
db.session.commit()
|
|
db.session.commit()
|
|
return self
|
|
return self
|
|
|
|
|
|
- def delete(self):
|
|
|
|
- """Deletes a report."""
|
|
|
|
- db.session.delete(self)
|
|
|
|
- db.session.commit()
|
|
|
|
- return self
|
|
|
|
-
|
|
|
|
|
|
|
|
-class Post(db.Model):
|
|
|
|
|
|
+class Post(db.Model, CRUDMixin):
|
|
__tablename__ = "posts"
|
|
__tablename__ = "posts"
|
|
__searchable__ = ['content', 'username']
|
|
__searchable__ = ['content', 'username']
|
|
|
|
|
|
@@ -205,7 +171,6 @@ class Post(db.Model):
|
|
operation was successful.
|
|
operation was successful.
|
|
|
|
|
|
:param user: The user who has created the post
|
|
:param user: The user who has created the post
|
|
-
|
|
|
|
:param topic: The topic in which the post was created
|
|
:param topic: The topic in which the post was created
|
|
"""
|
|
"""
|
|
# update/edit the post
|
|
# update/edit the post
|
|
@@ -223,7 +188,7 @@ class Post(db.Model):
|
|
|
|
|
|
topic.last_updated = datetime.utcnow()
|
|
topic.last_updated = datetime.utcnow()
|
|
|
|
|
|
- # This needs to be done before I update the last_post_id.
|
|
|
|
|
|
+ # This needs to be done before the last_post_id gets updated.
|
|
db.session.add(self)
|
|
db.session.add(self)
|
|
db.session.commit()
|
|
db.session.commit()
|
|
|
|
|
|
@@ -248,7 +213,7 @@ class Post(db.Model):
|
|
return self
|
|
return self
|
|
|
|
|
|
def delete(self):
|
|
def delete(self):
|
|
- """Deletes a post and returns self"""
|
|
|
|
|
|
+ """Deletes a post and returns self."""
|
|
# This will delete the whole topic
|
|
# This will delete the whole topic
|
|
if self.topic.first_post_id == self.id:
|
|
if self.topic.first_post_id == self.id:
|
|
self.topic.delete()
|
|
self.topic.delete()
|
|
@@ -292,7 +257,7 @@ class Post(db.Model):
|
|
return self
|
|
return self
|
|
|
|
|
|
|
|
|
|
-class Topic(db.Model):
|
|
|
|
|
|
+class Topic(db.Model, CRUDMixin):
|
|
__tablename__ = "topics"
|
|
__tablename__ = "topics"
|
|
__searchable__ = ['title', 'username']
|
|
__searchable__ = ['title', 'username']
|
|
|
|
|
|
@@ -368,12 +333,9 @@ class Topic(db.Model):
|
|
Also, if the ``TRACKER_LENGTH`` is configured, it will just recognize
|
|
Also, if the ``TRACKER_LENGTH`` is configured, it will just recognize
|
|
topics that are newer than the ``TRACKER_LENGTH`` (in days) as unread.
|
|
topics that are newer than the ``TRACKER_LENGTH`` (in days) as unread.
|
|
|
|
|
|
- TODO: Couldn't think of a better name for this method - ideas?
|
|
|
|
-
|
|
|
|
:param forumsread: The ForumsRead object is needed because we also
|
|
:param forumsread: The ForumsRead object is needed because we also
|
|
need to check if the forum has been cleared
|
|
need to check if the forum has been cleared
|
|
sometime ago.
|
|
sometime ago.
|
|
-
|
|
|
|
:param topicsread: The topicsread object is used to check if there is
|
|
:param topicsread: The topicsread object is used to check if there is
|
|
a new post in the topic.
|
|
a new post in the topic.
|
|
"""
|
|
"""
|
|
@@ -407,9 +369,7 @@ class Topic(db.Model):
|
|
Returns True if the tracker has been updated.
|
|
Returns True if the tracker has been updated.
|
|
|
|
|
|
:param user: The user for whom the readstracker should be updated.
|
|
:param user: The user for whom the readstracker should be updated.
|
|
-
|
|
|
|
:param forum: The forum in which the topic is.
|
|
:param forum: The forum in which the topic is.
|
|
-
|
|
|
|
:param forumsread: The forumsread object. It is used to check if there
|
|
:param forumsread: The forumsread object. It is used to check if there
|
|
is a new post since the forum has been marked as
|
|
is a new post since the forum has been marked as
|
|
read.
|
|
read.
|
|
@@ -456,71 +416,40 @@ class Topic(db.Model):
|
|
|
|
|
|
return updated
|
|
return updated
|
|
|
|
|
|
- def move(self, forum):
|
|
|
|
|
|
+ def move(self, new_forum):
|
|
"""Moves a topic to the given forum.
|
|
"""Moves a topic to the given forum.
|
|
Returns True if it could successfully move the topic to forum.
|
|
Returns True if it could successfully move the topic to forum.
|
|
|
|
|
|
- :param forum: The new forum for the topic
|
|
|
|
|
|
+ :param new_forum: The new forum for the topic
|
|
"""
|
|
"""
|
|
|
|
|
|
# if the target forum is the current forum, abort
|
|
# if the target forum is the current forum, abort
|
|
- if self.forum_id == forum.id:
|
|
|
|
|
|
+ if self.forum_id == new_forum.id:
|
|
return False
|
|
return False
|
|
|
|
|
|
old_forum = self.forum
|
|
old_forum = self.forum
|
|
self.forum.post_count -= self.post_count
|
|
self.forum.post_count -= self.post_count
|
|
self.forum.topic_count -= 1
|
|
self.forum.topic_count -= 1
|
|
- self.forum_id = forum.id
|
|
|
|
|
|
+ self.forum_id = new_forum.id
|
|
|
|
|
|
- forum.post_count += self.post_count
|
|
|
|
- forum.topic_count += 1
|
|
|
|
|
|
+ new_forum.post_count += self.post_count
|
|
|
|
+ new_forum.topic_count += 1
|
|
|
|
|
|
db.session.commit()
|
|
db.session.commit()
|
|
|
|
|
|
- forum.update_last_post()
|
|
|
|
|
|
+ new_forum.update_last_post()
|
|
old_forum.update_last_post()
|
|
old_forum.update_last_post()
|
|
|
|
|
|
TopicsRead.query.filter_by(topic_id=self.id).delete()
|
|
TopicsRead.query.filter_by(topic_id=self.id).delete()
|
|
|
|
|
|
return True
|
|
return True
|
|
|
|
|
|
- def merge(self, topic):
|
|
|
|
- """Merges a topic with another topic
|
|
|
|
-
|
|
|
|
- :param topic: The new topic for the posts in this topic
|
|
|
|
- """
|
|
|
|
-
|
|
|
|
- # You can only merge a topic with a differrent topic in the same forum
|
|
|
|
- if self.id == topic.id or not self.forum_id == topic.forum_id:
|
|
|
|
- return False
|
|
|
|
-
|
|
|
|
- # Update the topic id
|
|
|
|
- Post.query.filter_by(topic_id=self.id).\
|
|
|
|
- update({Post.topic_id: topic.id})
|
|
|
|
-
|
|
|
|
- # Update the last post
|
|
|
|
- if topic.last_post.date_created < self.last_post.date_created:
|
|
|
|
- topic.last_post_id = self.last_post_id
|
|
|
|
-
|
|
|
|
- # Increase the post and views count
|
|
|
|
- topic.post_count += self.post_count
|
|
|
|
- topic.views += self.views
|
|
|
|
-
|
|
|
|
- topic.save()
|
|
|
|
-
|
|
|
|
- # Finally delete the old topic
|
|
|
|
- Topic.query.filter_by(id=self.id).delete()
|
|
|
|
-
|
|
|
|
- return True
|
|
|
|
-
|
|
|
|
def save(self, user=None, forum=None, post=None):
|
|
def save(self, user=None, forum=None, post=None):
|
|
"""Saves a topic and returns the topic object. If no parameters are
|
|
"""Saves a topic and returns the topic object. If no parameters are
|
|
given, it will only update the topic.
|
|
given, it will only update the topic.
|
|
|
|
|
|
:param user: The user who has created the topic
|
|
:param user: The user who has created the topic
|
|
-
|
|
|
|
:param forum: The forum where the topic is stored
|
|
:param forum: The forum where the topic is stored
|
|
-
|
|
|
|
:param post: The post object which is connected to the topic
|
|
:param post: The post object which is connected to the topic
|
|
"""
|
|
"""
|
|
|
|
|
|
@@ -567,7 +496,7 @@ class Topic(db.Model):
|
|
filter_by(forum_id=self.forum_id).\
|
|
filter_by(forum_id=self.forum_id).\
|
|
order_by(Topic.last_post_id.desc()).limit(2).offset(0).all()
|
|
order_by(Topic.last_post_id.desc()).limit(2).offset(0).all()
|
|
|
|
|
|
- # do want to delete the topic with the last post?
|
|
|
|
|
|
+ # do we want to delete the topic with the last post in the forum?
|
|
if topic and topic[0].id == self.id:
|
|
if topic and topic[0].id == self.id:
|
|
try:
|
|
try:
|
|
# Now the second last post will be the last post
|
|
# Now the second last post will be the last post
|
|
@@ -616,7 +545,7 @@ class Topic(db.Model):
|
|
return self
|
|
return self
|
|
|
|
|
|
|
|
|
|
-class Forum(db.Model):
|
|
|
|
|
|
+class Forum(db.Model, CRUDMixin):
|
|
__tablename__ = "forums"
|
|
__tablename__ = "forums"
|
|
__searchable__ = ['title', 'description']
|
|
__searchable__ = ['title', 'description']
|
|
|
|
|
|
@@ -777,13 +706,17 @@ class Forum(db.Model):
|
|
forumsread.save()
|
|
forumsread.save()
|
|
return True
|
|
return True
|
|
|
|
|
|
- # Nothing updated, because there are still more than 0 unread topicsread
|
|
|
|
|
|
+ # Nothing updated, because there are still more than 0 unread
|
|
|
|
+ # topicsread
|
|
return False
|
|
return False
|
|
|
|
|
|
def save(self, groups=None):
|
|
def save(self, groups=None):
|
|
"""Saves a forum
|
|
"""Saves a forum
|
|
|
|
|
|
- :param groups: A list with group objects."""
|
|
|
|
|
|
+ :param moderators: If given, it will update the moderators in this
|
|
|
|
+ forum with the given iterable of user objects.
|
|
|
|
+ :param groups: A list with group objects.
|
|
|
|
+ """
|
|
if self.id:
|
|
if self.id:
|
|
db.session.merge(self)
|
|
db.session.merge(self)
|
|
else:
|
|
else:
|
|
@@ -822,6 +755,17 @@ class Forum(db.Model):
|
|
|
|
|
|
return self
|
|
return self
|
|
|
|
|
|
|
|
+ def move_topics_to(self, topics):
|
|
|
|
+ """Moves a bunch a topics to the forum. Returns ``True`` if all
|
|
|
|
+ topics were moved successfully to the forum.
|
|
|
|
+
|
|
|
|
+ :param topics: A iterable with topic objects.
|
|
|
|
+ """
|
|
|
|
+ status = False
|
|
|
|
+ for topic in topics:
|
|
|
|
+ status = topic.move(self)
|
|
|
|
+ return status
|
|
|
|
+
|
|
# Classmethods
|
|
# Classmethods
|
|
@classmethod
|
|
@classmethod
|
|
@can_access_forum
|
|
@can_access_forum
|
|
@@ -829,7 +773,6 @@ class Forum(db.Model):
|
|
"""Returns the forum and forumsread object as a tuple for the user.
|
|
"""Returns the forum and forumsread object as a tuple for the user.
|
|
|
|
|
|
:param forum_id: The forum id
|
|
:param forum_id: The forum id
|
|
-
|
|
|
|
:param user: The user object is needed to check if we also need their
|
|
:param user: The user object is needed to check if we also need their
|
|
forumsread object.
|
|
forumsread object.
|
|
"""
|
|
"""
|
|
@@ -855,11 +798,8 @@ class Forum(db.Model):
|
|
forumsread relation to check if it is read or unread.
|
|
forumsread relation to check if it is read or unread.
|
|
|
|
|
|
:param forum_id: The forum id
|
|
:param forum_id: The forum id
|
|
-
|
|
|
|
:param user: The user object
|
|
:param user: The user object
|
|
-
|
|
|
|
:param page: The page whom should be loaded
|
|
:param page: The page whom should be loaded
|
|
-
|
|
|
|
:param per_page: How many topics per page should be shown
|
|
:param per_page: How many topics per page should be shown
|
|
"""
|
|
"""
|
|
if user.is_authenticated():
|
|
if user.is_authenticated():
|
|
@@ -880,7 +820,7 @@ class Forum(db.Model):
|
|
return topics
|
|
return topics
|
|
|
|
|
|
|
|
|
|
-class Category(db.Model):
|
|
|
|
|
|
+class Category(db.Model, CRUDMixin):
|
|
__tablename__ = "categories"
|
|
__tablename__ = "categories"
|
|
__searchable__ = ['title', 'description']
|
|
__searchable__ = ['title', 'description']
|
|
|
|
|
|
@@ -914,13 +854,6 @@ class Category(db.Model):
|
|
"""
|
|
"""
|
|
return "<{} {}>".format(self.__class__.__name__, self.id)
|
|
return "<{} {}>".format(self.__class__.__name__, self.id)
|
|
|
|
|
|
- def save(self):
|
|
|
|
- """Saves a category"""
|
|
|
|
-
|
|
|
|
- db.session.add(self)
|
|
|
|
- db.session.commit()
|
|
|
|
- return self
|
|
|
|
-
|
|
|
|
def delete(self, users=None):
|
|
def delete(self, users=None):
|
|
"""Deletes a category. If a list with involved user objects is passed,
|
|
"""Deletes a category. If a list with involved user objects is passed,
|
|
it will also update their post counts
|
|
it will also update their post counts
|
|
@@ -955,48 +888,23 @@ class Category(db.Model):
|
|
:param user: The user object is needed to check if we also need their
|
|
:param user: The user object is needed to check if we also need their
|
|
forumsread object.
|
|
forumsread object.
|
|
"""
|
|
"""
|
|
- # import Group model locally to avoid cicular imports
|
|
|
|
- from flaskbb.user.models import Group
|
|
|
|
if user.is_authenticated():
|
|
if user.is_authenticated():
|
|
- # get list of user group ids
|
|
|
|
- user_groups = [gr.id for gr in user.groups]
|
|
|
|
- # filter forums by user groups
|
|
|
|
- user_forums = Forum.query.filter(Forum.groups.any(
|
|
|
|
- Group.id.in_(user_groups))
|
|
|
|
- ).subquery()
|
|
|
|
- forum_alias = aliased(Forum, user_forums)
|
|
|
|
- # get all
|
|
|
|
- forums = cls.query.join(
|
|
|
|
- forum_alias,
|
|
|
|
- cls.id == forum_alias.category_id
|
|
|
|
- ).outerjoin(
|
|
|
|
- ForumsRead,
|
|
|
|
- db.and_(
|
|
|
|
- ForumsRead.forum_id == forum_alias.id,
|
|
|
|
- ForumsRead.user_id == user.id
|
|
|
|
- )
|
|
|
|
- ).add_entity(
|
|
|
|
- forum_alias
|
|
|
|
- ).add_entity(
|
|
|
|
- ForumsRead
|
|
|
|
- ).order_by(
|
|
|
|
- Category.position, Category.id, forum_alias.position
|
|
|
|
- ).all()
|
|
|
|
|
|
+ forums = cls.query.\
|
|
|
|
+ join(Forum, cls.id == Forum.category_id).\
|
|
|
|
+ outerjoin(ForumsRead,
|
|
|
|
+ db.and_(ForumsRead.forum_id == Forum.id,
|
|
|
|
+ ForumsRead.user_id == user.id)).\
|
|
|
|
+ add_entity(Forum).\
|
|
|
|
+ add_entity(ForumsRead).\
|
|
|
|
+ order_by(Category.id, Category.position, Forum.position).\
|
|
|
|
+ all()
|
|
else:
|
|
else:
|
|
- guest_group = Group.get_guest_group()
|
|
|
|
- # filter forums by guest groups
|
|
|
|
- guest_forums = Forum.query.filter(
|
|
|
|
- Forum.groups.any(Group.id == guest_group.id)
|
|
|
|
- ).subquery()
|
|
|
|
- forum_alias = aliased(Forum, guest_forums)
|
|
|
|
- forums = cls.query.join(
|
|
|
|
- forum_alias,
|
|
|
|
- cls.id == forum_alias.category_id
|
|
|
|
- ).add_entity(
|
|
|
|
- forum_alias
|
|
|
|
- ).order_by(
|
|
|
|
- Category.position, Category.id, forum_alias.position
|
|
|
|
- ).all()
|
|
|
|
|
|
+ # Get all the forums
|
|
|
|
+ forums = cls.query.\
|
|
|
|
+ join(Forum, cls.id == Forum.category_id).\
|
|
|
|
+ add_entity(Forum).\
|
|
|
|
+ order_by(Category.id, Category.position, Forum.position).\
|
|
|
|
+ all()
|
|
|
|
|
|
return get_categories_and_forums(forums, user)
|
|
return get_categories_and_forums(forums, user)
|
|
|
|
|
|
@@ -1011,52 +919,27 @@ class Category(db.Model):
|
|
(<Category 1>, [(<Forum 1>, None), (<Forum 2>, None)])
|
|
(<Category 1>, [(<Forum 1>, None), (<Forum 2>, None)])
|
|
|
|
|
|
:param category_id: The category id
|
|
:param category_id: The category id
|
|
-
|
|
|
|
:param user: The user object is needed to check if we also need their
|
|
:param user: The user object is needed to check if we also need their
|
|
forumsread object.
|
|
forumsread object.
|
|
"""
|
|
"""
|
|
- from flaskbb.user.models import Group
|
|
|
|
if user.is_authenticated():
|
|
if user.is_authenticated():
|
|
- # get list of user group ids
|
|
|
|
- user_groups = [gr.id for gr in user.groups]
|
|
|
|
- # filter forums by user groups
|
|
|
|
- user_forums = Forum.query.filter(Forum.groups.any(
|
|
|
|
- Group.id.in_(user_groups))
|
|
|
|
- ).subquery()
|
|
|
|
- forum_alias = aliased(Forum, user_forums)
|
|
|
|
- forums = cls.query.filter(
|
|
|
|
- cls.id == category_id
|
|
|
|
- ).join(
|
|
|
|
- forum_alias,
|
|
|
|
- cls.id == forum_alias.category_id
|
|
|
|
- ).outerjoin(
|
|
|
|
- ForumsRead,
|
|
|
|
- db.and_(
|
|
|
|
- ForumsRead.forum_id == forum_alias.id,
|
|
|
|
- ForumsRead.user_id == user.id)
|
|
|
|
- ).add_entity(
|
|
|
|
- forum_alias
|
|
|
|
- ).add_entity(
|
|
|
|
- ForumsRead
|
|
|
|
- ).order_by(
|
|
|
|
- forum_alias.position
|
|
|
|
- ).all()
|
|
|
|
|
|
+ forums = cls.query.\
|
|
|
|
+ filter(cls.id == category_id).\
|
|
|
|
+ join(Forum, cls.id == Forum.category_id).\
|
|
|
|
+ outerjoin(ForumsRead,
|
|
|
|
+ db.and_(ForumsRead.forum_id == Forum.id,
|
|
|
|
+ ForumsRead.user_id == user.id)).\
|
|
|
|
+ add_entity(Forum).\
|
|
|
|
+ add_entity(ForumsRead).\
|
|
|
|
+ order_by(Forum.position).\
|
|
|
|
+ all()
|
|
else:
|
|
else:
|
|
- guest_group = Group.get_guest_group()
|
|
|
|
- # filter forums by guest groups
|
|
|
|
- guest_forums = Forum.query.filter(
|
|
|
|
- Forum.groups.any(Group.id == guest_group.id)
|
|
|
|
- ).subquery()
|
|
|
|
- forum_alias = aliased(Forum, guest_forums)
|
|
|
|
- forums = cls.query.filter(
|
|
|
|
- cls.id == category_id
|
|
|
|
- ).join(
|
|
|
|
- forum_alias, cls.id == forum_alias.category_id
|
|
|
|
- ).add_entity(
|
|
|
|
- forum_alias
|
|
|
|
- ).order_by(
|
|
|
|
- forum_alias.position
|
|
|
|
- ).all()
|
|
|
|
|
|
+ forums = cls.query.\
|
|
|
|
+ filter(cls.id == category_id).\
|
|
|
|
+ join(Forum, cls.id == Forum.category_id).\
|
|
|
|
+ add_entity(Forum).\
|
|
|
|
+ order_by(Forum.position).\
|
|
|
|
+ all()
|
|
|
|
|
|
if not forums:
|
|
if not forums:
|
|
abort(404)
|
|
abort(404)
|