Commits

Anonymous committed 3099491

1) pep8 2) slugify via javascript in admin 3) complete refactoring of middleware 4) remove unused functions

  • Participants
  • Parent commits 56567af

Comments (0)

Files changed (5)

+\.ropeproject/.*

affiliate/admin.py

 from django.core.urlresolvers import reverse
 
 class AffiliateOptions(admin.ModelAdmin):
-    
+
     list_display = (
         'name',
         'query_string',
         'total_visits',
         'report',
     )
-    
+
+    prepopulated_fields = {"slug": ("name",)}
+
     def name(self, obj):
         return obj.name
     name.short_description = 'Affiliate Name'
-    
+
     def query_string(self, obj):
         return "?affiliate="+obj.slug
     query_string.short_description = "Query String"
-    
+
     def anon_visits(self, obj):
         return obj.visit_set.filter(user=None).count()
     anon_visits.short_description = "Anonymous Visits"
-    
+
     def auth_visits(self, obj):
         return obj.visit_set.exclude(user=None).count()
     auth_visits.short_description = "Authenticated Visits"
-    
+
     def total_visits(self, obj):
         return obj.visit_set.all().count()
     total_visits.short_description = "Total Visits"
-    
+
     def report(self, obj):
         link = reverse('affiliate.views.affiliate_report', args=[obj.pk])
         return '<a href="'+link+'">'+obj.name+' csv report</a>'

affiliate/middleware.py

-#python imports
-from datetime import datetime
+import logging
 
-#django imports
-from django.template import RequestContext
-from django.http import HttpResponse, HttpResponseRedirect
-from django.contrib.auth.models import User
+from django.http import HttpResponseRedirect
 
-# affiliate imports
 from affiliate.models import Affiliate, Visit
 
 
-def _delete_visit_from_session(request):
+AFFILIATE_KEY = 'affiliate'
+
+
+def read_affiliate(somedict):
+    if AFFILIATE_KEY in somedict:
+        affiliate_slug = somedict[AFFILIATE_KEY]
+        try:
+            affiliate = Affiliate.objects.get(
+                slug=affiliate_slug)
+        except Affiliate.DoesNotExist:
+            affiliate = None
+            logging.warn('Request from non-existing affiliate: {0}'.format(
+                affiliate_slug))
+    return affiliate
+
+
+def read_affiliate_from_request(request):
+    return read_affiliate(request.REQUEST)
+
+
+def read_affiliate_from_session(request):
+    return read_affiliate(request.session)
+
+
+def save_visit(request, affiliate):
+    visit = Visit(affiliate=affiliate,
+                  session_key=request.session.session_key)
+    if request.user.is_authenticated():
+        visit.user = request.user
+    else:
+        request.session[AFFILIATE_KEY] = affiliate
+    visit.save()
+
+
+def update_visit(request, affiliate):
     try:
-        del request.session['visit_id']
-    except KeyError:
-        pass
+        visit = Visit.objects.get(affiliate=affiliate,
+                                  session_key=request.session.session_key)
+        visit.user = request.user
+        visit.save()
+    except Visit.DoesNotExist:
+        logging.warn('Visit object not found for session key: {0}'.format(
+            request.session.session_key))
 
 
-def _get_visit_from_request(request):
+def relate_logged_user(request, affiliate):
+    """ If a user is logs later it assocaites the user with previously stored
+    affilite link.
+    """
     try:
-        visit = Visit.objects.get(pk=request.session['visit_id'])
+        previously_logged_visits = Visit.objects.filter(
+            session_key=request.session.session_key).order_by('-date')
+        if previously_logged_visits.count() > 0:
+            previously_logged_visit = previously_logged_visits[0]
     except Visit.DoesNotExist:
-        visit = None
-    return visit
+        previously_logged_visit = None
+
+    if request.user.is_authenticated() \
+         and affiliate \
+         and previously_logged_visit \
+         and not previously_logged_visit.user:
+        previously_logged_visit.user = request.user
+        previously_logged_visit.save()
 
 
 class AffiliateMiddleware(object):
-    
+
     """
-    Affiliate Middleware takes a get parameter, records as a Visit instance.
-    If a user is logged in or logs later it assocaites the user.
-    
-    AffiliateMiddleware's current philosophy  is that only the first
-    affiliate that brings in an authenticated user should get the credit.
-    This might be optional in future versions depending on demand for
-    alternative philosophies.
-    
-    For now, there is no unique=True constraint for users, although
-    uniqueness is enforced in the middleware.
+    Affiliate Middleware takes request parameter, records as a Visit instance.
+
+    It will save every visit from every affiliate: let site owner
+    decide which information is useful.
+
+    If a user is logs later it assocaites the user with previously stored
+    affilite link.
     """
-    
+
     def process_request(self, request):
-        
-        #if there already is a visit_id in the session
-        if 'visit_id' in request.session:
-            if request.user.is_authenticated():
-                if Visit.objects.filter(user=request.user).count() == 0:
-                    # Add the user to the visit
-                    visit = _get_visit_from_request(request)
-                    if visit:
-                        visit.user = request.user
-                        visit.save()
 
-                #If there is an anonomous visit, but the user already has a visit delete the anon visit.
-                else:
-                    visit = _get_visit_from_request(request)
-                    if visit:
-                        visit.delete()
-    
-                _delete_visit_from_session(request)
+        affiliate_from_request = read_affiliate_from_request(request)
+        affiliate_from_session = read_affiliate_from_session(request)
+        relate_logged_user(request, affiliate_from_session)
 
