diff --git a/README b/README index 602055ad..b14cc1f3 100644 --- a/README +++ b/README @@ -7,7 +7,8 @@ python, bazaar, pip and virtualenv and several other python modules: * Packages apt-get install bzr git subversion mercurial \ python-setuptools python-pip python-virtualenv ipython \ - python-dev python-imaging python-numpy python-psycopg2 + python-dev python-imaging python-numpy python-psycopg2 \ + python-geoip * Pan.do/ra Get code from bazzar diff --git a/pandora/app/config.py b/pandora/app/config.py index bedd8cda..41c97808 100644 --- a/pandora/app/config.py +++ b/pandora/app/config.py @@ -100,6 +100,14 @@ def update_static(): if not os.path.exists(image): shutil.copyfile(pandora, image) + #download geo data + path = os.path.join(settings.GEOIP_PATH, 'GeoLiteCity.dat') + if not os.path.exists(path): + url = 'http://geolite.maxmind.com/download/geoip/database/GeoLiteCity.dat.gz' + print 'download', url + ox.net.saveUrl(url, "%s.gz"%path) + os.system('gunzip "%s.gz"' % path) + def init(): load_config() thread.start_new_thread(reloader_thread, ()) diff --git a/pandora/settings.py b/pandora/settings.py index 59992bbe..a712e14d 100644 --- a/pandora/settings.py +++ b/pandora/settings.py @@ -43,6 +43,7 @@ APPEND_SLASH = False # Example: "/home/media/media.lawrence.com/" MEDIA_ROOT = normpath(join(PROJECT_ROOT, '..', 'data')) STATIC_ROOT = normpath(join(PROJECT_ROOT, '..', 'static')) +GEOIP_PATH = normpath(join(PROJECT_ROOT, '..', 'data', 'geo')) # URL that handles the media served from MEDIA_ROOT. Make sure to use a # trailing slash if there is a path component (optional in other cases). diff --git a/pandora/user/models.py b/pandora/user/models.py index 8c581a61..4a183078 100644 --- a/pandora/user/models.py +++ b/pandora/user/models.py @@ -7,6 +7,7 @@ from django.contrib.auth.models import User from django.db import models from django.db.models import Max from django.conf import settings +from django.contrib.gis.utils import GeoIP import ox from ox.django.fields import DictField @@ -31,12 +32,40 @@ class SessionData(models.Model): screensize = models.CharField(default='', max_length=255) info = DictField(default={}) + location = models.CharField(default='', max_length=255) + system = models.CharField(default='', max_length=255) + browser = models.CharField(default='', max_length=255) objects = managers.SessionDataManager() def __unicode__(self): return u"%s" % self.session_key + def parse_data(self): + if self.useragent: + self.browser = 'Unknown' + for browser in ('Webkit', 'Safari', 'Chrome', 'Firefox', 'Safari Mobile', 'Opera'): + if { + 'Safari Mobile': 'Mobile/', + + }.get(browser, browser) in self.useragent: + self.browser = browser + for system in ('Windows', 'Mac OS X', 'Andorid', 'iOS', 'Linux'): + if { + }.get(system, system) in self.useragent: + self.system = system + if self.ip: + try: + g = GeoIP() + location = g.city(self.ip) + if location: + self.location = u'%s, %s' % (location['city'].decode('latin-1'), + location['country_name'].decode('latin-1')) + else: + self.location = '' + except: + self.location = '' + pass def save(self, *args, **kwargs): if self.user: self.username = self.user.username @@ -44,6 +73,7 @@ class SessionData(models.Model): self.firstseen = self.user.date_joined else: self.level = 0 + self.parse_data() super(SessionData, self).save(*args, **kwargs) @classmethod @@ -75,6 +105,7 @@ class SessionData(models.Model): def json(self, keys=None, user=None): j = { + 'browser': self.browser, 'disabled': False, 'email': '', 'firstseen': self.firstseen, @@ -82,9 +113,11 @@ class SessionData(models.Model): 'id': self.get_id(), 'lastseen': self.lastseen, 'level': 'guest', + 'location': self.location, 'notes': '', 'numberoflists': 0, 'screensize': self.screensize, + 'system': self.system, 'timesseen': self.timesseen, 'username': self.username or '', 'useragent': self.useragent, diff --git a/static/js/pandora/usersDialog.js b/static/js/pandora/usersDialog.js index 12c719ff..f482a6b4 100644 --- a/static/js/pandora/usersDialog.js +++ b/static/js/pandora/usersDialog.js @@ -189,6 +189,27 @@ pandora.ui.usersDialog = function() { visible: true, width: 90 }, + { + id: 'location', + operator: '+', + title: 'Location', + visible: true, + width: 120 + }, + { + id: 'browser', + operator: '+', + title: 'Browser', + visible: true, + width: 60 + }, + { + id: 'system', + operator: '+', + title: 'System', + visible: true, + width: 60 + }, { id: 'useragent', operator: '+',