Commit 3e13bc798b277823e4bb3ab0992fbb6fa5eb99ec

Authored by Sergio Oliveira
1 parent dab8f064

Refactorign signup process

src/accounts/forms.py
1 # -*- coding: utf-8 -*- 1 # -*- coding: utf-8 -*-
2 2
3 from django import forms 3 from django import forms
4 -from django.contrib.auth.models import User 4 +from django.contrib.auth import get_user_model
5 from django.contrib.auth.forms import UserCreationForm as UserCreationForm_ 5 from django.contrib.auth.forms import UserCreationForm as UserCreationForm_
6 from django.utils.translation import ugettext_lazy as _ 6 from django.utils.translation import ugettext_lazy as _
7 7
8 from super_archives.models import MailingList 8 from super_archives.models import MailingList
9 -from super_archives.validators import UniqueValidator  
10 9
11 10
12 -LISTS_NAMES = []  
13 -for list_ in MailingList.objects.iterator():  
14 - choice = (list_.name, list_.name)  
15 - LISTS_NAMES.append(choice) 11 +User = get_user_model()
16 12
17 13
18 -class UserCreationForm(UserCreationForm_):  
19 - first_name = forms.CharField(max_length=30, label=_(u'Name'),  
20 - widget=forms.TextInput(attrs={'class':'form-control'}))  
21 - last_name = forms.CharField(max_length=30, label=_(u'Last name'),  
22 - widget=forms.TextInput(attrs={'class':'form-control'}))  
23 - email = forms.EmailField(validators=[UniqueValidator(User, 'email')],  
24 - widget=forms.TextInput(attrs={'class':'form-control'}))  
25 - lists = forms.MultipleChoiceField(label=u'Listas',  
26 - required=False,  
27 - widget=forms.CheckboxSelectMultiple,  
28 - choices=LISTS_NAMES)  
29 - 14 +class NewUserForm(forms.ModelForm):
  15 + class Meta:
  16 + model = User
  17 + fields = ('first_name', 'last_name', 'email', 'username')
30 18
31 def __init__(self, *args, **kwargs): 19 def __init__(self, *args, **kwargs):
32 - super(UserCreationForm, self).__init__(*args, **kwargs)  
33 - self.fields.pop('password1')  
34 - self.fields.pop('password2')  
35 -  
36 -  
37 -class UserUpdateForm(UserCreationForm):  
38 - institution= forms.CharField(max_length=120, label=_(u'Institution'), required=False,  
39 - widget=forms.TextInput(attrs={'class':'form-control'}))  
40 - role = forms.CharField(max_length=60, label=_(u'Role'), required=False,  
41 - widget=forms.TextInput(attrs={'class':'form-control'}))  
42 - twitter = forms.URLField(label=_(u'Twitter'), required=False,  
43 - widget=forms.TextInput(attrs={'class':'form-control'}))  
44 - facebook = forms.URLField(label=_(u'Facebook'), required=False,  
45 - widget=forms.TextInput(attrs={'class':'form-control'}))  
46 - google_talk = forms.EmailField(label=_(u'Google Talk'), required=False,  
47 - widget=forms.TextInput(attrs={'class':'form-control'}))  
48 - webpage = forms.URLField(label=_(u'Personal Website/Blog'), required=False,  
49 - widget=forms.TextInput(attrs={'class':'form-control'})) 20 + super(NewUserForm, self).__init__(*args, **kwargs)
  21 + for field in self.fields.values():
  22 + field.widget.attrs.update({'class': 'form-control'})
  23 + field.required = True
50 24
51 - def __init__(self, *args, **kwargs):  
52 - super(UserUpdateForm, self).__init__(*args, **kwargs)  
53 - self.fields.pop('username')  
54 - self.fields.pop('first_name')  
55 - self.fields.pop('last_name')  
56 - self.fields.pop('email')  
57 - self.fields.pop('lists') 25 +
  26 +class ListsForm(forms.Form):
  27 + LISTS_NAMES = ((list.name, list.name) for list in MailingList.objects.all())
  28 + lists = forms.MultipleChoiceField(label=_(u'Mailing lists'),
  29 + required=False,
  30 + widget=forms.CheckboxSelectMultiple,
  31 + choices=LISTS_NAMES)
