Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactoring du forum #4621

Closed
wants to merge 14 commits into from
6 changes: 6 additions & 0 deletions .gitignore
Expand Up @@ -128,3 +128,9 @@ $RECYCLE.BIN/
#############

*.*~

#############
## Visual Studio Code
#############

.vscode/
95 changes: 38 additions & 57 deletions zds/forum/commons.py
Expand Up @@ -17,31 +17,23 @@

class ForumEditMixin(object):
@staticmethod
def perform_follow(forum_or_tag, user):
return NewTopicSubscription.objects.toggle_follow(forum_or_tag, user).is_active

@staticmethod
def perform_follow_by_email(forum_or_tag, user):
return NewTopicSubscription.objects.toggle_follow(forum_or_tag, user, True).is_active
def perform_follow(forum_or_tag, user, follow_by_email=False):
return NewTopicSubscription.objects.toggle_follow(forum_or_tag, user, follow_by_email).is_active


class TopicEditMixin(object):
@staticmethod
def perform_follow(topic, user):
return TopicAnswerSubscription.objects.toggle_follow(topic, user)
def perform_follow(topic, user, follow_by_email=False):
return TopicAnswerSubscription.objects.toggle_follow(topic, user, follow_by_email)

@staticmethod
def perform_follow_by_email(topic, user):
return TopicAnswerSubscription.objects.toggle_follow(topic, user, True)

@staticmethod
def perform_solve_or_unsolve(user, topic):
if user == topic.author or user.has_perm('forum.change_topic'):
topic.is_solved = not topic.is_solved
return topic.is_solved
else:
def toggle_solve(user, topic):
if user != topic.author and not user.has_perm('forum.change_topic'):
raise PermissionDenied

topic.is_solved = not topic.is_solved
return topic.is_solved

@staticmethod
@permission_required('forum.change_topic', raise_exception=True)
def perform_lock(request, topic):
Expand All @@ -57,28 +49,28 @@ def perform_lock(request, topic):
def perform_sticky(request, topic):
topic.is_sticky = request.POST.get('sticky') == 'true'
if topic.is_sticky:
success_message = _('Le sujet « {0} » est désormais épinglé.').format(topic.title)
success_message = _('Le sujet « {0} » est désormais épinglé.').format(topic.title)
else:
success_message = _("Le sujet « {0} » n'est désormais plus épinglé.").format(topic.title)
success_message = _("Le sujet « {0} » n'est désormais plus épinglé.").format(topic.title)
messages.success(request, success_message)

def perform_move(self):
if self.request.user.has_perm('forum.change_topic'):
try:
forum_pk = int(self.request.POST.get('forum'))
except (KeyError, ValueError, TypeError) as e:
raise Http404('Forum not found', e)
forum = get_object_or_404(Forum, pk=forum_pk)
self.object.forum = forum
if not self.request.user.has_perm('forum.change_topic'):
raise PermissionDenied()

# Save topic to update update_index_date
self.object.save()
try:
forum_pk = int(self.request.POST.get('forum'))
except (KeyError, ValueError, TypeError) as e:
raise Http404('Forum not found', e)

signals.edit_content.send(sender=self.object.__class__, instance=self.object, action='move')
message = _('Le sujet « {0} » a bien été déplacé dans « {1} ».').format(self.object.title, forum.title)
messages.success(self.request, message)
else:
raise PermissionDenied()
self.object.forum = forum = get_object_or_404(Forum, pk=forum_pk)

# Save topic to update update_index_date
self.object.save()

signals.edit_content.send(sender=self.object.__class__, instance=self.object, action='move')
message = _('Le sujet « {0} » a bien été déplacé dans « {1} ».').format(self.object.title, forum.title)
messages.success(self.request, message)

@staticmethod
def perform_edit_info(request, topic, data, editor):
Expand All @@ -100,21 +92,13 @@ class PostEditMixin(object):
@staticmethod
def perform_hide_message(request, post, user, data):
is_staff = user.has_perm('forum.change_post')
if post.author == user or is_staff:
for alert in post.alerts_on_this_comment.all():
alert.solve(user, _('Le message a été masqué.'))
post.is_visible = False
post.editor = user

if is_staff:
post.text_hidden = data.get('text_hidden', '')

messages.success(request, _('Le message est désormais masqué.'))
for user in Notification.objects.get_users_for_unread_notification_on(post):
signals.content_read.send(sender=post.topic.__class__, instance=post.topic, user=user)
else:

if post.author != user and not is_staff:
raise PermissionDenied

post.hide(user, data.get('text_hidden', '') if is_staff else '')
messages.success(request, _(u'Le message est désormais masqué.'))

