from django.http import HttpResponse, HttpResponseRedirect from django.shortcuts import get_object_or_404 from django.core.mail import send_mail from django.template import Context, loader from django.core import validators from django.contrib.auth.decorators import login_required from django.contrib.auth.models import User from archweb_dev.lib.utils import validate, render_response from datetime import datetime from archweb_dev.packages.models import Package, PackageFile, Repo, Category def update(request): if request.POST.has_key('adopt'): mode = 'adopt' message = 'Adoption was successful' if request.POST.has_key('disown'): mode = 'disown' message = 'Disown was successful' try: maint = User.objects.get(username=request.user.username) except User.DoesNotExist: return render_response(request, 'error_page.html', {'errmsg':'No maintainer record found! Are you a maintainer?'}) ids = request.POST.getlist('pkgid') for id in ids: pkg = Package.objects.get(id=id) if mode == 'adopt' and pkg.maintainer_id == 0: pkg.maintainer = maint elif mode == 'disown' and pkg.maintainer == maint: pkg.maintainer_id = 0 else: message = "You are not the current maintainer" pkg.save() return render_response(request, 'status_page.html', {'message':message}) def details(request, pkgid=0, name='', repo=''): if pkgid == 0: p = Package.objects.filter(pkgname=name) if repo: p = p.filter(repo__name__exact=repo) # if more then one result, send to the search view if len(p) > 1: return search(request, name) if len(p) < 1: return render_response(request, 'error_page.html', {'errmsg': 'No matching packages.'}) pkgid = p[0].id pkg = get_object_or_404(Package, id=pkgid) return render_response(request, 'packages/details.html', {'pkg':pkg}) def search(request, query=''): if request.GET.has_key('q'): # take the q GET var over the one passed on the URL query = request.GET['q'].strip() # fetch the form vars repo = request.GET.get('repo', 'all') category = request.GET.get('category', 'all') lastupdate = request.GET.get('lastupdate', '') limit = int(request.GET.get('limit', '50')) skip = int(request.GET.get('skip', '0')) sort = request.GET.get('sort', '') maint = request.GET.get('maint', 'all') # build the form lists repos = Repo.objects.order_by('name') cats = Category.objects.order_by('category') # copy GET data over and add the lists c = request.GET.copy() c['repos'], c['categories'] = repos, cats c['limit'], c['skip'] = limit, skip c['lastupdate'] = lastupdate c['sort'] = sort # 'q' gets renamed to 'query', so it's not in GET c['query'] = query # validate errors = {} validate(errors, 'Last Update', lastupdate, validators.isValidANSIDate, True, request) validate(errors, 'Page Limit', str(limit), validators.isOnlyDigits, True, request) validate(errors, 'Page Skip', str(skip), validators.isOnlyDigits, True, request) if errors: c['errors'] = errors return render_response(request, 'packages/search.html', c) if query: res1 = Package.objects.filter(pkgname__icontains=query) res2 = Package.objects.filter(pkgdesc__icontains=query) results = res1 | res2 else: results = Package.objects.all() if repo != 'all': results = results.filter(repo__name__exact=repo) if category != 'all': results = results.filter(category__category__exact=category) if maint != 'all': results = results.filter(maintainer=maint) if lastupdate: results = results.filter(last_update__gte=datetime(int(lastupdate[0:4]),int(lastupdate[5:7]),int(lastupdate[8:10]))) # select_related() shouldn't be needed -- we're working around a Django bug #results = results.select_related().order_by('repos.name', 'category', 'pkgname') # sort results if sort == '': results = results.order_by('repo', 'category', 'pkgname') else: # duplicate sort fields shouldn't hurt anything results = results.order_by(sort, 'repo', 'category', 'pkgname') qs = request.GET.copy() # build pagination urls if results.count() > (skip + limit): qs['skip'] = skip + limit c['nextpage'] = '?' + qs.urlencode() if skip > 0: qs['skip'] = max(0, skip - limit) c['prevpage'] = '?' + qs.urlencode() # pass the querystring to the template so we can build sort queries c['querystring'] = request.GET # if only there's only one result, pass right to the package details view if results.count() == 1: return details(request, results[0].id) # limit result set if limit > 0: results = results[skip:(skip+limit)] c['results'] = results return render_response(request, 'packages/search.html', c) def files(request, pkgid): pkg = get_object_or_404(Package, id=pkgid) files = PackageFile.objects.filter(pkg=pkgid) return render_response(request, 'packages/files.html', {'pkg':pkg,'files':files}) def flaghelp(request): return render_response(request, 'packages/flaghelp.html') def flag(request, pkgid): pkg = get_object_or_404(Package, id=pkgid) context = {'pkg': pkg} if request.POST.has_key('confirmemail'): email = request.POST['confirmemail'] if request.POST.has_key('usermessage'): message = request.POST['usermessage'] else: message = None # validate errors = {} validate(errors, 'Email Address', email, validators.isValidEmail, False, request) if errors: context['errors'] = errors return render_response(request, 'packages/flag.html', context) context['confirmemail'] = email pkg.needupdate = 1 pkg.save() if pkg.maintainer_id > 0: # send notification email to the maintainer t = loader.get_template('packages/outofdate.txt') c = Context({ 'email': request.POST['confirmemail'], 'message': message, 'pkgname': pkg.pkgname, 'weburl': 'http://www.archlinux.org/packages/' + str(pkg.id) + '/' }) send_mail('arch: Package [%s] marked out-of-date' % pkg.pkgname, t.render(c), 'Arch Website Notification ', [pkg.maintainer.email], fail_silently=True) return render_response(request, 'packages/flag.html', context) @login_required def unflag(request, pkgid): pkg = get_object_or_404(Package, id=pkgid) if pkg.maintainer.username != request.user.username: return render_response(request, 'error_page.html', {'errmsg': 'You do not own this package.'}) pkg.needupdate = 0 pkg.save() return HttpResponseRedirect('/packages/%d/' % (pkg.id))