move oxuser to user

This commit is contained in:
j 2010-10-16 13:58:57 +02:00
commit b6431b70a4
13 changed files with 8 additions and 6 deletions

0
pandora/user/__init__.py Normal file
View file

View file

@ -0,0 +1,92 @@
# -*- coding: utf-8 -*-
from south.db import db
from django.db import models
from oxuser.models import *
class Migration:
def forwards(self, orm):
# Adding model 'Preference'
db.create_table('oxuser_preference', (
('id', orm['oxuser.Preference:id']),
('user', orm['oxuser.Preference:user']),
('created', orm['oxuser.Preference:created']),
('modified', orm['oxuser.Preference:modified']),
('key', orm['oxuser.Preference:key']),
('value', orm['oxuser.Preference:value']),
))
db.send_create_signal('oxuser', ['Preference'])
# Adding model 'UserProfile'
db.create_table('oxuser_userprofile', (
('id', orm['oxuser.UserProfile:id']),
('recover_key', orm['oxuser.UserProfile:recover_key']),
('user', orm['oxuser.UserProfile:user']),
))
db.send_create_signal('oxuser', ['UserProfile'])
def backwards(self, orm):
# Deleting model 'Preference'
db.delete_table('oxuser_preference')
# Deleting model 'UserProfile'
db.delete_table('oxuser_userprofile')
models = {
'auth.group': {
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
},
'auth.permission': {
'Meta': {'unique_together': "(('content_type', 'codename'),)"},
'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
},
'auth.user': {
'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True', 'blank': 'True'}),
'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
},
'contenttypes.contenttype': {
'Meta': {'unique_together': "(('app_label', 'model'),)", 'db_table': "'django_content_type'"},
'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
},
'oxuser.preference': {
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'key': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
'modified': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'preferences'", 'to': "orm['auth.User']"}),
'value': ('django.db.models.fields.TextField', [], {'blank': 'True'})
},
'oxuser.userprofile': {
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'recover_key': ('django.db.models.fields.TextField', [], {}),
'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'unique': 'True'})
}
}
complete_apps = ['oxuser']

View file

@ -0,0 +1,74 @@
# -*- coding: utf-8 -*-
from south.db import db
from django.db import models
from oxuser.models import *
class Migration:
def forwards(self, orm):
# Adding field 'UserProfile.files_updated'
db.add_column('oxuser_userprofile', 'files_updated', orm['oxuser.userprofile:files_updated'])
def backwards(self, orm):
# Deleting field 'UserProfile.files_updated'
db.delete_column('oxuser_userprofile', 'files_updated')
models = {
'auth.group': {
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
},
'auth.permission': {
'Meta': {'unique_together': "(('content_type', 'codename'),)"},
'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
},
'auth.user': {
'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True', 'blank': 'True'}),
'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
},
'contenttypes.contenttype': {
'Meta': {'unique_together': "(('app_label', 'model'),)", 'db_table': "'django_content_type'"},
'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
},
'oxuser.preference': {
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'key': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
'modified': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'preferences'", 'to': "orm['auth.User']"}),
'value': ('django.db.models.fields.TextField', [], {'blank': 'True'})
},
'oxuser.userprofile': {
'files_updated': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'recover_key': ('django.db.models.fields.TextField', [], {}),
'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'unique': 'True'})
}
}
complete_apps = ['oxuser']

View file

93
pandora/user/models.py Normal file
View file

