1
from datetime import datetime, timedelta
5
from django.contrib.gis.geoip import HAS_GEOIP
8
from django.contrib.gis.geoip import GeoIP, GeoIPException
10
from django.conf import settings
11
from django.contrib.auth.models import User
12
from django.db import models
13
from django.utils.translation import ugettext, ugettext_lazy as _
14
from tracking import utils
16
USE_GEOIP = getattr(settings, 'TRACKING_USE_GEOIP', False)
17
CACHE_TYPE = getattr(settings, 'GEOIP_CACHE_TYPE', 4)
19
log = logging.getLogger('tracking.models')
22
class VisitorManager(models.Manager):
24
def active(self, timeout=None):
25
"""Retrieves only visitors who have been active within the timeout
28
timeout = utils.get_timeout()
31
cutoff = now - timedelta(minutes=timeout)
33
return self.get_queryset().filter(last_update__gte=cutoff)
36
class Visitor(models.Model):
37
session_key = models.CharField(max_length=40)
38
ip_address = models.CharField(max_length=20)
39
user = models.ForeignKey(User, null=True)
40
user_agent = models.CharField(max_length=255)
41
referrer = models.CharField(max_length=255)
42
url = models.CharField(max_length=255)
43
page_views = models.PositiveIntegerField(default=0)
44
session_start = models.DateTimeField()
45
last_update = models.DateTimeField()
47
objects = VisitorManager()
49
def _time_on_site(self):
50
"""Attempts to determine the amount of time a visitor has spent on the
51
site based upon their information that's in the database."""
52
if self.session_start:
53
seconds = (self.last_update - self.session_start).seconds
55
hours = seconds / 3600
56
seconds -= hours * 3600
57
minutes = seconds / 60
58
seconds -= minutes * 60
60
return u'%i:%02i:%02i' % (hours, minutes, seconds)
62
return ugettext(u'unknown')
63
time_on_site = property(_time_on_site)
65
def _get_geoip_data(self):
66
"""Attempts to retrieve MaxMind GeoIP data based upon the visitor's
69
if not HAS_GEOIP or not USE_GEOIP:
70
# go no further when we don't need to
71
log.debug('Bailing out. HAS_GEOIP: %s; TRACKING_USE_GEOIP: %s' % (
72
HAS_GEOIP, USE_GEOIP))
75
if not hasattr(self, '_geoip_data'):
76
self._geoip_data = None
78
gip = GeoIP(cache=CACHE_TYPE)
79
self._geoip_data = gip.city(self.ip_address)
80
except GeoIPException:
81
# don't even bother...
82
log.error('Error getting GeoIP data for IP "%s": %s' %
83
(self.ip_address, traceback.format_exc()))
85
return self._geoip_data
87
geoip_data = property(_get_geoip_data)
89
def _get_geoip_data_json(self):
90
"""Cleans out any dirty unicode characters to make the geoip data safe
93
if not self.geoip_data:
96
for key, value in self.geoip_data.items():
97
clean[key] = utils.u_clean(value)
100
geoip_data_json = property(_get_geoip_data_json)
103
ordering = ('-last_update',)
104
unique_together = ('session_key', 'ip_address',)
105
app_label = 'tracking'
108
class UntrackedUserAgent(models.Model):
109
keyword = models.CharField(_('keyword'), max_length=100, help_text=_(
110
'Part or all of a user-agent string. For example, "Googlebot" here will be found in "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" and that visitor will not be tracked.'))
112
def __unicode__(self):
116
ordering = ('keyword',)
117
verbose_name = _('Untracked User-Agent')
118
verbose_name_plural = _('Untracked User-Agents')
119
app_label = 'tracking'
122
class BannedIP(models.Model):
123
ip_address = models.GenericIPAddressField(
124
'IP Address', help_text=_('The IP address that should be banned'))
126
def __unicode__(self):
127
return self.ip_address
130
ordering = ('ip_address',)
131
verbose_name = _('Banned IP')
132
verbose_name_plural = _('Banned IPs')
133
app_label = 'tracking'