summaryrefslogtreecommitdiff
path: root/project/kiwipycon/user
diff options
context:
space:
mode:
Diffstat (limited to 'project/kiwipycon/user')
-rw-r--r--project/kiwipycon/user/__init__.py0
-rw-r--r--project/kiwipycon/user/admin.py17
-rw-r--r--project/kiwipycon/user/forms.py135
-rw-r--r--project/kiwipycon/user/migrations/0001_initial.py44
-rw-r--r--project/kiwipycon/user/migrations/__init__.py0
-rw-r--r--project/kiwipycon/user/models.py36
-rw-r--r--project/kiwipycon/user/utils.py122
-rw-r--r--project/kiwipycon/user/views.py238
8 files changed, 592 insertions, 0 deletions
diff --git a/project/kiwipycon/user/__init__.py b/project/kiwipycon/user/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/project/kiwipycon/user/__init__.py
diff --git a/project/kiwipycon/user/admin.py b/project/kiwipycon/user/admin.py
new file mode 100644
index 0000000..c72a5b5
--- /dev/null
+++ b/project/kiwipycon/user/admin.py
@@ -0,0 +1,17 @@
+# -*- coding: utf-8 -*-
+from __future__ import absolute_import
+
+#django
+from django.contrib import admin
+
+#kiwipycon
+from .models import UserProfile
+
+class UserProfileAdmin(admin.ModelAdmin):
+ list_display = ('user', 'email', 'url', 'about')
+
+ def email(self, obj):
+ return obj.user.email
+
+admin.site.register(UserProfile, UserProfileAdmin)
+
diff --git a/project/kiwipycon/user/forms.py b/project/kiwipycon/user/forms.py
new file mode 100644
index 0000000..46ad2f6
--- /dev/null
+++ b/project/kiwipycon/user/forms.py
@@ -0,0 +1,135 @@
+# -*- coding: utf-8 -*-
+from __future__ import absolute_import
+
+#django
+from django import forms
+from django.contrib.auth.models import User
+
+class RegistrantForm(forms.Form):
+ """Form to register an attendee
+ """
+ username = forms.RegexField(label="Nickname", max_length=30,
+ regex=r'^\w+$',
+ help_text = "30 characters or fewer. Alphanumeric" \
+ + " characters only (letters, digits and underscores).",
+ error_message = "This value must contain only letters, numbers and underscores.")
+ name = forms.CharField(label=u"Name", max_length=50, required=True)
+ email = forms.EmailField(label=u"E-mail", max_length=50, required=True)
+
+ def clean_email(self):
+ """Validates that the entered e-mail is unique.
+ """
+ email = self.cleaned_data.get("email")
+ if email and User.objects.filter(email=email).count() > 0:
+ raise forms.ValidationError(
+ u"That email address is already in use. Are you a member of " \
+ "site? Please log in.")
+
+ return email
+
+ def clean_username(self):
+ """Validates that the entered username is unique.
+ """
+ username = self.cleaned_data.get("username")
+ if username and User.objects.filter(username=username).count() > 0:
+ raise forms.ValidationError(
+ u"That username is already in use.")
+
+ return username
+
+class RegisterForm(forms.Form):
+ """Form to register speaker
+ """
+ username = forms.RegexField(label="Username", max_length=30,
+ regex=r'^\w+$',
+ help_text = "Required. 30 characters or fewer. Alphanumeric" \
+ + " characters only (letters, digits and underscores).",
+ error_message = "This value must contain only letters, numbers and underscores.")
+ first_name = forms.CharField(label=u"First name", max_length=50)
+ last_name = forms.CharField(label=u"Last name", max_length=50)
+ email = forms.EmailField(label=u"E-mail", max_length=50)
+ url = forms.URLField(required=False)
+ about = forms.CharField(label=u'Short Bio', max_length=50, required=False)
+ photo = forms.FileField(label=u'Profile Photo', required=False)
+ password_1 = forms.CharField(
+ label=u"Password", widget=forms.PasswordInput(), max_length=20)
+ password_2 = forms.CharField(
+ label=u"Confirm password", widget=forms.PasswordInput(), max_length=20)
+
+ def clean_password_2(self):
+ """Validates that password 1 and password 2 are the same.
+ """
+ p1 = self.cleaned_data.get('password_1')
+ p2 = self.cleaned_data.get('password_2')
+
+ if not (p1 and p2 and p1 == p2):
+ raise forms.ValidationError(u"The two passwords do not match.")
+
+ return p2
+
+ def clean_email(self):
+ """Validates that the entered e-mail is unique.
+ """
+ email = self.cleaned_data.get("email")
+ if email and User.objects.filter(email=email).count() > 0:
+ raise forms.ValidationError(
+ u"That email address is already in use.")
+
+ return email
+
+ def clean_username(self):
+ """Validates that the entered username is unique.
+ """
+ username = self.cleaned_data.get("username")
+ if username and User.objects.filter(username=username).count() > 0:
+ raise forms.ValidationError(
+ u"That username is already in use.")
+
+ return username
+
+class EditProfileForm(forms.Form):
+ """Edit user profile form
+ """
+ first_name = forms.CharField(max_length=50)
+ last_name = forms.CharField(max_length=50)
+ email = forms.EmailField(max_length=50)
+ email2 = forms.CharField(widget=forms.HiddenInput)
+ url = forms.URLField(required=False)
+ about = forms.CharField(label=u'Short Bio',
+ widget=forms.Textarea, required=False)
+ photo = forms.FileField(label=u'Profile Photo',
+ required=False)
+
+ def clean_email(self):
+ """Validates that the entered e-mail is unique.
+ """
+ email = self.cleaned_data.get("email")
+ email2 = self.data.get("email2").strip()
+ print email, email2
+ if email != email2: # email has been changed
+ if email and User.objects.filter(email=email).count() > 0:
+ raise forms.ValidationError(
+ u"That email address is already in use.")
+
+ return email
+
+class UsernameForm(forms.Form):
+ """Form to edit email address
+ """
+ username = forms.RegexField(label="Username", max_length=30,
+ regex=r'^\w+$',
+ help_text = "Required. 30 characters or fewer. Alphanumeric" \
+ + " characters only (letters, digits and underscores).",
+ error_message = "This value must contain only letters, numbers and underscores.")
+
+ def clean_username(self):
+ """Validates that the entered username is unique.
+ """
+ username = self.cleaned_data.get("username")
+ if username and User.objects.filter(username=username).count() > 0:
+ raise forms.ValidationError(
+ u"That username is already in use.")
+
+ return username
+
+
diff --git a/project/kiwipycon/user/migrations/0001_initial.py b/project/kiwipycon/user/migrations/0001_initial.py
new file mode 100644
index 0000000..8cb8788
--- /dev/null
+++ b/project/kiwipycon/user/migrations/0001_initial.py
@@ -0,0 +1,44 @@
+# -*- coding: utf-8 -*-
+
+from south.db import db
+from django.db import models
+from project.kiwipycon.user.models import *
+
+class Migration:
+
+ def forwards(self, orm):
+
+ # Adding model 'UserProfile'
+ db.create_table('user_userprofile', (
+ ('id', models.AutoField(primary_key=True)),
+ ('user', models.ForeignKey(orm['auth.User'], unique=True)),
+ ('url', models.URLField(verify_exists=False, blank=True)),
+ ('photo', models.CharField(max_length=64, blank=True)),
+ ('about', models.TextField(blank=True)),
+ ))
+ db.send_create_signal('user', ['UserProfile'])
+
+
+
+ def backwards(self, orm):
+
+ # Deleting model 'UserProfile'
+ db.delete_table('user_userprofile')
+
+
+
+ models = {
+ 'auth.user': {
+ '_stub': True,
+ 'id': ('models.AutoField', [], {'primary_key': 'True'})
+ },
+ 'user.userprofile': {
+ 'about': ('models.TextField', [], {'blank': 'True'}),
+ 'id': ('models.AutoField', [], {'primary_key': 'True'}),
+ 'photo': ('models.CharField', [], {'max_length': '64', 'blank': 'True'}),
+ 'url': ('models.URLField', [], {'verify_exists': 'False', 'blank': 'True'}),
+ 'user': ('models.ForeignKey', ['User'], {'unique': 'True'})
+ }
+ }
+
+ complete_apps = ['user']
diff --git a/project/kiwipycon/user/migrations/__init__.py b/project/kiwipycon/user/migrations/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/project/kiwipycon/user/migrations/__init__.py
diff --git a/project/kiwipycon/user/models.py b/project/kiwipycon/user/models.py
new file mode 100644
index 0000000..85cf762
--- /dev/null
+++ b/project/kiwipycon/user/models.py
@@ -0,0 +1,36 @@
+# -*- coding: utf-8 -*-
+from __future__ import absolute_import
+
+#django
+from django.db import models
+from django.conf import settings
+from django.db.models.signals import post_save
+from django.contrib.auth.models import User
+
+class UserProfile(models.Model):
+ """
+ Extend atributes for django User
+ """
+ user = models.ForeignKey(User, unique=True)
+ url = models.URLField(blank=True, verify_exists=False)
+ photo = models.CharField(max_length=64, blank=True)
+ about = models.TextField(blank=True)
+
+ def __unicode__(self):
+ return 'UserProfile for user: <%s %s> %s' % (self.user.first_name,
+ self.user.last_name, self.user.email)
+
+ def fullname(self):
+ return '%s %s' % (self.user.first_name, self.user.last_name)
+
+def add_profile(sender, instance, signal, *args, **kwargs):
+ """Create user profile on create of new user"""
+ if not instance.is_superuser:
+ try:
+ profile, new = UserProfile.objects.get_or_create(user=instance)
+ if new:
+ profile.save()
+ except:
+ pass
+
+post_save.connect(add_profile, sender=User, weak=False)
diff --git a/project/kiwipycon/user/utils.py b/project/kiwipycon/user/utils.py
new file mode 100644
index 0000000..b912a7b
--- /dev/null
+++ b/project/kiwipycon/user/utils.py
@@ -0,0 +1,122 @@
+# -*- coding: utf-8 -*-
+from __future__ import absolute_import
+
+#python imports
+import os
+
+#django
+from django.conf import settings
+from django.core.exceptions import ObjectDoesNotExist
+
+#django.contrib
+from django.contrib.auth.models import User
+
+#PIL
+from PIL import Image
+
+
+def kiwipycon_createregistrant(request, data):
+ """Create user"""
+ email = data.get("email")
+ name = data.get("name")
+ username = data.get("username")
+
+ n = name.split(" ")
+ if len(n) > 1:
+ first_name = ' '.join(n[:-1])
+ last_name = n[-1]
+ else:
+ first_name = ''
+ last_name = n[0]
+
+
+ # Create user
+ user = User.objects.create_user(username=username, email=email)
+ user.first_name = first_name
+ user.last_name = last_name
+ user.save()
+
+ return user
+
+def kiwipycon_createuser(request, data):
+ """Create user"""
+ email = data.get("email")
+ username = data.get("username")
+ password = data.get("password_1")
+ password = data.get("password_1")
+
+ # Create user
+ user = User.objects.create_user(
+ username=username, email=email, password=password)
+ user.first_name = data.get("first_name")
+ user.last_name = data.get("last_name")
+ user.save()
+
+ # Log in user
+ from django.contrib.auth import authenticate
+ user = authenticate(username=username, password=password)
+
+ from django.contrib.auth import login
+ login(request, user)
+
+ profile = user.get_profile()
+ photo = request.FILES.get('photo', None)
+ filename= None
+ if photo:
+ filename = handle_uploaded_photo(user, request.FILES['photo'])
+ if filename:
+ profile.photo = filename
+ print photo, filename
+
+ profile.url = data.get("url")
+ profile.about = data.get("about")
+ profile.save()
+
+ return user
+
+def handle_uploaded_photo(user, ufile):
+ usermedia = settings.USER_MEDIA_ROOT
+ filename = ufile.name
+ ext = filename.split('.')[-1]
+ filesize = ufile.size
+ filecontent = ufile.read()
+ userfilename = 'user-%d.%s' % (user.id, ext)
+ if not filecontent:
+ return None
+
+ #save
+ foutname = os.path.join(usermedia, userfilename)
+
+ fout = file(foutname, 'wb')
+ fout.write(filecontent)
+ fout.close()
+
+ # crop and resize
+ image = Image.open(foutname)
+ pw = image.size[0]
+ ph = image.size[1]
+ nw = nh = 80
+ if (pw, ph) != (nw, nh):
+ pr = float(pw) / float(ph)
+ nr = float(nw) / float(nh)
+
+ if pr > nr:
+ # photo aspect is wider than destination ratio
+ tw = int(round(nh * pr))
+ image = image.resize((tw, nh), Image.ANTIALIAS)
+ l = int(round(( tw - nw ) / 2.0))
+ image = image.crop((l, 0, l + nw, nh))
+ elif pr < nr:
+ # photo aspect is taller than destination ratio
+ th = int(round(nw / pr))
+ image = image.resize((nw, th), Image.ANTIALIAS)
+ t = int(round(( th - nh ) / 2.0))
+ print((0, t, nw, t + nh))
+ image = image.crop((0, t, nw, t + nh))
+ else:
+ # photo aspect matches the destination ratio
+ image = image.resize((nw, nh), Image.ANTIALIAS)
+
+ image.save(str(foutname))
+ return userfilename
+
diff --git a/project/kiwipycon/user/views.py b/project/kiwipycon/user/views.py
new file mode 100644
index 0000000..e9a0454
--- /dev/null
+++ b/project/kiwipycon/user/views.py
@@ -0,0 +1,238 @@
+# -*- coding: utf-8 -*-
+from __future__ import absolute_import
+#python
+from urlparse import urlparse
+import urllib
+import os
+
+#django
+from django.conf import settings
+from django.shortcuts import render_to_response
+from django.template import RequestContext
+from django.core.urlresolvers import reverse
+from django.db.models.signals import post_save
+
+#django.contrib
+from django.contrib.auth.decorators import login_required
+from django.contrib.auth.forms import AuthenticationForm
+from django.contrib.auth.forms import PasswordChangeForm
+from django.core.exceptions import ObjectDoesNotExist
+
+#PIL
+from PIL import Image
+
+#kiwipycon
+from project.kiwipycon.utils import set_message_cookie
+from project.kiwipycon.talk.models import Talk
+from project.kiwipycon.registration.models import Registration
+from project.kiwipycon.registration.models import Wifi
+from project.kiwipycon.registration.forms import WifiForm
+from project.kiwipycon.sponsor.models import Sponsor
+
+from .utils import kiwipycon_createuser
+from .utils import handle_uploaded_photo
+from .forms import RegisterForm
+from .forms import EditProfileForm
+from .forms import UsernameForm
+
+@login_required
+def account(request, template_name="user/account.html"):
+ """Displays the main screen of the current user's account.
+ """
+ user = request.user
+ profile = user.get_profile()
+
+ talks = Talk.objects.filter(speaker=user)
+ try:
+ registration = Registration.objects.get(registrant=user)
+ except ObjectDoesNotExist:
+ registration = None
+ try:
+ wifiobj = Wifi.objects.get(user=user)
+ except ObjectDoesNotExist:
+ wifiobj = None
+
+ if profile.photo:
+ photo = os.path.join(settings.USER_MEDIA_URL, profile.photo)
+ else:
+ photo = '/img/user-default.png'
+
+ qstring = ""
+
+ wifi_comment = None
+ if wifiobj:
+ wifi_form = False
+ else:
+ if request.method == "POST":
+ wifi_form = WifiForm(request.POST)
+ if wifi_form.is_valid():
+ wifi_form.save(user)
+ wifi_comment = 'Thanks, your wifi preference has been saved'
+ wifi_form = None
+ else:
+ wifi_form = WifiForm()
+
+ return render_to_response(template_name, RequestContext(request, {
+ "form" : wifi_form, "comment": wifi_comment,
+ "user" : user, "profile" : profile, "photo" : photo,
+ "talks" : talks, "registration" : registration,
+ }))
+
+@login_required
+def edit_profile(request, template_name="user/editprofile.html"):
+ """Allows user to edit profile
+ """
+ user = request.user
+ profile = user.get_profile()
+
+ if request.method == "POST":
+ form = EditProfileForm(data=request.POST,
+ files=request.FILES)
+
+ if form.is_valid():
+ photo = request.FILES.get('photo', None)
+ filename= None
+ if photo:
+ filename = handle_uploaded_photo(user, request.FILES['photo'])
+ if filename:
+ profile.photo = filename
+
+ user.email = form.data.get("email")
+ user.first_name = form.data.get("first_name")
+ user.last_name = form.data.get("last_name")
+ user.save()
+
+ profile.url = form.data.get("url")
+ profile.about = form.data.get("about")
+ profile.save()
+
+ redirect_to = reverse("kiwipycon_account")
+ return set_message_cookie(redirect_to,
+ msg = u"Your profile has been changed.")
+
+ else:
+ form = EditProfileForm(initial={"email" : user.email,
+ "email2" : user.email, # hidden field
+ "first_name" : user.first_name,
+ "last_name" : user.last_name,
+ "url" : profile.url,
+ "about" : profile.about,
+ })
+
+ return render_to_response(template_name, RequestContext(request, {
+ "form": form
+ }))
+
+def login(request, template_name="user/login.html"):
+ """Custom view to login or register/login a user.
+ Integration of register and login form
+ It uses Django's standard AuthenticationForm, though.
+ """
+ user = request.user
+ if user.is_authenticated():
+ redirect_to = reverse("kiwipycon_account")
+ return set_message_cookie(redirect_to,
+ msg = u"Redirected to account from login form.")
+
+ # Using Djangos default AuthenticationForm
+ login_form = AuthenticationForm()
+ register_form = RegisterForm()
+
+ if request.POST.get("action") == "login":
+ login_form = AuthenticationForm(data=request.POST)
+
+ if login_form.is_valid():
+ redirect_to = request.POST.get("next")
+ # Light security check -- make sure redirect_to isn't garbage.
+ if not redirect_to or '//' in redirect_to or ' ' in redirect_to:
+ redirect_to = reverse("kiwipycon_account")
+
+ from django.contrib.auth import login
+ login(request, login_form.get_user())
+
+ return set_message_cookie(redirect_to, msg = u"You have been logged in.")
+
+ elif request.POST.get("action") == "register":
+ register_form = RegisterForm(data=request.POST)
+ if register_form.is_valid():
+
+ user = kiwipycon_createuser(request, register_form.data)
+
+ redirect_to = request.POST.get("next")
+ if not redirect_to or '//' in redirect_to or ' ' in redirect_to:
+ redirect_to = reverse("kiwipycon_account")
+
+ return set_message_cookie(
+ redirect_to, msg = u"You have been registered and logged in.")
+
+ # Get next_url
+ next_url = request.REQUEST.get("next")
+ if next_url is None:
+ next_url = request.META.get("HTTP_REFERER")
+ if next_url is None:
+ next_url = reverse("kiwipycon_account")
+ # Get just the path of the url. See django.contrib.auth.views.login for more
+ next_url = urlparse(next_url)
+ next_url = next_url[2]
+
+ try:
+ login_form_errors = login_form.errors["__all__"]
+ except KeyError:
+ login_form_errors = None
+
+ return render_to_response(template_name, RequestContext(request, {
+ "login_form" : login_form,
+ "login_form_errors" : login_form_errors,
+ "register_form" : register_form,
+ "next_url" : next_url,
+ }))
+
+def logout(request):
+ """Custom method to logout a user.
+
+ The reason to use a custom logout method is just to provide a login and a
+ logoutmethod on one place.
+ """
+ from django.contrib.auth import logout
+ logout(request)
+
+ redirect_to = '/'
+ return set_message_cookie(redirect_to, msg = u"You have been logged out.")
+
+@login_required
+def password(request, template_name="user/password.html"):
+ """Changes the password of current user.
+ """
+ if request.method == "POST":
+ form = PasswordChangeForm(request.user, request.POST)
+ if form.is_valid():
+ form.save()
+ redirect_to = reverse("kiwipycon_account")
+ return set_message_cookie(redirect_to,
+ msg = u"Your password has been changed.")
+ else:
+ form = PasswordChangeForm(request.user)
+
+ return render_to_response(template_name, RequestContext(request, {
+ "form" : form
+ }))
+
+@login_required
+def username(request, template_name="user/username.html"):
+ """Saves the username from the data form.
+ """
+ if request.method == "POST":
+ username_form = UsernameForm(initial={"username" : request.user.username}, data=request.POST)
+ if username_form.is_valid():
+ request.user.username = username_form.cleaned_data.get("username")
+ request.user.save()
+ redirect_to = reverse("kiwipycon_account")
+ return set_message_cookie(redirect_to,
+ msg = u"Your username has been changed.")
+ else:
+ username_form = UsernameForm(initial={"username" : request.user.username})
+
+ return render_to_response(template_name, RequestContext(request, {
+ "form": username_form
+ }))
+