pandora/pandora/user/models.py

349 lines
13 KiB
Python
Raw Normal View History

2009-10-09 15:58:38 +02:00
# -*- coding: utf-8 -*-
# vi:si:et:sw=4:sts=4:ts=4
import copy
2010-11-28 17:46:20 +01:00
from datetime import datetime
2009-10-09 15:58:38 +02:00
from django.contrib.auth.models import User
2010-02-03 17:35:38 +05:30
from django.db import models
2011-01-14 09:54:35 +00:00
from django.db.models import Max
2011-09-06 08:06:59 -04:00
from django.conf import settings
2011-12-03 17:17:07 +01:00
from django.contrib.gis.utils import GeoIP
2010-02-03 17:29:11 +05:30
2011-10-03 18:10:53 +00:00
import ox
2011-01-11 15:48:18 +05:30
from ox.django.fields import DictField
2011-10-03 13:52:16 +02:00
from ox.utils import json
2010-02-03 17:29:11 +05:30
2011-01-11 21:49:27 +05:30
from itemlist.models import List, Position
2013-02-16 01:20:40 +00:00
import text
2011-01-11 15:48:18 +05:30
2011-11-07 15:25:16 +01:00
import managers
2012-02-13 11:20:17 +05:30
import tasks
2011-11-07 15:25:16 +01:00
class SessionData(models.Model):
session_key = models.CharField(max_length=40, primary_key=True)
user = models.ForeignKey(User, unique=True, null=True, blank=True, related_name='data')
firstseen = models.DateTimeField(auto_now_add=True, db_index=True)
2011-11-07 23:13:04 +01:00
lastseen = models.DateTimeField(default=datetime.now, db_index=True)
2011-11-07 15:25:16 +01:00
username = models.CharField(max_length=255, null=True, db_index=True)
2013-06-30 22:53:09 +02:00
level = models.IntegerField(default=0, db_index=True)
2011-11-07 15:25:16 +01:00
timesseen = models.IntegerField(default=0)
ip = models.CharField(max_length=255, null=True)
useragent = models.CharField(max_length=255, null=True)
windowsize = models.CharField(max_length=255, null=True)
screensize = models.CharField(max_length=255, null=True)
2011-11-07 15:25:16 +01:00
info = DictField(default={})
location = models.CharField(max_length=255, null=True)
location_sort = models.CharField(max_length=255, null=True)
system = models.CharField(max_length=255, null=True)
browser = models.CharField(max_length=255, null=True)
2011-11-07 15:25:16 +01:00
numberoflists = models.IntegerField(default=0, null=True)
2011-11-07 15:25:16 +01:00
objects = managers.SessionDataManager()
groupssort = models.CharField(default=None,blank=True,null=True, max_length=255)
2011-11-07 15:25:16 +01:00
def __unicode__(self):
return u"%s" % self.session_key
def parse_useragent(self):
2011-12-03 17:17:07 +01:00
if self.useragent:
ua = ox.parse_useragent(self.useragent)
self.browser = ua['browser']['string'].lower()
self.system = ua['system']['string'].lower()
if not self.browser:
self.browser = None
if not self.system:
self.system = None
2012-03-27 10:24:16 +00:00
if ua['robot']['name']:
2012-03-26 13:58:33 +02:00
self.level = -1
def parse_data(self):
self.parse_useragent()
2011-12-03 17:17:07 +01:00
if self.ip:
try:
g = GeoIP()
location = g.city(self.ip)
if location:
country = ox.get_country_name(location['country_code'])
2012-03-21 20:56:57 +01:00
if location['city']:
2012-06-04 21:22:44 +02:00
city = location['city']
if type(city) != unicode:
city = city.decode('latin-1')
2012-03-21 20:56:57 +01:00
self.location = u'%s, %s' % (city, country)
self.location_sort = u'%s, %s' % (country, city)
else:
self.location_sort = self.location = country
2011-12-03 17:17:07 +01:00
else:
self.location_sort = self.location = None
2011-12-03 17:17:07 +01:00
except:
self.location_sort = self.location = None
2011-12-03 17:17:07 +01:00
pass
2012-02-13 11:20:17 +05:30
2011-11-07 15:25:16 +01:00
def save(self, *args, **kwargs):
if self.user:
self.username = self.user.username
2011-11-07 16:05:21 +01:00
self.level = self.user.get_profile().level
2011-11-07 15:25:16 +01:00
self.firstseen = self.user.date_joined
self.groupssort = ''.join([g.name for g in self.user.groups.all()])
self.numberoflists = self.user.lists.count()
2011-11-07 16:05:21 +01:00
else:
self.groupssort = None
2011-11-07 15:25:16 +01:00
super(SessionData, self).save(*args, **kwargs)
@classmethod
def get_or_create(cls, request):
if not request.session.session_key:
request.session.save()
request.session.modified = True
2011-11-07 15:25:16 +01:00
session_key = request.session.session_key
assert session_key
2011-11-07 15:25:16 +01:00
if request.user.is_authenticated():
cls.objects.filter(user=request.user).update(session_key=session_key)
data, created = cls.objects.get_or_create(session_key=session_key)
if request.user.is_authenticated():
data.user = request.user
2012-03-03 01:43:27 +01:00
data.ip = request.META['REMOTE_ADDR']
2012-05-19 13:46:06 +02:00
if data.ip.startswith('::ffff:'):
data.ip = data.ip[len('::ffff:'):]
2012-03-03 01:43:27 +01:00
data.useragent = request.META['HTTP_USER_AGENT']
2011-11-07 15:25:16 +01:00
data.info = json.loads(request.POST.get('data', '{}'))
screen = data.info.get('screen', {})
if screen and 'height' in screen and 'width' in screen:
data.screensize = u'%s\xd7%s' % (screen['width'], screen['height'])
2011-11-07 15:25:16 +01:00
window = data.info.get('window', {})
2012-06-10 12:22:45 +02:00
if window and 'outerHeight' in window and 'outerWidth' in window:
data.windowsize = u'%s\xd7%s' % (window['outerWidth'], window['outerHeight'])
2011-11-07 15:25:16 +01:00
if not data.timesseen:
data.timesseen = 0
data.timesseen += 1
2011-11-07 23:13:04 +01:00
data.lastseen = datetime.now()
2011-11-07 15:25:16 +01:00
data.save()
tasks.parse_data.delay(data.session_key)
2011-11-07 15:25:16 +01:00
return data
2011-11-08 00:00:08 +01:00
def get_id(self):
2011-12-18 15:05:49 +05:30
return self.user and ox.toAZ(self.user.id) or self.session_key
2011-11-08 00:00:08 +01:00
2011-11-07 15:25:16 +01:00
def json(self, keys=None, user=None):
ua = ox.parse_useragent(self.useragent or '')
2011-11-07 15:25:16 +01:00
j = {
'browser': ua['browser']['string'],
2011-11-07 15:25:16 +01:00
'disabled': False,
'email': '',
'firstseen': self.firstseen,
'ip': self.ip,
2011-11-08 00:00:08 +01:00
'id': self.get_id(),
2011-11-07 15:25:16 +01:00
'lastseen': self.lastseen,
2012-03-27 10:24:16 +00:00
'level': 'robot' if ua['robot']['name'] else 'guest',
2011-12-03 17:17:07 +01:00
'location': self.location,
2011-12-18 09:27:15 +00:00
'newsletter': False,
2011-11-07 15:25:16 +01:00
'notes': '',
'numberoflists': 0,
'screensize': self.screensize,
'system': ua['system']['string'],
2011-11-07 15:25:16 +01:00
'timesseen': self.timesseen,
'username': self.username or '',
'useragent': self.useragent,
'windowsize': self.windowsize,
}
if self.user:
p = self.user.get_profile()
j['disabled'] = not self.user.is_active
j['email'] = self.user.email
2012-01-13 15:17:18 +05:30
j['groups'] = [g.name for g in self.user.groups.all()]
2011-11-07 15:25:16 +01:00
j['level'] = p.get_level()
2011-12-18 09:27:15 +00:00
j['newsletter'] = p.newsletter
2011-11-07 15:25:16 +01:00
j['notes'] = p.notes
2012-03-20 20:34:26 +01:00
j['numberoflists'] = self.numberoflists
2011-11-07 15:25:16 +01:00
if keys:
for key in j.keys():
if key not in keys:
del j[key]
return j
2011-01-01 17:14:42 +05:30
2010-02-03 17:29:11 +05:30
class UserProfile(models.Model):
reset_code = models.CharField(max_length=255, blank=True, null=True, unique=True)
2011-09-06 08:06:59 -04:00
user = models.ForeignKey(User, unique=True, related_name='profile')
2011-01-01 17:14:42 +05:30
2011-09-06 08:06:59 -04:00
level = models.IntegerField(default=1)
2010-08-10 23:59:20 +02:00
files_updated = models.DateTimeField(default=datetime.now)
newsletter = models.BooleanField(default=True)
2011-01-11 15:48:18 +05:30
ui = DictField(default={})
2011-01-11 17:21:09 +05:30
preferences = DictField(default={})
2011-01-01 17:14:42 +05:30
2011-10-03 18:10:53 +00:00
notes = models.TextField(default='')
2011-10-03 13:52:16 +02:00
def __unicode__(self):
return self.user.username
2011-01-11 20:26:08 +05:30
def get_ui(self):
2011-10-09 15:39:31 +02:00
return get_ui(self.ui, self.user)
2011-01-11 20:26:08 +05:30
2011-10-03 18:09:11 +02:00
def set_level(self, level):
self.level = settings.CONFIG['userLevels'].index(level)
if self.level == len(settings.CONFIG['userLevels']) - 1:
if not self.user.is_superuser:
self.user.is_superuser = True
self.user.save()
elif self.user.is_superuser:
self.user.is_superuser = False
self.user.save()
2011-10-03 18:09:11 +02:00
2011-08-23 19:39:34 +02:00
def get_level(self):
#django superuser should always be admin
if self.user.is_superuser:
if self.level != len(settings.CONFIG['userLevels']) - 1:
self.level = len(settings.CONFIG['userLevels']) - 1
self.save()
2011-10-03 18:09:11 +02:00
return settings.CONFIG['userLevels'][self.level]
2011-08-23 19:39:34 +02:00
2011-10-22 14:42:45 +02:00
def capability(self, capability):
return settings.CONFIG['capabilities'][capability].get(self.get_level()) == True
2010-02-03 17:29:11 +05:30
def user_post_save(sender, instance, **kwargs):
profile, new = UserProfile.objects.get_or_create(user=instance)
if new and instance.is_superuser:
profile.level = len(settings.CONFIG['userLevels']) - 1
2012-03-19 20:20:11 +01:00
profile.newsletter = True
profile.save()
2011-11-07 23:28:28 +01:00
SessionData.objects.filter(user=instance).update(level=profile.level,
username=instance.username)
2010-02-03 17:29:11 +05:30
models.signals.post_save.connect(user_post_save, sender=User)
2011-01-01 17:14:42 +05:30
2011-11-07 23:28:28 +01:00
def profile_post_save(sender, instance, **kwargs):
SessionData.objects.filter(user=instance.user).update(level=instance.level,
username=instance.user.username)
models.signals.post_save.connect(profile_post_save, sender=UserProfile)
2011-10-09 15:39:31 +02:00
def get_ui(user_ui, user=None):
ui = {}
config = copy.deepcopy(settings.CONFIG)
ui.update(config['user']['ui'])
2012-02-13 11:20:17 +05:30
def update_ui(ui, new):
2011-10-09 15:39:31 +02:00
'''
only update set keys in dicts
'''
for key in new:
if isinstance(new[key], dict) and key in ui:
2012-02-13 11:20:17 +05:30
ui[key] = update_ui(ui[key], new[key])
2011-10-09 15:39:31 +02:00
elif isinstance(ui, dict):
ui[key] = new[key]
return ui
2012-02-13 11:20:17 +05:30
ui = update_ui(ui, user_ui)
2011-10-09 15:39:31 +02:00
if not 'lists' in ui:
ui['lists'] = {}
def add(lists, section):
ids = []
for l in lists:
qs = Position.objects.filter(section=section)
if section == 'featured':
try:
pos = Position.objects.get(list=l, section=section)
created = False
except Position.DoesNotExist:
pos = Position(list=l, section=section, user=l.user)
2011-10-09 15:39:31 +02:00
pos.save()
created = True
else:
pos, created = Position.objects.get_or_create(list=l, user=user, section=section)
qs = qs.filter(user=user)
if created:
pos.position = qs.aggregate(Max('position'))['position__max'] + 1
pos.save()
id = l.get_id()
'''
if id not in ui['lists']:
ui['lists'][id] = {}
ui['lists'][id].update(ui['lists'][''])
'''
ids.append(id)
return ids
2013-02-16 01:20:40 +00:00
def add_texts(texts, section):
P = text.models.Position
ids = []
for t in texts:
qs = P.objects.filter(section=section)
if section == 'featured':
try:
pos = P.objects.get(text=t, section=section)
created = False
except P.DoesNotExist:
pos = P(text=t, section=section, user=t.user)
2013-02-16 01:20:40 +00:00
pos.save()
created = True
else:
pos, created = P.objects.get_or_create(text=t, user=user, section=section)
qs = qs.filter(user=user)
if created:
pos.position = qs.aggregate(Max('position'))['position__max'] + 1
pos.save()
ids.append(t.get_id())
return ids
2011-10-09 15:39:31 +02:00
ids = ['']
if user:
ids += add(user.lists.exclude(status="featured"), 'personal')
ids += add(user.subscribed_lists.filter(status='public'), 'public')
ids += add(List.objects.filter(status='featured'), 'featured')
for i in ui['lists'].keys():
if i not in ids:
del ui['lists'][i]
2013-02-16 01:20:40 +00:00
tids = ['']
if user:
tids += add_texts(user.texts.exclude(status="featured"), 'personal')
tids += add_texts(user.subscribed_texts.filter(status='public'), 'public')
tids += add_texts(text.models.Text.objects.filter(status='featured'), 'featured')
2011-10-09 15:39:31 +02:00
return ui
2011-11-07 15:25:16 +01:00
def init_user(user, request=None):
2012-03-03 01:43:27 +01:00
if request:
SessionData.get_or_create(request)
2011-11-07 15:25:16 +01:00
if user.is_anonymous():
result = settings.CONFIG['user'].copy()
result['ui'] = get_ui(json.loads(request.session.get('ui', '{}')))
else:
profile = user.get_profile()
result = {}
for key in ('username', ):
result[key] = getattr(user, key)
result['level'] = profile.get_level()
result['groups'] = [g.name for g in user.groups.all()]
result['email'] = user.email
2011-12-18 09:27:15 +00:00
result['newsletter'] = profile.newsletter
2011-11-07 15:25:16 +01:00
result['ui'] = profile.get_ui()
result['volumes'] = [v.json() for v in user.volumes.all()]
return result
def user_json(user, keys=None):
2011-10-03 13:52:16 +02:00
p = user.get_profile()
j = {
2011-10-03 18:10:53 +00:00
'disabled': not user.is_active,
2011-10-03 13:52:16 +02:00
'email': user.email,
'firstseen': user.date_joined,
2011-12-18 15:05:49 +05:30
'id': ox.toAZ(user.id),
2011-10-03 13:52:16 +02:00
'lastseen': user.last_login,
'level': p.get_level(),
2011-12-18 09:27:15 +00:00
'newsletter': p.newsletter,
2011-10-03 18:10:53 +00:00
'notes': p.notes,
2012-03-20 20:34:26 +01:00
'numberoflists': user.lists.count(),
'username': user.username,
}
2011-10-03 13:52:16 +02:00
if keys:
for key in j.keys():
if key not in keys:
del j[key]
return j
def has_capability(user, capability):
if user.is_anonymous():
level = 'guest'
else:
level = user.get_profile().get_level()
return level in settings.CONFIG['capabilities'][capability] \
and settings.CONFIG['capabilities'][capability][level]