@staticmethod
@permission_required('forum.change_post', raise_exception=True)
def perform_show_message(request, post):
Expand All @@ -123,18 +107,17 @@ def perform_show_message(request, post):

@staticmethod
def perform_alert_message(request, post, user, alert_text):
alert = Alert(
Alert.objects.create(
author=user,
comment=post,
scope='FORUM',
text=alert_text,
pubdate=datetime.now())
alert.save()

messages.success(request, _("Une alerte a été envoyée à l'équipe concernant ce message."))

@staticmethod
def perform_useful(post):
def toggle_useful(post):
post.is_useful = not post.is_useful
post.save()

Expand All @@ -148,17 +131,15 @@ def perform_unread_message(post, user):
# issue 3227 proves that you can have post.position==1 AND topic_read to None
# it can happen whether on double click (the event "mark as not read" is therefore sent twice)
# or if you have two tabs in your browser.
if topic_read is None and post.position > 1:
if post.position > 1:
unread = Post.objects.filter(topic=post.topic, position=(post.position - 1)).first()
topic_read = TopicRead(post=unread, topic=unread.topic, user=user)
topic_read.save()
else:
if post.position > 1:
unread = Post.objects.filter(topic=post.topic, position=(post.position - 1)).first()
if topic_read is None:
TopicRead.objects.create(post=unread, topic=unread.topic, user=user)
else:
topic_read.post = unread
topic_read.save()
elif topic_read:
topic_read.delete()
elif topic_read:
topic_read.delete()

signals.answer_unread.send(sender=post.topic.__class__, instance=post, user=user)

Expand Down
10 changes: 5 additions & 5 deletions zds/forum/feeds.py
Expand Up @@ -29,11 +29,11 @@ def items(self, obj):
topic__forum__pk=int(obj['forum']),
topic__tags__pk__in=[obj['tag']]) \
.order_by('-pubdate')[:settings.ZDS_APP['forum']['posts_per_page']]
elif 'forum' in obj and 'tag' not in obj:
elif 'forum' in obj:
posts = Post.objects.filter(topic__forum__groups__isnull=True,
topic__forum__pk=int(obj['forum'])) \
.order_by('-pubdate')[:settings.ZDS_APP['forum']['posts_per_page']]
elif 'forum' not in obj and 'tag' in obj:
elif 'tag' in obj:
posts = Post.objects.filter(topic__forum__groups__isnull=True,
topic__tags__pk__in=[obj['tag']]) \
.order_by('-pubdate')[:settings.ZDS_APP['forum']['posts_per_page']]
Expand Down Expand Up @@ -88,15 +88,15 @@ def items(self, obj):
forum__pk=int(obj['forum']),
tags__pk__in=[obj['tag']])\
.order_by('-pubdate')[:settings.ZDS_APP['forum']['posts_per_page']]
elif 'forum' in obj and 'tag' not in obj:
elif 'forum' in obj:
topics = Topic.objects.filter(forum__groups__isnull=True,
forum__pk=int(obj['forum']))\
.order_by('-pubdate')[:settings.ZDS_APP['forum']['posts_per_page']]
elif 'forum' not in obj and 'tag' in obj:
elif 'tag' in obj:
topics = Topic.objects.filter(forum__groups__isnull=True,
tags__pk__in=[obj['tag']])\
.order_by('-pubdate')[:settings.ZDS_APP['forum']['posts_per_page']]
if 'forum' not in obj and 'tag' not in obj:
else:
topics = Topic.objects.filter(forum__groups__isnull=True)\
.order_by('-pubdate')[:settings.ZDS_APP['forum']['posts_per_page']]
except (Topic.DoesNotExist, ValueError):
Expand Down
101 changes: 59 additions & 42 deletions zds/forum/managers.py
Expand Up @@ -32,9 +32,12 @@ def get_public_forums_of_category(self, category, with_count=False):
return queryset.all()

def get_private_forums_of_category(self, category, user):
return self.filter(category=category, groups__in=user.groups.all())\
return self \
.filter(category=category, groups__in=user.groups.all())\
.order_by('position_in_category')\
.select_related('category').distinct().all()
.select_related('category') \
.distinct() \
.all()


