Example #1
0
def list_index(request, template='postorius/index.html'):
    """Show a table of all public mailing lists.
    """
    if request.method == 'POST':
        return redirect("list_summary", list_id=request.POST["list"])

    def _get_list_page(count, page):
        filtering = settings.MAILMAN_LIST_INDEX_FILTERING
        client = get_mailman_client()

        if filtering == 'owner-only' and not request.user.is_superuser:
            return client.get_list_page(owner=request.user.email,
                                        count=count,
                                        page=page)

        advertised = not request.user.is_superuser
        return client.get_list_page(advertised=advertised,
                                    count=count,
                                    page=page)

    lists = paginate(_get_list_page,
                     request.GET.get('page'),
                     request.GET.get('count'),
                     paginator_class=MailmanPaginator)

    lists = paginate(_get_list_page, request.GET.get('page'),
                     request.GET.get('count'))
    choosable_domains = _get_choosable_domains(request)
    return render(request, template, {
        'lists': lists,
        'domain_count': len(choosable_domains)
    })
def _thread_list(request,
                 mlist,
                 threads,
                 template_name='hyperkitty/thread_list.html',
                 extra_context=None):
    threads = paginate(threads, request.GET.get('page'),
                       request.GET.get('count'))
    for thread in threads:
        # Favorites
        thread.favorite = False
        if request.user.is_authenticated:
            try:
                Favorite.objects.get(thread=thread, user=request.user)
            except Favorite.DoesNotExist:
                pass
            else:
                thread.favorite = True
        # Category
        thread.category_hk, thread.category_form = \
            get_category_widget(request, thread.category)

    context = {
        'mlist': mlist,
        'threads': threads,
        'months_list': get_months(mlist),
    }
    if extra_context is not None:
        context.update(extra_context)
    return render(request, template_name, context)
Example #3
0
def posts(request, user_id):
    mlist_fqdn = request.GET.get("list")
    if mlist_fqdn is None:
        mlist = None
        return HttpResponse("Not implemented yet", status=500)
    else:
        try:
            mlist = MailingList.objects.get(name=mlist_fqdn)
        except MailingList.DoesNotExist:
            raise Http404("No archived mailing-list by that name.")
        if not is_mlist_authorized(request, mlist):
            return render(request, "hyperkitty/errors/private.html", {
                            "mlist": mlist,
                          }, status=403)

    fullname = Email.objects.filter(
            sender__mailman_id=user_id, sender_name__isnull=False
        ).exclude(sender_name="").values_list(
        "sender_name", flat=True).first()
    # Get the messages and paginate them
    emails = Email.objects.filter(
        mailinglist=mlist, sender__mailman_id=user_id)
    emails = paginate(emails, request.GET.get("page"))

    for email in emails:
        email.myvote = email.votes.filter(user=request.user).first()

    context = {
        'user_id': user_id,
        'mlist': mlist,
        'emails': emails,
        'fullname': fullname,
    }
    return render(request, "hyperkitty/user_posts.html", context)
Example #4
0
def votes(request):
    all_votes = paginate(
        request.user.votes.all(), request.GET.get('vpage'))
    return render(request, 'hyperkitty/user_profile/votes.html', {
                "votes": all_votes,
                "subpage": "votes",
            })