@ -0,0 +1,93 @@
# -*- coding: utf-8 -*-
# vi:si:et:sw=4:sts=4:ts=4
from django.contrib.auth.models import User
from django.db import models
from django.db.models import signals
from django.dispatch import dispatcher
from django.utils import simplejson as json
from datetime import datetime
class UserProfile(models.Model):
recover_key = models.TextField()
user = models.ForeignKey(User, unique=True)
files_updated = models.DateTimeField(default=datetime.now)
def user_post_save(sender, instance, **kwargs):
profile, new = UserProfile.objects.get_or_create(user=instance)
models.signals.post_save.connect(user_post_save, sender=User)
class Preference(models.Model):
user = models.ForeignKey(User, related_name='preferences')
created = models.DateTimeField(auto_now_add=True)
modified = models.DateTimeField(auto_now=True)
key = models.CharField(blank=True, max_length=255)
value = models.TextField(blank=True)
def getUserJSON(user):
json = {}
for key in ('username', ):
json[key] = getattr(user, key)
json['group'] = 'user'
if user.is_staff:
json['group'] = 'admin'
elif user.has_perm('0x.vip'): #FIXME: permissions
json['group'] = 'vip'
json['preferences'] = getPreferences(user)
json['ui'] = getUI(user)
return json
def getUI(user):
return {
"columns": ["id", "title", "director", "country", "year", "language", "genre"],
"findQuery": {"conditions": [{"key": "", "value": "", "operator": ""}], "operator": ""},
"groupsQuery": {"conditions": [], "operator": "|"},
"groupsSize": 128,
"itemView": "info",
"listQuery": {"conditions": [], "operator": ""},
"listsSize": 192,
"listView": "list",
"sections": ["history", "lists", "public", "featured"],
"showGroups": True,
"showInfo": True,
"showLists": True,
"showMovies": True,
"sort": [
{"key": "director", "operator": ""}
],
"theme": "classic"
}
def getPreferences(user):
prefs = {}
for p in Preference.objects.filter(user=user):
prefs[p.key] = json.loads(p.value)
prefs['email'] = user.email
return prefs
def getPreference(user, key, value=None):
if key in ('email', ):
value = getattr(user, key)
else:
q = Preference.objects.filter(user=user, key=key)
if q.count() > 0:
value = json.loads(q[0].value)
return value
def setPreference(user, key, value):
if key in ('email', ):
setattr(user, key, value)
user.save()
else:
value = json.dumps(value)
q = Preference.objects.filter(user=user, key=key)
if q.count() > 0:
p = q[0]
p.value = value
p.save()
else:
p = Preference(user=user, key=key, value=value)
p.save()

View file

@ -0,0 +1,4 @@
Hi {{sitename}} admin,
someone sent you a message:
{{message}}

View file

@ -0,0 +1,10 @@
Somebody requested a new password for your {{sitename}} account.
If it is you, and if you forgot your password, you can login
by clicking the following url:
{{recover_url}}
If you did not request a password, you can safely ignore this e-mail.
{{sitename}}

23
pandora/user/tests.py Normal file
View file

@ -0,0 +1,23 @@
"""
This file demonstrates two different styles of tests (one doctest and one
unittest). These will both pass when you run "manage.py test".
Replace these with more appropriate tests for your application.
"""
from django.test import TestCase
class SimpleTest(TestCase):
def test_basic_addition(self):
"""
Tests that 1 + 1 always equals 2.
"""
self.failUnlessEqual(1 + 1, 2)
__test__ = {"doctest": """
Another way to test that 1 + 1 is equal to 2.
>>> 1 + 1 == 2
True
"""}

14
pandora/user/urls.py Normal file
View file

@ -0,0 +1,14 @@
# -*- coding: utf-8 -*-
# vi:si:et:sw=4:sts=4:ts=4
from django.conf.urls.defaults import *
urlpatterns = patterns("user.views",
(r'^preferences', 'api_preferences'),
(r'^login', 'api_login'),
(r'^logout', 'api_logout'),
(r'^register', 'api_register'),
(r'^recover', 'api_recover'),
)

247
pandora/user/views.py Normal file
View file

