From 0e5123ab39b2251932255fe1d5d25354c7b223ed Mon Sep 17 00:00:00 2001 From: Gust Date: Thu, 26 Feb 2015 14:18:41 -0300 Subject: [PATCH] Threads access permission and statistics --- colab/accounts/utils/mailman.py | 14 ++++++++++++++ colab/accounts/views.py | 19 +++++++++++++------ colab/home/views.py | 30 ++++++++++++++++++++++++------ colab/search/utils.py | 42 +++++++++++++++++++++++++++++++++--------- colab/super_archives/views.py | 22 +++++++++++++++++----- 5 files changed, 101 insertions(+), 26 deletions(-) diff --git a/colab/accounts/utils/mailman.py b/colab/accounts/utils/mailman.py index 94ae072..213e4bf 100644 --- a/colab/accounts/utils/mailman.py +++ b/colab/accounts/utils/mailman.py @@ -102,3 +102,17 @@ def list_users(listname): return [] return users.json() + + +def get_user_mailinglists(user): + lists_for_user = [] + emails = '' + + if user: + emails = user.emails.values_list('address', flat=True) + + lists_for_user = [] + for email in emails: + lists_for_user.extend(address_lists(email)) + + return lists_for_user \ No newline at end of file diff --git a/colab/accounts/views.py b/colab/accounts/views.py index f620188..3932c03 100644 --- a/colab/accounts/views.py +++ b/colab/accounts/views.py @@ -17,7 +17,8 @@ from conversejs.models import XMPPAccount from colab.super_archives.models import (EmailAddress, Message, EmailAddressValidation) -from colab.search.utils import get_collaboration_data +from colab.search.utils import get_collaboration_data, get_visible_threads +from colab.accounts.models import User from .forms import (UserCreationForm, UserForm, ListsForm, UserUpdateForm, ChangeXMPPPasswordForm) @@ -60,12 +61,17 @@ class UserProfileDetailView(UserProfileBaseMixin, DetailView): template_name = 'accounts/user_detail.html' def get_context_data(self, **kwargs): - user = self.object + profile_user = self.object context = {} count_types = OrderedDict() - collaborations, count_types_extras = get_collaboration_data(user) + logged_user = None + if self.request.user.is_authenticated(): + logged_user = User.objects.get(username=self.request.user) + + collaborations, count_types_extras = get_collaboration_data( + logged_user, profile_user) collaborations.sort(key=lambda elem: elem.modified, reverse=True) @@ -74,12 +80,13 @@ class UserProfileDetailView(UserProfileBaseMixin, DetailView): context['type_count'] = count_types context['results'] = collaborations[:10] - email_pks = [addr.pk for addr in user.emails.iterator()] - query = Message.objects.filter(from_address__in=email_pks) + email_pks = [addr.pk for addr in profile_user.emails.iterator()] + query = get_visible_threads(logged_user, profile_user) query = query.order_by('-received_time') context['emails'] = query[:10] - messages = Message.objects.filter(from_address__user__pk=user.pk) + messages = get_visible_threads(logged_user, profile_user) + count_by = 'thread__mailinglist__name' context['list_activity'] = dict(messages.values_list(count_by) .annotate(Count(count_by)) diff --git a/colab/home/views.py b/colab/home/views.py index 0806e05..3a25f1e 100644 --- a/colab/home/views.py +++ b/colab/home/views.py @@ -4,23 +4,41 @@ from django.http import HttpResponse, Http404 from colab.search.utils import get_collaboration_data from colab.super_archives.models import Thread - +from colab.accounts.utils import mailinglist +from colab.accounts.models import User def dashboard(request): """Dashboard page""" - highest_score_threads = Thread.highest_score.all()[:6] + highest_score_threads = Thread.highest_score.all() + + all_threads = Thread.objects.all() + latest_threads = [] + lists_for_user = [] - hottest_threads = [t.latest_message for t in highest_score_threads] + user = None + if request.user.is_authenticated(): + user = User.objects.get(username=request.user) + lists_for_user = mailinglist.get_user_mailinglists(user) - latest_threads = Thread.objects.all()[:6] + for t in all_threads: + if not t.mailinglist.is_private or \ + t.mailinglist.name in lists_for_user: + latest_threads.append(t) - latest_results, count_types = get_collaboration_data() + hottest_threads = [] + for t in highest_score_threads: + if not t.mailinglist.is_private or \ + t.mailinglist.name in lists_for_user: + hottest_threads.append(t.latest_message) + + latest_results, count_types = get_collaboration_data(user) latest_results.sort(key=lambda elem: elem.modified, reverse=True) + context = { 'hottest_threads': hottest_threads[:6], - 'latest_threads': latest_threads, + 'latest_threads': latest_threads[:6], 'type_count': count_types, 'latest_results': latest_results[:6], } diff --git a/colab/search/utils.py b/colab/search/utils.py index c7a60d8..2591dbb 100644 --- a/colab/search/utils.py +++ b/colab/search/utils.py @@ -6,26 +6,50 @@ from collections import OrderedDict from django.core.cache import cache from django.utils.translation import ugettext as _ from django.conf import settings +from django.db.models.query import QuerySet +from django.db.models import Q + from colab.super_archives.models import Thread, Message from colab.proxy.utils.models import Collaboration +from colab.accounts.utils import mailinglist + + +def get_visible_threads_queryset(logged_user): + qs = Thread.objects + lists_for_user = [] + if logged_user: + lists_for_user = mailinglist.get_user_mailinglists(logged_user) + + q1 = Q(mailinglist__name__in=lists_for_user) + q2 = Q(mailinglist__is_private=False) + qs = Thread.objects.filter(q1 | q2) + + return qs + +def get_visible_threads(logged_user, filter_by_user=None): + thread_qs = get_visible_threads_queryset(logged_user) + if filter_by_user: + message_qs = Message.objects.filter(thread__in=thread_qs) + messages = message_qs.filter( + from_address__user__pk=filter_by_user.pk) + else: + latest_threads = thread_qs.all() + messages = [t.latest_message for t in latest_threads] + return messages -def get_collaboration_data(filter_by_user=None): +def get_collaboration_data(logged_user, filter_by_user=None): latest_results = [] - count_types = cache.get('home_chart') + count_types = None#cache.get('home_chart') populate_count_types = False if count_types is None: populate_count_types = True count_types = OrderedDict() - count_types[_('Emails')] = Thread.objects.count() + visible_threads = get_visible_threads(logged_user) + count_types[_('Emails')] = len(visible_threads) - if filter_by_user: - messages = Message.objects.filter( - from_address__user__pk=filter_by_user.pk) - else: - latest_threads = Thread.objects.all()[:6] - messages = [t.latest_message for t in latest_threads] + messages = get_visible_threads(logged_user, filter_by_user) latest_results.extend(messages) diff --git a/colab/super_archives/views.py b/colab/super_archives/views.py index 80ee568..9595b6b 100644 --- a/colab/super_archives/views.py +++ b/colab/super_archives/views.py @@ -12,7 +12,7 @@ from django.contrib import messages from django.db import IntegrityError from django.views.generic import View from django.utils.translation import ugettext as _ -from django.core.exceptions import ObjectDoesNotExist +from django.core.exceptions import ObjectDoesNotExist, PermissionDenied from django.utils.decorators import method_decorator from django.contrib.auth.decorators import login_required from django.shortcuts import render, redirect, get_object_or_404 @@ -31,6 +31,18 @@ class ThreadView(View): thread = get_object_or_404(Thread, subject_token=thread_token, mailinglist__name=mailinglist) + + all_privates = dict(mailman.all_lists(private=True)) + if all_privates[thread.mailinglist.name]: + if not request.user.is_authenticated(): + raise PermissionDenied + else: + user = User.objects.get(username=request.user) + emails = user.emails.values_list('address', flat=True) + lists_for_user = mailman.get_user_mailinglists(user) + if not thread.mailinglist.name in lists_for_user: + raise PermissionDenied + thread.hit(request) try: @@ -126,11 +138,11 @@ class ThreadDashboardView(View): context['lists'] = [] - user = User.objects.get(username=request.user) - emails = user.emails.values_list('address', flat=True) lists_for_user = [] - for email in emails: - lists_for_user.extend(mailman.address_lists(email)) + if request.user.is_authenticated(): + user = User.objects.get(username=request.user) + emails = user.emails.values_list('address', flat=True) + lists_for_user = mailman.get_user_mailinglists(user) for list_ in MailingList.objects.order_by('name'): if not all_privates[list_.name] or list_.name in lists_for_user: -- libgit2 0.21.2