Add basic click & view tracking

break-out-core-urls-views
Eric Holscher 2016-03-30 15:25:06 -07:00
parent 5b3b1a843d
commit bf7cb1df3c
4 changed files with 132 additions and 3 deletions

View File

@ -1,5 +1,9 @@
import random
from django.db import models
from django.utils.translation import ugettext_lazy as _
from django.core.urlresolvers import reverse
DISPLAY_CHOICES = (
('doc', 'Documentation Pages'),
@ -50,9 +54,26 @@ class SupporterPromo(models.Model):
def as_dict(self):
"A dict respresentation of this for JSON encoding"
image_url = reverse(
'donate_view_proxy',
kwargs={'promo_id': self.pk, 'hash': random.random()}
)
link_url = reverse(
'donate_click_proxy',
kwargs={'promo_id': self.pk}
)
return {
'id': self.analytics_id,
'text': self.text,
'link': self.link,
'image': self.image,
'link': link_url,
'image': image_url,
}
class SupporterImpressions(models.Model):
promo = models.ForeignKey(SupporterPromo, related_name='impressions',
blank=True, null=True)
date = models.DateField(_('Date'))
offers = models.IntegerField(_('Offer'), default=0)
views = models.IntegerField(_('View'), default=0)
clicks = models.IntegerField(_('Clicks'), default=0)

View File

@ -0,0 +1,50 @@
import json
from django.test import TestCase
from django_dynamic_fixture import get
from .models import SupporterPromo
from readthedocs.projects.models import Project
class PromoTests(TestCase):
def setUp(self):
self.promo = get(SupporterPromo,
slug='promo-slug',
link='http://example.com',
image='http://media.example.com/img.png')
def test_clicks(self):
resp = self.client.get('http://testserver/sustainability/click/%s/' % self.promo.id)
self.assertEqual(resp._headers['location'][1], 'http://example.com')
promo = SupporterPromo.objects.get(pk=self.promo.pk)
impression = promo.impressions.first()
self.assertEqual(impression.clicks, 1)
def test_views(self):
resp = self.client.get('http://testserver/sustainability/click/%s/random_hash/' % self.promo.id)
self.assertEqual(resp._headers['location'][1], 'http://media.example.com/img.png')
promo = SupporterPromo.objects.get(pk=self.promo.pk)
impression = promo.impressions.first()
self.assertEqual(impression.views, 1)
class FooterTests(TestCase):
def setUp(self):
self.promo = get(SupporterPromo,
live=True,
slug='promo-slug',
display_type='doc',
link='http://example.com',
image='http://media.example.com/img.png')
self.pip = get(Project, slug='pip')
def test_footer(self):
r = self.client.get(
'/api/v2/footer_html/?project=pip&version=latest&page=index'
)
resp = json.loads(r.content)
self.assertEqual(resp['promo_data']['link'], '/sustainability/click/%s/' % self.promo.pk)

View File

@ -3,6 +3,7 @@ from django.conf.urls import url, patterns, include
from .views import DonateCreateView
from .views import DonateListView
from .views import DonateSuccessView
from .views import click_proxy, view_proxy
urlpatterns = patterns(
@ -10,4 +11,6 @@ urlpatterns = patterns(
url(r'^$', DonateListView.as_view(), name='donate'),
url(r'^contribute/$', DonateCreateView.as_view(), name='donate_add'),
url(r'^contribute/thanks$', DonateSuccessView.as_view(), name='donate_success'),
url(r'^click/(?P<promo_id>\d+)/(?P<hash>.+)/$', view_proxy, name='donate_view_proxy'),
url(r'^click/(?P<promo_id>\d+)/$', click_proxy, name='donate_click_proxy'),
)

View File

@ -1,15 +1,22 @@
"""Donation views"""
import logging
import datetime
from django.views.generic import TemplateView
from django.conf import settings
from django.core.urlresolvers import reverse
from django.db.models import F
from django.utils.translation import ugettext_lazy as _
from django.shortcuts import redirect
from vanilla import CreateView, ListView
from redis import Redis, ConnectionError
import pytz
from readthedocs.payments.mixins import StripeMixin
from .models import Supporter
from .models import Supporter, SupporterPromo
from .forms import SupporterForm
from .mixins import DonateProgressMixin
@ -54,3 +61,51 @@ class DonateListView(DonateProgressMixin, ListView):
def get_template_names(self):
return [self.template_name]
def click_proxy(request, promo_id, redis=False):
promo = SupporterPromo.objects.get(pk=promo_id)
date = pytz.utc.localize(datetime.datetime.utcnow())
day = datetime.datetime(
year=date.year,
month=date.month,
day=date.day,
tzinfo=pytz.utc,
)
if redis:
redis = Redis.from_url(settings.BROKER_URL)
redis.incr('{slug}-{year}-{month}-{day}-clicks'.format(
slug=promo.analytics_id,
year=day.year,
month=day.month,
day=day.day,
))
else:
impression, _ = promo.impressions.get_or_create(date=day)
impression.clicks = F('clicks') + 1
impression.save()
return redirect(promo.link)
def view_proxy(request, promo_id, hash, redis=False):
promo = SupporterPromo.objects.get(pk=promo_id)
date = pytz.utc.localize(datetime.datetime.utcnow())
day = datetime.datetime(
year=date.year,
month=date.month,
day=date.day,
tzinfo=pytz.utc,
)
if redis:
redis = Redis.from_url(settings.BROKER_URL)
redis.incr('{slug}-{year}-{month}-{day}-views'.format(
slug=promo.analytics_id,
year=day.year,
month=day.month,
day=day.day,
))
else:
impression, _ = promo.impressions.get_or_create(date=day)
impression.views = F('views') + 1
impression.save()
return redirect(promo.image)