Enhanced sponsorship features

It is a part of feedback from PyConJP development.
Here picks a sponsorship benefit management enhancement.

* sponsor zip download
* export sponsor data as csv

```
commit eb3261c12c910ec562e016f10431cc48747baef8
Author: Dan Poirier <dpoirier@caktusgroup.com>
Date:   Wed Aug 21 11:51:20 2013 -0400

    Enhanced sponsor admin page

    For #67:

    * admin list sorted by name
    * not limited to 100 per page
    * a sortable visual indicator for each sponsorship benefit
      (completed, missing, not applicable)
    * also the sponsorship level, admin contact name, and an active
      or not indication
    * the ones we have today: print logo, web logo, print
      description, web description and the ad.
    * an action pick list like “email” and check mark the sponsors
    * I want to email based on the assets that are missing.
    * in subject and body, replace %%NAME%% by sponsor name
```

Signed-off-by: Hiroshi Miura <miurahr@linux.com>
This commit is contained in:
Hiroshi Miura 2015-06-21 11:11:04 +09:00
parent 91ae3de6df
commit da82edf26d
2 changed files with 118 additions and 9 deletions

View file

@ -7,5 +7,6 @@ urlpatterns = patterns(
url(r"^$", TemplateView.as_view(template_name="sponsorship/list.html"), name="sponsor_list"), url(r"^$", TemplateView.as_view(template_name="sponsorship/list.html"), name="sponsor_list"),
url(r"^apply/$", "sponsor_apply", name="sponsor_apply"), url(r"^apply/$", "sponsor_apply", name="sponsor_apply"),
url(r"^add/$", "sponsor_add", name="sponsor_add"), url(r"^add/$", "sponsor_add", name="sponsor_add"),
url(r"^ziplogos/$", "sponsor_zip_logo_files", name="sponsor_zip_logos"),
url(r"^(?P<pk>\d+)/$", "sponsor_detail", name="sponsor_detail"), url(r"^(?P<pk>\d+)/$", "sponsor_detail", name="sponsor_detail"),
) )

View file

@ -1,13 +1,28 @@
from django.http import Http404 from cStringIO import StringIO
import itertools
import logging
import os
import time
from zipfile import ZipFile, ZipInfo
from django.conf import settings
from django.http import Http404, HttpResponse
from django.shortcuts import render_to_response, redirect, get_object_or_404 from django.shortcuts import render_to_response, redirect, get_object_or_404
from django.template import RequestContext from django.template import RequestContext
from django.utils.translation import ugettext_lazy as _
from django.contrib import messages from django.contrib import messages
from django.contrib.admin.views.decorators import staff_member_required
from django.contrib.auth.decorators import login_required from django.contrib.auth.decorators import login_required
from symposion.sponsorship.forms import SponsorApplicationForm, SponsorDetailsForm, \ from symposion.sponsorship.forms import SponsorApplicationForm, \
SponsorBenefitsFormSet SponsorDetailsForm, SponsorBenefitsFormSet
from symposion.sponsorship.models import Sponsor, SponsorBenefit from symposion.sponsorship.models import Benefit, Sponsor, SponsorBenefit, \
SponsorLevel
log = logging.getLogger(__name__)
@login_required @login_required
@ -18,13 +33,13 @@ def sponsor_apply(request):
sponsor = form.save() sponsor = form.save()
if sponsor.sponsor_benefits.all(): if sponsor.sponsor_benefits.all():
# Redirect user to sponsor_detail to give extra information. # Redirect user to sponsor_detail to give extra information.
messages.success(request, "Thank you for your sponsorship " messages.success(request, _("Thank you for your sponsorship "
"application. Please update your " "application. Please update your "
"benefit details below.") "benefit details below."))
return redirect("sponsor_detail", pk=sponsor.pk) return redirect("sponsor_detail", pk=sponsor.pk)
else: else:
messages.success(request, "Thank you for your sponsorship " messages.success(request, _("Thank you for your sponsorship "
"application.") "application."))
return redirect("dashboard") return redirect("dashboard")
else: else:
form = SponsorApplicationForm(user=request.user) form = SponsorApplicationForm(user=request.user)
@ -87,3 +102,96 @@ def sponsor_detail(request, pk):
"form": form, "form": form,
"formset": formset, "formset": formset,
}, context_instance=RequestContext(request)) }, context_instance=RequestContext(request))
@staff_member_required
def sponsor_export_data(request):
sponsors = []
data = ""
for sponsor in Sponsor.objects.order_by("added"):
d = {
"name": sponsor.name,
"url": sponsor.external_url,
"level": (sponsor.level.order, sponsor.level.name),
"description": "",
}
for sponsor_benefit in sponsor.sponsor_benefits.all():
if sponsor_benefit.benefit_id == 2:
d["description"] = sponsor_benefit.text
sponsors.append(d)
def izip_longest(*args):
fv = None
def sentinel(counter=([fv] * (len(args) - 1)).pop):
yield counter()
iters = [itertools.chain(it, sentinel(), itertools.repeat(fv)) for it in args]
try:
for tup in itertools.izip(*iters):
yield tup
except IndexError:
pass
def pairwise(iterable):
a, b = itertools.tee(iterable)
b.next()
return izip_longest(a, b)
def level_key(s):
return s["level"]
for level, level_sponsors in itertools.groupby(sorted(sponsors, key=level_key), level_key):
data += "%s\n" % ("-" * (len(level[1]) + 4))
data += "| %s |\n" % level[1]
data += "%s\n\n" % ("-" * (len(level[1]) + 4))
for sponsor, next in pairwise(level_sponsors):
description = sponsor["description"].strip()
description = description if description else "-- NO DESCRIPTION FOR THIS SPONSOR --"
data += "%s\n\n%s" % (sponsor["name"], description)
if next is not None:
data += "\n\n%s\n\n" % ("-" * 80)
else:
data += "\n\n"
return HttpResponse(data, content_type="text/plain;charset=utf-8")
@staff_member_required
def sponsor_zip_logo_files(request):
"""Return a zip file of sponsor web and print logos"""
zip_stringio = StringIO()
zipfile = ZipFile(zip_stringio, "w")
try:
benefits = Benefit.objects.all()
for benefit in benefits:
dir_name = benefit.name.lower().replace(" ", "_").replace('/', '_')
for level in SponsorLevel.objects.all():
level_name = level.name.lower().replace(" ", "_").replace('/', '_')
for sponsor in Sponsor.objects.filter(level=level, active=True):
sponsor_name = sponsor.name.lower().replace(" ", "_").replace('/', '_')
full_dir = "/".join([dir_name, level_name, sponsor_name])
for sponsor_benefit in SponsorBenefit.objects.filter(
benefit=benefit,
sponsor=sponsor,
active=True,
).exclude(upload=''):
if os.path.exists(sponsor_benefit.upload.path):
modtime = time.gmtime(os.stat(sponsor_benefit.upload.path).st_mtime)
with open(sponsor_benefit.upload.path, "rb") as f:
fname = os.path.split(sponsor_benefit.upload.name)[-1]
zipinfo = ZipInfo(filename=full_dir + "/" + fname,
date_time=modtime)
zipfile.writestr(zipinfo, f.read())
else:
log.debug("No such sponsor file: %s" % sponsor_benefit.upload.path)
finally:
zipfile.close()
response = HttpResponse(zip_stringio.getvalue(),
content_type="application/zip")
prefix = settings.CONFERENCE_URL_PREFIXES[settings.CONFERENCE_ID]
response['Content-Disposition'] = \
'attachment; filename="%s_sponsorlogos.zip"' % prefix
return response