def bans_view(request, template, list_id=None):
    """Ban or unban email addresses.

    This is a reusable view which works for both global and list specific bans.
    Whether a MailingList ban is updated or a Global one depends on list_id
    being passed in.

    :list_id: MailingList Id if this is a List ban, None otherwise.

    """
    if list_id:
        m_list = List.objects.get_or_404(fqdn_listname=list_id)
        url = reverse('list_bans', args=[list_id])
        ban_list = m_list.bans
    else:
        ban_list = get_mailman_client().bans
        url = reverse('global_bans')
        m_list = None

    # Process form submission.
    if request.method == 'POST':
        if 'add' in request.POST:
            addban_form = AddBanForm(request.POST)
            if addban_form.is_valid():
                try:
                    ban_list.add(addban_form.cleaned_data['email'])
                    messages.success(request, _(
                        'The email {} has been banned.'.format(
                            addban_form.cleaned_data['email'])))
                except HTTPError as e:
                    messages.error(
                        request, _('An error occurred: %s') % e.reason)
                except ValueError as e:
                    messages.error(request, _('Invalid data: %s') % e)
                return redirect(url)
        elif 'del' in request.POST:
            try:
                ban_list.remove(request.POST['email'])
                messages.success(request, _(
                    'The email {} has been un-banned'.format(
                        request.POST['email'])))
            except HTTPError as e:
                messages.error(request, _('An error occurred: %s') % e.reason)
            except ValueError as e:
                messages.error(request, _('Invalid data: %s') % e)
            return redirect(url)
    else:
        addban_form = AddBanForm(initial=request.GET)
    banned_addresses = paginate(
        list(ban_list), request.GET.get('page'), request.GET.get('count'))

    context = {
        'addban_form': addban_form,
        'banned_addresses': banned_addresses,
    }

    if list_id:
        context['list'] = m_list

    return render(request, template, context)
Example #6
0
def list_index(request, template='postorius/index.html'):
    """Show a table of all public mailing lists.
    """
    if request.method == 'POST':
        return redirect("list_summary", list_id=request.POST["list"])
    lists = []
    error = None
    only_public = True
    if request.user.is_superuser:
        only_public = False
    try:
        # FIXME: this is not paginated, all lists will
        # always be retrieved.
        lists = sorted(List.objects.all(only_public=only_public),
                       key=lambda l: l.fqdn_listname)
        logger.debug(lists)
    except MailmanApiError:
        return utils.render_api_error(request)
    choosable_domains = _get_choosable_domains(request)
    return render(request, template,
                  {'error': error,
                   'lists': paginate(
                       lists, request.GET.get('page'),
                       request.GET.get('count', 10)),
                   'domain_count': len(choosable_domains)})
Example #7
0
    def get(self, request, list_id, role):
        """Handle GET for Member view.

        This includes all the membership roles (self.allowed_roles).
        """
        member_form = MemberForm()
        # If the role is misspelled, redirect to the default subscribers.
        if role not in self.allowed_roles:
            return redirect('list_members', list_id, 'member')
        context = dict()
        context['list'] = self.mailing_list
        context['role'] = role
        context['member_form'] = member_form
        context['page_title'] = _('List {}s'.format(role.capitalize()))
        context['query'] = self._prepare_query(request)

        def find_method(count, page):
            return self.mailing_list.find_members(
                context['query'], role=role, count=count, page=page)

        context['members'] = paginate(
            find_method,
            request.GET.get('page', 1),
            request.GET.get('count', 25),
            paginator_class=MailmanPaginator)
        context['page_subtitle'] = '({})'.format(
            context['members'].paginator.count)
        context['form_action'] = _('Add {}'.format(role))
        if context['query']:
            context['empty_error'] = _(
                'No {}s were found matching the search.'.format(role))
        else:
            context['empty_error'] = _('List has no {}s'.format(role))

        return render(request, 'postorius/lists/members.html', context)