class TopicManager(models.Manager):
Expand All @@ -61,14 +64,18 @@ def last_topics_of_a_member(self, author, user):
:param user: Request user.
:return: List of topics.
"""
queryset = self.filter(author=author) \
.prefetch_related('author')
queryset = queryset.filter(self.visibility_check_query(user)).distinct()

return queryset.order_by('-pubdate').all()[:settings.ZDS_APP['forum']['home_number']]
return self \
.filter(author=author) \
.prefetch_related('author') \
.filter(self.visibility_check_query(user)) \
.distinct() \
.order_by('-pubdate') \
.all()[:settings.ZDS_APP['forum']['home_number']]

def get_beta_topic_of(self, tutorial):
return self.filter(key=tutorial.pk, key__isnull=False).first()
return self \
.filter(key=tutorial.pk, key__isnull=False) \
.first()

def get_last_topics(self):
"""
Expand All @@ -77,28 +84,37 @@ def get_last_topics(self):
:return:
:rtype: django.models.Queryset
"""
return self.filter(is_locked=False, forum__groups__isnull=True) \
.select_related('forum', 'author', 'last_message') \
.prefetch_related('tags').order_by('-pubdate') \
.all()[:settings.ZDS_APP['topic']['home_number']]
return self \
.filter(is_locked=False, forum__groups__isnull=True) \
.select_related('forum', 'author', 'last_message') \
.prefetch_related('tags') \
.order_by('-pubdate') \
.all()[:settings.ZDS_APP['topic']['home_number']]

def get_all_topics_of_a_forum(self, forum_pk, is_sticky=False):
return self.filter(forum__pk=forum_pk, is_sticky=is_sticky) \
.order_by('-last_message__pubdate')\
.select_related('author__profile')\
.prefetch_related('last_message', 'tags').all()
return self \
.filter(forum__pk=forum_pk, is_sticky=is_sticky) \
.order_by('-last_message__pubdate') \
.select_related('author__profile') \
.prefetch_related('last_message', 'tags') \
.all()

def get_all_topics_of_a_user(self, current, target):
queryset = self.filter(author=target)\
.prefetch_related('author')
queryset = queryset.filter(self.visibility_check_query(current)).distinct()
return queryset.order_by('-pubdate').all()
return self \
.filter(author=target) \
.prefetch_related('author') \
.filter(self.visibility_check_query(current)) \
.distinct() \
.order_by('-pubdate') \
.all()

def get_all_topics_of_a_tag(self, tag, user):
queryset = self.filter(tags__in=[tag])\
.prefetch_related('author', 'last_message', 'tags')
queryset = queryset.filter(self.visibility_check_query(user)).distinct()
return queryset.order_by('-last_message__pubdate')
return self \
.filter(tags__in=[tag]) \
.prefetch_related('author', 'last_message', 'tags') \
.filter(self.visibility_check_query(user)) \
.distinct() \
.order_by('-last_message__pubdate')


class PostManager(InheritanceManager):
Expand All @@ -112,18 +128,23 @@ def visibility_check_query(self, current_user):
:param current_user:
:return:
"""
if current_user.is_authenticated():
return Q(topic__forum__groups__isnull=True) | Q(topic__forum__groups__pk__in=current_user.profile.group_pks)
return Q(topic__forum__groups__isnull=True)
res = Q(topic__forum__groups__isnull=True)

if not current_user.is_authenticated():
return res

return res | Q(topic__forum__groups__pk__in=current_user.profile.group_pks)

def get_messages_of_a_topic(self, topic_pk):
return self.filter(topic__pk=topic_pk)\
.select_related('hat')\
.select_related('author__profile')\
.prefetch_related('alerts_on_this_comment')\
.prefetch_related('alerts_on_this_comment__author')\
.prefetch_related('alerts_on_this_comment__author__profile')\
.order_by('position').all()
return self \
.filter(topic__pk=topic_pk) \
.select_related('hat') \
.select_related('author__profile') \
.prefetch_related('alerts_on_this_comment') \
.prefetch_related('alerts_on_this_comment__author') \
.prefetch_related('alerts_on_this_comment__author__profile') \
.order_by('position') \
.all()

def get_all_messages_of_a_user(self, current, target):
queryset = self.filter(author=target).distinct()
Expand All @@ -132,13 +153,11 @@ def get_all_messages_of_a_user(self, current, target):
if not current.has_perm('forum.change_post'):
queryset = queryset.filter(is_visible=True)

queryset = queryset\
.filter(self.visibility_check_query(current))\
.prefetch_related('author')\
return queryset \
.filter(self.visibility_check_query(current)) \
.prefetch_related('author') \
.order_by('-pubdate')

return queryset


class TopicReadManager(models.Manager):

Expand All @@ -154,9 +173,7 @@ def topic_read_by_user(self, user, topic_sub_list=None):
base_queryset = self.filter(user__pk=user.pk)
if topic_sub_list is not None:
base_queryset = base_queryset.filter(topic__in=topic_sub_list)
base_queryset = base_queryset.filter(post=F('topic__last_message'))

return base_queryset
return base_queryset.filter(post=F('topic__last_message'))

def list_read_topic_pk(self, user, topic_sub_list=None):
""" get all the topic that the user has already read in a flat list.
Expand Down