session data for users and guests

This commit is contained in:
j 2011-11-07 15:25:16 +01:00
parent e669790e0f
commit 3cec9cefa2
6 changed files with 170 additions and 83 deletions

View file

@ -13,7 +13,7 @@ from django.db.models import Max, Sum
from ox.django.shortcuts import render_to_json_response, json_response from ox.django.shortcuts import render_to_json_response, json_response
from ox.utils import json from ox.utils import json
from user.models import init_user, get_ui from user.models import init_user
from item.models import ItemSort from item.models import ItemSort
from actions import actions from actions import actions
@ -69,11 +69,7 @@ def init(request):
key['format']['args'][0] = value key['format']['args'][0] = value
response['data']['site'] = config response['data']['site'] = config
if request.user.is_authenticated(): response['data']['user'] = init_user(request.user, request)
response['data']['user'] = init_user(request.user, request)
else:
response['data']['user'] = response['data']['site']['user']
response['data']['user']['ui'] = get_ui(json.loads(request.session.get('ui', '{}')))
return render_to_json_response(response) return render_to_json_response(response)
actions.register(init) actions.register(init)

View file

@ -14,6 +14,7 @@ from django.contrib.auth.models import User
import ox.jsonc import ox.jsonc
from ox.utils import json from ox.utils import json
_win = (sys.platform == "win32") _win = (sys.platform == "win32")
RUN_RELOADER = True RUN_RELOADER = True

View file

@ -1,16 +1,13 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# vi:si:et:sw=4:sts=4:ts=4 # vi:si:et:sw=4:sts=4:ts=4
from django.contrib.auth.models import User from django.db.models import Q, Manager
from ox.django.query import QuerySet
from django.db.models import Q
def parseCondition(condition, user): def parseCondition(condition, user):
k = condition.get('key', 'name') k = condition.get('key', 'name')
k = { k = {
'firstseen': 'created', 'email': 'user__email',
'lastseen': 'last_login',
'user': 'username', 'user': 'username',
'name': 'username',
}.get(k, k) }.get(k, k)
v = condition['value'] v = condition['value']
op = condition.get('operator') op = condition.get('operator')
@ -61,12 +58,40 @@ def parseConditions(conditions, operator, user):
return q return q
return None return None
def find_user(data, user): class SessionDataManager(Manager):
qs = User.objects.all()
query = data.get('query', {}) def get_query_set(self):
conditions = parseConditions(query.get('conditions', []), return QuerySet(self.model)
query.get('operator', '&'),
user) def find(self, data, user):
if conditions: '''
qs = qs.filter(conditions) query: {
return qs conditions: [
{
value: "war"
}
{
key: "year",
value: "1970-1980,
operator: "!="
},
{
key: "country",
value: "f",
operator: "^"
}
],
operator: "&"
}
'''
#join query with operator
qs = self.get_query_set()
query = data.get('query', {})
conditions = parseConditions(query.get('conditions', []),
query.get('operator', '&'),
user)
if conditions:
qs = qs.filter(conditions)
return qs

View file