Example #8
0
def list_moderation(request, list_id, held_id=-1):
    mailing_list = List.objects.get_or_404(fqdn_listname=list_id)
    if request.method == 'POST':
        form = MultipleChoiceForm(request.POST)
        if form.is_valid():
            message_ids = form.cleaned_data['choices']
            try:
                if 'accept' in request.POST:
                    _perform_action(message_ids, mailing_list.accept_message)
                    messages.success(request,
                                     _('The selected messages were accepted'))
                elif 'reject' in request.POST:
                    _perform_action(message_ids, mailing_list.reject_message)
                    messages.success(request,
                                     _('The selected messages were rejected'))
                elif 'discard' in request.POST:
                    _perform_action(message_ids, mailing_list.discard_message)
                    messages.success(request,
                                     _('The selected messages were discarded'))
            except MailmanApiError:
                return utils.render_api_error(request)
            except HTTPError:
                messages.error(request, _('Message could not be found'))
    else:
        form = MultipleChoiceForm()
    held_messages = paginate(
        mailing_list.get_held_page,
        request.GET.get('page'), request.GET.get('count'),
        paginator_class=MailmanPaginator)
    context = {
        'list': mailing_list,
        'held_messages': held_messages,
        'form': form,
        }
    return render(request, 'postorius/lists/held_messages.html', context)
Example #9
0
def list_index(request, template='postorius/index.html'):
    """Show a table of all public mailing lists."""
    # TODO maxking: Figure out why does this view accept POST request and why
    # can't it be just a GET with list parameter.
    if request.method == 'POST':
        return redirect("list_summary", list_id=request.POST["list"])
    # If the user is logged-in, show them only related lists in the index,
    # except role is present in requests.GET.
    if request.user.is_authenticated and 'all-lists' not in request.GET:
        return list_index_authenticated(request)

    def _get_list_page(count, page):
        client = get_mailman_client()
        advertised = not request.user.is_superuser
        return client.get_list_page(
            advertised=advertised, count=count, page=page)

    lists = paginate(
        _get_list_page, request.GET.get('page'), request.GET.get('count'),
        paginator_class=MailmanPaginator)

    choosable_domains = _get_choosable_domains(request)

    return render(request, template,
                  {'lists': lists,
                   'all_lists': True,
                   'domain_count': len(choosable_domains)})
def last_views(request):
    # Last viewed threads
    lviews = LastView.objects.filter(user=request.user).order_by("-view_date")
    lviews = paginate(lviews, request.GET.get('lvpage'))
    return render(request, 'hyperkitty/user_profile/last_views.html', {
        "last_views": lviews,
        "subpage": "last_views",
    })
def favorites(request):
    # Favorite threads
    favs = Favorite.objects.filter(
        user=request.user).order_by("-thread__date_active")
    favs = paginate(favs, request.GET.get('favpage'))
    return render(request, 'hyperkitty/user_profile/favorites.html', {
        "favorites": favs,
        "subpage": "favorites",
    })
Example #12
0
 def test_paginator_tag(self):
     objects = paginate(list(range(100)), 1, 20)
     context = Context({'title': 'My Title'})
     updated_context = paginator(context, objects)
     self.assertEqual(updated_context['label_previous'], 'Previous')
     self.assertEqual(updated_context['label_next'], 'Next')
     self.assertEqual(updated_context['page'], objects)
     self.assertEqual(updated_context['per_page_options'],
                      [10, 25, 50, 100, 200])
     dated_pages_ctxt = paginator(context, objects, bydate=True)
     self.assertEqual(dated_pages_ctxt['label_previous'], 'Newer')
     self.assertEqual(dated_pages_ctxt['label_next'], 'Older')
def user_profile(request):
    # Get the messages and paginate them
    email_addresses = EmailAddress.objects.filter(
        user=request.user).values("email")
    last_posts = Email.objects.filter(
        sender__address__in=email_addresses).order_by("-date")
    last_posts = paginate(last_posts, request.GET.get("lppage"),
                          request.GET.get("lpcount", "10"))

    context = {
        "last_posts": last_posts,
        "subpage": "profile",
    }
    return render(request, "hyperkitty/user_profile/profile.html", context)
Example #14
0
def list_subscription_requests(request, list_id):
    """Shows a list of subscription requests.
    """
    m_list = List.objects.get_or_404(fqdn_listname=list_id)
    requests = [req
                for req in m_list.requests
                if req['token_owner'] == 'moderator']
    paginated_requests = paginate(
        requests,
        request.GET.get('page'),
        request.GET.get('count', 25))
    page_subtitle = '(%d)' % len(requests)
    return render(request, 'postorius/lists/subscription_requests.html',
                  {'list': m_list,
                   'paginated_requests': paginated_requests,
                   'page_subtitle': page_subtitle})
