damned-lies r1215 - in trunk: . common media/css people templates templates/people
- From: claudep svn gnome org
- To: svn-commits-list gnome org
- Subject: damned-lies r1215 - in trunk: . common media/css people templates templates/people
- Date: Sat, 13 Dec 2008 20:40:54 +0000 (UTC)
Author: claudep
Date: Sat Dec 13 20:40:54 2008
New Revision: 1215
URL: http://svn.gnome.org/viewvc/damned-lies?rev=1215&view=rev
Log:
2008-12-13 Claude Paroz <claude 2xlibre net>
* common/views.py: Add site_register and activate_account views to support
registration.
* media/css/main.css: Add help and errorlist classes for forms display.
* people/forms.py: New RegistrationForm class.
* people/models.py: New activation_key field to support registration.
* people/urls.py: More precise matches with 'begin of line' (^).
* templates/error.html: Added general-purpose error template.
* templates/login.html:
* templates/logout_form.html: Externalize logout form.
* templates/people/person_detail.html: Allow logout from 'profile'
template.
* templates/register.html:
* templates/register_success.html: New templates for registration.
* urls.py: Add registration urls.
Added:
trunk/templates/error.html
trunk/templates/logout_form.html
trunk/templates/register.html
trunk/templates/register_success.html
Modified:
trunk/ChangeLog
trunk/common/views.py
trunk/media/css/main.css
trunk/people/forms.py
trunk/people/models.py
trunk/people/urls.py
trunk/templates/login.html
trunk/templates/people/person_detail.html
trunk/urls.py
Modified: trunk/common/views.py
==============================================================================
--- trunk/common/views.py (original)
+++ trunk/common/views.py Sat Dec 13 20:40:54 2008
@@ -25,6 +25,8 @@
from django.utils.translation import ugettext as _
from django.contrib.auth import login, authenticate, logout
from django.conf import settings
+from people.models import Person
+from people.forms import RegistrationForm
def index(request):
@@ -41,9 +43,8 @@
}
return render_to_response('index.html', context, context_instance=RequestContext(request))
-def site_login(request):
+def site_login(request, messages=[]):
""" Site-specific login page. Not named 'login' to not confuse with auth.login """
- messages = []
referer = None
openid_path = ''
if request.method == 'POST':
@@ -79,3 +80,32 @@
'referer': referer,
}
return render_to_response('login.html', context, context_instance=RequestContext(request))
+
+def site_register(request):
+ openid_path = ''
+ if request.method == 'POST':
+ form = RegistrationForm(data = request.POST)
+ if form.is_valid():
+ new_user = form.save()
+ return HttpResponseRedirect(reverse('register_success'))
+ else:
+ form = RegistrationForm()
+ if 'django_openid' in settings.INSTALLED_APPS:
+ openid_path = '/openid/'
+ context = {
+ 'pageSection': 'home',
+ 'form': form,
+ 'openid_path': openid_path,
+ }
+ return render_to_response('register.html', context, context_instance=RequestContext(request))
+
+def activate_account(request, key):
+ """ Activate an account through the link a requestor has received by email """
+ try:
+ person = Person.objects.get(activation_key=key)
+ except Person.DoesNotExist:
+ return render_to_response('error.html', {'error':"Sorry, the key you provided is not valid."})
+ person.activate()
+ Person.clean_unactivated_accounts()
+ return site_login(request, messages=[_("Your account has been activated.")])
+
Modified: trunk/media/css/main.css
==============================================================================
--- trunk/media/css/main.css (original)
+++ trunk/media/css/main.css Sat Dec 13 20:40:54 2008
@@ -144,6 +144,11 @@
color: #666666;
}
+.help {
+ font-size:10px;
+ color:#999;
+}
+
.error {
font-style: italic;
color: #666666;
@@ -155,6 +160,8 @@
background: #FAE28E;
}
+.errorlist li { font-size:12px !important; display:block; padding:4px 5px 4px 25px; margin:0 0 3px 0; border:1px solid red; color:white; background:red url(../img/admin/icon_alert.gif) 5px .3em no-repeat; }
+
.footnote {
text-align: center;
font-size: small;
Modified: trunk/people/forms.py
==============================================================================
--- trunk/people/forms.py (original)
+++ trunk/people/forms.py Sat Dec 13 20:40:54 2008
@@ -1,7 +1,79 @@
+import sha, random
+
from django import forms
+from django.conf import settings
+from django.utils.translation import ugettext as _
+from django.core.urlresolvers import reverse
+from django.contrib.sites.models import Site
from teams.models import Team
+from people.models import Person
class JoinTeamForm(forms.Form):
def __init__(self, *args, **kwargs):
super(JoinTeamForm, self).__init__(*args, **kwargs)
self.fields['teams'] = forms.ModelChoiceField(queryset=Team.objects.all())
+
+class RegistrationForm(forms.Form):
+ """ Form for user registration """
+ username = forms.CharField(max_length=30,
+ label=_(u'Choose a username:'),
+ help_text=_(u'May contain only letters, numbers, underscores or hyphens'))
+ email = forms.EmailField(label=_(u'Email:'))
+ openid_url = forms.URLField(label=_(u'OpenID:'),
+ required=False)
+ password1 = forms.CharField(widget=forms.PasswordInput(render_value=False),
+ label=_(u'Password:'), required=False, min_length=7,
+ help_text=_(u'At least 7 characters'))
+ password2 = forms.CharField(widget=forms.PasswordInput(render_value=False),
+ label=_(u'Confirm password:'), required=False)
+
+ def clean_username(self):
+ """ Validate the username (correctness and uniqueness)"""
+ try:
+ user = Person.objects.get(username__iexact=self.cleaned_data['username'])
+ except Person.DoesNotExist:
+ return self.cleaned_data['username']
+ raise forms.ValidationError(_(u'This username is already taken. Please choose another.'))
+
+ def clean(self):
+ cleaned_data = self.cleaned_data
+ password1 = cleaned_data.get('password1')
+ password2 = cleaned_data.get('password2')
+ openid_url = cleaned_data.get('openid_url')
+ if not password1 and not openid_url:
+ raise forms.ValidationError(_(u'You must either provide an OpenId or a password'))
+
+ if password1 and password1 != password2:
+ raise forms.ValidationError(_(u'The passwords do not match'))
+ return cleaned_data
+
+ def save(self):
+ """ Create the user """
+ username = self.cleaned_data['username']
+ email = self.cleaned_data['email']
+
+ password = self.cleaned_data['password1']
+ new_user = Person.objects.create_user(username=username,
+ email=email,
+ password=password or "!")
+ openid = self.cleaned_data['openid_url']
+ if openid:
+ new_user.openids.create(openid = openid)
+ salt = sha.new(str(random.random())).hexdigest()[:5]
+ activation_key = sha.new(salt+username).hexdigest()
+ new_user.activation_key = activation_key
+ new_user.is_active = False
+ new_user.save()
+ # Send activation email
+ from django.core.mail import send_mail
+ current_site = Site.objects.get_current()
+ subject = settings.EMAIL_SUBJECT_PREFIX + _(u'Account activation')
+ message = _(u"This is a confirmation that your registration on %s succeeded. To activate your account, please click on the link below or copy and paste it in a browser.") % current_site.name
+ message += "\n\nhttp://%s%s\n\n" % (current_site.domain, str(reverse("register_activation", kwargs={'key': activation_key})))
+ message += _(u"Administrators of %s" % current_site.name)
+
+ send_mail(subject, message, settings.SERVER_EMAIL,
+ (email,), fail_silently=False)
+
+ return new_user
+
Modified: trunk/people/models.py
==============================================================================
--- trunk/people/models.py (original)
+++ trunk/people/models.py Sat Dec 13 20:40:54 2008
@@ -1,3 +1,5 @@
+import datetime
+
from django.db import models
from django.contrib.auth.models import User, UserManager
@@ -14,19 +16,32 @@
webpage_url = models.URLField(null=True, blank=True)
irc_nick = models.SlugField(max_length=20, null=True, blank=True)
bugzilla_account = models.EmailField(null=True, blank=True)
+ activation_key = models.CharField(max_length=40, null=True, blank=True)
# Use UserManager to get the create_user method, etc.
objects = UserManager()
-
+
class Meta:
db_table = 'person'
ordering = ('username',)
+ @classmethod
+ def clean_unactivated_accounts(cls):
+ accounts = cls.objects.filter(activation_key__isnull=False)
+ for account in accounts:
+ if account.date_joined + datetime.timedelta(days=5) <= datetime.datetime.now():
+ account.delete()
+
def save(self):
if not self.password or self.password == "!":
self.password = None
self.set_unusable_password()
super(User, self).save()
+
+ def activate(self):
+ self.activation_key = None
+ self.is_active = True
+ self.save()
def no_spam_email(self):
return obfuscate_email(self.email)
Modified: trunk/people/urls.py
==============================================================================
--- trunk/people/urls.py (original)
+++ trunk/people/urls.py Sat Dec 13 20:40:54 2008
@@ -11,7 +11,7 @@
urlpatterns = patterns('',
url(r'^$', 'django.views.generic.list_detail.object_list', dict(info_dict_list), 'persons'),
- url(r'(?P<object_id>\d+)/$', 'people.views.person_detail_from_id', name='person'),
+ url(r'^(?P<object_id>\d+)/$', 'people.views.person_detail_from_id', name='person'),
# equivalent to the previous, but using username instead of user pk
- url(r'(?P<slug>\w+)/$', 'people.views.person_detail_from_username', name='person'),
+ url(r'^(?P<slug>\w+)/$', 'people.views.person_detail_from_username', name='person'),
)
Added: trunk/templates/error.html
==============================================================================
--- (empty file)
+++ trunk/templates/error.html Sat Dec 13 20:40:54 2008
@@ -0,0 +1,14 @@
+{% extends "base.html" %}
+{% load i18n %}
+
+{% block title %} {% trans "Damned Lies about GNOME" %} {% endblock %}
+
+{% block content %}
+<div class="mainpage">
+
+<h1>{% trans "Error:" %}</h1>
+
+<p class="errornote">{{ error }}</p>
+
+</div>
+{% endblock %}
Modified: trunk/templates/login.html
==============================================================================
--- trunk/templates/login.html (original)
+++ trunk/templates/login.html Sat Dec 13 20:40:54 2008
@@ -8,15 +8,13 @@
{% if user.is_authenticated %}
<p>{% blocktrans with user.username as username %}You are already logged in as {{ username }}.{% endblocktrans %}</p>
- <form action="" method="post">
- <input type="hidden" name="logout" value="1" />
- <div class="submit-row">
- <label> </label><input type="submit" value="{% trans 'Log out' %}" />
- </div>
- </form>
+ {% include "logout_form.html" %}
{% else %}
+{% url register as link %}
+<p>{% blocktrans %}If you do not own an account on this site, you can <a href='{{ link }}'>register</a> for a new account.{% endblocktrans %}</p>
+
<p>{% trans 'Log in with your username and password:' %}</p>
-<form action="{{ app_path }}" method="post" id="login-form" class="login">
+<form action="{% url login %}" method="post" id="login-form" class="login">
<div class="form-row">
<label for="id_username">{% trans 'Username:' %}</label> <input type="text" name="username" id="id_username" />
</div>
Added: trunk/templates/logout_form.html
==============================================================================
--- (empty file)
+++ trunk/templates/logout_form.html Sat Dec 13 20:40:54 2008
@@ -0,0 +1,8 @@
+{% load i18n %}
+<form action="{% url login %}" method="post">
+ <input type="hidden" name="logout" value="1" />
+ <div class="submit-row">
+ <label> </label><input type="submit" value="{% trans 'Log out' %}" />
+ </div>
+</form>
+
Modified: trunk/templates/people/person_detail.html
==============================================================================
--- trunk/templates/people/person_detail.html (original)
+++ trunk/templates/people/person_detail.html Sat Dec 13 20:40:54 2008
@@ -7,6 +7,12 @@
{% block content %}
<div class="mainpage">
<h2>{{ person.name }}</h2>
+ {% if user.is_authenticated %}
+ {% ifequal user.username person.username %}
+ <div style="float: right">{% include "logout_form.html" %}</div>
+ {% endifequal %}
+ {% endif %}
+
{% with 1 as printroles %}
{% include "person_base.html" %}
{% endwith %}
Added: trunk/templates/register.html
==============================================================================
--- (empty file)
+++ trunk/templates/register.html Sat Dec 13 20:40:54 2008
@@ -0,0 +1,57 @@
+{% extends "base.html" %}
+{% load i18n %}
+
+{% block title %} {% trans "Damned Lies about GNOME" %} {% endblock %}
+{% block extrahead %} <link rel="stylesheet" href="/media/css/login.css"/> {% endblock %}
+{% block content %}
+<div class="mainpage">
+
+<h2>{% trans "Account Registration" %}</h2>
+{% if user.is_authenticated %}
+ <p>{% blocktrans with user.username as username %}You are already logged in as {{ username }}.{% endblocktrans %}</p>
+ {% include "logout_form.html" %}
+{% else %}
+<p>{% trans "You can register here for an account on this site. This is only useful if you plan to contribute to GNOME translations." %}</p>
+<p>{% trans "After registration and connection, you will be able to join an existing team from your profile page." %}</p>
+
+<form action="{{ app_path }}" method="post" id="login-form" class="login">
+ <div class="form-row">
+ {{ form.username.errors }}
+ <label for="id_username">{{ form.username.label }}</label> {{ form.username }} <span class="help">{{ form.username.help_text }}</span>
+ </div>
+ <div class="form-row">
+ {{ form.email.errors }}
+ <label for="id_email">{{ form.email.label }}</label> {{ form.email }}
+ </div>
+ <table style="clear:both"><tr><td colspan="2">
+ <div style="clear:both">{{ form.non_field_errors }}</div>
+{% if openid_path %}
+ <p>Authenticate via OpenID <strong>or</strong> password:</p></td></tr><tr><td valign="bottom">
+ <div>
+ {{ form.openid_url.errors }}
+ <label for="id_openid"><img src="{{ openid_path }}logo/" alt=""> {{ form.openid_url.label }}</label> {{ form.openid_url }}
+ </div>
+ <div style="text-align:center; padding-top:8px;">
+ <label> </label><input type="submit" value="{% trans 'Register with OpenId' %}" />
+ </div>
+ </td><td valign="bottom">
+{% endif %}
+ <div class="form-row">
+ {{ form.password1.errors }}
+ <label for="id_password">{{ form.password1.label }}</label> {{ form.password1 }} <span class="help">{{ form.password1.help_text }}</span>
+ </div>
+ <div class="form-row">
+ <label for="id_password">{{ form.password2.label }}</label> {{ form.password2 }}
+ </div>
+ <div style="text-align:center; padding-top:8px;">
+ <label> </label><input type="submit" value="{% trans 'Register with password' %}" />
+ </div>
+ </td></tr></table>
+</form>
+
+<script type="text/javascript">
+document.getElementById('id_username').focus()
+</script>
+{% endif %}
+</div>
+{% endblock %}
Added: trunk/templates/register_success.html
==============================================================================
--- (empty file)
+++ trunk/templates/register_success.html Sat Dec 13 20:40:54 2008
@@ -0,0 +1,13 @@
+{% extends "base.html" %}
+{% load i18n %}
+
+{% block title %} {% trans "Damned Lies about GNOME" %} {% endblock %}
+{% block content %}
+<div class="mainpage">
+
+<h2>{% trans "Registration Success" %}</h2>
+
+<p>{% trans "The registration succeeded. You will now receive an email containing a link to activate your account." %}</p>
+
+</div>
+{% endblock %}
Modified: trunk/urls.py
==============================================================================
--- trunk/urls.py (original)
+++ trunk/urls.py Sat Dec 13 20:40:54 2008
@@ -8,6 +8,9 @@
urlpatterns = patterns('',
url(r'^$', 'common.views.index', name='home'),
url(r'^login/$', 'common.views.site_login', name='login'),
+ url(r'^register/$', 'common.views.site_register', name='register'),
+ url(r'^register/success$', 'django.views.generic.simple.direct_to_template', {'template': 'register_success.html'}, name='register_success'),
+ url(r'^register/activate/(?P<key>\w+)$', 'common.views.activate_account', name='register_activation'),
(r'^teams/', include('teams.urls')),
(r'^people/', include('people.urls')),
# users is the hardcoded url in the contrib.auth User class, making it identical to /people
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]