src/accounts/models.py
@@ -4,13 +4,13 @@ from django.contrib.auth.models import AbstractUser @@ -4,13 +4,13 @@ from django.contrib.auth.models import AbstractUser
4 4
5 5
6 class User(AbstractUser): 6 class User(AbstractUser):
7 - institution = models.CharField(max_length=128, null=True)  
8 - role = models.CharField(max_length=128, null=True)  
9 - twitter = models.CharField(max_length=128, null=True)  
10 - facebook = models.CharField(max_length=128, null=True)  
11 - google_talk = models.EmailField(null=True)  
12 - webpage = models.CharField(max_length=256, null=True)  
13 - verification_hash = models.CharField(max_length=32, null=True) 7 + institution = models.CharField(max_length=128, null=True, blank=True)
  8 + role = models.CharField(max_length=128, null=True, blank=True)
  9 + twitter = models.CharField(max_length=128, null=True, blank=True)
  10 + facebook = models.CharField(max_length=128, null=True, blank=True)
  11 + google_talk = models.EmailField(null=True, blank=True)
  12 + webpage = models.CharField(max_length=256, null=True, blank=True)
  13 + verification_hash = models.CharField(max_length=32, null=True, blank=True)
14 14
15 # We need to have `email` field set as unique but Django does not 15 # We need to have `email` field set as unique but Django does not
16 # support field overriding (at least not until 1.6). 16 # support field overriding (at least not until 1.6).
src/accounts/templates/accounts/account_message.html
@@ -1,8 +0,0 @@ @@ -1,8 +0,0 @@
1 -{% extends "base.html" %}  
2 -{% load i18n %}  
3 -  
4 -{% block main-content %}  
5 -  
6 -<div class="alert {{ msg_css_class }}">{% trans msg %}</div>  
7 -  
8 -{% endblock %}  
src/accounts/templates/accounts/email_signup-email-confirmation.html
@@ -1,9 +0,0 @@ @@ -1,9 +0,0 @@
1 -{% load i18n %}  
2 -  
3 -{% trans "Welcome to the Colab!" %}  
4 -  
5 -{% trans "To activate your account, please confirm your mail's activation by accessing the following link:" %}  
6 -  
7 -<a href="http://{{ server_name }}{% url 'email_verification' hash %}">  
8 - http://{{ server_name }}{% url 'email_verification' hash %}  
9 -</a>  
src/accounts/urls.py
@@ -5,10 +5,9 @@ from .views import UserProfileDetailView @@ -5,10 +5,9 @@ from .views import UserProfileDetailView
5 5
6 6
7 urlpatterns = patterns('', 7 urlpatterns = patterns('',
8 - url(r'^$', 'accounts.views.signup', name='signup'), 8 + #url(r'^$', 'accounts.views.signup', name='signup'),
9 9
10 - url(r'^verify/(?P<hash>[\w]{32})/$',  
11 - 'accounts.views.verify_email', name='email_verification'), 10 + url(r'^register/$', 'accounts.views.signup', name='signup'),
12 11
13 url(r'^(?P<username>[\w@+.-]+)/?$', 12 url(r'^(?P<username>[\w@+.-]+)/?$',
14 UserProfileDetailView.as_view(), name='user_profile'), 13 UserProfileDetailView.as_view(), name='user_profile'),
src/accounts/views.py
1 #!/usr/bin/env python 1 #!/usr/bin/env python
2 # encoding: utf-8 2 # encoding: utf-8
3 3
4 -import uuid  
5 -from colab.deprecated import signup as signup_ 4 +from django.contrib import messages
6 5
7 -from django.template import RequestContext  
8 from django.contrib.auth import get_user_model 6 from django.contrib.auth import get_user_model
9 from django.views.generic import DetailView 7 from django.views.generic import DetailView
10 from django.utils.translation import ugettext as _ 8 from django.utils.translation import ugettext as _
11 -from django.shortcuts import render, get_object_or_404 9 +from django.shortcuts import render, redirect
12 10
13 from colab.deprecated import solrutils 11 from colab.deprecated import solrutils
  12 +from colab.deprecated import signup as signup_
14 13
15 -from .forms import UserCreationForm  
16 from super_archives.models import EmailAddress, Message 14 from super_archives.models import EmailAddress, Message
17 -  
18 -  
19 -# helper  
20 -def get_field_set(form):  
21 - fieldsets = (  
22 - (_('Personal Information'), (  
23 - form['first_name'],  
24 - form['last_name'],  
25 - form['email'],  
26 - form['username'],  
27 - )  
28 - ),  
29 - (_('Subscribe to mail lists'), (  
30 - form['lists'],  
31 - )  
32 - ),  
33 - )  
34 - return fieldsets  
35 -  
36 -  
37 -def signup(request):  
38 -  
39 - # If the request method is GET just return the form  
40 - if request.method == 'GET':  
41 - form = UserCreationForm()  
42 - return render(request, 'accounts/signup-form.html',  
43 - {'form': form, 'fieldsets': get_field_set(form)})  
44 -  
45 - # If the request method is POST try to store data  
46 - form = UserCreationForm(request.POST)  
47 -  
48 - # If there is validation errors give the form back to the user  
49 - if not form.is_valid():  
50 - return render(request, 'accounts/signup-form.html',  
51 - {'form': form, 'fieldsets': get_field_set(form)})  
52 -  
53 - user = User(  
54 - username=form.cleaned_data.get('username'),  
55 - email=form.cleaned_data.get('email'),  
56 - first_name=form.cleaned_data.get('first_name'),  
57 - last_name=form.cleaned_data.get('last_name'),  
58 - is_active=False,  
59 - )  
60 - user.set_password(form.cleaned_data.get('password1'))  
61 - user.save()  
62 -  
63 - profile = UserProfile(  
64 - user=user,  
65 - institution=form.cleaned_data.get('institution'),  
66 - role=form.cleaned_data.get('role'),  
67 - twitter=form.cleaned_data.get('twitter'),  
68 - facebook=form.cleaned_data.get('facebook'),  
69 - google_talk=form.cleaned_data.get('google_talk'),  
70 - webpage=form.cleaned_data.get('webpage'),  
71 - verification_hash=uuid.uuid4().get_hex(),  
72 - )  
73 - profile.save()  
74 -  
75 - signup_.send_verification_email(request, user)  
76 -  
77 - mailing_lists = form.cleaned_data.get('lists')  
78 - if mailing_lists:  
79 - signup_.send_email_lists(user, mailing_lists)  
80 -  
81 -  
82 - # Check if the user's email have been used previously  
83 - # in the mainling lists to link the user to old messages  
84 - email_addr, created = EmailAddress.objects.get_or_create(address=user.email)  
85 - if created:  
86 - email_addr.real_name = user.get_full_name()  
87 -  
88 - email_addr.user = user  
89 - email_addr.save()  
90 -  
91 - template_data = {  
92 - 'msg': _(u'Registration completed successfully. Please visit your email address to validate it.'),  
93 - 'msg_css_class': 'alert-success',  
94 - }  
95 -  
96 - return render(request, 'accounts/account_message.html', template_data)  
97 -  
98 -  
99 -def verify_email(request, hash):  
100 - """Verify hash and activate user's account"""  
101 -  
102 - profile = get_object_or_404(UserProfile, verification_hash=hash)  
103 -  
104 - profile.verification_hash = 'verified'  
105 - profile.save()  
106 -  
107 - profile.user.is_active = True  
108 - profile.user.save()  
109 -  
110 - template_data = {  
111 - 'msg': _(u'E-mail validated correctly.'),  
112 - 'msg_css_class': 'alert-success',  
113 - }  
114 -  
115 - return render(request, 'accounts/account_message.html', template_data) 15 +from .forms import NewUserForm, ListsForm
116 16
117 17
118 class UserProfileDetailView(DetailView): 18 class UserProfileDetailView(DetailView):
@@ -141,5 +41,43 @@ class UserProfileDetailView(DetailView): @@ -141,5 +41,43 @@ class UserProfileDetailView(DetailView):
141 query = query.order_by('-received_time') 41 query = query.order_by('-received_time')
142 context['emails'] = query[:10] 42 context['emails'] = query[:10]
143 43
  44 + context.update(kwargs)
144 return super(UserProfileDetailView, self).get_context_data(**context) 45 return super(UserProfileDetailView, self).get_context_data(**context)
145 46
  47 +
  48 +def signup(request):
  49 + # If the request method is GET just return the form
  50 + if request.method == 'GET':
  51 + user_form = NewUserForm()
  52 + lists_form = ListsForm()
  53 + return render(request, 'registration/registration_form.html',
  54 + {'user_form': user_form, 'lists_form': lists_form})
  55 +
  56 + user_form = NewUserForm(request.POST)
  57 + lists_form = ListsForm(request.POST)
  58 +
  59 + if not user_form.is_valid() or not lists_form.is_valid():
  60 + return render(request, 'registration/registration_form.html',
  61 + {'user_form': user_form, 'lists_form': lists_form})
  62 +
  63 + user = user_form.save()
  64 +
  65 + mailing_lists = lists_form.cleaned_data.get('lists')
  66 + if mailing_lists:
  67 + signup_.send_email_lists(user, mailing_lists)
  68 +
  69 + # Check if the user's email have been used previously
  70 + # in the mainling lists to link the user to old messages
  71 + email_addr, created = EmailAddress.objects.get_or_create(address=user.email)
  72 + if created:
  73 + email_addr.real_name = user.get_full_name()
  74 +
  75 + email_addr.user = user
  76 + email_addr.save()
  77 +
  78 + messages.success(request, _('Your profile has been created!'))
  79 + messages.warning(request, _('You must login to validated your profile. '
  80 + 'Profiles not validated are deleted in 24h.'))
  81 +
  82 + return redirect('user_profile', username=user.username)
  83 +
src/colab/custom_settings.py
@@ -23,7 +23,6 @@ INSTALLED_APPS = INSTALLED_APPS + ( @@ -23,7 +23,6 @@ INSTALLED_APPS = INSTALLED_APPS + (
23 'cliauth', 23 'cliauth',
24 'django_browserid', 24 'django_browserid',
25 'conversejs', 25 'conversejs',
26 - 'registration',  
27 26
28 # Own apps 27 # Own apps
29 'super_archives', 28 'super_archives',
@@ -145,6 +144,14 @@ STATIC_ROOT = os.path.join(BASE_DIR, &#39;..&#39;, &#39;www&#39;, &#39;static&#39;) @@ -145,6 +144,14 @@ STATIC_ROOT = os.path.join(BASE_DIR, &#39;..&#39;, &#39;www&#39;, &#39;static&#39;)
145 144
146 AUTH_USER_MODEL = 'accounts.User' 145 AUTH_USER_MODEL = 'accounts.User'
147 146
  147 +from django.contrib.messages import constants as messages
  148 +MESSAGE_TAGS = {
  149 + messages.INFO: 'alert-info',
  150 + messages.SUCCESS: 'alert-success',
  151 + messages.WARNING: 'alert-warning',
  152 + messages.ERROR: 'alert-danger',
  153 +}
  154 +
148 155
149 ### Proxy configuration 156 ### Proxy configuration
150 SOCKS_SERVER = None 157 SOCKS_SERVER = None
src/colab/deprecated/templates/base.html
@@ -47,8 +47,6 @@ @@ -47,8 +47,6 @@
47 <div class="row"> 47 <div class="row">
48 </div> 48 </div>
49 49
50 - {% block header %}{% endblock %}  
51 -  
52 <nav class="navbar navbar-default navbar-fixed-top" role="navigation"> 50 <nav class="navbar navbar-default navbar-fixed-top" role="navigation">
53 <div class="navbar-header"> 51 <div class="navbar-header">
54 <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-main"> 52 <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-main">
@@ -119,6 +117,17 @@ @@ -119,6 +117,17 @@
119 </div> 117 </div>
120 </nav> 118 </nav>
121 119
  120 + {% block messages %}
  121 + {% for message in messages %}
  122 + <div class="alert alert-dismissable {{ message.tags }}">
  123 + <button type="button" class="close" data-dismiss="alert" aria-hidden="true">&times;</button>
  124 + {{ message }}
  125 + </div>
  126 + {% endfor %}
  127 + {% endblock %}
  128 +
  129 + {% block header %}{% endblock %}
  130 +
122 <div> 131 <div>
123 {% block main-content %} {% endblock %} 132 {% block main-content %} {% endblock %}
124 </div> 133 </div>