Example #15
0
def list_bans(request, list_id):
    """
    Ban or unban email addresses.
    """
    # Get the list and cache the archivers property.
    m_list = List.objects.get_or_404(fqdn_listname=list_id)
    ban_list = m_list.bans

    # Process form submission.
    if request.method == 'POST':
        if 'add' in request.POST:
            addban_form = ListAddBanForm(request.POST)
            if addban_form.is_valid():
                try:
                    ban_list.add(addban_form.cleaned_data['email'])
                    messages.success(
                        request,
                        _('The email {} has been banned.'.format(
                            addban_form.cleaned_data['email'])))
                except HTTPError as e:
                    messages.error(request,
                                   _('An error occured: %s') % e.reason)
                except ValueError as e:
                    messages.error(request, _('Invalid data: %s') % e)
                return redirect('list_bans', list_id)
        elif 'del' in request.POST:
            try:
                ban_list.remove(request.POST['email'])
                messages.success(
                    request,
                    _('The email {} has been un-banned'.format(
                        request.POST['email'])))
            except HTTPError as e:
                messages.error(request, _('An error occured: %s') % e.reason)
            except ValueError as e:
                messages.error(request, _('Invalid data: %s') % e)
            return redirect('list_bans', list_id)
    else:
        addban_form = ListAddBanForm()
    banned_addresses = paginate(list(ban_list), request.GET.get('page'),
                                request.GET.get('count'))
    return render(
        request, 'postorius/lists/bans.html', {
            'list': m_list,
            'addban_form': addban_form,
            'banned_addresses': banned_addresses,
        })
Example #16
0
def list_index(request, template='postorius/index.html'):
    """Show a table of all public mailing lists.
    """
    if request.method == 'POST':
        return redirect("list_summary", list_id=request.POST["list"])

    def _get_list_page(count, page):
        client = get_mailman_client()
        advertised = not request.user.is_superuser
        return client.get_list_page(
            advertised=advertised, count=count, page=page)
    lists = paginate(
        _get_list_page, request.GET.get('page'), request.GET.get('count'),
        paginator_class=MailmanPaginator)
    choosable_domains = _get_choosable_domains(request)
    return render(request, template,
                  {'lists': lists,
                   'domain_count': len(choosable_domains)})
Example #17
0
def index(request):
    mlists = MailingList.objects.all()
    sort_mode = request.GET.get("sort", "popular")

    # Domain filtering
    if settings.FILTER_VHOST:
        domain = request.get_host().split(":")[0]
        if domain.startswith("www."):
            domain = domain[4:]
        domain = "@%s" % domain
        mlists = mlists.filter(name__iendswith=domain)

    # Name filtering
    name_filter = request.GET.get('name')
    if name_filter:
        sort_mode = "name"
        mlists = mlists.filter(
            Q(name__icontains=name_filter)
            | Q(display_name__icontains=name_filter))
        if mlists.count() == 1:
            return redirect('hk_list_overview', mlist_fqdn=mlists.first().name)

    # Sorting
    if sort_mode == "name":
        mlists = mlists.order_by("name")
    elif sort_mode == "active":
        # Don't show private lists when sorted by activity, to avoid disclosing
        # info about the private list's activity
        mlists = list(
            mlists.exclude(archive_policy=ArchivePolicy.private.value))
        mlists.sort(key=lambda l: l.recent_threads_count, reverse=True)
    elif sort_mode == "popular":
        # Don't show private lists when sorted by popularity, to avoid
        # disclosing info about the private list's popularity.
        mlists = list(
            mlists.exclude(archive_policy=ArchivePolicy.private.value))
        mlists.sort(key=lambda l: l.recent_participants_count, reverse=True)
    elif sort_mode == "creation":
        mlists = mlists.order_by("-created_at")
    else:
        return HttpResponse("Wrong search parameter",
                            content_type="text/plain",
                            status=500)

    mlists = paginate(mlists, request.GET.get('page'),
                      request.GET.get('count'))

    # Permissions
    for mlist in mlists:
        if not mlist.is_private:
            mlist.can_view = True
        else:
            if is_mlist_authorized(request, mlist):
                mlist.can_view = True
            else:
                mlist.can_view = False

    context = {
        'view_name': 'all_lists',
        'all_lists': mlists,
        'sort_mode': sort_mode,
    }
    return render(request, "hyperkitty/index.html", context)
