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:
		
							parent
							
								
									91ae3de6df
								
							
						
					
					
						commit
						da82edf26d
					
				
					 2 changed files with 118 additions and 9 deletions
				
			
		|  | @ -7,5 +7,6 @@ urlpatterns = patterns( | |||
|     url(r"^$", TemplateView.as_view(template_name="sponsorship/list.html"), name="sponsor_list"), | ||||
|     url(r"^apply/$", "sponsor_apply", name="sponsor_apply"), | ||||
|     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"), | ||||
| ) | ||||
|  |  | |||
|  | @ -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.template import RequestContext | ||||
| from django.utils.translation import ugettext_lazy as _ | ||||
| 
 | ||||
| from django.contrib import messages | ||||
| from django.contrib.admin.views.decorators import staff_member_required | ||||
| from django.contrib.auth.decorators import login_required | ||||
| 
 | ||||
| from symposion.sponsorship.forms import SponsorApplicationForm, SponsorDetailsForm, \ | ||||
|     SponsorBenefitsFormSet | ||||
| from symposion.sponsorship.models import Sponsor, SponsorBenefit | ||||
| from symposion.sponsorship.forms import SponsorApplicationForm, \ | ||||
|     SponsorDetailsForm, SponsorBenefitsFormSet | ||||
| from symposion.sponsorship.models import Benefit, Sponsor, SponsorBenefit, \ | ||||
|     SponsorLevel | ||||
| 
 | ||||
| 
 | ||||
| log = logging.getLogger(__name__) | ||||
| 
 | ||||
| 
 | ||||
| @login_required | ||||
|  | @ -18,13 +33,13 @@ def sponsor_apply(request): | |||
|             sponsor = form.save() | ||||
|             if sponsor.sponsor_benefits.all(): | ||||
|                 # Redirect user to sponsor_detail to give extra information. | ||||
|                 messages.success(request, "Thank you for your sponsorship " | ||||
|                                  "application. Please update your " | ||||
|                                  "benefit details below.") | ||||
|                 messages.success(request, _("Thank you for your sponsorship " | ||||
|                                             "application. Please update your " | ||||
|                                             "benefit details below.")) | ||||
|                 return redirect("sponsor_detail", pk=sponsor.pk) | ||||
|             else: | ||||
|                 messages.success(request, "Thank you for your sponsorship " | ||||
|                                  "application.") | ||||
|                 messages.success(request, _("Thank you for your sponsorship " | ||||
|                                             "application.")) | ||||
|                 return redirect("dashboard") | ||||
|     else: | ||||
|         form = SponsorApplicationForm(user=request.user) | ||||
|  | @ -87,3 +102,96 @@ def sponsor_detail(request, pk): | |||
|         "form": form, | ||||
|         "formset": formset, | ||||
|     }, 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 | ||||
|  |  | |||
		Loading…
	
	Add table
		
		Reference in a new issue
	
	 Hiroshi Miura
						Hiroshi Miura