Mercurial > public > sg101
changeset 558:9a68fd3bd8a5
Creating a simple banner / ad campaign application, initially as a RFB / SG101
tie-in.
author | Brian Neal <bgneal@gmail.com> |
---|---|
date | Thu, 02 Feb 2012 18:56:48 -0600 |
parents | 7247a406f92b |
children | b9a41956be23 |
files | gpp/banners/__init__.py gpp/banners/admin.py gpp/banners/models.py gpp/banners/templatetags/__init__.py gpp/banners/templatetags/banner_tags.py gpp/settings/base.py gpp/templates/core/rfb_block.html |
diffstat | 5 files changed, 164 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gpp/banners/admin.py Thu Feb 02 18:56:48 2012 -0600 @@ -0,0 +1,34 @@ +""" +This file contains the automatic admin site definitions for the banners models. + +""" +from django.contrib import admin + +from banners.models import Campaign, Banner + + +class BannerInline(admin.TabularInline): + model = Banner + extra = 1 + + +class CampaignAdmin(admin.ModelAdmin): + prepopulated_fields = {'slug': ['name']} + list_display = ['name', 'slug', 'creation_date'] + date_hierarchy = 'creation_date' + search_fields = ['name'] + inlines = [BannerInline] + + +class BannerAdmin(admin.ModelAdmin): + list_display = ['campaign', 'description', 'image_tag', 'creation_date'] + date_hierarchy = 'creation_date' + search_fields = ['description'] + list_filter = ['campaign'] + + def image_tag(self, obj): + return '<img src="%s" alt="%s" />' % (obj.image.url, obj.description) + image_tag.allow_tags = True + +admin.site.register(Campaign, CampaignAdmin) +admin.site.register(Banner, BannerAdmin)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gpp/banners/models.py Thu Feb 02 18:56:48 2012 -0600 @@ -0,0 +1,60 @@ +""" +Models for the banners application. + +""" +import datetime + +from django.db import models + + +class Campaign(models.Model): + """ + A model to represent an ad or banner campaign. + + """ + name = models.CharField(max_length=128) + slug = models.SlugField() + creation_date = models.DateTimeField(blank=True) + + def __unicode__(self): + return self.name + + class Meta: + ordering = ['name'] + + def save(self, *args, **kwargs): + if not self.pk and not self.creation_date: + self.creation_date = datetime.datetime.now() + + super(Campaign, self).save(*args, **kwargs) + + +def banner_upload_to(instance, filename): + """ + An "upload_to" function for the Banner model. + + """ + return "banners/%s/%s" % (instance.campaign.slug, filename) + + +class Banner(models.Model): + """ + A model to represent a banner. + + """ + campaign = models.ForeignKey(Campaign) + image = models.ImageField(upload_to=banner_upload_to) + description = models.CharField(max_length=128) + creation_date = models.DateTimeField(blank=True) + + def __unicode__(self): + return self.description + + class Meta: + ordering = ['-creation_date'] + + def save(self, *args, **kwargs): + if not self.pk and not self.creation_date: + self.creation_date = datetime.datetime.now() + + super(Banner, self).save(*args, **kwargs)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gpp/banners/templatetags/banner_tags.py Thu Feb 02 18:56:48 2012 -0600 @@ -0,0 +1,60 @@ +""" +Template tags for the banners application. + +""" +import logging + +from django import template +import redis + +from core.services import get_redis_connection +from banners.models import Banner + + +register = template.Library() +logger = logging.getLogger(__name__) + +BANNER_URL_KEY = 'banners:url:%s' + + +@register.simple_tag +def banner_url(slug): + """ + Returns the URL for the next banner in the campaign whose slug is 'slug'. + + For each campaign, a list of banner URLs are kept in Redis. Each time this + tag is called, the front banner is popped off the list. When the list is + empty, we refresh the list from the database. In this way the banners for a + campaign are cycled through. + """ + key = BANNER_URL_KEY % slug + + try: + conn = get_redis_connection() + url = conn.lpop(key) + except redis.RedisError, e: + logger.error("banner_url: '%s' on lpop", e) + return u'' + + if url: + return url + + # list not found or empty, rebuild it from the database + + qs = Banner.objects.filter(campaign__slug=slug) + urls = [banner.image.url for banner in qs] + if not urls: + logger.warning("banner_url: no banners for campaign '%s'", slug) + return u'' + + url = urls[0] + urls = urls[1:] + + if urls: + try: + conn.rpush(key, *urls) + except redis.RedisError: + logger.error("banner_url: '%s' on rpush", e) + pass + + return url
--- a/gpp/settings/base.py Sun Jan 29 14:45:09 2012 -0600 +++ b/gpp/settings/base.py Thu Feb 02 18:56:48 2012 -0600 @@ -121,6 +121,7 @@ 'tagging', 'accounts', 'antispam', + 'banners', 'bio', 'bulletins', 'comments',
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gpp/templates/core/rfb_block.html Thu Feb 02 18:56:48 2012 -0600 @@ -0,0 +1,9 @@ +{% extends 'side_block.html' %} +{% load banner_tags %} +{% block block_title %}R.F.B.{% endblock %} +{% block block_content %} +<center> +<a href="http://radiofreebakersfield.com/"><img src="{% banner_url 'rfb' %}" alt="Radio Free Bakersfield" title="Radio Free Bakersfield" /></a> +<p>Listen to <a href="http://radiofreebakersfield.com/">Radio Free Bakersfield</a> for the SG101 Pick of the Week!</p> +</center> +{% endblock %}