Example #18
0
 def test_page_not_an_int(self):
     self.assertEqual(paginate(range(100), "dummy").number, 1)
Example #19
0
 def test_page_range_ellipsis(self):
     objects = range(1000)
     self.assertEqual(
         paginate(objects, 1, 20).paginator.page_range_ellipsis,
         [1, 2, 3, 4, '...', 50])
     self.assertEqual(
         paginate(objects, 2, 20).paginator.page_range_ellipsis,
         [1, 2, 3, 4, 5, '...', 50])
     self.assertEqual(
         paginate(objects, 3, 20).paginator.page_range_ellipsis,
         [1, 2, 3, 4, 5, 6, '...', 50])
     self.assertEqual(
         paginate(objects, 4, 20).paginator.page_range_ellipsis,
         [1, 2, 3, 4, 5, 6, 7, '...', 50])
     self.assertEqual(
         paginate(objects, 5, 20).paginator.page_range_ellipsis,
         [1, 2, 3, 4, 5, 6, 7, 8, '...', 50])
     self.assertEqual(
         paginate(objects, 6, 20).paginator.page_range_ellipsis,
         [1, 2, 3, 4, 5, 6, 7, 8, 9, '...', 50])
     self.assertEqual(
         paginate(objects, 7, 20).paginator.page_range_ellipsis,
         [1, '...', 4, 5, 6, 7, 8, 9, 10, '...', 50])
     self.assertEqual(
         paginate(objects, 8, 20).paginator.page_range_ellipsis,
         [1, '...', 5, 6, 7, 8, 9, 10, 11, '...', 50])
     self.assertEqual(
         paginate(objects, 9, 20).paginator.page_range_ellipsis,
         [1, '...', 6, 7, 8, 9, 10, 11, 12, '...', 50])
     self.assertEqual(
         paginate(objects, 10, 20).paginator.page_range_ellipsis,
         [1, '...', 7, 8, 9, 10, 11, 12, 13, '...', 50])
     self.assertEqual(
         paginate(objects, 30, 20).paginator.page_range_ellipsis,
         [1, '...', 27, 28, 29, 30, 31, 32, 33, '...', 50])
     self.assertEqual(
         paginate(objects, 40, 20).paginator.page_range_ellipsis,
         [1, '...', 37, 38, 39, 40, 41, 42, 43, '...', 50])
     self.assertEqual(
         paginate(objects, 41, 20).paginator.page_range_ellipsis,
         [1, '...', 38, 39, 40, 41, 42, 43, 44, '...', 50])
     self.assertEqual(
         paginate(objects, 42, 20).paginator.page_range_ellipsis,
         [1, '...', 39, 40, 41, 42, 43, 44, 45, '...', 50])
     self.assertEqual(
         paginate(objects, 43, 20).paginator.page_range_ellipsis,
         [1, '...', 40, 41, 42, 43, 44, 45, 46, '...', 50])
     self.assertEqual(
         paginate(objects, 44, 20).paginator.page_range_ellipsis,
         [1, '...', 41, 42, 43, 44, 45, 46, 47, '...', 50])
     self.assertEqual(
         paginate(objects, 45, 20).paginator.page_range_ellipsis,
         [1, '...', 42, 43, 44, 45, 46, 47, 48, 49, 50])
     self.assertEqual(
         paginate(objects, 46, 20).paginator.page_range_ellipsis,
         [1, '...', 43, 44, 45, 46, 47, 48, 49, 50])
     self.assertEqual(
         paginate(objects, 47, 20).paginator.page_range_ellipsis,
         [1, '...', 44, 45, 46, 47, 48, 49, 50])
     self.assertEqual(
         paginate(objects, 48, 20).paginator.page_range_ellipsis,
         [1, '...', 45, 46, 47, 48, 49, 50])
     self.assertEqual(
         paginate(objects, 49, 20).paginator.page_range_ellipsis,
         [1, '...', 46, 47, 48, 49, 50])
     self.assertEqual(
         paginate(objects, 50, 20).paginator.page_range_ellipsis,
         [1, '...', 47, 48, 49, 50])
