summaryrefslogtreecommitdiff
path: root/project/scipycon/user
diff options
context:
space:
mode:
Diffstat (limited to 'project/scipycon/user')
-rw-r--r--project/scipycon/user/__init__.py0
-rw-r--r--project/scipycon/user/admin.py17
-rw-r--r--project/scipycon/user/forms.py135
-rw-r--r--project/scipycon/user/models.py26
-rw-r--r--project/scipycon/user/utils.py138
-rw-r--r--project/scipycon/user/views.py386
6 files changed, 702 insertions, 0 deletions
diff --git a/project/scipycon/user/__init__.py b/project/scipycon/user/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/project/scipycon/user/__init__.py
diff --git a/project/scipycon/user/admin.py b/project/scipycon/user/admin.py
new file mode 100644
index 0000000..3d4813b
--- /dev/null
+++ b/project/scipycon/user/admin.py
@@ -0,0 +1,17 @@
+# -*- coding: utf-8 -*-
+from __future__ import absolute_import
+
+#django
+from django.contrib import admin
+
+#scipycon
+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/scipycon/user/forms.py b/project/scipycon/user/forms.py
new file mode 100644
index 0000000..46ad2f6
--- /dev/null
+++ b/project/scipycon/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/scipycon/user/models.py b/project/scipycon/user/models.py
new file mode 100644
index 0000000..4688b79
--- /dev/null
+++ b/project/scipycon/user/models.py
@@ -0,0 +1,26 @@
+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
+
+from project.scipycon.base import models as base_models
+
+
+class UserProfile(base_models.ScopedBase):
+ """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)
diff --git a/project/scipycon/user/utils.py b/project/scipycon/user/utils.py
new file mode 100644
index 0000000..f4b4741
--- /dev/null
+++ b/project/scipycon/user/utils.py
@@ -0,0 +1,138 @@
+import os
+
+from django.conf import settings
+from django.core.exceptions import ObjectDoesNotExist
+from django.contrib.auth.models import User
+
+from PIL import Image
+
+from project.scipycon.base.models import Event
+from project.scipycon.user.models import UserProfile
+
+
+def scipycon_createregistrant(request, data, scope):
+ """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()
+
+ scope_entity = Event.objects.get(scope=scope)
+ try:
+ profile = user.get_profile()
+ except:
+ profile, new = UserProfile.objects.get_or_create(
+ user=user, scope=scope_entity)
+ profile.save()
+
+ return user
+
+def scipycon_createuser(request, data, scope):
+ """Create user
+ """
+
+ from django.contrib.auth import authenticate
+ from django.contrib.auth import login
+
+ 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
+
+ user = authenticate(username=username, password=password)
+
+ login(request, user)
+
+ scope_entity = Event.objects.get(scope=scope)
+
+ try:
+ profile = user.get_profile()
+ except:
+ profile, new = UserProfile.objects.get_or_create(
+ user=user, scope=scope_entity)
+
+ photo = request.FILES.get('photo', None)
+ filename= None
+ if photo:
+ filename = handle_uploaded_photo(user, request.FILES['photo'])
+ if filename:
+ profile.photo = filename
+
+ profile.url = data.get('url')
+ profile.about = data.get('about')
+ profile.save()
+
+ return user
+
+def handle_uploaded_photo(user, ufile):
+ """Handles the upload and gives the file path to be saved.
+ """
+
+ usermedia = settings.USER_MEDIA_ROOT
+ filename = ufile.name
+ ext = filename.split('.')[-1]
+
+ 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))
+ 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/scipycon/user/views.py b/project/scipycon/user/views.py
new file mode 100644
index 0000000..d46e77d
--- /dev/null
+++ b/project/scipycon/user/views.py
@@ -0,0 +1,386 @@
+from urlparse import urlparse
+
+import simplejson as json
+import os
+
+from django.conf import settings
+from django.contrib.auth.decorators import login_required
+from django.contrib.auth.forms import AuthenticationForm
+from django.contrib.auth.forms import PasswordChangeForm
+from django.contrib.auth.models import User
+from django.core.exceptions import ObjectDoesNotExist
+from django.core.urlresolvers import reverse
+from django.db.models import Q
+from django.http import HttpResponse
+from django.shortcuts import render_to_response
+from django.template import RequestContext
+
+from PIL import Image
+
+from project.scipycon.base.models import Event
+from project.scipycon.registration.models import Registration
+from project.scipycon.registration.models import Wifi
+from project.scipycon.registration.forms import WifiForm
+from project.scipycon.talk.models import Talk
+from project.scipycon.user.forms import EditProfileForm
+from project.scipycon.user.forms import RegisterForm
+from project.scipycon.user.forms import UsernameForm
+from project.scipycon.user.utils import handle_uploaded_photo
+from project.scipycon.user.utils import scipycon_createuser
+from project.scipycon.utils import set_message_cookie
+
+#User_dump Http404 Error
+from django.http import Http404
+#for user_dump creation
+from project.scipycon.registration.models import Accommodation
+
+#Pdf badge generation
+from reportlab.pdfgen import canvas
+from reportlab.lib.units import cm
+from reportlab.platypus import Image as reportlabImage
+from django.core.exceptions import ObjectDoesNotExist
+
+
+@login_required
+def account(request, scope, 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
+
+ event = Event.objects.get(scope=scope)
+
+ if profile.photo:
+ photo = os.path.join(settings.USER_MEDIA_URL, profile.photo)
+ else:
+ photo = '/img/user-default.png'
+
+ return render_to_response(template_name, RequestContext(request, {
+ 'params': {'scope': scope},
+ 'user' : user,
+ 'profile' : profile,
+ 'photo' : photo,
+ 'talks' : talks,
+ 'registration' : registration,
+ 'event': event}))
+
+@login_required
+def edit_profile(request, scope, 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('scipycon_account',
+ kwargs={'scope': scope})
+ 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, {
+ 'params': {'scope': scope},
+ 'form': form
+ }))
+
+def login(request, scope, 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("scipycon_account", kwargs={'scope': scope})
+ 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('scipycon_account',
+ kwargs={'scope': scope})
+
+ 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 = scipycon_createuser(request, register_form.data, scope)
+
+ redirect_to = request.POST.get("next")
+ if not redirect_to or '//' in redirect_to or ' ' in redirect_to:
+ redirect_to = reverse('scipycon_account',
+ kwargs={'scope': scope})
+
+ 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('scipycon_account', kwargs={'scope': scope})
+
+ # 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, {
+ 'params': {'scope': scope},
+ 'login_form' : login_form,
+ 'login_form_errors' : login_form_errors,
+ 'register_form' : register_form,
+ 'next_url' : next_url,
+ }))
+
+def logout(request, scope):
+ """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 = '/%s' % (scope)
+ return set_message_cookie(redirect_to, msg = u"You have been logged out.")
+
+@login_required
+def password(request, scope, 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('scipycon_account', kwargs={'scope': scope})
+ 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, {
+ 'params': {'scope': scope},
+ 'form' : form
+ }))
+
+@login_required
+def username(request, scope, 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('scipycon_account',
+ kwargs={'scope': scope})
+ 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, {
+ 'params': {'scope': scope},
+ 'form': username_form
+ }))
+
+
+def get_usernames(request, scope):
+ """Returns in json the list of ten possible usernames
+ starting with the last pattern in the comma separated string
+ """
+
+ get_params = request.GET
+ authors_str = get_params.get('input')
+
+ if not authors_str:
+ return HttpResponse(json.dumps(''))
+
+ authors = authors_str.split(',')
+ search_author = authors[-1].strip()
+
+ users = User.objects.filter(
+ Q(username__istartswith=search_author) | Q(
+ first_name__istartswith=search_author) | Q(
+ last_name__istartswith=search_author))
+
+ results = [{'id': '',
+ 'info': 'plugin_header',
+ 'value': 'User Names'
+ }]
+
+ for user in users:
+ results.append(
+ {'id': 'author_name',
+ 'info': str(user.get_full_name()),
+ 'value': str(user.username)
+ })
+
+ json_response = {'results': results}
+
+ return HttpResponse(json.dumps(json_response))
+
+
+@login_required
+def get_user_dump(request, scope,template_name='user/dump.html'):
+ """ Gets a general dump of user related info
+ """
+ print request.user.is_staff
+ if request.user.is_staff:
+ qs=Registration.objects.all()
+ rows=[]
+ for obj in qs:
+ row = {}
+ row['first_name'] = obj.registrant.first_name
+ row['last_name'] = obj.registrant.last_name
+ try:
+ accomodation_require = Accommodation.objects.filter(user__username=obj.registrant.username)[0]
+ row['sex'] = accomodation_require.sex
+ except:
+ row['sex'] = '-'
+ row['city'] = obj.city
+ row['organization'] = obj.organisation
+ row['occupation'] = obj.occupation
+ row['conference'] = obj.conference
+ row['sprint'] = obj.sprint
+ row['tutorial'] = obj.tutorial
+ try:
+ wifi_require = Wifi.objects.filter(user__username=obj.registrant.username)[0]
+ row['wifi'] = wifi_require.wifi
+ except:
+ row['wifi']='Wifi Unspecified'
+ rows.append(row)
+ return render_to_response(template_name, RequestContext(request, {
+ 'rows': rows}))
+
+
+ else:
+ raise Http404
+
+
+@login_required
+def badge(request,scope):
+
+ from django.conf import settings
+
+ # Create the HttpResponse object with the appropriate PDF headers.
+ response = HttpResponse(mimetype='application/pdf')
+ response['Content-Disposition'] = 'attachment; filename=scipybadge.pdf'
+
+ # Create the PDF object, using the response object as its "file."
+ c = canvas.Canvas(response)
+
+ ref=5*cm
+ # Draw things on the PDF. Here's where the PDF generation happens.
+ # See the ReportLab documentation for the full list of functionality.
+ c.rect(ref,ref,9*cm,6*cm)
+
+ img_path = os.path.join(settings.STATIC_ROOT, 'img', 'scipyshiny_small.png')
+ im = reportlabImage(img_path, width=1.75*cm, height=1.75*cm)
+ im.drawOn(c,(ref+0.8*cm),(ref+4.3*cm))
+ c.setFont('Helvetica', 6)
+ c.drawString((ref+1.0*cm),(ref+4.2*cm),'scipy.in 2010')
+ c.drawString((ref+1.1*cm),(ref+4.0*cm),'Hyderabad')
+
+ c.setFont('Helvetica', 14)
+ print request.user.id
+ reg_obj=Registration.objects.get(registrant=request.user.id)
+ c.drawString((ref+3.4*cm),(ref+4.9*cm),str(reg_obj.slug))
+
+ c.setFont('Helvetica-Bold', 15)
+ c.drawString((ref+0.6*cm),(ref+3.4*cm),str(request.user.get_full_name()))
+ c.setFont('Helvetica', 11)
+ c.drawString((ref+2.8*cm),(ref+2.7*cm),reg_obj.organisation)
+ c.setFont('Helvetica', 11)
+ try:
+ c.drawString((ref+2.8*cm),(ref+2.2*cm),reg_obj.occupation.split(':')[1])
+ except IndexError:
+ c.drawString((ref+2.8*cm),(ref+2.3*cm),reg_obj.occupation)
+
+ c.setFont('Helvetica', 10)
+ c.drawString((ref+2.8*cm),(ref+1.7*cm),reg_obj.city)
+ c.setFont('Helvetica', 10)
+ c.drawString((ref+2.8*cm),(ref+1*cm),'Participant')
+
+
+ try:
+ wifi_obj=Wifi.objects.get(user=request.user.id)
+ c.setFont('Helvetica', 10)
+ c.drawString((ref+5.6*cm),(ref+0.5*cm),wifi_obj.registration_id)
+ except :
+ pass
+
+
+ # Close the PDF object cleanly, and we're done.
+ c.showPage()
+ c.save()
+ return response