-        #if there is no visit for this session or user (and implictly no visit_id in the session)
-        elif request.method == 'GET' and Visit.objects.filter(session_key=request.session.session_key).count() == 0:
-            if 'affiliate' in request.GET:
-                try:
-                    affiliate = Affiliate.objects.get(slug=request.GET['affiliate'])
-                except Affiliate.DoesNotExist:
-                    affiliate = None
-                    
-                if affiliate:
-                    if request.user.is_authenticated():
-                        if Visit.objects.filter(user=request.user).count() == 0:
-                            #associate the user with the affiliate
-                            visit = Visit(user=request.user)
-                            #add the session key
-                            visit.session_key=request.session.session_key
-                            #add the affiliate
-                            visit.affiliate=affiliate
-                            visit.date = datetime.now()
-                            visit.save()
-                    else:
-                        #record the affiliate link visit
-                        visit = Visit(session_key=request.session.session_key)
-                        #add the affiliate
-                        visit.affiliate=affiliate
-                        visit.date = datetime.now()
-                        visit.save()
-                        #record the visit id in the session for future matching with authenticated user
-                        request.session['visit_id']=visit.pk
+        if affiliate_from_request:
+            save_visit(request, affiliate_from_request)
 
-        #Forwarding so that the affiliate get parameter isn't making things ugly for the user.
-        if request.method == 'GET':
-            if 'affiliate' in request.GET:
-                #preserve other get parameters during redirect
-                q = request.GET.urlencode().replace('affiliate='+request.GET['affiliate'],'').replace('&&','&').rstrip('&').lstrip('&')
-                if len(q) > 0:
-                    return HttpResponseRedirect(request.path_info+"?"+q)
-                else:
-                    return HttpResponseRedirect(request.path_info)
+        request.affiliate = affiliate_from_request \
+                            or affiliate_from_session \
+                            or Visit.get_last_visit(request.user)
+
+        # Forwarding so that the affiliate get parameter
+        # isn't making things ugly for the user.
+        if request.method == 'GET' and \
+               AFFILIATE_KEY in request.GET:
+            q = request.GET.urlencode().replace(
+                'affiliate=' + request.GET[AFFILIATE_KEY],
+                '').replace('&&', '&').rstrip('&').lstrip('&')
+
+            if len(q) > 0:
+                return HttpResponseRedirect(request.path_info + "?" + q)

affiliate/models.py

 from django.db import models
-from django.template.defaultfilters import slugify
 from django.contrib.auth.models import User
-from django.contrib.sites.models import Site
 
-def _check_for_dupes(slug):
-    return Affiliate.objects.filter(slug=slug).count() != 0
 
-"""
-Affiliate model with auto slugify on save
-"""
 class Affiliate(models.Model):
+    """
+    Affiliate model with auto slugify on save
+    """
     name = models.CharField(max_length=30)
     slug = models.SlugField(unique=True, blank=True, null=True)
-    
-    def save(self, *args, **kwargs):
-        if not self.slug:
-            slug_candidate = slugify(self.name)
-            length = len(slug_candidate)
-            index = 0
-            while _check_for_dupes(slug_candidate):
-                index += 1
-                slug_candidate = slug_candidate[:length] + str(index)
-            self.slug = slug_candidate
-        
-        super(Affiliate, self).save(*args, **kwargs)
-    
+
     def __unicode__(self):
-        site = Site.objects.get_current()
-        return self.name + " ?affiliate="+self.slug
+        return self.name + " ?affiliate=" + self.slug
 
-"""
-Model to log visits
-"""
+
 class Visit(models.Model):
+    """
+    Model to log visits
+    """
     affiliate = models.ForeignKey(Affiliate, related_name="visit_set")
     user = models.ForeignKey(User, blank=True, null=True)
     date = models.DateTimeField(auto_now_add=True)
     session_key = models.CharField(max_length=64, unique=True)
-    
+
     def __unicode__(self):
         if self.user:
             return self.user.username
         else:
             return self.session_key
-    
+
     class Meta:
         ordering = ('date',)
-    
-    def get_is_authenticated(self):
-        return self.user != None
-    is_authenticated = property(get_is_authenticated)
+
+    @classmethod
+    def get_last_visit(cls, user):
+        if user.is_authenticated():
+            visits = cls.objects.filter(user=user).order_by('-date')
+            if visits.count() > 0:
+                return visits[0]

affiliate/views.py

-#Python imports
+import csv
 from datetime import datetime
-import csv
 
-#Django imports
-from django.http import HttpResponse, HttpResponseRedirect, Http404
-from django.template import RequestContext, loader, Context
-from django.template.loader import get_template
-from django.contrib.admin.views.decorators import staff_member_required
+from django.http import HttpResponse
 
-#affiliate imports
 from affiliate.models import Affiliate, Visit
 
+
 def affiliate_report(request, affiliate_id):
     affiliate = Affiliate.objects.get(pk=affiliate_id)
     response = HttpResponse(mimetype='text/csv')
-    response['Content-Disposition'] = 'attachment; filename='+affiliate.name+'_'+str(datetime.now())+'.csv'
+    response['Content-Disposition'] = 'attachment; filename=' + \
+                                      affiliate.name + '_' + \
+                                      str(datetime.now())+'.csv'
     rows = []
     headers = ['Affiliate', 'Authenticated', 'Anonymous', 'Date',]
     rows.append(headers)
     writer = csv.writer(response)
     for row in rows:
         writer.writerow(row)
-        
+
     return response