Example #20
0
 def test_last_page(self):
     self.assertEqual(paginate(range(100), 1000).number, 10)
Example #21
0
 def test_page_str(self):
     try:
         self.assertEqual(paginate(range(1000), "2").number, 2)
     except TypeError as e:
         self.fail(e)
Example #22
0
 def test_default_page(self):
     self.assertEqual(paginate(range(100), None).number, 1)
Example #23
0
def index(request):
    mlists = MailingList.objects.all()
    sort_mode = request.GET.get("sort", "popular")

    # Domain filtering
    if getattr(settings, 'FILTER_VHOST', False):
        domain = request.get_host().split(":")[0]
        if domain.startswith("www."):
            domain = domain[4:]
        domain = "@%s" % domain
        mlists = mlists.filter(name__iendswith=domain)

    # Name filtering
    name_filter = request.GET.get('name')
    if name_filter:
        sort_mode = "name"
        mlists = mlists.filter(
            Q(name__icontains=name_filter) |
            Q(display_name__icontains=name_filter)
            )
        if mlists.count() == 1:
            return redirect(
                'hk_list_overview', mlist_fqdn=mlists.first().name)

    # Access Filtering
    if request.user.is_superuser:
        # Superusers see everything
        pass
    elif request.user.is_authenticated:
        # For authenticated users show only their subscriptions
        # and public lists
        mlists = mlists.filter(
            Q(list_id__in=get_subscriptions(request.user)) |
            Q(archive_policy=ArchivePolicy.public.value)
        )
    else:
        # Unauthenticated users only see public lists
        mlists = mlists.filter(
            archive_policy=ArchivePolicy.public.value)

    # Sorting
    if sort_mode == "name":
        mlists = mlists.order_by("name")
    elif sort_mode == "active":
        mlists = list(mlists)
        mlists.sort(key=lambda l: l.recent_threads_count, reverse=True)
    elif sort_mode == "popular":
        mlists = list(mlists)
        mlists.sort(key=lambda l: l.recent_participants_count, reverse=True)
    elif sort_mode == "creation":
        mlists = mlists.order_by("-created_at")
    else:
        return HttpResponse("Wrong search parameter",
                            content_type="text/plain", status=500)

    mlists = paginate(mlists, request.GET.get('page'),
                      request.GET.get('count'))

    context = {
        'view_name': 'all_lists',
        'all_lists': mlists,
        'sort_mode': sort_mode,
        }
    return render(request, "hyperkitty/index.html", context)