@ -4,6 +4,7 @@ import copy
from datetime import datetime from datetime import datetime
from django.contrib.auth.models import User from django.contrib.auth.models import User
from django.contrib.sessions.models import Session
from django.db import models from django.db import models
from django.db.models import Max from django.db.models import Max
from django.conf import settings from django.conf import settings
@ -14,6 +15,86 @@ from ox.utils import json
from itemlist.models import List, Position from itemlist.models import List, Position
import managers
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)
lastseen = models.DateTimeField(auto_now=True, db_index=True)
username = models.CharField(max_length=255, null=True, db_index=True)
timesseen = models.IntegerField(default=0)
ip = models.CharField(default='', max_length=255)
useragent = models.CharField(default='', max_length=255)
windowsize = models.CharField(default='', max_length=255)
screensize = models.CharField(default='', max_length=255)
info = DictField(default={})
objects = managers.SessionDataManager()
def __unicode__(self):
return u"%s" % self.session_key
def save(self, *args, **kwargs):
if self.user:
self.username = self.user.username
self.firstseen = self.user.date_joined
super(SessionData, self).save(*args, **kwargs)
@classmethod
def get_or_create(cls, request):
session_key = request.session.session_key
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
data.info = json.loads(request.POST.get('data', '{}'))
screen = data.info.get('screen', {})
if 'height' in screen and 'width' in screen:
data.screensize = '%sx%s' % (screen['width'], screen['height'])
window = data.info.get('window', {})
if 'outerHeight' in window and 'outerWidth' in window:
data.windowsize = '%sx%s' % (window['outerWidth'], window['outerHeight'])
data.ip = request.META['REMOTE_ADDR']
data.useragent = request.META['HTTP_USER_AGENT']
if not data.timesseen:
data.timesseen = 0
data.timesseen += 1
data.save()
return data
def json(self, keys=None, user=None):
j = {
'disabled': False,
'email': '',
'firstseen': self.firstseen,
'ip': self.ip,
'id': self.user and ox.to26(self.user.id) or self.session_key,
'lastseen': self.lastseen,
'level': 'guest',
'notes': '',
'numberoflists': 0,
'screensize': self.screensize,
'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
j['level'] = p.get_level()
j['notes'] = p.notes
j['numberoflists'] = self.user.lists.count()
if keys:
for key in j.keys():
if key not in keys:
del j[key]
return j
class UserProfile(models.Model): class UserProfile(models.Model):
reset_code = models.CharField(max_length=255, blank=True, null=True, unique=True) reset_code = models.CharField(max_length=255, blank=True, null=True, unique=True)
@ -25,12 +106,6 @@ class UserProfile(models.Model):
ui = DictField(default={}) ui = DictField(default={})
preferences = DictField(default={}) preferences = DictField(default={})
timesseen = models.IntegerField(default=0)
ip = models.CharField(default='', max_length=255)
useragent = models.CharField(default='', max_length=255)
windowsize = models.CharField(default='', max_length=255)
screensize = models.CharField(default='', max_length=255)
info = DictField(default={})
notes = models.TextField(default='') notes = models.TextField(default='')
def get_ui(self): def get_ui(self):
@ -105,54 +180,39 @@ def get_ui(user_ui, user=None):
del ui['lists'][i] del ui['lists'][i]
return ui return ui
def user_json(user, keys=None, request_user=None): def init_user(user, request=None):
data = SessionData.get_or_create(request)
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
result['ui'] = profile.get_ui()
result['volumes'] = [v.json() for v in user.volumes.all()]
return result
def user_json(user, keys=None):
p = user.get_profile() p = user.get_profile()
j = { j = {
'disabled': not user.is_active, 'disabled': not user.is_active,
'email': user.email, 'email': user.email,
'firstseen': user.date_joined, 'firstseen': user.date_joined,
'ip': p.ip,
'id': ox.to26(user.id), 'id': ox.to26(user.id),
'lastseen': user.last_login, 'lastseen': user.last_login,
'level': p.get_level(), 'level': p.get_level(),
'notes': p.notes, 'notes': p.notes,
'numberoflists': user.lists.count(), 'numberoflists': user.lists.count(),
'screensize': p.screensize,
'timesseen': p.timesseen,
'username': user.username, 'username': user.username,
'useragent': p.useragent,
'windowsize': p.windowsize,
} }
if keys: if keys:
for key in j.keys(): for key in j.keys():
if key not in keys: if key not in keys:
del j[key] del j[key]
return j return j
def init_user(user, request=None):
profile = user.get_profile()
if request:
data = json.loads(request.POST.get('data', '{}'))
profile.info = data
screen = data.get('screen', {})
if 'height' in screen and 'width' in screen:
profile.screensize = '%sx%s' % (screen['width'], screen['height'])
window = data.get('window', {})
if 'outerHeight' in window and 'outerWidth' in window:
profile.windowsize = '%sx%s' % (window['outerWidth'], window['outerHeight'])
profile.ip = request.META['REMOTE_ADDR']
profile.useragent = request.META['HTTP_USER_AGENT']
if not profile.timesseen:
profile.timesseen = 0
profile.timesseen += 1
profile.save()
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
result['ui'] = profile.get_ui()
result['volumes'] = [v.json() for v in user.volumes.all()]
return result

View file

@ -340,7 +340,7 @@ def editUser(request):
user.username = data['username'] user.username = data['username']
user.save() user.save()
profile.save() profile.save()
response['data'] = models.user_json(user) response['data'] = user.data.get().json()
return render_to_json_response(response) return render_to_json_response(response)
actions.register(editUser, cache=False) actions.register(editUser, cache=False)
@ -403,7 +403,7 @@ def parse_query(data, user):
for key in ('keys', 'range', 'sort', 'query'): for key in ('keys', 'range', 'sort', 'query'):
if key in data: if key in data:
query[key] = data[key] query[key] = data[key]
query['qs'] = managers.find_user(query, user) query['qs'] = models.SessionData.objects.find(query, user)
return query return query
def order_query(qs, sort): def order_query(qs, sort):
@ -413,21 +413,23 @@ def order_query(qs, sort):
if operator != '-': if operator != '-':
operator = '' operator = ''
key = { key = {
'email': 'email', 'email': 'user__email',
'firstseen': 'date_joined', 'firstseen': 'firstseen',
'lastseen': 'last_login', 'ip': 'ip',
'lastseen': 'lastseen',
'screensize': 'screensize',
'timesseen': 'timesseen',
'useragent': 'useragent',
'username': 'username', 'username': 'username',
'name': 'username', 'windowsize': 'windowsize',
}.get(e['key'], 'profile__%s'%e['key']) }.get(e['key'], 'user__profile__%s'%e['key'])
if key == 'profile__numberoflists': if key == 'user__profile__numberoflists':
qs = qs.annotate(numberoflists=Sum('lists')) qs = qs.annotate(numberoflists=Sum('user__lists'))
key = 'numberoflists' key = 'numberoflists'
order = '%s%s' % (operator, key) order = '%s%s' % (operator, key)
order_by.append(order) order_by.append(order)
if order_by: if order_by:
#user table does not support this qs = qs.order_by(*order_by, nulls_last=True)
#qs = qs.order_by(*order_by, nulls_last=True)
qs = qs.order_by(*order_by)
return qs return qs
@admin_required_json @admin_required_json
@ -499,7 +501,7 @@ Positions
qs = order_query(query['qs'], query['sort']) qs = order_query(query['qs'], query['sort'])
if 'keys' in data: if 'keys' in data:
qs = qs[query['range'][0]:query['range'][1]] qs = qs[query['range'][0]:query['range'][1]]
response['data']['items'] = [models.user_json(p, data['keys'], request.user) for p in qs] response['data']['items'] = [p.json(data['keys'], request.user) for p in qs]
elif 'position' in query: elif 'position' in query:
ids = [i.get_id() for i in qs] ids = [i.get_id() for i in qs]
data['conditions'] = data['conditions'] + { data['conditions'] = data['conditions'] + {

View file

@ -77,9 +77,6 @@ pandora.ui.usersDialog = function() {
title: $('<img>').attr({ title: $('<img>').attr({
src: Ox.UI.getImageURL('symbolCheck') src: Ox.UI.getImageURL('symbolCheck')
}), }),
tooltip: function(data) {
return data.disabled ? 'Enable User' : 'Disable User';
},
visible: true, visible: true,
width: 16 width: 16
}, },
@ -221,10 +218,14 @@ pandora.ui.usersDialog = function() {
$user.empty(); $user.empty();
if (data.ids.length) { if (data.ids.length) {
values = $list.value(data.ids[0]); values = $list.value(data.ids[0]);
$userLabel.options({ if(values.level != 'guest') {
title: values.username + ' &lt;' + values.email + '&gt;' $userLabel.options({
}); title: values.username + ' &lt;' + values.email + '&gt;'
$user.append(renderUserForm(values)) });
$user.append(renderUserForm(values));
} else {
$userLabel.options({title: 'Guest'});
}
} else { } else {
$userLabel.options({title: 'No user selected'}); $userLabel.options({title: 'No user selected'});
} }
@ -269,8 +270,10 @@ pandora.ui.usersDialog = function() {
.addClass('OxSelectable') .addClass('OxSelectable')
.css({margin: '16px'}) .css({margin: '16px'})
.html( .html(
result.data.items.map(function(item) { result.data.items.filter(function(item) {
return item.username + ' &lt;' + item.email + '&gt;' return item.email;
}).map(function(item) {
return item.username + ' &lt;' + item.email + '&gt;';
}).join(', ') }).join(', ')
), ),
title: 'E-Mail Addresses' title: 'E-Mail Addresses'