diff options
Diffstat (limited to 'packages/views/search.py')
-rw-r--r-- | packages/views/search.py | 143 |
1 files changed, 58 insertions, 85 deletions
diff --git a/packages/views/search.py b/packages/views/search.py index a09de0a7..0362602e 100644 --- a/packages/views/search.py +++ b/packages/views/search.py @@ -1,37 +1,16 @@ -from datetime import datetime +import json from django import forms -from django.contrib.admin.widgets import AdminDateWidget from django.contrib.auth.models import User from django.db.models import Q from django.http import HttpResponse -from django.views.generic import list_detail -from django.utils import simplejson +from django.views.generic import ListView from main.models import Package, Arch, Repo from main.utils import make_choice from ..models import PackageRelation -from ..utils import PackageJSONEncoder - - -def coerce_limit_value(value): - if not value: - return None - if value == 'all': - # negative value indicates show all results - return -1 - value = int(value) - if value < 0: - raise ValueError - return value - -class LimitTypedChoiceField(forms.TypedChoiceField): - def valid_value(self, value): - try: - coerce_limit_value(value) - return True - except (ValueError, TypeError): - return False +from ..utils import attach_maintainers, PackageJSONEncoder + class PackageSearchForm(forms.Form): repo = forms.MultipleChoiceField(required=False) @@ -39,24 +18,21 @@ class PackageSearchForm(forms.Form): name = forms.CharField(required=False) desc = forms.CharField(required=False) q = forms.CharField(required=False) - sort = forms.CharField(required=False) + sort = forms.CharField(required=False, widget=forms.HiddenInput()) maintainer = forms.ChoiceField(required=False) packager = forms.ChoiceField(required=False) - last_update = forms.DateField(required=False, widget=AdminDateWidget(), - label='Last Updated After') flagged = forms.ChoiceField( choices=[('', 'All')] + make_choice(['Flagged', 'Not Flagged']), required=False) - limit = LimitTypedChoiceField( - choices=make_choice([50, 100, 250]) + [('all', 'All')], - coerce=coerce_limit_value, - required=False, - initial=50) def __init__(self, *args, **kwargs): + show_staging = kwargs.pop('show_staging', False) super(PackageSearchForm, self).__init__(*args, **kwargs) + repos = Repo.objects.all() + if not show_staging: + repos = repos.filter(staging=False) self.fields['repo'].choices = make_choice( - [repo.name for repo in Repo.objects.all()]) + [repo.name for repo in repos]) self.fields['arch'].choices = make_choice( [arch.name for arch in Arch.objects.all()]) self.fields['q'].widget.attrs.update({"size": "30"}) @@ -69,6 +45,7 @@ class PackageSearchForm(forms.Form): [('', 'All'), ('unknown', 'Unknown')] + \ [(m.username, m.get_full_name()) for m in maints] + def parse_form(form, packages): if form.cleaned_data['repo']: packages = packages.filter( @@ -97,11 +74,6 @@ def parse_form(form, packages): elif form.cleaned_data['flagged'] == 'Not Flagged': packages = packages.filter(flag_date__isnull=True) - if form.cleaned_data['last_update']: - lu = form.cleaned_data['last_update'] - packages = packages.filter(last_update__gte= - datetime(lu.year, lu.month, lu.day, 0, 0)) - if form.cleaned_data['name']: name = form.cleaned_data['name'] packages = packages.filter(pkgname=name) @@ -117,48 +89,43 @@ def parse_form(form, packages): return packages -def search(request, page=None): - limit = 50 - sort = None - packages = Package.objects.normal() - if request.GET: - form = PackageSearchForm(data=request.GET) - if form.is_valid(): - packages = parse_form(form, packages) - asked_limit = form.cleaned_data['limit'] - if asked_limit and asked_limit < 0: - limit = None - elif asked_limit: - limit = asked_limit - sort = form.cleaned_data['sort'] - else: - # Form had errors, don't return any results, just the busted form - packages = Package.objects.none() - else: - form = PackageSearchForm() - - current_query = request.GET.urlencode() - page_dict = { - 'search_form': form, - 'current_query': current_query - } - allowed_sort = ["arch", "repo", "pkgname", "pkgbase", - "compressed_size", "installed_size", - "build_date", "last_update", "flag_date"] - allowed_sort += ["-" + s for s in allowed_sort] - if sort in allowed_sort: - packages = packages.order_by(sort) - page_dict['sort'] = sort - else: - packages = packages.order_by('pkgname') - - return list_detail.object_list(request, packages, - template_name="packages/search.html", - page=page, - paginate_by=limit, - template_object_name="package", - extra_context=page_dict) +class SearchListView(ListView): + template_name = "packages/search.html" + paginate_by = 100 + + sort_fields = ("arch", "repo", "pkgname", "pkgbase", "compressed_size", + "installed_size", "build_date", "last_update", "flag_date") + allowed_sort = list(sort_fields) + ["-" + s for s in sort_fields] + + def get(self, request, *args, **kwargs): + self.form = PackageSearchForm(data=request.GET, + show_staging=self.request.user.is_authenticated()) + return super(SearchListView, self).get(request, *args, **kwargs) + + def get_queryset(self): + packages = Package.objects.normal() + if not self.request.user.is_authenticated(): + packages = packages.filter(repo__staging=False) + if self.form.is_valid(): + packages = parse_form(self.form, packages) + sort = self.form.cleaned_data['sort'] + if sort in self.allowed_sort: + packages = packages.order_by(sort) + else: + packages = packages.order_by('pkgname') + return packages + + # Form had errors so don't return any results + return Package.objects.none() + + def get_context_data(self, **kwargs): + context = super(SearchListView, self).get_context_data(**kwargs) + query_params = self.request.GET.copy() + query_params.pop('page', None) + context['current_query'] = query_params.urlencode() + context['search_form'] = self.form + return context def search_json(request): @@ -172,15 +139,21 @@ def search_json(request): } if request.GET: - form = PackageSearchForm(data=request.GET) + form = PackageSearchForm(data=request.GET, + show_staging=request.user.is_authenticated()) if form.is_valid(): - packages = Package.objects.normal() + packages = Package.objects.select_related('arch', 'repo', + 'packager') + if not request.user.is_authenticated(): + packages = packages.filter(repo__staging=False) packages = parse_form(form, packages)[:limit] + packages = packages.prefetch_related('groups', 'licenses', + 'conflicts', 'provides', 'replaces', 'depends') + attach_maintainers(packages) container['results'] = packages container['valid'] = True - to_json = simplejson.dumps(container, ensure_ascii=False, - cls=PackageJSONEncoder) - return HttpResponse(to_json, mimetype='application/json') + to_json = json.dumps(container, ensure_ascii=False, cls=PackageJSONEncoder) + return HttpResponse(to_json, content_type='application/json') # vim: set ts=4 sw=4 et: |