Example #24
0
def list_members_view(request, list_id, role=None):
    """Display all members of a given list."""
    if role not in ['owner', 'moderator', 'subscriber']:
        return redirect('list_members', list_id, 'subscriber')
    mailing_list = List.objects.get_or_404(fqdn_listname=list_id)
    if request.method == 'POST':
        if role == 'subscriber':
            form = MultipleChoiceForm(request.POST)
            if form.is_valid():
                members = form.cleaned_data['choices']
                for member in members:
                    mailing_list.unsubscribe(member)
                messages.success(request, _('The selected members'
                                            ' have been unsubscribed'))
                return redirect('list_members', list_id, role)
        else:
            member_form = MemberForm(request.POST)
            if member_form.is_valid():
                try:
                    getattr(mailing_list, 'add_%s' % role)(
                        member_form.cleaned_data['email'])
                    messages.success(
                        request, _('%(email)s has been added'
                                   ' with the role %(role)s')
                        % {'email': member_form.cleaned_data['email'],
                           'role': role})
                    return redirect('list_members', list_id, role)
                except HTTPError as e:
                    messages.error(request, _(e.msg))
    else:
        form = MultipleChoiceForm()
        member_form = MemberForm()
    context = {
        'list': mailing_list,
        'role': role,
    }
    if role == 'subscriber':
        context['page_title'] = _('List subscribers')
        if request.GET.get('q'):
            query = context['query'] = request.GET['q']
            if "*" not in query:
                query = '*{}*'.format(query)

            # Proxy the find_members method to insert the query
            def find_method(count, page):
                return mailing_list.find_members(query, count=count, page=page)
        else:
            find_method = mailing_list.get_member_page
        context['members'] = paginate(
            find_method,
            request.GET.get('page'),
            request.GET.get('count', 25),
            paginator_class=MailmanPaginator)
        if mailing_list.member_count == 0:
            context['empty_error'] = _('List has no Subscribers')
        else:
            context['empty_error'] =\
                _('No member was found matching the search')
        context['form'] = form
    else:
        context['member_form'] = member_form
        if role == 'owner':
            context['page_title'] = _('List owners')
            context['members'] = mailing_list.owners
            context['form_action'] = _('Add owner')
        elif role == 'moderator':
            context['page_title'] = _('List moderators')
            context['members'] = mailing_list.moderators
            context['empty_error'] = _('List has no moderators')
            context['form_action'] = _('Add moderator')
    return render(request, 'postorius/lists/members.html', context)
def index(request):
    mlists = MailingList.objects.all()
    sort_mode = request.GET.get("sort", "popular")

    # Domain filtering
    if getattr(settings, 'FILTER_VHOST', False):
        our_lists = MailingList.objects.none()
        domain = request.get_host().split(":")[0]
        mail_hosts = []
        for mlist in mlists:
            mail_host = re.sub('^.*@', '', mlist.name)
            try:
                if (MailDomain.objects.get(
                        mail_domain=mail_host).site.domain == domain):
                    if mail_host not in mail_hosts:
                        mail_hosts.append(mail_host)
            except MailDomain.DoesNotExist:
                pass
        if len(mail_hosts) == 0:
            mail_hosts = [domain]
        for domain in mail_hosts:
            domain = '@%s' % domain
            our_lists = our_lists | mlists.filter(name__iendswith=domain)
        mlists = our_lists

    # Name filtering
    name_filter = request.GET.get('name')
    if name_filter:
        sort_mode = "name"
        mlists = mlists.filter(
            Q(name__icontains=name_filter)
            | Q(display_name__icontains=name_filter))
        if mlists.count() == 1:
            return redirect('hk_list_overview', mlist_fqdn=mlists.first().name)

    # Access Filtering
    if request.user.is_superuser:
        # Superusers see everything
        pass
    elif request.user.is_authenticated:
        # For authenticated users show only their subscriptions
        # and public lists
        mlists = mlists.filter(
            Q(list_id__in=get_subscriptions(request.user))
            | Q(archive_policy=ArchivePolicy.public.value))
    else:
        # Unauthenticated users only see public lists
        mlists = mlists.filter(archive_policy=ArchivePolicy.public.value)

    # Sorting
    if sort_mode == "name":
        mlists = mlists.order_by("name")
    elif sort_mode == "active":
        mlists = list(mlists)
        mlists.sort(key=lambda l: l.recent_threads_count, reverse=True)
    elif sort_mode == "popular":
        mlists = list(mlists)
        mlists.sort(key=lambda l: l.recent_participants_count, reverse=True)
    elif sort_mode == "creation":
        mlists = mlists.order_by("-created_at")
    else:
        return HttpResponse("Wrong search parameter",
                            content_type="text/plain",
                            status=500)

    # Inactive List Setting
    show_inactive = getattr(settings, 'SHOW_INACTIVE_LISTS_DEFAULT', False)

    mlists = paginate(mlists, request.GET.get('page'),
                      request.GET.get('count'))

    context = {
        'view_name': 'all_lists',
        'all_lists': mlists,
        'sort_mode': sort_mode,
        'show_inactive': show_inactive
    }
    return render(request, "hyperkitty/index.html", context)