@ -0,0 +1,247 @@
# -*- coding: utf-8 -*-
# vi:si:et:sw=4:sts=4:ts=4
import uuid
import hashlib
from django import forms
from django.contrib.auth.models import User
from django.contrib.auth import authenticate, login, logout
from django.shortcuts import render_to_response, get_object_or_404, get_list_or_404, redirect
from django.template import RequestContext, loader, Context
from django.utils import simplejson as json
from django.conf import settings
from django.core.mail import send_mail, BadHeaderError
from oxdjango.shortcuts import render_to_json_response, json_response
from oxdjango.decorators import login_required_json
import models
def json_errors(form):
return {'status': {'code': 402, 'text': 'form error', 'data': form.errors}}
class LoginForm(forms.Form):
username = forms.TextInput()
password = forms.TextInput()
def api_login(request):
'''
param data
{'username': username, 'password': password}
return {'status': {'code': int, 'text': string}}
'''
response = json_response(status=403, text='login failed')
data = json.loads(request.POST['data'])
form = LoginForm(data, request.FILES)
if form.is_valid():
user = authenticate(username=data['username'], password=data['password'])
if user is not None:
if user.is_active:
login(request, user)
user_json = models.getUserJSON(user)
response = json_response({'user': user_json},
text='You are logged in.')
else:
response = json_response(status=401,
text='Your account is disabled.')
else:
errors = json_errors(form)
response = json_response(errors,
status=401, text='Your username and password were incorrect.')
else:
response = json_response(status=400, text='invalid data')
return render_to_json_response(response)
def api_logout(request):
'''
param data
{}
return {'status': {'code': int, 'text': string}}
'''
response = json_response(text='logged out')
if request.user.is_authenticated():
logout(request)
return render_to_json_response(response)
class RegisterForm(forms.Form):
username = forms.TextInput()
password = forms.TextInput()
email = forms.TextInput()
def api_register(request):
'''
param data
{'username': username, 'password': password, 'email': email}
return {'status': {'code': int, 'text': string}}
'''
data = json.loads(request.POST['data'])
form = RegisterForm(data, request.FILES)
if form.is_valid():
if models.User.objects.filter(username=form.data['username']).count() > 0:
response = json_response(status=400, text='username or email exists')
elif models.User.objects.filter(email=form.data['email']).count() > 0:
response = json_response(status=400, text='username or email exists')
else:
user = models.User(username=form.data['username'], email=form.data['email'])
user.set_password(form.data['password'])
user.save()
user = authenticate(username=form.data['username'],
password=form.data['password'])
login(request, user)
response = json_response(text='account created')
else:
response = json_response(status=400, text='username exists')
return render_to_json_response(response)
class RecoverForm(forms.Form):
username_or_email = forms.TextInput()
def api_recover(request):
'''
param data
{'username_or_email': username}
return {'status': {'code': int, 'text': string}}
'''
data = json.loads(request.POST['data'])
form = RegisterForm(data, request.FILES)
if form.is_valid():
username = data['username_or_email']
user = None
q = models.User.objects.filter(username=username)
if q.count() > 0:
user = q[0]
else:
q = models.User.objects.filter(email=username)
if q.count() > 0:
user = q[0]
if user:
key = hashlib.sha1(str(uuid.uuid4())).hexdigest()
user_profile = user.get_profile()
user_profile.recover_key = key
user_profile.save()
template = loader.get_template('recover_email.txt')
context = RequestContext(request, {
'recover_url': request.build_absolute_uri("/r/%s" % key),
'sitename': settings.SITENAME,
})
message = template.render(context)
subject = '%s account recovery' % settings.SITENAME
user.email_user(subject, message)
response = json_response(text='recover email sent')
else:
response = json_response(status=404, text='username or email not found')
else:
response = json_response(status=400, text='invalid data')
return render_to_json_response(response)
def api_findUser(request):
'''
param data
{key: "username", value: "foo", operator: "="}
return {
'status': {'code': int, 'text': string}
'data': {
users = ['user1', 'user2']
}
}
'''
#FIXME: support other operators and keys
data = json.loads(request.POST['data'])
response = json_response(status=200, text='ok')
response['data']['users'] = [u.username for u in User.objects.filter(username__iexact=data['value'])]
return render_to_json_response(response)
def recover(request, key):
qs = models.UserProfile.objects.filter(recover_key=key)
if qs.count() == 1:
user = qs[0].user
user.set_password(key)
user.save()
user_profile = user.get_profile()
user_profile.recover_key = ''
user_profile.save()
user = authenticate(username=user.username, password=key)
login(request, user)
#FIXME: set message to notify user to update password
return redirect('/#settings')
return redirect('/')
class ContactForm(forms.Form):
email = forms.EmailField()
subject = forms.TextInput()
message = forms.TextInput()
def api_contact(request):
'''
param data
{'email': string, 'message': string}
return {'status': {'code': int, 'text': string}}
'''
data = json.loads(request.POST['data'])
form = ContactForm(data, request.FILES)
if form.is_valid():
email = data['email']
template = loader.get_template('contact_email.txt')
context = RequestContext(request, {
'sitename': settings.SITENAME,
'email': email,
'message': data['message'],
})
message = template.render(context)
subject = '%s contact: %s' % (settings.SITENAME, data['subject'])
response = json_response(text='message sent')
try:
send_mail(subject, message, email, [settings.DEFAULT_FROM_EMAIL, ])
except BadHeaderError:
response = json_response(status=400, text='invalid data')
else:
response = json_response(status=400, text='invalid data')
return render_to_json_response(response)
@login_required_json
def api_preferences(request):
'''
param data
string
array
object
return
if data is empy or {}
if data is string:
return preference with name
if data is array:
return preferences with names
if data is object:
set key values in dict as preferences
'''
response = json_response()
if 'data' not in request.POST:
response['data']['preferences'] = models.getPreferences(request.user)
else:
data = json.loads(request.POST['data'])
if isinstance(data, basestring):
response['data']['preferences'] = {}
response['data']['preferences'][data] = models.getPreference(request.user, data)
elif isinstance(data, list):
response['data']['preferences'] = {}
for preference in data:
response['preferences'][preference] = models.getPreference(request.user, preference)
elif isinstance(data, dict):
if not data:
response['data']['preferences'] = models.getPreferences(request.user)
else:
del response['data']
for key in data:
models.setPreference(request.user, key, data[key])
return render_to_json_response(response)