Example #26
0
def search(request):
    """ Returns messages corresponding to a query """
    mlist_fqdn = request.GET.get("mlist")
    if mlist_fqdn is None:
        mlist = None
    else:
        try:
            mlist = MailingList.objects.get(name=mlist_fqdn)
        except MailingList.DoesNotExist:
            raise Http404("No archived mailing-list by that name.")
        if not is_mlist_authorized(request, mlist):
            return render(request,
                          "hyperkitty/errors/private.html", {
                              "mlist": mlist,
                          },
                          status=403)
    query = ''
    results = EmptySearchQuerySet()
    sqs = RelatedSearchQuerySet()

    # Remove private non-subscribed lists
    if mlist is not None:
        sqs = sqs.filter(mailinglist__exact=mlist.name)
    else:
        excluded_mlists = MailingList.objects.filter(
            archive_policy=ArchivePolicy.private.value)
        if request.user.is_authenticated:
            subscriptions = get_subscriptions(request.user)
            excluded_mlists = excluded_mlists.exclude(
                list_id__in=subscriptions.keys())
        excluded_mlists = excluded_mlists.values_list("name", flat=True)
        sqs = sqs.exclude(mailinglist__in=excluded_mlists)

    # Sorting
    sort_mode = request.GET.get('sort')
    if sort_mode == "date-asc":
        sqs = sqs.order_by("date")
    elif sort_mode == "date-desc":
        sqs = sqs.order_by("-date")

    # Handle data
    if request.GET.get('q'):
        form = SearchForm(request.GET, searchqueryset=sqs, load_all=True)
        if form.is_valid():
            query = form.cleaned_data['q']
            results = form.search()
    else:
        form = SearchForm(searchqueryset=sqs, load_all=True)

    try:
        emails = paginate(
            results,
            request.GET.get('page'),
            request.GET.get('count'),
        )
    except Exception as e:
        backend = settings.HAYSTACK_CONNECTIONS[DEFAULT_ALIAS]["ENGINE"]
        if backend == "haystack.backends.whoosh_backend.WhooshEngine":
            from whoosh.qparser.common import QueryParserError
            search_exception = QueryParserError
        if backend == "xapian_backend.XapianEngine":
            from xapian import QueryParserError
            search_exception = QueryParserError
        if not isinstance(e, search_exception):
            raise
        emails = paginate([])
        form.add_error(
            "q",
            ValidationError(
                _('Parsing error: %(error)s'),
                params={"error": e},
                code="parse",
            ))
    for email in emails:
        if request.user.is_authenticated:
            email.object.myvote = email.object.votes.filter(
                user=request.user).first()
        else:
            email.object.myvote = None

    context = {
        'mlist': mlist,
        'form': form,
        'emails': emails,
        'query': query,
        'sort_mode': sort_mode,
        'suggestion': None,
    }
    if results.query.backend.include_spelling:
        context['suggestion'] = form.get_suggestion()

    return render(request, "hyperkitty/search_results.html", context)