From 7c10fc5e39ad8cda89dce4d2d458bc5222d19f90 Mon Sep 17 00:00:00 2001 From: aaron Date: Fri, 30 Jan 2009 00:02:03 +0100 Subject: [PATCH] [svn r8231] Add user registration and user profiles. Used modified versions of django-registration and django-profiles , both on bitbucket. The Person model is now set up as the profile for auth.User s. I set up a requestcontext so that settings is automatically passed to every template, no need to repeat ourselves in views. However, this needs to be refined: I will soon change it to only pass a subset of settings. E.G. we do not need to be passing the DB login and password! --- troggle/context.py | 4 + troggle/expo/admin.py | 5 + troggle/expo/forms.py | 8 +- troggle/expo/models.py | 4 +- troggle/expo/views_logbooks.py | 6 + troggle/media/css/main2.css | 2 + troggle/profiles/__init__.py | 0 troggle/profiles/urls.py | 43 +++ troggle/profiles/utils.py | 45 +++ troggle/profiles/views.py | 340 +++++++++++++++++ troggle/registration/__init__.py | 0 troggle/registration/admin.py | 11 + troggle/registration/forms.py | 134 +++++++ .../locale/ar/LC_MESSAGES/django.mo | Bin 0 -> 2135 bytes .../locale/ar/LC_MESSAGES/django.po | 81 ++++ .../locale/bg/LC_MESSAGES/django.mo | Bin 0 -> 2302 bytes .../locale/bg/LC_MESSAGES/django.po | 78 ++++ .../locale/de/LC_MESSAGES/django.mo | Bin 0 -> 1909 bytes .../locale/de/LC_MESSAGES/django.po | 85 +++++ .../locale/el/LC_MESSAGES/django.mo | Bin 0 -> 2424 bytes .../locale/el/LC_MESSAGES/django.po | 84 +++++ .../locale/en/LC_MESSAGES/django.mo | Bin 0 -> 367 bytes .../locale/en/LC_MESSAGES/django.po | 81 ++++ .../locale/es/LC_MESSAGES/django.mo | Bin 0 -> 1909 bytes .../locale/es/LC_MESSAGES/django.po | 85 +++++ .../locale/es_AR/LC_MESSAGES/django.mo | Bin 0 -> 1849 bytes .../locale/es_AR/LC_MESSAGES/django.po | 83 ++++ .../locale/fr/LC_MESSAGES/django.mo | Bin 0 -> 1883 bytes .../locale/fr/LC_MESSAGES/django.po | 81 ++++ .../locale/he/LC_MESSAGES/django.mo | Bin 0 -> 1896 bytes .../locale/he/LC_MESSAGES/django.po | 86 +++++ .../locale/it/LC_MESSAGES/django.mo | Bin 0 -> 1864 bytes .../locale/it/LC_MESSAGES/django.po | 82 ++++ .../locale/ja/LC_MESSAGES/django.mo | Bin 0 -> 2035 bytes .../locale/ja/LC_MESSAGES/django.po | 78 ++++ .../locale/nl/LC_MESSAGES/django.mo | Bin 0 -> 1898 bytes .../locale/nl/LC_MESSAGES/django.po | 77 ++++ .../locale/pl/LC_MESSAGES/django.mo | Bin 0 -> 1769 bytes .../locale/pl/LC_MESSAGES/django.po | 84 +++++ .../locale/pt_BR/LC_MESSAGES/django.mo | Bin 0 -> 1796 bytes .../locale/pt_BR/LC_MESSAGES/django.po | 81 ++++ .../locale/ru/LC_MESSAGES/django.mo | Bin 0 -> 2360 bytes .../locale/ru/LC_MESSAGES/django.po | 81 ++++ .../locale/sr/LC_MESSAGES/django.mo | Bin 0 -> 1966 bytes .../locale/sr/LC_MESSAGES/django.po | 80 ++++ .../locale/sv/LC_MESSAGES/django.mo | Bin 0 -> 1687 bytes .../locale/sv/LC_MESSAGES/django.po | 81 ++++ .../locale/zh_CN/LC_MESSAGES/django.mo | Bin 0 -> 1669 bytes .../locale/zh_CN/LC_MESSAGES/django.po | 77 ++++ .../locale/zh_TW/LC_MESSAGES/django.mo | Bin 0 -> 1669 bytes .../locale/zh_TW/LC_MESSAGES/django.po | 77 ++++ troggle/registration/management/__init__.py | 0 .../management/commands/__init__.py | 0 .../commands/cleanupregistration.py | 19 + troggle/registration/models.py | 255 +++++++++++++ troggle/registration/signals.py | 8 + troggle/registration/tests.py | 355 ++++++++++++++++++ troggle/registration/urls.py | 72 ++++ troggle/registration/views.py | 153 ++++++++ troggle/settings.py | 10 + troggle/templates/base.html | 29 +- troggle/templates/personForm.html | 6 + .../templates/profiles/create_profile.html | 13 + troggle/templates/profiles/profile_list.html | 0 troggle/templates/registration/activate.html | 13 + .../registration/activation_email.txt | 3 + .../registration/activation_email_subject.txt | 1 + troggle/templates/registration/login.html | 19 + troggle/templates/registration/logout.html | 4 + .../registration/registration_activate.html | 6 + .../registration/registration_complete.html | 13 + .../registration/registration_form.html | 56 +++ troggle/urls.py | 5 + 73 files changed, 3173 insertions(+), 11 deletions(-) create mode 100644 troggle/context.py create mode 100644 troggle/profiles/__init__.py create mode 100644 troggle/profiles/urls.py create mode 100644 troggle/profiles/utils.py create mode 100644 troggle/profiles/views.py create mode 100644 troggle/registration/__init__.py create mode 100644 troggle/registration/admin.py create mode 100644 troggle/registration/forms.py create mode 100644 troggle/registration/locale/ar/LC_MESSAGES/django.mo create mode 100644 troggle/registration/locale/ar/LC_MESSAGES/django.po create mode 100644 troggle/registration/locale/bg/LC_MESSAGES/django.mo create mode 100644 troggle/registration/locale/bg/LC_MESSAGES/django.po create mode 100644 troggle/registration/locale/de/LC_MESSAGES/django.mo create mode 100644 troggle/registration/locale/de/LC_MESSAGES/django.po create mode 100644 troggle/registration/locale/el/LC_MESSAGES/django.mo create mode 100644 troggle/registration/locale/el/LC_MESSAGES/django.po create mode 100644 troggle/registration/locale/en/LC_MESSAGES/django.mo create mode 100644 troggle/registration/locale/en/LC_MESSAGES/django.po create mode 100644 troggle/registration/locale/es/LC_MESSAGES/django.mo create mode 100644 troggle/registration/locale/es/LC_MESSAGES/django.po create mode 100644 troggle/registration/locale/es_AR/LC_MESSAGES/django.mo create mode 100644 troggle/registration/locale/es_AR/LC_MESSAGES/django.po create mode 100644 troggle/registration/locale/fr/LC_MESSAGES/django.mo create mode 100644 troggle/registration/locale/fr/LC_MESSAGES/django.po create mode 100644 troggle/registration/locale/he/LC_MESSAGES/django.mo create mode 100644 troggle/registration/locale/he/LC_MESSAGES/django.po create mode 100644 troggle/registration/locale/it/LC_MESSAGES/django.mo create mode 100644 troggle/registration/locale/it/LC_MESSAGES/django.po create mode 100644 troggle/registration/locale/ja/LC_MESSAGES/django.mo create mode 100644 troggle/registration/locale/ja/LC_MESSAGES/django.po create mode 100644 troggle/registration/locale/nl/LC_MESSAGES/django.mo create mode 100644 troggle/registration/locale/nl/LC_MESSAGES/django.po create mode 100644 troggle/registration/locale/pl/LC_MESSAGES/django.mo create mode 100644 troggle/registration/locale/pl/LC_MESSAGES/django.po create mode 100644 troggle/registration/locale/pt_BR/LC_MESSAGES/django.mo create mode 100644 troggle/registration/locale/pt_BR/LC_MESSAGES/django.po create mode 100644 troggle/registration/locale/ru/LC_MESSAGES/django.mo create mode 100644 troggle/registration/locale/ru/LC_MESSAGES/django.po create mode 100644 troggle/registration/locale/sr/LC_MESSAGES/django.mo create mode 100644 troggle/registration/locale/sr/LC_MESSAGES/django.po create mode 100644 troggle/registration/locale/sv/LC_MESSAGES/django.mo create mode 100644 troggle/registration/locale/sv/LC_MESSAGES/django.po create mode 100644 troggle/registration/locale/zh_CN/LC_MESSAGES/django.mo create mode 100644 troggle/registration/locale/zh_CN/LC_MESSAGES/django.po create mode 100644 troggle/registration/locale/zh_TW/LC_MESSAGES/django.mo create mode 100644 troggle/registration/locale/zh_TW/LC_MESSAGES/django.po create mode 100644 troggle/registration/management/__init__.py create mode 100644 troggle/registration/management/commands/__init__.py create mode 100644 troggle/registration/management/commands/cleanupregistration.py create mode 100644 troggle/registration/models.py create mode 100644 troggle/registration/signals.py create mode 100644 troggle/registration/tests.py create mode 100644 troggle/registration/urls.py create mode 100644 troggle/registration/views.py create mode 100644 troggle/templates/personForm.html create mode 100644 troggle/templates/profiles/create_profile.html create mode 100644 troggle/templates/profiles/profile_list.html create mode 100644 troggle/templates/registration/activate.html create mode 100644 troggle/templates/registration/activation_email.txt create mode 100644 troggle/templates/registration/activation_email_subject.txt create mode 100644 troggle/templates/registration/login.html create mode 100644 troggle/templates/registration/logout.html create mode 100644 troggle/templates/registration/registration_activate.html create mode 100644 troggle/templates/registration/registration_complete.html create mode 100644 troggle/templates/registration/registration_form.html diff --git a/troggle/context.py b/troggle/context.py new file mode 100644 index 000000000..f0fd20857 --- /dev/null +++ b/troggle/context.py @@ -0,0 +1,4 @@ +import troggle.settings as settings + +def settingsContext(request): + return { 'settings':settings } \ No newline at end of file diff --git a/troggle/expo/admin.py b/troggle/expo/admin.py index 52138af30..d5a7ddd6c 100644 --- a/troggle/expo/admin.py +++ b/troggle/expo/admin.py @@ -18,8 +18,13 @@ class SurveyAdmin(admin.ModelAdmin): class LogbookEntryAdmin(admin.ModelAdmin): search_fields = ('title','expedition__year') +class PersonExpeditionInline(admin.TabularInline): + model = PersonExpedition + extra = 1 + class PersonAdmin(admin.ModelAdmin): search_fields = ('first_name','last_name') + inlines = (PersonExpeditionInline,) class PersonExpeditionAdmin(admin.ModelAdmin): search_fields = ('person__first_name','expedition__year') diff --git a/troggle/expo/forms.py b/troggle/expo/forms.py index c8e284268..91f39f094 100644 --- a/troggle/expo/forms.py +++ b/troggle/expo/forms.py @@ -1,6 +1,10 @@ from django.forms import ModelForm -from models import Cave +from models import Cave, Person class CaveForm(ModelForm): class Meta: - model = Cave \ No newline at end of file + model = Cave + +class PersonForm(ModelForm): + class Meta: + model = Person \ No newline at end of file diff --git a/troggle/expo/models.py b/troggle/expo/models.py index 2b3919c91..98b5d2b5d 100644 --- a/troggle/expo/models.py +++ b/troggle/expo/models.py @@ -4,6 +4,7 @@ from django.forms import ModelForm from django.db import models from django.contrib import admin from django.core.files.storage import FileSystemStorage +from django.contrib.auth.models import User import os import troggle.settings as settings import datetime @@ -59,6 +60,7 @@ class Person(models.Model): mug_shot = models.CharField(max_length=100, blank=True,null=True) blurb = models.TextField(blank=True,null=True) href = models.CharField(max_length=200) + user = models.ForeignKey(User, unique=True, null=True, blank=True) class Meta: verbose_name_plural = "People" @@ -482,4 +484,4 @@ class Survey(models.Model): def elevations(self): return self.scannedimage_set.filter(contents='elevation') - \ No newline at end of file + diff --git a/troggle/expo/views_logbooks.py b/troggle/expo/views_logbooks.py index 72c44e816..513701b99 100644 --- a/troggle/expo/views_logbooks.py +++ b/troggle/expo/views_logbooks.py @@ -4,6 +4,7 @@ import troggle.settings as settings from troggle.parsers.logbooks import LoadLogbookForExpedition from troggle.parsers.people import GetPersonExpeditionNameLookup +from troggle.expo.forms import PersonForm import search import re @@ -58,3 +59,8 @@ def logbookSearch(request, extra): return render_to_response('logbooksearch.html', { 'query_string': query_string, 'found_entries': found_entries, 'settings': settings}) #context_instance=RequestContext(request)) + +def personForm(request,pk): + person=Person.objects.get(pk=pk) + form=PersonForm(instance=person) + return render_to_response('personform.html', {'form':form,'settings':settings}) \ No newline at end of file diff --git a/troggle/media/css/main2.css b/troggle/media/css/main2.css index c7c7276b5..fee993c15 100644 --- a/troggle/media/css/main2.css +++ b/troggle/media/css/main2.css @@ -62,6 +62,8 @@ div#footer margin-right:auto; } +#frontPageBanner{ position:relative; width:inherit; height:inherit; } + div.logbookentry { text-align:left; diff --git a/troggle/profiles/__init__.py b/troggle/profiles/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/troggle/profiles/urls.py b/troggle/profiles/urls.py new file mode 100644 index 000000000..05ff9e434 --- /dev/null +++ b/troggle/profiles/urls.py @@ -0,0 +1,43 @@ +""" +URLConf for Django user profile management. + +Recommended usage is to use a call to ``include()`` in your project's +root URLConf to include this URLConf for any URL beginning with +'/profiles/'. + +If the default behavior of the profile views is acceptable to you, +simply use a line like this in your root URLConf to set up the default +URLs for profiles:: + + (r'^profiles/', include('profiles.urls')), + +But if you'd like to customize the behavior (e.g., by passing extra +arguments to the various views) or split up the URLs, feel free to set +up your own URL patterns for these views instead. If you do, it's a +good idea to keep the name ``profiles_profile_detail`` for the pattern +which points to the ``profile_detail`` view, since several views use +``reverse()`` with that name to generate a default post-submission +redirect. If you don't use that name, remember to explicitly pass +``success_url`` to those views. + +""" + +from django.conf.urls.defaults import * + +from profiles import views + + +urlpatterns = patterns('', + url(r'^create/$', + views.create_profile, + name='profiles_create_profile'), + url(r'^edit/$', + views.edit_profile, + name='profiles_edit_profile'), + url(r'^(?P\w+)/$', + views.profile_detail, + name='profiles_profile_detail'), + url(r'^$', + views.profile_list, + name='profiles_profile_list'), + ) diff --git a/troggle/profiles/utils.py b/troggle/profiles/utils.py new file mode 100644 index 000000000..faacfcbc1 --- /dev/null +++ b/troggle/profiles/utils.py @@ -0,0 +1,45 @@ +""" +Utility functions for retrieving and generating forms for the +site-specific user profile model specified in the +``AUTH_PROFILE_MODULE`` setting. + +""" + +from django import forms +from django.conf import settings +from django.contrib.auth.models import SiteProfileNotAvailable +from django.db.models import get_model + + +def get_profile_model(): + """ + Return the model class for the currently-active user profile + model, as defined by the ``AUTH_PROFILE_MODULE`` setting. If that + setting is missing, raise + ``django.contrib.auth.models.SiteProfileNotAvailable``. + + """ + if (not hasattr(settings, 'AUTH_PROFILE_MODULE')) or \ + (not settings.AUTH_PROFILE_MODULE): + raise SiteProfileNotAvailable + profile_mod = get_model(*settings.AUTH_PROFILE_MODULE.split('.')) + if profile_mod is None: + raise SiteProfileNotAvailable + return profile_mod + + +def get_profile_form(): + """ + Return a form class (a subclass of the default ``ModelForm``) + suitable for creating/editing instances of the site-specific user + profile model, as defined by the ``AUTH_PROFILE_MODULE`` + setting. If that setting is missing, raise + ``django.contrib.auth.models.SiteProfileNotAvailable``. + + """ + profile_mod = get_profile_model() + class _ProfileForm(forms.ModelForm): + class Meta: + model = profile_mod + exclude = ('user',) # User will be filled in by the view. + return _ProfileForm diff --git a/troggle/profiles/views.py b/troggle/profiles/views.py new file mode 100644 index 000000000..c1191655b --- /dev/null +++ b/troggle/profiles/views.py @@ -0,0 +1,340 @@ +""" +Views for creating, editing and viewing site-specific user profiles. + +""" + +from django.contrib.auth.decorators import login_required +from django.contrib.auth.models import User +from django.core.exceptions import ObjectDoesNotExist +from django.core.urlresolvers import reverse +from django.http import Http404 +from django.http import HttpResponseRedirect +from django.shortcuts import get_object_or_404 +from django.shortcuts import render_to_response +from django.template import RequestContext +from django.views.generic.list_detail import object_list + +from profiles import utils + +import troggle.settings as settings + + + +def create_profile(request, form_class=None, success_url=None, + template_name='profiles/create_profile.html', + extra_context=None): + """ + Create a profile for the current user, if one doesn't already + exist. + + If the user already has a profile, as determined by + ``request.user.get_profile()``, a redirect will be issued to the + :view:`profiles.views.edit_profile` view. If no profile model has + been specified in the ``AUTH_PROFILE_MODULE`` setting, + ``django.contrib.auth.models.SiteProfileNotAvailable`` will be + raised. + + **Optional arguments:** + + ``extra_context`` + A dictionary of variables to add to the template context. Any + callable object in this dictionary will be called to produce + the end result which appears in the context. + + ``form_class`` + The form class to use for validating and creating the user + profile. This form class must define a method named + ``save()``, implementing the same argument signature as the + ``save()`` method of a standard Django ``ModelForm`` (this + view will call ``save(commit=False)`` to obtain the profile + object, and fill in the user before the final save). If the + profile object includes many-to-many relations, the convention + established by ``ModelForm`` of using a method named + ``save_m2m()`` will be used, and so your form class should + also define this method. + + If this argument is not supplied, this view will use a + ``ModelForm`` automatically generated from the model specified + by ``AUTH_PROFILE_MODULE``. + + ``success_url`` + The URL to redirect to after successful profile creation. If + this argument is not supplied, this will default to the URL of + :view:`profiles.views.profile_detail` for the newly-created + profile object. + + ``template_name`` + The template to use when displaying the profile-creation + form. If not supplied, this will default to + :template:`profiles/create_profile.html`. + + **Context:** + + ``form`` + The profile-creation form. + + **Template:** + + ``template_name`` keyword argument, or + :template:`profiles/create_profile.html`. + + """ + try: + profile_obj = request.user.get_profile() + return HttpResponseRedirect(reverse('profiles_edit_profile')) + except ObjectDoesNotExist: + pass + + # + # We set up success_url here, rather than as the default value for + # the argument. Trying to do it as the argument's default would + # mean evaluating the call to reverse() at the time this module is + # first imported, which introduces a circular dependency: to + # perform the reverse lookup we need access to profiles/urls.py, + # but profiles/urls.py in turn imports this module. + # + + if success_url is None: + success_url = reverse('profiles_profile_detail', + kwargs={ 'username': request.user.username }) + if form_class is None: + form_class = utils.get_profile_form() + if request.method == 'POST': + form = form_class(data=request.POST, files=request.FILES) + if form.is_valid(): + profile_obj = form.save(commit=False) + profile_obj.user = request.user + profile_obj.save() + if hasattr(form, 'save_m2m'): + form.save_m2m() + return HttpResponseRedirect(success_url) + else: + form = form_class() + + if extra_context is None: + extra_context = {} + context = RequestContext(request) + for key, value in extra_context.items(): + context[key] = callable(value) and value() or value + + return render_to_response(template_name, + { 'form': form, 'settings':settings }, + context_instance=context) +create_profile = login_required(create_profile) + +def edit_profile(request, form_class=None, success_url=None, + template_name='profiles/edit_profile.html', + extra_context=None): + """ + Edit the current user's profile. + + If the user does not already have a profile (as determined by + ``User.get_profile()``), a redirect will be issued to the + :view:`profiles.views.create_profile` view; if no profile model + has been specified in the ``AUTH_PROFILE_MODULE`` setting, + ``django.contrib.auth.models.SiteProfileNotAvailable`` will be + raised. + + **Optional arguments:** + + ``extra_context`` + A dictionary of variables to add to the template context. Any + callable object in this dictionary will be called to produce + the end result which appears in the context. + + ``form_class`` + The form class to use for validating and editing the user + profile. This form class must operate similarly to a standard + Django ``ModelForm`` in that it must accept an instance of the + object to be edited as the keyword argument ``instance`` to + its constructor, and it must implement a method named + ``save()`` which will save the updates to the object. If this + argument is not specified, this view will use a ``ModelForm`` + generated from the model specified in the + ``AUTH_PROFILE_MODULE`` setting. + + ``success_url`` + The URL to redirect to following a successful edit. If not + specified, this will default to the URL of + :view:`profiles.views.profile_detail` for the profile object + being edited. + + ``template_name`` + The template to use when displaying the profile-editing + form. If not specified, this will default to + :template:`profiles/edit_profile.html`. + + **Context:** + + ``form`` + The form for editing the profile. + + ``profile`` + The user's current profile. + + **Template:** + + ``template_name`` keyword argument or + :template:`profiles/edit_profile.html`. + + """ + try: + profile_obj = request.user.get_profile() + except ObjectDoesNotExist: + return HttpResponseRedirect(reverse('profiles_create_profile')) + + # + # See the comment in create_profile() for discussion of why + # success_url is set up here, rather than as a default value for + # the argument. + # + + if success_url is None: + success_url = reverse('profiles_profile_detail', + kwargs={ 'username': request.user.username }) + if form_class is None: + form_class = utils.get_profile_form() + if request.method == 'POST': + form = form_class(data=request.POST, files=request.FILES, instance=profile_obj) + if form.is_valid(): + form.save() + return HttpResponseRedirect(success_url) + else: + form = form_class(instance=profile_obj) + + if extra_context is None: + extra_context = {} + context = RequestContext(request) + for key, value in extra_context.items(): + context[key] = callable(value) and value() or value + + return render_to_response(template_name, + { 'form': form, + 'profile': profile_obj, }, + context_instance=context) +edit_profile = login_required(edit_profile) + +def profile_detail(request, username, public_profile_field=None, + template_name='profiles/profile_detail.html', + extra_context=None): + """ + Detail view of a user's profile. + + If no profile model has been specified in the + ``AUTH_PROFILE_MODULE`` setting, + ``django.contrib.auth.models.SiteProfileNotAvailable`` will be + raised. + + If the user has not yet created a profile, ``Http404`` will be + raised. + + **Required arguments:** + + ``username`` + The username of the user whose profile is being displayed. + + **Optional arguments:** + + ``extra_context`` + A dictionary of variables to add to the template context. Any + callable object in this dictionary will be called to produce + the end result which appears in the context. + + ``public_profile_field`` + The name of a ``BooleanField`` on the profile model; if the + value of that field on the user's profile is ``False``, the + ``profile`` variable in the template will be ``None``. Use + this feature to allow users to mark their profiles as not + being publicly viewable. + + If this argument is not specified, it will be assumed that all + users' profiles are publicly viewable. + + ``template_name`` + The name of the template to use for displaying the profile. If + not specified, this will default to + :template:`profiles/profile_detail.html`. + + **Context:** + + ``profile`` + The user's profile, or ``None`` if the user's profile is not + publicly viewable (see the description of + ``public_profile_field`` above). + + **Template:** + + ``template_name`` keyword argument or + :template:`profiles/profile_detail.html`. + + """ + user = get_object_or_404(User, username=username) + try: + profile_obj = user.get_profile() + except ObjectDoesNotExist: + raise Http404 + if public_profile_field is not None and \ + not getattr(profile_obj, public_profile_field): + profile_obj = None + + if extra_context is None: + extra_context = {} + context = RequestContext(request) + for key, value in extra_context.items(): + context[key] = callable(value) and value() or value + + return render_to_response(template_name, + { 'profile': profile_obj }, + context_instance=context) + +def profile_list(request, public_profile_field=None, + template_name='profiles/profile_list.html', **kwargs): + """ + A list of user profiles. + + If no profile model has been specified in the + ``AUTH_PROFILE_MODULE`` setting, + ``django.contrib.auth.models.SiteProfileNotAvailable`` will be + raised. + + **Optional arguments:** + + ``public_profile_field`` + The name of a ``BooleanField`` on the profile model; if the + value of that field on a user's profile is ``False``, that + profile will be excluded from the list. Use this feature to + allow users to mark their profiles as not being publicly + viewable. + + If this argument is not specified, it will be assumed that all + users' profiles are publicly viewable. + + ``template_name`` + The name of the template to use for displaying the profiles. If + not specified, this will default to + :template:`profiles/profile_list.html`. + + Additionally, all arguments accepted by the + :view:`django.views.generic.list_detail.object_list` generic view + will be accepted here, and applied in the same fashion, with one + exception: ``queryset`` will always be the ``QuerySet`` of the + model specified by the ``AUTH_PROFILE_MODULE`` setting, optionally + filtered to remove non-publicly-viewable proiles. + + **Context:** + + Same as the :view:`django.views.generic.list_detail.object_list` + generic view. + + **Template:** + + ``template_name`` keyword argument or + :template:`profiles/profile_list.html`. + + """ + profile_model = utils.get_profile_model() + queryset = profile_model._default_manager.all() + if public_profile_field is not None: + queryset = queryset.filter(**{ public_profile_field: True }) + kwargs['queryset'] = queryset + return object_list(request, template_name=template_name, **kwargs) diff --git a/troggle/registration/__init__.py b/troggle/registration/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/troggle/registration/admin.py b/troggle/registration/admin.py new file mode 100644 index 000000000..3f36c1807 --- /dev/null +++ b/troggle/registration/admin.py @@ -0,0 +1,11 @@ +from django.contrib import admin + +from registration.models import RegistrationProfile + + +class RegistrationAdmin(admin.ModelAdmin): + list_display = ('__unicode__', 'activation_key_expired') + search_fields = ('user__username', 'user__first_name') + + +admin.site.register(RegistrationProfile, RegistrationAdmin) diff --git a/troggle/registration/forms.py b/troggle/registration/forms.py new file mode 100644 index 000000000..f2298aca0 --- /dev/null +++ b/troggle/registration/forms.py @@ -0,0 +1,134 @@ +""" +Forms and validation code for user registration. + +""" + + +from django.contrib.auth.models import User +from django import forms +from django.utils.translation import ugettext_lazy as _ + +from registration.models import RegistrationProfile + + +# I put this on all required fields, because it's easier to pick up +# on them with CSS or JavaScript if they have a class of "required" +# in the HTML. Your mileage may vary. If/when Django ticket #3515 +# lands in trunk, this will no longer be necessary. +attrs_dict = { 'class': 'required' } + + +class RegistrationForm(forms.Form): + """ + Form for registering a new user account. + + Validates that the requested username is not already in use, and + requires the password to be entered twice to catch typos. + + Subclasses should feel free to add any additional validation they + need, but should either preserve the base ``save()`` or implement + a ``save()`` method which returns a ``User``. + + """ + username = forms.RegexField(regex=r'^\w+$', + max_length=30, + widget=forms.TextInput(attrs=attrs_dict), + label=_(u'username')) + email = forms.EmailField(widget=forms.TextInput(attrs=dict(attrs_dict, + maxlength=75)), + label=_(u'email address')) + password1 = forms.CharField(widget=forms.PasswordInput(attrs=attrs_dict, render_value=False), + label=_(u'password')) + password2 = forms.CharField(widget=forms.PasswordInput(attrs=attrs_dict, render_value=False), + label=_(u'password (again)')) + + def clean_username(self): + """ + Validate that the username is alphanumeric and is not already + in use. + + """ + try: + user = User.objects.get(username__iexact=self.cleaned_data['username']) + except User.DoesNotExist: + return self.cleaned_data['username'] + raise forms.ValidationError(_(u'This username is already taken. Please choose another.')) + + def clean(self): + """ + Verifiy that the values entered into the two password fields + match. Note that an error here will end up in + ``non_field_errors()`` because it doesn't apply to a single + field. + + """ + if 'password1' in self.cleaned_data and 'password2' in self.cleaned_data: + if self.cleaned_data['password1'] != self.cleaned_data['password2']: + raise forms.ValidationError(_(u'You must type the same password each time')) + return self.cleaned_data + + def save(self): + """ + Create the new ``User`` and ``RegistrationProfile``, and + returns the ``User`` (by calling + ``RegistrationProfile.objects.create_inactive_user()``). + + """ + new_user = RegistrationProfile.objects.create_inactive_user(username=self.cleaned_data['username'], + password=self.cleaned_data['password1'], + email=self.cleaned_data['email']) + return new_user + + +class RegistrationFormTermsOfService(RegistrationForm): + """ + Subclass of ``RegistrationForm`` which adds a required checkbox + for agreeing to a site's Terms of Service. + + """ + tos = forms.BooleanField(widget=forms.CheckboxInput(attrs=attrs_dict), + label=_(u'I have read and agree to the Terms of Service'), + error_messages={ 'required': u"You must agree to the terms to register" }) + + +class RegistrationFormUniqueEmail(RegistrationForm): + """ + Subclass of ``RegistrationForm`` which enforces uniqueness of + email addresses. + + """ + def clean_email(self): + """ + Validate that the supplied email address is unique for the + site. + + """ + if User.objects.filter(email__iexact=self.cleaned_data['email']): + raise forms.ValidationError(_(u'This email address is already in use. Please supply a different email address.')) + return self.cleaned_data['email'] + + +class RegistrationFormNoFreeEmail(RegistrationForm): + """ + Subclass of ``RegistrationForm`` which disallows registration with + email addresses from popular free webmail services; moderately + useful for preventing automated spam registrations. + + To change the list of banned domains, subclass this form and + override the attribute ``bad_domains``. + + """ + bad_domains = ['aim.com', 'aol.com', 'email.com', 'gmail.com', + 'googlemail.com', 'hotmail.com', 'hushmail.com', + 'msn.com', 'mail.ru', 'mailinator.com', 'live.com'] + + def clean_email(self): + """ + Check the supplied email address against a list of known free + webmail domains. + + """ + email_domain = self.cleaned_data['email'].split('@')[1] + if email_domain in self.bad_domains: + raise forms.ValidationError(_(u'Registration using free email addresses is prohibited. Please supply a different email address.')) + return self.cleaned_data['email'] diff --git a/troggle/registration/locale/ar/LC_MESSAGES/django.mo b/troggle/registration/locale/ar/LC_MESSAGES/django.mo new file mode 100644 index 0000000000000000000000000000000000000000..07bc79f1242872c701e463e947846ef4e77f8ceb GIT binary patch literal 2135 zcmb`GO>Y}j6oxO*QffYhKrCQ!#Dcy6I+Tvl^ALK%-lJj?>YYCZ?1GEo`4N|6c3G!#`-*whp((Yy+m z-Kr90Rd=-srEvqF+S>K&w8ZwRDP50btrjY+l_pnHD-0U$E!U`8n&vzuwIbbawY(LQ zRCAY>RH%G2>X;Ul20TZCaVY6=c`M{{PW8Cq;1c?>sfHsNd0Y8MfvSxlKzY&+&~%s< z3w;kwRq0dUqvmSh8;Sg$GDd~^BKhs+Ej+}Uwf!0%s{xu9H-k1c+uDo@2_FavRl`_7 z6&~A}l@|1d*qUo>Nv*#O!Wt=AZIE%BO312lmlMTrs}(V#ju_YN1^9MlBqu` z3}eal)QN{$utM<<%OvK);0skXPNC*3qAg51OLMuYPjWZ%w3si?7iMQtWz`Bo)NRVSxU{#R-7r!ir2%LmPTdiQYQ1hlbLYFCTMIT`)+OY?*SF{c@gpRgwgbFt8Js8F>X~IztA(6go@3S{MAyi!7zXaki z`?ib9SJPtHfr}r`&fN@Gz>eI+M)JVgbpEe0pa?4w3p@}92mg_=6F0I0Ju$062%PoO ziTdj-=q`RB&d+EWA|2cDEQeAJX4!#dFIu(VvSp8Z~sGVt;dyNyAm~cwR)@sXJ^ro7AAbs!, YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2007-09-19 19:30-0500\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: forms.py:38 +msgid "username" +msgstr "اسم المستخدم" + +#: forms.py:41 +msgid "email address" +msgstr "عنوان البريد الالكتروني" + +#: forms.py:43 +msgid "password" +msgstr "كلمة المرور" + +#: forms.py:45 +msgid "password (again)" +msgstr "تأكيد كلمة المرور" + +#: forms.py:54 +msgid "Usernames can only contain letters, numbers and underscores" +msgstr "يمكن أن يحتوي اسم المستخدم على احرف، ارقام وشرطات سطرية فقط" + +#: forms.py:59 +msgid "This username is already taken. Please choose another." +msgstr "اسم المستخدم مسجل مسبقا. يرجى اختيار اسم اخر." + +#: forms.py:68 +msgid "You must type the same password each time" +msgstr "يجب ادخال كلمة المرور مطابقة كل مرة" + +#: forms.py:96 +msgid "I have read and agree to the Terms of Service" +msgstr "أقر بقراءة والموافقة على شروط الخدمة" + +#: forms.py:105 +msgid "You must agree to the terms to register" +msgstr "يجب الموافقة على الشروط للتسجيل" + +#: forms.py:124 +msgid "" +"This email address is already in use. Please supply a different email " +"address." +msgstr "عنوان البريد الالكتروني مسجل مسبقا. يرجى تزويد عنوان بريد الكتروني مختلف." + +#: forms.py:149 +msgid "" +"Registration using free email addresses is prohibited. Please supply a " +"different email address." +msgstr "يمنع التسجيل باستخدام عناوين بريد الكترونية مجانية. يرجى تزويد عنوان بريد الكتروني مختلف." + +#: models.py:188 +msgid "user" +msgstr "مستخدم" + +#: models.py:189 +msgid "activation key" +msgstr "رمز التفعيل" + +#: models.py:194 +msgid "registration profile" +msgstr "ملف التسجيل الشخصي" + +#: models.py:195 +msgid "registration profiles" +msgstr "ملفات التسجيل الشخصية" diff --git a/troggle/registration/locale/bg/LC_MESSAGES/django.mo b/troggle/registration/locale/bg/LC_MESSAGES/django.mo new file mode 100644 index 0000000000000000000000000000000000000000..be9adf4d3defce5ee8274e2cb996d8c63100a637 GIT binary patch literal 2302 zcmb7D&u<$=6doW@Fi;QzaR9^<5~875V>f~(ZmF7vP(`Gvl{yh{sV4TsUSjWByJOP` zA(6DAr3iwAdZ{XbxNzX&{4lZNB)uWH&7P6C@E7nG!1reTBZ0IME3dzqH*eni-uK@A z@yx(2f#+$wFXFv}_jz7FfImD}fDUj8cp3O3a2j~zK_T7(&H+yWzXHAn{0%q={0n## z_`*X%JPCXq_$Y7$$hpRV&jM$F&jE|T0pO=V_FDml$n_;~9{ay>_!DscVQ>K+eME>4 zfj5Ak0RIG*fR~TNe0~KI_5%p^67W^v6Torc%fKv)zd)B%POgAO_ox=SUXd2qUsa@ACRr#1DhyRfZb;R@FS+xsR)r*G z%Swid!dkUjULr{acVR&V%F_ogCPl7F<(e>{w z=$I^m=%9!*by|gHEVyNLs4*0*ko{wsL^kk0QhDu67MwYhg-&NEJ2w8_*!c;Xo0z#Y zd2u>1qpE(OoeN>nEjZ_D#n8$58A@a?=A3c#ipRrwM{1R!6RFfmCpGG%M=3p;8BRH= zH&ZD%Iy0*7a`3+2h?5$|F{MvrhEE<(;bvk=hT6#m(hJK{`$2~0%Cg{MQ>WAQ?lM_% zwO>D5(==_0mZO_yhfJ%xvW5-QHjQW*9=otp zbQSBi*)!{=6|F`qra@+l|C(kSCwJ{xgYD7h>>QV38zq2l?C4Dw%aKUWaiL?lvNOZGl6}*0j4XSdV5K z{@a$z9s=$%_q)*G3)2whn_g;I?Gc3ew?7xxyJH!)Yzg25TxXv5*S$l>O^8Fs#qL1Y4YX*5 zplBl=gU#qB!u}jv*Fb!mTR%j$z1MJrCgBGOQ5XgZ#X%qVY@3!aKVZ8GYEY#YGj2UP z*BveH`u#>L=E4KR`t)b1g*{JA6GeW@XVDF0<=(`!7=lZ!h414IQ&Y_AwX~$h^OT_-o)f, YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2007-09-19 19:30-0500\n" +"PO-Revision-Date: 2008-03-05 12:37+0200\n" +"Last-Translator: Vladislav \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Poedit-Bookmarks: -1,-1,-1,-1,10,-1,-1,-1,-1,-1\n" + +#: forms.py:38 +msgid "username" +msgstr "Потребителско име " + +#: forms.py:41 +msgid "email address" +msgstr "Електронна поща" + +#: forms.py:43 +msgid "password" +msgstr "Парола" + +#: forms.py:45 +msgid "password (again)" +msgstr "Парола (проверка)" + +#: forms.py:54 +msgid "Usernames can only contain letters, numbers and underscores" +msgstr "Потребителските имена могат да съдържат букви, цифри и подчертавки" + +#: forms.py:59 +msgid "This username is already taken. Please choose another." +msgstr "Потребителското име е заето. Моля изберето друго." + +#: forms.py:68 +msgid "You must type the same password each time" +msgstr "Грешка при проверка на паролата." + +#: forms.py:96 +msgid "I have read and agree to the Terms of Service" +msgstr "Прочел съм и съм съгласен с условията за експлоатация" + +#: forms.py:105 +msgid "You must agree to the terms to register" +msgstr "Трябва да сте съгласни с условията за да се регистрирате." + +#: forms.py:124 +msgid "This email address is already in use. Please supply a different email address." +msgstr "Адреса на електронната поща е използван. Моля въведете друг адрес." + +#: forms.py:149 +msgid "Registration using free email addresses is prohibited. Please supply a different email address." +msgstr "Регистрациите с безплатни адреси е забранен. Моля въведете различен адрес за електронна поща" + +#: models.py:188 +msgid "user" +msgstr "Потребител" + +#: models.py:189 +msgid "activation key" +msgstr "Ключ за активация" + +#: models.py:194 +msgid "registration profile" +msgstr "регистрационен профил" + +#: models.py:195 +msgid "registration profiles" +msgstr "регистрационни профили" + diff --git a/troggle/registration/locale/de/LC_MESSAGES/django.mo b/troggle/registration/locale/de/LC_MESSAGES/django.mo new file mode 100644 index 0000000000000000000000000000000000000000..b9bc1faa0953a658be81c2df89acaef26762cb74 GIT binary patch literal 1909 zcmbVM&u`pB6ds_Zut2F$fde4D8x7Q3r==y?{!o)9MT?p?N;gGtsb=lB_H^x;)y#O) zjl>0xh$FWik+^c=)Z3o8az)}#K;l2(8+&)tjdB4?_BUg{AK!fMJ^%I2sh_zUnp@XX6XTmwD=UI+dN{22H zvHunL9`J8q;Bop)6ZbqYy#ELo@_z;l`Mb04kAZJup97J;z5@U7F7SK1e$za{Io_D< zkw$=OeFgsW3t0?G`K@ldDFfVnUKqH5jmE?Ux;NsA~hKe&WX`p zB7ec&vvn6qS7jfITC+;0SSALC7hju-%F6j=A>jidp{lI~WP4=iCnM+$v0dOelFl6% zn-a?;C$CBtGVyBMC_dzgSW-vK?H3EWATtnM5lyC9sZfl8D)_{gP6UPON03SETJwYx zA9d5{5srmQcPM=#b!MWam~s0Gwf1;qtdDkFrqXD$%3Rbl9ct}9=tXx>w9qHfmh{}A z%W?d96t73C>$JMwxe`b5)i{P>w8vu=vK+I!47+QctMR8XJX`mq^HI-A?F#9Q?a-G} zYqZ8aRw);B1N^YPUDVsQ(gSk~K02#p#!-)D*`Y12yo0DWQodcNwz1i*)=qb4`{XboN85?!Rq zWuMXPO!q5)Sn14-(e+CArNxFaF4!@88e`{B>d>OOrNc^W!DTjTifh|aVOEr8OGD#8 zut39V+KzTGchN>Oc4%;qV4*){=G(NX(5uMOhvh>=4E~{C!Qr^4)a{TILvSqQfkH1r zHH>@48mIW5aV>4u?u$|Mv#3y{W;mxCNa`6&O$XDT^8%A9Ui8*9oc^YRnXVAGN^<8R zw7y8+$Y5Oyx?k(ytx7OjC}=JV$R>gg<@7mzQko#d$%Q$@{DyKMVpWnu2oz;Dx)udN zoJQMJI?B*9JjMV3 literal 0 HcmV?d00001 diff --git a/troggle/registration/locale/de/LC_MESSAGES/django.po b/troggle/registration/locale/de/LC_MESSAGES/django.po new file mode 100644 index 000000000..96e00ee23 --- /dev/null +++ b/troggle/registration/locale/de/LC_MESSAGES/django.po @@ -0,0 +1,85 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# Jannis Leidel , 2007. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: django-registration 0.3 \n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2007-09-19 19:30-0500\n" +"PO-Revision-Date: 2007-09-29 16:50+0200\n" +"Last-Translator: Jannis Leidel \n" +"Language-Team: Deutsch \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: forms.py:38 +msgid "username" +msgstr "Benutzername" + +#: forms.py:41 +msgid "email address" +msgstr "E-Mail-Adresse" + +#: forms.py:43 +msgid "password" +msgstr "Passwort" + +#: forms.py:45 +msgid "password (again)" +msgstr "Passwort (wiederholen)" + +#: forms.py:54 +msgid "Usernames can only contain letters, numbers and underscores" +msgstr "Benutzernamen können nur Buchstaben, Zahlen und Unterstriche enthalten" + +#: forms.py:59 +msgid "This username is already taken. Please choose another." +msgstr "Dieser Benutzername ist schon vergeben. Bitte einen anderen wählen." + +#: forms.py:68 +msgid "You must type the same password each time" +msgstr "Bitte das gleiche Passwort zur Überprüfung nochmal eingeben" + +#: forms.py:96 +msgid "I have read and agree to the Terms of Service" +msgstr "Ich habe die Nutzungsvereinbarung gelesen und stimme ihr zu" + +#: forms.py:105 +msgid "You must agree to the terms to register" +msgstr "Sie müssen der Nutzungsvereinbarung zustimmen, um sich zu registrieren" + +#: forms.py:124 +msgid "" +"This email address is already in use. Please supply a different email " +"address." +msgstr "" +"Diese E-Mail-Adresse wird schon genutzt. Bitte geben Sie eine andere " +"E-Mail-Adresse an." + +#: forms.py:149 +msgid "" +"Registration using free email addresses is prohibited. Please supply a " +"different email address." +msgstr "" +"Die Registrierung mit einer kostenlosen E-Mail-Adresse ist untersagt. Bitte " +"geben Sie eine andere E-Mail-Adresse an." + +#: models.py:188 +msgid "user" +msgstr "Benutzer" + +#: models.py:189 +msgid "activation key" +msgstr "Aktivierungsschlüssel" + +#: models.py:194 +msgid "registration profile" +msgstr "Registrierungsprofil" + +#: models.py:195 +msgid "registration profiles" +msgstr "Registrierungsprofile" diff --git a/troggle/registration/locale/el/LC_MESSAGES/django.mo b/troggle/registration/locale/el/LC_MESSAGES/django.mo new file mode 100644 index 0000000000000000000000000000000000000000..acc972683e0c03dee9cf816301d9653f1f8bccc3 GIT binary patch literal 2424 zcmbtUO>Y}j6n#LUU_Mn55CWvjiner&-4aOLQq?4G72%{Iae}&n7yHE?YR_0Rr3E=*#C^fI`E}Oh1drE3j7@S z^Ay7hpLKr003n)neQLJQGD1v#e3Q!+==!JGG#qQIq~ zpeUofl27g^4JvQU&MGmW^0ps%GO%5TD!%RHX_Wm{N!mq{xtynbU-@MFRQBA0Jz@tc z7p4B9lD;CpQZ5(ANm9-p9aWxkg2NZ1B2&Q4L%}$dEHb@uvN@-E&~UioIkKbm(g!D+h>kt>HD9$UXGN^7AUYwO2}+rk2N}eU5$%F z-4XZvTMIfV^B{UkG%__ug<*`^MRlan7u+H9!)+4%p8JW)23Akb8b(=|bb|VmUGFEa zq-Z!bFxYdoFEXIYt`}Ine%{Vm?^W`?m2ndk>A#w>x-cu2ht(|um7ue+*gICN(~5Ue zyfbkwX2sfLF*sTSYRu-~2mRu4EB+RpjVIb;Z^Upjl9qm8WjyKlMH#qWf-VoG)6|#j zP0@u^Z?Y$SDcRjUkQyAk2v;Xxk$Gihlq@AEo$R|Z#FQ_j)0c{N)b;WgBfUMnsr{nj z(O9GlbA=AA45pBvK-~!5EEmzg^OP+}&sV{_Lz&A~$G#tPfp)EwlXY{@e}Xz7@`%vi z=q+8ovVa;dD5wcf+}GUf07V(z|+-!Wq36&W2N@7sAQr61Ey!eheqD znADpHvWiesLf<64sn_*7tZU(%Ug03ih&xYuBb;Ynq^)Cv{F}&jCtO6XX{?cxbWQKT zV>_JTT)GaYZRA{J7Hi=b@ZT^8AclnCMKDi*`#LtvV-YW0^;VShEu4XcscnbL*$9`w zWClgSR>i$N#7FT}B;C=qD6=;$SjRcDn8Z2ggGcQi<3%u@HH=|;V74e>5*?d1arc@G zP)dU{=@s;)_TQ*~g(1y^3uayvE`akMxUZ2(xnk;p-79&Gyq~(CEY~Z!T!`R$l`<%-gBm1RRIfs7F)Qt z%HLPrG>tXS8eTPu!UrjuU)BH8s4!o^KUm$zOeghSOs=l0r$jhmW;+K$JAeBZ0Jr;| PvNps)m9q2E`W1fx4LxjP literal 0 HcmV?d00001 diff --git a/troggle/registration/locale/el/LC_MESSAGES/django.po b/troggle/registration/locale/el/LC_MESSAGES/django.po new file mode 100644 index 000000000..cd38eb1b4 --- /dev/null +++ b/troggle/registration/locale/el/LC_MESSAGES/django.po @@ -0,0 +1,84 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# Panos Laganakos , 2007. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2007-09-19 19:30-0500\n" +"PO-Revision-Date: 2007-11-14 21:50+0200\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: forms.py:38 +msgid "username" +msgstr "όνομα χρήστη" + +#: forms.py:41 +msgid "email address" +msgstr "διεύθυνση ηλεκτρονικού ταχυδρομείου" + +#: forms.py:43 +msgid "password" +msgstr "συνθηματικό" + +#: forms.py:45 +msgid "password (again)" +msgstr "συνθηματικό (ξανά)" + +#: forms.py:54 +msgid "Usernames can only contain letters, numbers and underscores" +msgstr "Τα ονόματα χρηστών μπορούν να περιλαμβάνουν μόνο γράμματα, αριθμούς και υπογραμμίσεις" + +#: forms.py:59 +msgid "This username is already taken. Please choose another." +msgstr "Αυτό το όνομα χρήστη χρησιμοποίειται ήδη. Παρακαλώ διαλέξτε ένα άλλο." + +#: forms.py:68 +msgid "You must type the same password each time" +msgstr "Πρέπει να εισάγετε το ίδιο συνθηματικό κάθε φορά" + +#: forms.py:96 +msgid "I have read and agree to the Terms of Service" +msgstr "Διάβασα και συμφωνώ με τους Όρους της Υπηρεσίας" + +#: forms.py:105 +msgid "You must agree to the terms to register" +msgstr "Πρέπει να συμφωνείται με τους όρους για να εγγραφείτε" + +#: forms.py:124 +msgid "" +"This email address is already in use. Please supply a different email " +"address." +msgstr "" +"Η συγκεκριμένη διεύθυνση ηλεκτρονικού ταχυδρομείου χρησιμοποιείται ήδη. " +"Παρακαλώ δώστε κάποια άλλη." + +#: forms.py:149 +msgid "" +"Registration using free email addresses is prohibited. Please supply a " +"different email address." +msgstr "" +"Η εγγραφή μέσω δωρεάν διευθύνσεων ηλεκτρονικού ταχυδρομείου απαγορεύεται. ""Παρακαλώ δώστε κάποια άλλη." + +#: models.py:188 +msgid "user" +msgstr "χρήστης" + +#: models.py:189 +msgid "activation key" +msgstr "κλειδί ενεργοποίησης" + +#: models.py:194 +msgid "registration profile" +msgstr "προφίλ εγγραφής" + +#: models.py:195 +msgid "registration profiles" +msgstr "προφίλ εγγραφών" diff --git a/troggle/registration/locale/en/LC_MESSAGES/django.mo b/troggle/registration/locale/en/LC_MESSAGES/django.mo new file mode 100644 index 0000000000000000000000000000000000000000..4728fe062f9baac03c648bc2102e16292b50f838 GIT binary patch literal 367 zcmYL^K~KUk7=|%=+R?Lz9=z#?MMGp236&LGY&S9niQX#IS%dA;6{A1IzvpkUON_k9 zlOFnf?fd;4AANU14gx2E)4*ZiJkVwk=!eTVoUQYpxwCI-?IGR3O1VZ`L(rT~9_Wmr z6)P5Lo<)VKt@9w7N^jt9S2a*tf}(j|!o(@*!w@9WD}pXDz6KmaFGjtXTw%a{jDrY; z`q1s;f8Hab1&ACHitckF(zB;LV-c5)htf&YY^Ar3py`rxlu^OZkO`XdF-?+!Ef%Ao znrbI21*MYj1aX?pmTl!B=i{yJT33xCkqWk7s@KKQ#2T+m_~WY%Wxe|J7xh+ZbA#5e e(lyH8F3Twl_FmiNMLA$*Z8zFf1Pz|Gk2=2%fMUP^ literal 0 HcmV?d00001 diff --git a/troggle/registration/locale/en/LC_MESSAGES/django.po b/troggle/registration/locale/en/LC_MESSAGES/django.po new file mode 100644 index 000000000..37bc9e2ff --- /dev/null +++ b/troggle/registration/locale/en/LC_MESSAGES/django.po @@ -0,0 +1,81 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2007-09-19 19:30-0500\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: forms.py:38 +msgid "username" +msgstr "" + +#: forms.py:41 +msgid "email address" +msgstr "" + +#: forms.py:43 +msgid "password" +msgstr "" + +#: forms.py:45 +msgid "password (again)" +msgstr "" + +#: forms.py:54 +msgid "Usernames can only contain letters, numbers and underscores" +msgstr "" + +#: forms.py:59 +msgid "This username is already taken. Please choose another." +msgstr "" + +#: forms.py:68 +msgid "You must type the same password each time" +msgstr "" + +#: forms.py:96 +msgid "I have read and agree to the Terms of Service" +msgstr "" + +#: forms.py:105 +msgid "You must agree to the terms to register" +msgstr "" + +#: forms.py:124 +msgid "" +"This email address is already in use. Please supply a different email " +"address." +msgstr "" + +#: forms.py:149 +msgid "" +"Registration using free email addresses is prohibited. Please supply a " +"different email address." +msgstr "" + +#: models.py:188 +msgid "user" +msgstr "" + +#: models.py:189 +msgid "activation key" +msgstr "" + +#: models.py:194 +msgid "registration profile" +msgstr "" + +#: models.py:195 +msgid "registration profiles" +msgstr "" diff --git a/troggle/registration/locale/es/LC_MESSAGES/django.mo b/troggle/registration/locale/es/LC_MESSAGES/django.mo new file mode 100644 index 0000000000000000000000000000000000000000..3872adf0a0eed30b1ec9fa6410addb3c6db915cf GIT binary patch literal 1909 zcmb7^zmFU>6vqt&0tegqGU+h77t!JFWZ;78!eM}>GBybfLfzX4wZe+4(dzrkn0R~{4M6!<#$ zB)A1eU+;l0fCu1F{1NXF zZN>rf0-<&z#=jiVCZrGuv(uvoK7}cEXe=j8j%7j8V3v-Vf~7EK%GuSP?1-+in`p)2 zfJ^OzlR;ZUt=FccQQXh9)D_91aO^#M(w-V;$NEqQE>haBSb8SkHcd4pNrfJb*s%%g z2UC%cadORAG$pGT-jsCo$^X|JjyNN0UbPhDEjITIsj;;PPa2C$yHs3TobaTiA!`t` zvL;CQuQ&vD{ydqsKE$HatThFe%Hs0k6WdbV`min}&Ok`0>N)}09q$X%26{tmA7gB! z_n%o;5KA?tplcRV1wEN7ev7AKO&zh^e{VtOWQjmG#N5*&RY=B2SNyLZy@(2Rk0_Ja zclL-?NOp?kIT=Udyi}TgUrigedJ~Xp}9`9s}A!5A?)` zjMAC?Tv$T=D{c^ZWl<5cpIogCRs{;6Ycg%cuv*lKvnY6UC17ILI95u}?wYt8<>uHD zSICvax2QuI(~So5VfOv90SlY%TSp@~!4q|Wd?~0c$)b-}Y^Gv&_4U78Oy$D7*W3l> zWg*c?OBWCIF!X`R*!s|MwBPzxIt@vdHmzzKiGYvI!I`op$6&44g--L+onDLMp8V`? zWvOYoVAFLf8+Nf(os6A2`=w@wqf;td+#Ekohw{jJk>dt<`Lspr$COB%S<6Wyq0qAC zUEtLd+90B$RT_sR)!Nsxa}Ad~yMr}kp$UI3R26?;aoc$xcli?!r1HK@iuil8Ftxg- fb6wV8cSAJn(9_ZKB1F6RggdQ%T*xFI&|UlkAoEAZ literal 0 HcmV?d00001 diff --git a/troggle/registration/locale/es/LC_MESSAGES/django.po b/troggle/registration/locale/es/LC_MESSAGES/django.po new file mode 100644 index 000000000..ba0384fe5 --- /dev/null +++ b/troggle/registration/locale/es/LC_MESSAGES/django.po @@ -0,0 +1,85 @@ +# Spanish translation for django-registration. +# Copyright (C) 2007, James Bennet +# This file is distributed under the same license as the registration package. +# Ernesto Rico Schmidt , 2008. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: django-registration 0.3 \n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2008-03-11 00:19-0400\n" +"PO-Revision-Date: 2008-03-11 00:19-0400\n" +"Last-Translator: Ernesto Rico Schmidt \n" +"Language-Team: Español \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: forms.py:38 +msgid "username" +msgstr "nombre de usuario" + +#: forms.py:41 +msgid "email address" +msgstr "dirección de coreo electrónico" + +#: forms.py:43 +msgid "password" +msgstr "contraseña" + +#: forms.py:45 +msgid "password (again)" +msgstr "contraseña (otra vez)" + +#: forms.py:54 +msgid "Usernames can only contain letters, numbers and underscores" +msgstr "Los nombres de usuarios sólo pueden contener letras, números y guiones bajos" + +#: forms.py:59 +msgid "This username is already taken. Please choose another." +msgstr "Este nombre de usuario ya está ocupado. Por favor escoge otro" + +#: forms.py:71 +msgid "You must type the same password each time" +msgstr "Tienes que introducir la misma contraseña cada vez" + +#: forms.py:100 +msgid "I have read and agree to the Terms of Service" +msgstr "He leído y acepto los términos de servicio" + +#: forms.py:109 +msgid "You must agree to the terms to register" +msgstr "Tienes que aceptar los términos para registrarte" + +#: forms.py:128 +msgid "" +"This email address is already in use. Please supply a different email " +"address." +msgstr "" +"La dirección de correo electrónico ya está siendo usada. Por favor" +"proporciona otra dirección." + +#: forms.py:153 +msgid "" +"Registration using free email addresses is prohibited. Please supply a " +"different email address." +msgstr "" +"El registro usando una dirección de correo electrónico gratis está prohibido." +"Por favor proporciona otra dirección." + +#: models.py:188 +msgid "user" +msgstr "usuario" + +#: models.py:189 +msgid "activation key" +msgstr "clave de activación" + +#: models.py:194 +msgid "registration profile" +msgstr "perfil de registro" + +#: models.py:195 +msgid "registration profiles" +msgstr "perfiles de registro" diff --git a/troggle/registration/locale/es_AR/LC_MESSAGES/django.mo b/troggle/registration/locale/es_AR/LC_MESSAGES/django.mo new file mode 100644 index 0000000000000000000000000000000000000000..ce8b4e56c8250021193dd307b05b803d3fbba025 GIT binary patch literal 1849 zcmb7^&2Jk;7{&)E6wFttKp=s{dus!%aX^K{O{18^ZLQi#&=%4NF8bRH{P9j=ACEW*AFgV_)4H% zLVpeYYxI}H_z^tN?t>9H13v=41vkNqj|%Y~xCdSbzXY#3R>7aZ9{4A?2HtpL zzW--n(EqOHFW}So{X6&y_yD{N{#Ac(T*R61`*l2C0Iz`9zG@->N8%jtXlgYF~LynzWsLqYE6<1pDVc@vW~9QN{IGIZVztcqw33(iSRV_;6Jrpb)CPyPO|e_Aa1={TMkD6f zXfLsU#@@4aZ;>wZeGDqkN}XUB8ysHTH6`Vx^Jk638W;&zZDk&g zAw8lE>A6ksv|8^+t>tKOnHHDZ@3x}WwN?ugqajaK5U=Om?RJLIU@O|_(Cw}Ep!ep7 zTbtcRUpgO+tkf=(-q<$X-0k;ivoq+@N_Wud_18KZ8^i9-&MKzrw3I1FBbIra`kl>N zyCLM2et#`fO=Hv5#-KOoo*Zhi*=nrgUXh2<2)EEC&-eY?MF#(_Q#_H@vA?l9x*08< z%nPv~ccZS3O@jPy(-M-rA#O8r%_1!R);_8YC)-qqpGe_++wMaJrF+p=BTm~i3B#5#&U`$T)&pt9gPPzbxnGihtQH{sFN^CdB{% literal 0 HcmV?d00001 diff --git a/troggle/registration/locale/es_AR/LC_MESSAGES/django.po b/troggle/registration/locale/es_AR/LC_MESSAGES/django.po new file mode 100644 index 000000000..fb746b5b9 --- /dev/null +++ b/troggle/registration/locale/es_AR/LC_MESSAGES/django.po @@ -0,0 +1,83 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) 2008 Leonardo Manuel Rocha +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2007-09-19 19:30-0500\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: forms.py:38 +msgid "username" +msgstr "nombre de usuario" + +#: forms.py:41 +msgid "email address" +msgstr "dirección de e-mail" + +#: forms.py:43 +msgid "password" +msgstr "contraseña" + +#: forms.py:45 +msgid "password (again)" +msgstr "contraseña (nuevamente)" + +#: forms.py:54 +msgid "Usernames can only contain letters, numbers and underscores" +msgstr "El nombre de usuario solo puede contener letras, números y guiones bajos" + +#: forms.py:59 +msgid "This username is already taken. Please choose another." +msgstr "Ese nombre de usuario ya está asignado. Por favor elija otro." + +#: forms.py:68 +msgid "You must type the same password each time" +msgstr "Debe tipear la misma contraseña cada vez" + +#: forms.py:96 +msgid "I have read and agree to the Terms of Service" +msgstr "He leído y estoy de acuerdo con las Condiciones de Servicio" + +#: forms.py:105 +msgid "You must agree to the terms to register" +msgstr "Debe estar de acuerdo con las Condiciones para poder registrarse" + +#: forms.py:124 +msgid "" +"This email address is already in use. Please supply a different email " +"address." +msgstr "Esa dirección de e-mail ya está en uso. Por favor provea otra " +"dirección." + +#: forms.py:149 +msgid "" +"Registration using free email addresses is prohibited. Please supply a " +"different email address." +msgstr "La registración con un e-mail gratuito está prohibida. Por favor " +"de una dirección de e-mail diferente." + +#: models.py:188 +msgid "user" +msgstr "usuario" + +#: models.py:189 +msgid "activation key" +msgstr "clave de activación" + +#: models.py:194 +msgid "registration profile" +msgstr "perfil de registro" + +#: models.py:195 +msgid "registration profiles" +msgstr "perfiles de registro" diff --git a/troggle/registration/locale/fr/LC_MESSAGES/django.mo b/troggle/registration/locale/fr/LC_MESSAGES/django.mo new file mode 100644 index 0000000000000000000000000000000000000000..f8911c7ec65960e02435383ea87d2d79adc420db GIT binary patch literal 1883 zcmb7^%WfP+6oxAh2n_cK#DXB5-NcX{+KvEwVxk0-fRPQBGq%JERl3gfl+#_+)McHPwJu=c?WJODojAAz5MmmU-19dH-C0e%bi!C%1z@GtOr@U_Q@$I z%iuQn3Rr>{!LPt{?rU%zvAzLU@%=mgSb~?Iz&`j8O#8opTi}H!g;)c(!LzhzY*T(Ov^(8Tx<|4}E7>5`cBTA} z7u*O)A&_RPM-O}&k65RPoH99VPCEJsz`T6Xp#EVl;u}oU`Og zRw=y$(kUkYUw1HZM%H}RQ;-kXoH!~b)*?M=EH3Q^V&}-hQy~pmgPaR%f<*j^Lty8x zk%{$vytJA{qwrc-TwZ);Bh}G|c_Co~A)%^k1!Q-6E*vz_8)EyEV)gq)_{lWD;A>?r{;ab(QVn zTB!7p)Sfh@&E|aOgX`4W=Ek~^ZTeEH?EP5!Y-ESj+xm2rt)XbCPqGhW;2|yL`MX)Z zk}a;#;>z%Pp5<@nISyvqJk=@6xpPZ7E#^4)X1<7X8`6htD=f?2$x6t&ZKTN)N0nZ}v9VH}9NYba9aP z)=+EoW;Q})h7@=|ywz0D^ad3Z={$$`c1Cxz<&Fs+0w5|F(L08(hs)>!hHokDWX=e>HT2M4-(r(0# zhD7zFL2uSgU@B4Ts4-G#K8+hV#K5rZa@1AD4~Y%7mHr~K>paEacp%nNN1t<>T&UUM z-t0$;ZA!Dl|Ky1p&r#Vng>&}viD2ST^OOh4E{zTJerJqJHXK7ca%^x28IyuOY4$K; z*H8xh|G--kwqgva!;H*+a+o0-D_ug-f!MVXlJXQc@5INolggOnWAUNhso>Pu=xCa( zI^i9Q6YWlfL%4eOGX}M`kf@tiWQPW5ohy#}sY~j{i=slgRsVE+#a!*gSr2m`bajfB g&|_V+ov4mQ|9dWdoy5{We@r5`#(djAv0Y}F-M*si- literal 0 HcmV?d00001 diff --git a/troggle/registration/locale/fr/LC_MESSAGES/django.po b/troggle/registration/locale/fr/LC_MESSAGES/django.po new file mode 100644 index 000000000..34b520b8b --- /dev/null +++ b/troggle/registration/locale/fr/LC_MESSAGES/django.po @@ -0,0 +1,81 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# Samuel Adam , 2007. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: django-registration 0.3 \n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2007-09-19 19:30-0500\n" +"PO-Revision-Date: 2007-09-20 10:30+0100\n" +"Last-Translator: Samuel Adam \n" +"Language-Team: Français \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: forms.py:38 +msgid "username" +msgstr "pseudo" + +#: forms.py:41 +msgid "email address" +msgstr "adresse email" + +#: forms.py:43 +msgid "password" +msgstr "mot de passe" + +#: forms.py:45 +msgid "password (again)" +msgstr "mot de passe (vérification)" + +#: forms.py:54 +msgid "Usernames can only contain letters, numbers and underscores" +msgstr "Le pseudo ne peut contenir que des lettres, chiffres et le caractère souligné." + +#: forms.py:59 +msgid "This username is already taken. Please choose another." +msgstr "Ce pseudo est déjà utilisé. Veuillez en choisir un autre." + +#: forms.py:68 +msgid "You must type the same password each time" +msgstr "Veuillez indiquer le même mot de passe dans les deux champs" + +#: forms.py:96 +msgid "I have read and agree to the Terms of Service" +msgstr "J'ai lu et accepté les Conditions Générales d'Utilisation" + +#: forms.py:105 +msgid "You must agree to the terms to register" +msgstr "Vous devez accepter les conditions d'utilisation pour vous inscrire" + +#: forms.py:124 +msgid "" +"This email address is already in use. Please supply a different email " +"address." +msgstr "Cette adresse email est déjà utilisée. Veuillez en indiquer une autre." + +#: forms.py:149 +msgid "" +"Registration using free email addresses is prohibited. Please supply a " +"different email address." +msgstr "L'inscription avec une adresse email d'un compte gratuit est interdite. Veuillez en indiquer une autre." + +#: models.py:188 +msgid "user" +msgstr "utilisateur" + +#: models.py:189 +msgid "activation key" +msgstr "clé d'activation" + +#: models.py:194 +msgid "registration profile" +msgstr "profil d'inscription" + +#: models.py:195 +msgid "registration profiles" +msgstr "profils d'inscription" diff --git a/troggle/registration/locale/he/LC_MESSAGES/django.mo b/troggle/registration/locale/he/LC_MESSAGES/django.mo new file mode 100644 index 0000000000000000000000000000000000000000..be936503238a6df8192233f1fe242e7e60d41895 GIT binary patch literal 1896 zcmb7C&u<$=6ds@uFh9i)Ayf|UMpL@R2?7Nd5KxMUs38h&MGqC4>^`rT*t^!uIIRy{ zxFRG+wEM2 z%$G5Tm@mru0sJs-00UqL_$BZF_$hGdL8aaVUICs5eg}L7_#1E;_!sag;OU2ydJ=dR z_$Y7 z1HOfA5BMDLci>CFd%yzl@9Fu{(xlGQK)HV%DEAfM)4(r)2%ith{|QXVPwtL})baRq z16qYt^C9^k4bUh^p^#>-hs1acQ>{~7?=TtG5$O~&Hq7KQa&@LEo2I3#MxV3UNkUee z94FQp?UF2|woTHQYGTh#ois>Ckzs4uQevrPvU;+WIF5?6(O_+vY`fKJbVyT_)M{)v zb&HNgRjtEwflR1$L(=O|A~E^@(!s@~y2Aryg*v4y zMb2TCI*s@Zc8-lbM`^pcg+;DeJB_dmGZe3`W^HP=ty>flJ`fVBnp{9OGdtI5L2rm{ zCC8Sw_IhR_Vjb4WB~4a3bji*{@ony?1$ESs{qcg%=opDEt4XA3tI&*E(%=&htrCUu zpU9*(O!gIrE?AF(D<}({E>F{*kQFw$l^GXQY@9^F2kqDf)vQc~jnAsV1vEF-e^p z3BBFK?!D%=&1$X~X2qoOZsC$n0{n9e7#UvuUwp!vQjJ+E})xueL)r4 zm&x%B_gbp~)y`8`*T%AY=W_L7t=6{@aoI7hNrFkfj{(JKlTIiec$tU z{Vl&Y*$x4BaEF_oANc{!`+lUbImBj!&293#{%8L^4#p%-*kW-LS6zQd_zl7TBd+^k z0?!XHxdWbom~|1X?+=S4Q3$4Y{k}gSBrwK#&eVkmxQlB3ur~|PyFbJjBz;izglPA_ z>E{wXiZha;dPs4EEby1Ia>D!Qc99#>mpb5#6i2y0C~VGofF$}TZ6LHm5Z}UbNGJ-0 zc5x-5;eU?u>P09J^r2cGU+y&qy$AvU{cQ!gh3%&an{;bReR8kRr-|i3?sijx=F&@K zNF)s(VD8CgALP=TJkB1r2rVXZj@;Eu_kT53%~, 2008. +# , fuzzy +# <>, 2008. +# +# +msgid "" +msgstr "" +"Project-Id-Version: registration\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2008-02-10 02:01+0200\n" +"PO-Revision-Date: 2008-02-10 02:05+0200\n" +"Last-Translator: Meir Kriheli \n" +"Language-Team: Hebrew\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit" + +#: forms.py:38 +msgid "username" +msgstr "שם משתמש" + +#: forms.py:41 +msgid "email address" +msgstr "דואר אלקטרוני" + +#: forms.py:43 +msgid "password" +msgstr "סיסמה" + +#: forms.py:45 +msgid "password (again)" +msgstr "סיסמה (שוב)" + +#: forms.py:54 +msgid "Usernames can only contain letters, numbers and underscores" +msgstr "שמות משתמש יכולים להכיל רק אותיות, ספרות וקווים תחתונים" + +#: forms.py:59 +msgid "This username is already taken. Please choose another." +msgstr "שם המשתמש תפוס כבר. נא לבחור אחר." + +#: forms.py:64 +msgid "You must type the same password each time" +msgstr "יש להקליד את אותה הסיסמה פעמיים" + +#: forms.py:93 +msgid "I have read and agree to the Terms of Service" +msgstr "קראתי והסכמתי לתנאי השימוש" + +#: forms.py:102 +msgid "You must agree to the terms to register" +msgstr "עליך להסכים לתנאי השימוש" + +#: forms.py:121 +msgid "" +"This email address is already in use. Please supply a different email " +"address." +msgstr "" +"כתובת הדואר האלקטרוני תפוסה כבר. נא לספק כתובת דואר אחרת." + +#: forms.py:146 +msgid "" +"Registration using free email addresses is prohibited. Please supply a " +"different email address." +msgstr "" +"הרישום בעזרת תיבת דואר אלקטרוני חינמית אסור. נא לספק כתובת אחרת." + +#: models.py:188 +msgid "user" +msgstr "משתמש" + +#: models.py:189 +msgid "activation key" +msgstr "מפתח הפעלה" + +#: models.py:194 +msgid "registration profile" +msgstr "פרופיל רישום" + +#: models.py:195 +msgid "registration profiles" +msgstr "פרופילי רישום" + diff --git a/troggle/registration/locale/it/LC_MESSAGES/django.mo b/troggle/registration/locale/it/LC_MESSAGES/django.mo new file mode 100644 index 0000000000000000000000000000000000000000..83ec9ddb1646693415fb7b3a37786f84d642c655 GIT binary patch literal 1864 zcmb7^OLH7G5XS`x1eRyDM_5DFa>`A zqut-Z7r;NkX!im5GWa+6I(X*Xgcm@3Qp?~o;8hUUw=MerEPC`W+M2caj<`3rcowd< zE#5P0Fry%af}5=#9q?&%wM7FS2|3|{*r1nAgo33o5bBE?da?&}OWa83qV}ZJJ~$5A z8fv^YB^|{5GGtv57ljk=#gq0_J3G+(I!KYyZYAu6d{fuen3xKEa3D@hIDIfx{Q*v% zG8Rp772O+?j(5tVn!^!icqk_=1wIrrHh4w3;=hz%aLXy!yg6G;Dl0EhNrBNT}*s0mU8f3*#DkLu?;?tl9gott&`4 zA5hRkQJe=onkarKV|7X$HQPTQ&;plmbWu%inuZF&IM9{+??UOUr-PNSG zO1;(Woo>=y?sl;;*^`luHjnqMU@cj?LcQgzyL_>Wlbvn$A?Z6dzT#kAMmKeCE2eFB z)-zo-n0^rCFn&&rg!gd5lns}X^o55RZ3V70;@R2R+SxpQMlbDlt|5}hyrd7^GYWDq zT&gQ5wnq7YotLnFyMH5DIo=oDK(;2ECbtDLKBE<+b?5WsBQXMfqko@l@V->kOMAWa za%Z<{99PK=i=byjrf%nceQAv*!}SG2Z>&>qajm1S>wKW`E))f!5?z~OmZY862;7LB z;3L8DLLWgo9hcgQ#7u4TG^rfNMTx13N-4C{M@M>EOl8aiPXDfRtdCPir<$&|6k^d?3@=4KiXB~!YUOIc~W zV&+eZe<_#txIX^5-);$-iBbKDGrT8RzulYNg%0dUwc~` zCO#=Kq?<~tHm2*kRVYS)$%m-gagD-&rje}zs~AK4jm8*;Sgvg-)I*xhi*!Dq1)MOA d9oa=SsnIqMW{ys*OcvUxpI(?qqE5)E{sRa2Dzg9p literal 0 HcmV?d00001 diff --git a/troggle/registration/locale/it/LC_MESSAGES/django.po b/troggle/registration/locale/it/LC_MESSAGES/django.po new file mode 100644 index 000000000..00129b044 --- /dev/null +++ b/troggle/registration/locale/it/LC_MESSAGES/django.po @@ -0,0 +1,82 @@ +# translation of django.po to Italiano +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# +# Nicola Larosa , 2008. +msgid "" +msgstr "" +"Project-Id-Version: django\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2007-09-19 19:30-0500\n" +"PO-Revision-Date: 2008-05-27 15:05+0200\n" +"Last-Translator: Nicola Larosa \n" +"Language-Team: Italiano\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: KBabel 1.11.4\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: forms.py:38 +msgid "username" +msgstr "nome utente" + +#: forms.py:41 +msgid "email address" +msgstr "indirizzo email" + +#: forms.py:43 +msgid "password" +msgstr "password" + +#: forms.py:45 +msgid "password (again)" +msgstr "password (di nuovo)" + +#: forms.py:54 +msgid "Usernames can only contain letters, numbers and underscores" +msgstr "I nomi utente possono contenere solo lettere, numeri e sottolineature" + +#: forms.py:59 +msgid "This username is already taken. Please choose another." +msgstr "Questo nome utente è già usato. Scegline un altro." + +#: forms.py:68 +msgid "You must type the same password each time" +msgstr "Bisogna inserire la stessa password ogni volta" + +#: forms.py:96 +msgid "I have read and agree to the Terms of Service" +msgstr "Dichiaro di aver letto e di approvare le Condizioni di Servizio" + +#: forms.py:105 +msgid "You must agree to the terms to register" +msgstr "Per registrarsi bisogna approvare le condizioni" + +#: forms.py:124 +msgid "This email address is already in use. Please supply a different email " +"address." +msgstr "Questo indirizzo email è già in uso. Inserisci un altro indirizzo email." + +#: forms.py:149 +msgid "Registration using free email addresses is prohibited. Please supply a " +"different email address." +msgstr "La registrazione con indirizzi email gratis non è permessa. " +"Inserisci un altro indirizzo email." + +#: models.py:188 +msgid "user" +msgstr "utente" + +#: models.py:189 +msgid "activation key" +msgstr "chiave di attivazione" + +#: models.py:194 +msgid "registration profile" +msgstr "profilo di registrazione" + +#: models.py:195 +msgid "registration profiles" +msgstr "profili di registrazione" + diff --git a/troggle/registration/locale/ja/LC_MESSAGES/django.mo b/troggle/registration/locale/ja/LC_MESSAGES/django.mo new file mode 100644 index 0000000000000000000000000000000000000000..e0332b0e7cce033c22f9b774b117cf5d78e6becd GIT binary patch literal 2035 zcmbu8%WoS+9LEPJl$!Do0)YgF;Y0(hS+_hAH&lg^Ng zr0i}=X&!2uCWHV|X@I08O+zW~0y!WdapjD-O#I-;f53OPb{s=fff#B0*`578zrXSC z_ivjaSodK+iv0ohL+be!{9p}(8dw5f0~f(p!R@ya@*H>++zU>EkAuH}ZQ!5aJ>Vm^ z5pp;91b8Rd4ys%)f)9ZG;DewEZUf&0m0bWHM6PjA<@psK$G{!86H)}H!3-F?gOC*X zI@ksN40eJ$w-fRh*bS=qgW$cO4?YZ@t#hf)pTHeB{|(#;RzReWma1Q!srpom#!`LU zRewQRf>NWU>TfKBA&`Qg+(?fYsPd3*nq@G%+A%Bj09(To4)Gp?a;~~y6`(i77OKVq6XFfWO;gT{EcL8BC(Q7yq3end@)BuLhcxUr9_TJ+qR=*S zJyU&D7)Hj*@f#irq7;gLluV@0bq2WMY29hoC;%`H-cu zH0|0oJ)!MM(1f1ctv{)Ez^;c0PfNMX7CGiQZjv6(T6T%iLxY$a?HnE!St0h97$zAv zocKUtA6#s+$V{%KILjyLE3Ck5jxl%k^z6@BamO|H#d^DYyP91l;(F`=291lUr7)Hx z_4u&&bRh>p_fjLvT*18;j-(E1?M*vX6E3sXWgAW!e~2V)$E}YM8GI?j?`3#S2H%$7 z{4fc1WICZ{zRkiMd_oy#_$^R zn3DlIIxhns5+QVb^8RvT;L4!9cA~Zb0}L#X!B{g2jHLgr49}{8hpW*oIEBfVPkd4y zdtcp?n>ec?1NgipgO6l57Zv}t3>RgH`d9EuZg>@N+LG???{rsn{=3@JWE-jX7|zNN X;V}0LGWb}A%Uget4XF{dDLVNJiZWT^ literal 0 HcmV?d00001 diff --git a/troggle/registration/locale/ja/LC_MESSAGES/django.po b/troggle/registration/locale/ja/LC_MESSAGES/django.po new file mode 100644 index 000000000..afaaf948b --- /dev/null +++ b/troggle/registration/locale/ja/LC_MESSAGES/django.po @@ -0,0 +1,78 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# Shinya Okano , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: django-registration 0.4 \n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2007-09-19 19:30-0500\n" +"PO-Revision-Date: 2008-01-31 10:20+0900\n" +"Last-Translator: Shinya Okano \n" +"Language-Team: Japanese \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: forms.py:38 +msgid "username" +msgstr "ユーザ名" + +#: forms.py:41 +msgid "email address" +msgstr "メールアドレス" + +#: forms.py:43 +msgid "password" +msgstr "パスワード" + +#: forms.py:45 +msgid "password (again)" +msgstr "パスワード (確認)" + +#: forms.py:54 +msgid "Usernames can only contain letters, numbers and underscores" +msgstr "ユーザ名には半角英数とアンダースコアのみが使用できます。" + +#: forms.py:59 +msgid "This username is already taken. Please choose another." +msgstr "このユーザ名は既に使用されています。他のユーザ名を指定してください。" + +#: forms.py:68 +msgid "You must type the same password each time" +msgstr "同じパスワードを入力する必要があります。" + +#: forms.py:96 +msgid "I have read and agree to the Terms of Service" +msgstr "サービス利用規約を読み、同意します。" + +#: forms.py:105 +msgid "You must agree to the terms to register" +msgstr "登録するためには規約に同意する必要があります。" + +#: forms.py:124 +msgid "This email address is already in use. Please supply a different email address." +msgstr "このメールアドレスは既に使用されています。他のメールアドレスを指定して下さい。" + +#: forms.py:149 +msgid "Registration using free email addresses is prohibited. Please supply a different email address." +msgstr "自由なメールアドレスを使用した登録は禁止されています。他のメールアドレスを指定してください。" + +#: models.py:188 +msgid "user" +msgstr "ユーザ" + +#: models.py:189 +msgid "activation key" +msgstr "アクティベーションキー" + +#: models.py:194 +msgid "registration profile" +msgstr "登録プロファイル" + +#: models.py:195 +msgid "registration profiles" +msgstr "登録プロファイル" + diff --git a/troggle/registration/locale/nl/LC_MESSAGES/django.mo b/troggle/registration/locale/nl/LC_MESSAGES/django.mo new file mode 100644 index 0000000000000000000000000000000000000000..9e84eb3ed60d06c9e37b1d48fa0edf3b5410f230 GIT binary patch literal 1898 zcmbW1&u<$=6vqcBl$xKaia5aGAr2(aHBJgB+9XxeG>rmINrO{_IH2+F^Lpalnbpj! zT~~qw2QG*sH}3o$9QhA8@h5<|bKpC>c5I^xsf@h-%*?)d^XB{J?eAAF{V330#q%bf zpYXgM`cL5x?I9R}Q}8SBXYd|)`Dr0O0v~|e;1A$C;IH61_!syx_{K9ryac`rJ`Zkz zVXr;#8h8r624>(T@M|#GeG4Yo>wEA9#(&~vAAI{+A?}0UfuDoFfyZFyIU#O?-+}8h91s_1Sm_yn^w4FvR^Oi0$hZ`~)8%zE|p*<}aM%h1nSH z1wyS`h=1PTMnDRIFl)bc4B_Pw4ds~0vP?;8Jeg%CZ^#dsdTa|vW{aF2q<$=O)Ic z#4;I@R|N~1cr|VmAMsSIs3Yd~7adxY83J7w%}%paAsGXe^J6ES2nyAIK_+ox%{eDN zI!dDlI2JM;&%$n;wNAM-)ai?h>h9e;Jli`wpq*~_R<7E{W;a{MN5=OK~e{RH0%j(u(~&BcY0@ zz?g$|ND%5LnpGq2W1Buv4ACkSk@HnQS3GEpQS5A2ZN(jhcT1~7$)LPb6m$ryZ!0x= zLXSAfd?hZEma_OCPXFzqEe@MtYL^9$4rw$X^E?Q#T%|=gC8kuCF^)|5d@+~j_(=5` zWrfrSX$u1lXHr9TlzkBO@%b?Yd!g#4mYo, YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: registration\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2008-08-14 13:25+0200\n" +"PO-Revision-Date: 2008-08-14 13:25+0200\n" +"Last-Translator: Joost Cassee \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: forms.py:38 +msgid "username" +msgstr "gebruikersnaam" + +#: forms.py:41 +msgid "email address" +msgstr "e-mail adres" + +#: forms.py:43 +msgid "password" +msgstr "wachtwoord" + +#: forms.py:45 +msgid "password (again)" +msgstr "wachtwoord (opnieuw)" + +#: forms.py:54 +msgid "Usernames can only contain letters, numbers and underscores" +msgstr "Gebruikersnamen kunnen alleen letters, nummer en liggende streepjes bevatten." + +#: forms.py:59 +msgid "This username is already taken. Please choose another." +msgstr "Deze gebruikersnaam is reeds in gebruik. Kiest u alstublieft een andere gebruikersnaam." + +#: forms.py:71 +msgid "You must type the same password each time" +msgstr "U moet twee maal hetzelfde wachtwoord typen." + +#: forms.py:100 +msgid "I have read and agree to the Terms of Service" +msgstr "Ik heb de servicevoorwaarden gelezen en ga akkoord." + +#: forms.py:109 +msgid "You must agree to the terms to register" +msgstr "U moet akkoord gaan met de servicevoorwaarden om u te registreren." + +#: forms.py:125 +msgid "This email address is already in use. Please supply a different email address." +msgstr "Dit e-mail adres is reeds in gebruik. Kiest u alstublieft een ander e-mail adres." + +#: forms.py:151 +msgid "Registration using free email addresses is prohibited. Please supply a different email address." +msgstr "U kunt u niet registreren met een gratis e-mail adres. Kiest u alstublieft een ander e-mail adres." + +#: models.py:191 +msgid "user" +msgstr "gebruiker" + +#: models.py:192 +msgid "activation key" +msgstr "activatiecode" + +#: models.py:197 +msgid "registration profile" +msgstr "registratieprofiel" + +#: models.py:198 +msgid "registration profiles" +msgstr "registratieprofielen" diff --git a/troggle/registration/locale/pl/LC_MESSAGES/django.mo b/troggle/registration/locale/pl/LC_MESSAGES/django.mo new file mode 100644 index 0000000000000000000000000000000000000000..1f2a228861c28105aae351cdeded9976e68bbd76 GIT binary patch literal 1769 zcmb7^&u=3&6vquLEE|3=AP#VNH@46TN!hY(cByt*id58=s-%nHf}EL`iIW*SvOUet zNN}h?NFWXzIH2Xmf&YM0xits)12}Ty58yxG>q+`cMMzk2J|53|&(Ggy&!1N>eJ{|S zMSlhTNA#D%_#ynE-3KGE1V06T2Dib>4-4@Ycn`b@eha<|{su09e}hkhFFzv0Q{Zdh zf+=_j{0t0s2Vfg(eFKKLzv5+B|1WS2Tz^!E8{ik z!t)*QIWPmC06z!u6JO8gzXPx0`6uvs@E0)H{XU=n1H|%m3;92Z9`bvpo|*lHeFUG- zU@nkq-9rAy?J@?CLLj|bj|O-JU2M=m?lW1I2}zBfT4wTw{D7&;Hg{zD^dZ}Q6|>mo zR5@>@S4LCeluoH1>^YYzBbg+YonuGJ(b$@S>M74jlXfzej>#3{aaNL~MD_b@S^M*j zP0<~|^IWhHN@gLwl2lle|8F?BSS@ot8_CNN>ytq7z!;<_wZW!sQ|!$>9K}+T(a1SA z+DojTvG;7IgX`s z6Jrx%84t*-oP~_N+Mg*t;!>PbM;zOq4CtCnk?4Y$tu!wciqTgY|Ldd^L81CD$Ru{G z8FK8SjU>8 zwN|6{Dz#TTZ?>Y=a;pWyXqWd@2zb`6y%e>VslC*>zWjQt4ZBV0eAKm4yG(jxJM_M^ zJfcrhlSsNX3=hpJJlsyhscXh2UxSlQ3z>4%Wtn$q$7IS4=+@@u?MyX|P1hP*8(ZtA z8)`ROjk~BR&S2C<1v=#UzJFt!LA#q252SVM-`?xK7p&c{ zC{}S?m0nH{I1eQ*GMVGBD3YU?$G#XI{XnS^+lncdl$+^crY2_kAXcy*a=20PP~pl{ zB^A@dGFAm8(&lEuslm0v!766gqDgyrKg3ng7hZ`j>zVQV3WdltM8G=eMC$Ut-6d&R zO=NBDM`ohcNYZJLN@5>gHtD0Xr`T2@iK8!@V*8>~*dkLUC$N)8Uy(1fk)aG<16wXq zT=p$)GgVrSuxpcyEKeU~td$g7_^P-Ht~2S(B)FeQx=6BDl2g#L!a=B|t4)smCS&F5 z1x>h51|K&!JuoyO(<`u2hFc{@SrJz#jV~uME{D1lwZb#e#LQz3x;8dC2*C?tc8AUu UY(5pfo+m{Vp?-7m#6>y9KORXKn*aa+ literal 0 HcmV?d00001 diff --git a/troggle/registration/locale/pl/LC_MESSAGES/django.po b/troggle/registration/locale/pl/LC_MESSAGES/django.po new file mode 100644 index 000000000..498fd5b6b --- /dev/null +++ b/troggle/registration/locale/pl/LC_MESSAGES/django.po @@ -0,0 +1,84 @@ +# Polish translation for django-registration. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the django-registration package. +# Jarek Zgoda , 2007. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: 0.4\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2007-09-19 19:30-0500\n" +"PO-Revision-Date: 2007-12-15 12:45+0100\n" +"Last-Translator: Jarek Zgoda \n" +"Language-Team: Polish \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: forms.py:38 +msgid "username" +msgstr "nazwa użytkownika" + +#: forms.py:41 +msgid "email address" +msgstr "adres email" + +#: forms.py:43 +msgid "password" +msgstr "hasło" + +#: forms.py:45 +msgid "password (again)" +msgstr "hasło (ponownie)" + +#: forms.py:54 +msgid "Usernames can only contain letters, numbers and underscores" +msgstr "" +"Nazwa użytkownika może zawierać tylko litery, cyfry i znaki podkreślenia" + +#: forms.py:59 +msgid "This username is already taken. Please choose another." +msgstr "Ta nazwa użytkownika jest już zajęta. Wybierz inną." + +#: forms.py:68 +msgid "You must type the same password each time" +msgstr "Musisz wpisać to samo hasło w obu polach" + +#: forms.py:96 +msgid "I have read and agree to the Terms of Service" +msgstr "Przeczytałem regulamin i akceptuję go" + +#: forms.py:105 +msgid "You must agree to the terms to register" +msgstr "Musisz zaakceptować regulamin, aby się zarejestrować" + +#: forms.py:124 +msgid "" +"This email address is already in use. Please supply a different email " +"address." +msgstr "Ten adres email jest już używany. Użyj innego adresu email." + +#: forms.py:149 +msgid "" +"Registration using free email addresses is prohibited. Please supply a " +"different email address." +msgstr "" +"Nie ma możliwości rejestracji przy użyciu darmowego adresu email. Użyj " +"innego adresu email." + +#: models.py:188 +msgid "user" +msgstr "użytkownik" + +#: models.py:189 +msgid "activation key" +msgstr "klucz aktywacyjny" + +#: models.py:194 +msgid "registration profile" +msgstr "profil rejestracji" + +#: models.py:195 +msgid "registration profiles" +msgstr "profile rejestracji" diff --git a/troggle/registration/locale/pt_BR/LC_MESSAGES/django.mo b/troggle/registration/locale/pt_BR/LC_MESSAGES/django.mo new file mode 100644 index 0000000000000000000000000000000000000000..e81b6207be3808b1553a40605d4c5f7ea270a843 GIT binary patch literal 1796 zcmbu9O>Y}T7{>=FZ*HMbKuCzgb0ZO5;}i;wTdJC5Qw)BI96M5xS~T5#yqdFT=>u0aT1jaVx-yMdOXj|{O5W0w{xey5*TMO zU&s6s^Ht0pMqb5J@7B^U2x}dAufZTgKvO8g6rV#;Pc?=Cxmzod<}d7 zTmxSQH^EoH9(W2&!Dm1PUW9K8Ucm2%_)~+wfH%R9o?OIx2yWx|AK*LS`cpz|fVaSx zz%Rga;J4t5;1A37pTQ9SS1`o;bIHF!gssLIJWpeWypE5cQ8-f=*e;M_HG-eR@ibm= zbb++0bJxIUF-4mua>is?rX)3HW|_$w@)M>Z+rp6<(;nNIN>~gyQ_frImC;l>r863b z{ai?ulT1^~&aorqXll(w-BzB{I_>5x9g{1k)BJ!WrD{B8%i5nbtc&3UmM5GAS27Rj z9gqq!`MS z+jyxoD|L$3#NhDahAF8ioj)lgY#=05wUvNukM{Y4DfEWeF620s&V6QVN-UEJc~!8G ziC43Q;&=H#oKQ!s_OHnd`K^mZfaMM04#q0ye_eDU2va?RI%3zFJDm8aoksgO4KBDz zyREH{Ti0XSj|Y40ey=v*sj)ulx=f|f2W94>p=nZWw?B-wa7CdiqHXE9Nf#Q8_oBvT zw6RGWo6WZyQR8BxfsN6CXDT>f?z<7U22r;kZMW#dezV(t^OJrru63mI(a=ima_Nn2 z($1*Up!XnJl}_hcuIk2SS8LsN zH$FPlM!iwn!gZqjq9Md@lIMH=t!WPZE>kj**0FzoG~9_U9qkLbpk$+1CniPNH|Y{; zyC&k2^7;3~p+HaosliJ@##OBYq)a1c2l}g?}#4 zR{zJlHb?}qOIObCTV<&7eGgxX(5y!}GkPSSNHV3jrY?FgtB$?0lT+3bpAM5EryvX4 z&~a9VhMWIXur+u?pjE?(eUr?;LvVb5!y1j+&ta7GmQOwJ$7zcJ!bQN_Y|O`9273hA$lWeWz=Wow$l Qwd(Av#X}L$kqZ^YKLzI-!vFvP literal 0 HcmV?d00001 diff --git a/troggle/registration/locale/pt_BR/LC_MESSAGES/django.po b/troggle/registration/locale/pt_BR/LC_MESSAGES/django.po new file mode 100644 index 000000000..9e8addb6f --- /dev/null +++ b/troggle/registration/locale/pt_BR/LC_MESSAGES/django.po @@ -0,0 +1,81 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2007-09-19 19:30-0500\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: forms.py:38 +msgid "username" +msgstr "usuário" + +#: forms.py:41 +msgid "email address" +msgstr "endereço de email" + +#: forms.py:43 +msgid "password" +msgstr "" + +#: forms.py:45 +msgid "password (again)" +msgstr "senha (novamente)" + +#: forms.py:54 +msgid "Usernames can only contain letters, numbers and underscores" +msgstr "Nomes de usuário apenas podem conter letras, números, e underscore" + +#: forms.py:59 +msgid "This username is already taken. Please choose another." +msgstr "Este nome de usuário já existe. Por favor, escolha outro." + +#: forms.py:68 +msgid "You must type the same password each time" +msgstr "Você deve escrever a mesma senha nos dois campos" + +#: forms.py:96 +msgid "I have read and agree to the Terms of Service" +msgstr "Eu lí e concordo com os Termos de Uso do serviço" + +#: forms.py:105 +msgid "You must agree to the terms to register" +msgstr "Você deve concordar com os termos para registrar-se" + +#: forms.py:124 +msgid "" +"This email address is already in use. Please supply a different email " +"address." +msgstr "Este endereço de email já está em uso. Por favor, informe um endereço de email diferente." + +#: forms.py:149 +msgid "" +"Registration using free email addresses is prohibited. Please supply a " +"different email address." +msgstr "Registrar-se com contas de email gratuitos está proibido. Por favor, informe um endereço de email diferente." + +#: models.py:188 +msgid "user" +msgstr "usuário" + +#: models.py:189 +msgid "activation key" +msgstr "chave de ativação" + +#: models.py:194 +msgid "registration profile" +msgstr "profile de registro" + +#: models.py:195 +msgid "registration profiles" +msgstr "profiles de registro" diff --git a/troggle/registration/locale/ru/LC_MESSAGES/django.mo b/troggle/registration/locale/ru/LC_MESSAGES/django.mo new file mode 100644 index 0000000000000000000000000000000000000000..b6eb3f11e78f2d8a75f43fbe480a3d1dd040ab44 GIT binary patch literal 2360 zcmbtTO>Y}j6n#LUU_OOFR1}H3K{Svt4yZJ7OI4G&CBjZ3$B76+La+9VJ=C7DW}ZW{ zKqR41p(I2?Aa#KRV#5mICU%?eh$Xu>OBTRyV9N&19Z!?EO)Eu=G;`kExgY1=d*;ul zk9;d|J%#%P+~47Tj?eeuf$K8R0!{-z1pWjZ0v^3zh&O@bz|+7*;LE_@fL*}9flmOB zKOn^8z*m3|1ABp7D+PQ8m;*iwECG)IKLN7e9PlJ+%>&=V`>*);7x4K9h4=>e53mMY zdPs;*f#RqT9{^^66Tm-!$APDitQ$BAe2l*XUji;hxDw&-z+=7YQKD?Me z$1=YsLreR?eLNbygN6Xr@Is2+3p4~qAwV~rM+}J6LJU$_PAT$~ERu9^mpr9NyQIsC z^2)3FU$7D7y3i08E(Pqin0NllB6>4;nY zy9YWUOCZ`M+LfYJVHuNlMIC7L1y3k^@R-Di=YFIL+8Qic<7f+;PSQxK|J~GuG>xZo zql3dkv7D;8p0=`n$u3%N*Gs;Ycaszw8O~e%*cHpe8jxBg>Gee7l$GeSditoRFZo8o zN}Nn2;ArL4l+DQ_zln4zXJv=2ffT(noXifs`u^}xI+l^Xw(_2I{EF1Bm!$J!nG6l3 zvS~V#&ZY)4=TZX$x%BAhS-3i-x-2OxuVghznbgpQF{XSblQ~zh=in+^4LO>w7RTct5q<+(^M!+&sX}bvHW?fch8TxK)Y7jDY!-GKS{k1c}$pJ z$m|3&W;?iQR)aayFdJl6DVR0eX2oon22L%r1p}Gy;ny(BW|i$`6K>`jKJUPFBUmsu zfy?-?g+xoj{D8O>9A|?$jtjnEbC?IVgM#3{$%U7Z=Q{4D*$U=^&%uw`fg93?2Bw6R z%i$A7Lg_}>MJxD{*_uWiY~gGb&cSQS0tUK zU=c00%z8+D8wt1C9ubpZJ}%79%qW;UR2ZSy4X)cU0vKDUG#f1aKiVMmBbrzTS1w^T zG4I<4&23{OSVY7G?V|R=-75$4*apx0j*+!c@Y=nrKqb5dwAYqYGt7jwa82R~hSC9L zGS@+AombpVp;)e9H}fpUu!klD$}HB=*glng%`Qz&gEG)dyUZ=+f^x9HgAH|efPS0p zSzzn8Yt^g@b4T(}KCH|zF`+Du_&fNIiPR9TcLxpPpW@yKj2qzA#2nWM)`qz$VA}}3 z3a+wvAhLE#+%#7`gbW2nvs0!>wIGT5xFpfL-unY5`lB9$pUYeV-S1cQ>zS RfziJoscS(X`MuO9{sTfWM{WQB literal 0 HcmV?d00001 diff --git a/troggle/registration/locale/ru/LC_MESSAGES/django.po b/troggle/registration/locale/ru/LC_MESSAGES/django.po new file mode 100644 index 000000000..8b0c30917 --- /dev/null +++ b/troggle/registration/locale/ru/LC_MESSAGES/django.po @@ -0,0 +1,81 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2007-09-19 19:30-0500\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: forms.py:38 +msgid "username" +msgstr "имя пользователя" + +#: forms.py:41 +msgid "email address" +msgstr "адрес электронной почты" + +#: forms.py:43 +msgid "password" +msgstr "пароль" + +#: forms.py:45 +msgid "password (again)" +msgstr "пароль (верификация)" + +#: forms.py:54 +msgid "Usernames can only contain letters, numbers and underscores" +msgstr "Имя пользователя может содержать только буквы, цифры и подчеркивания" + +#: forms.py:59 +msgid "This username is already taken. Please choose another." +msgstr "Такое имя пользователя уже есть. Пожалуйста, выберите другое." + +#: forms.py:68 +msgid "You must type the same password each time" +msgstr "Вы должны вводить один и тот же пароль каждый раз" + +#: forms.py:96 +msgid "I have read and agree to the Terms of Service" +msgstr "Я прочитал и согласен с Правилами Использования" + +#: forms.py:105 +msgid "You must agree to the terms to register" +msgstr "Вы должны согласиться с Правилами для регистрации" + +#: forms.py:124 +msgid "" +"This email address is already in use. Please supply a different email " +"address." +msgstr "Этот адрес электронной почты уже используется. Пожалуйста, введите другой адрес." + +#: forms.py:149 +msgid "" +"Registration using free email addresses is prohibited. Please supply a " +"different email address." +msgstr "Регистрация с использованием свободных почтовых серверов запрещена. Пожалуйста, введите другой адрес электронной почты." + +#: models.py:188 +msgid "user" +msgstr "пользователь" + +#: models.py:189 +msgid "activation key" +msgstr "ключ активации" + +#: models.py:194 +msgid "registration profile" +msgstr "профиль регистрации" + +#: models.py:195 +msgid "registration profiles" +msgstr "профили регистрации" diff --git a/troggle/registration/locale/sr/LC_MESSAGES/django.mo b/troggle/registration/locale/sr/LC_MESSAGES/django.mo new file mode 100644 index 0000000000000000000000000000000000000000..1699326553efe848408441bb04e452d14f341774 GIT binary patch literal 1966 zcmb7^O>Y}T7{>=F6wIqC5USwtP>GVzu30B7ik!L-`huc1ZIn0_(-_#C_gu7dmEC*YspBKR-(7WlzSLc9rn3cd=i zfFai!_%65wz6WOD3GjO`*!>9pgIqs@%lOtW3z34qfj7XDuL#isx4{kYC-55h7kC;x zeNu>1;4=6Icpb!$*aqJQzXe1791Qt?07KqK)A3(Hq_113Kg0<21>ac<^LTyw5n`j% zx`jBihA;wB2$Wsx(Ewk=Bi5-eM@*JwN>by=EHimSzR%QUTRJkkw9R&;5*AyWDd(;9 z%4n*b(i!ardoHCaNT#V}=h%^QG_!UzP-x!o9wZWuqQ|wGV93@hd(Wp5w+Dqgw z*n76_Jn5?Jp;K#C=@i|>VDjRwsi>@+pBEB75E81|T0pkPc78mB-Vob`8i&%k?~F}} zWzr|FN)|HlYBW)Nz+*9|j+ogWb!b6mD0ERwGEJ8Xi?OQ;e&$anf#H8yW|qbpdouu-C`(sP@Z z;&>&BFGTT0YAv@fw$8=)1H)*GM=GRwhTVmB9G{C@u)8UpkGfWBS4eMcn{IK>o6ahkanxm5qOOhgjcdo#YBl4=6|5|FV${Vtw8`^* z|JksBf~%DDrFHB(JKgKi%CTLj0lPQ4rW2Fm1hi=d+q|(^R8|(zb%T{|lOEQeuCu&K zlWs?U+=@G$7M(pyp&NhHX|?DJiV4>EzT8=w4PEM72;GI+>{2VH2M;DLu!$Gp(}K^^ zYU7(|({QSMG@E5R9MqnY`grJyskFD_Hr?I%`u6tCwL9x;jj+TA`^rlbHXSK~riXuU zN#Tr2oUy`;R4Hj-tU7#r@Q`&bkB)w#^0^VX_1Hl&uT@4IO>Y961xY#6p6o%eoV9Gy zhQW4Zsx*5=sjaeV&c14j+ao#ms}3>ZgNIa6H8kFGPaVYx`l}lR`2xlIN)x4hxFLd<-M~4j(Jrvtdw&a9FKM$U(Rl y5*!>wgCegE_K)s{Aik)5W}t, YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: django-registration trunk\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2008-04-05 13:51+0200\n" +"PO-Revision-Date: 2008-04-05 14:00+0100\n" +"Last-Translator: Nebojsa Djordjevic \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" +"X-Poedit-Language: Serbian\n" +"X-Poedit-Country: YUGOSLAVIA\n" + +#: forms.py:38 +msgid "username" +msgstr "korisničko ime" + +#: forms.py:41 +msgid "email address" +msgstr "email adresa" + +#: forms.py:43 +msgid "password" +msgstr "šifra" + +#: forms.py:45 +msgid "password (again)" +msgstr "šifra (ponovo)" + +#: forms.py:54 +msgid "Usernames can only contain letters, numbers and underscores" +msgstr "Korisničko ime može da se sastoji samo od slova, brojeva i donje crte (\"_\")" + +#: forms.py:59 +msgid "This username is already taken. Please choose another." +msgstr "Korisničko ime je već zauzeto. Izaberite drugo." + +#: forms.py:71 +msgid "You must type the same password each time" +msgstr "Unete šifre se ne slažu" + +#: forms.py:100 +msgid "I have read and agree to the Terms of Service" +msgstr "Pročitao sam i slažem se sa uslovima korišćenja" + +#: forms.py:109 +msgid "You must agree to the terms to register" +msgstr "Morate se složiti sa uslovima korišćenja da bi ste se registrovali" + +#: forms.py:128 +msgid "This email address is already in use. Please supply a different email address." +msgstr "Ova e-mail adresa je već u upotrebi. Morate koristiti drugu e-mail adresu." + +#: forms.py:153 +msgid "Registration using free email addresses is prohibited. Please supply a different email address." +msgstr "Registracija korišćenjem besplatnig e-mail adresa je zabranjena. Morate uneti drugu e-mail adresu." + +#: models.py:188 +msgid "user" +msgstr "korisnik" + +#: models.py:189 +msgid "activation key" +msgstr "aktivacioni ključ" + +#: models.py:194 +msgid "registration profile" +msgstr "registracioni profil" + +#: models.py:195 +msgid "registration profiles" +msgstr "registracioni profili" + diff --git a/troggle/registration/locale/sv/LC_MESSAGES/django.mo b/troggle/registration/locale/sv/LC_MESSAGES/django.mo new file mode 100644 index 0000000000000000000000000000000000000000..50eca67e21301f5081b881b054ec648a67e25509 GIT binary patch literal 1687 zcmb7^&2A$_5XT!>STLWbWfg3^`kvMRS#T(=W=EO_Dl`C(+zsF7-qrEW7%&%u$RbBnBs{Hx-jb8+=*Kog! z`#0Qg`}I?J;Cc)O;1v8C{2e?5Z$2%=C*Ub~7yKD~AN&Jc1OEYE0pEE>h?l_+z~{j# z==Z9FZ-QO$EieXefZu`M?g#Kw?DZ4)9^P~OxC8zT-T~L26=Dlya3A~?+y?&w34G%@ zA#Q;mfiHpk;0xd}==c8$#Gg=j`2EIU3H%=P`ThuE`{MHNK8DZl)#A(i;p4oxc!#+_ zs>S8wU0ye_fD{606?*tRd>*1n136(bEF+Q%cWju+X>tRm9-GXP?$a@wNfNT?a-3La zq)W7-u}xG=eQ(d1Oj43jWY}7^lvo-WJxI3eCnU!ZOr2ym+X`l#Q)h6%sxW5~`X)KsHM|HyuH5h;4n2BWdlo z+C;=M9FR*g7BY0nWUly-r(#7NacO_GpxZJ=qHAKl)1p);Mn6gUi65=-3Kb78lQ=T^ z8xCF2jDk}f3ze?XQGNHz`ay$E8{Ok(=dje}kv1-9+c=4WopEe~o~}{psM8B}Q7hjb z!Jc$nqpeD%8dSD}t!>(@);_+oUfHZvU>J0HlK9{YyN8W>H)wZ)y*ho~skNKyk2;5q zQcGGF^o&$Cl}?))H8S+sv15fU%r7#!$Jv9S8a=QBfR(nw^hc#zN1RMMFqT9=j|U)6b{E84ibH z4?~g9EKYc($)zL+dI5c~<)UMu7yd!SVke(P5^7#pR(>KD0VaO?G#N@!A7U`rpafP; k!y%`laZOgyy7XMG=yn2y)_jX&92P+DU!9VdORtak7w$#!*8l(j literal 0 HcmV?d00001 diff --git a/troggle/registration/locale/sv/LC_MESSAGES/django.po b/troggle/registration/locale/sv/LC_MESSAGES/django.po new file mode 100644 index 000000000..dec76e273 --- /dev/null +++ b/troggle/registration/locale/sv/LC_MESSAGES/django.po @@ -0,0 +1,81 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2008-03-23 18:59+0100\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: Emil Stenström \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: .\forms.py:38 +msgid "username" +msgstr "Användarnamn" + +#: .\forms.py:41 +msgid "email address" +msgstr "E-postadress" + +#: .\forms.py:43 +msgid "password" +msgstr "Lösenord" + +#: .\forms.py:45 +msgid "password (again)" +msgstr "Lösenord (igen)" + +#: .\forms.py:54 +msgid "Usernames can only contain letters, numbers and underscores" +msgstr "Användarnamn får bara innehålla bokstäver, siffror och understreck" + +#: .\forms.py:59 +msgid "This username is already taken. Please choose another." +msgstr "Det användarnamnet är upptaget. Prova ett annat." + +#: .\forms.py:71 +msgid "You must type the same password each time" +msgstr "Båda lösenord måste vara lika" + +#: .\forms.py:100 +msgid "I have read and agree to the Terms of Service" +msgstr "Jag har läst och accepterar avtalet" + +#: .\forms.py:109 +msgid "You must agree to the terms to register" +msgstr "Du måste acceptera avtalet för att registrera dig" + +#: .\forms.py:128 +msgid "" +"This email address is already in use. Please supply a different email " +"address." +msgstr "Den e-postadressen är upptagen, använd an annan adress." + +#: .\forms.py:153 +msgid "" +"Registration using free email addresses is prohibited. Please supply a " +"different email address." +msgstr "Gratis e-postadresser är inte tillåtna, använd en annan adress." + +#: .\models.py:188 +msgid "user" +msgstr "Användare" + +#: .\models.py:189 +msgid "activation key" +msgstr "Aktiveringsnyckel" + +#: .\models.py:194 +msgid "registration profile" +msgstr "Profil" + +#: .\models.py:195 +msgid "registration profiles" +msgstr "Profiler" diff --git a/troggle/registration/locale/zh_CN/LC_MESSAGES/django.mo b/troggle/registration/locale/zh_CN/LC_MESSAGES/django.mo new file mode 100644 index 0000000000000000000000000000000000000000..ece5cc97b10d0ace9a2ba33ce927e95d8e48ec49 GIT binary patch literal 1669 zcmb7@?@t^>7{{ktt)4&AXnav$%nPGdyXOK?;iwIWNKl}J9whq4O!tPpwRgLhojEKq zCI=P-%LPQMMri^KRMOg9qeLiBc;yTK3E%W)x$_P2Kkz%Z2iHq{)5-39W@evxetc*4 z@8d_W5VU9UzKC}L?+bc-1RdH%&;UolPrzTmKJeH>guDd~fvsR3dCj!2cH86z~@05JPLjRYP)f;1+gxJFJb;CKK6tEfFFRZkA!(mf+pr` z;0aKH+WyF+gggnpTxAo8hqR$P4t7=7Kd#aS@eqmbaqx2x;VVt&uYDmjd8V=wcDjxy zs&l;;saBfK|DYYi08$X7Rna2?YX790CfNw5K4%HaT)ei=Ih7ujNlxS3PYdb|({tP( zaV$;-xa|n(GwFCP%?ii0>9DrvY38ITOC)?Q1Q*m1G~;_o=e#3%B1-#HoC!`vHj_z> zQbrTb@G$qeE9*B#Nj!<2bMEfeYYy-&F%jqZdogtBnbG1}kW@nL&cCmre>IM;o)FEYS0 zo-d7FVLJ)q-K;H)xEG_5{)%3X~ccziWHNcAEU{v%tD_uJ$*20v-RDJT3-4L z%w0RnY;MFkOUGzWdtcX}PWyCEPg}}~dcJ)o(%aqJSu3m|YDPM6wz!K%948T@l3$c> zWKz(um0C&W3ohRojK6O**X(pYxW7iHYk3L$12Ni+iyk4t)HiDVxAKn@rNWlF^M{(7 z2`RRsQpl%H*1Pjx}&CM{z1G++1!PL5% z%fn6S+D(;T#7gJ`DU@^5VLCc+&2;ug>C3xnWpCBgWr+MOsbZH3B&rB-D*{8rleR!yuFH, YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2007-09-19 19:30-0500\n" +"PO-Revision-Date: 2008-03-20 23:22+0800\n" +"Last-Translator: hutuworm \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: forms.py:38 +msgid "username" +msgstr "用户名" + +#: forms.py:41 +msgid "email address" +msgstr "Email 地址" + +#: forms.py:43 +msgid "password" +msgstr "密码" + +#: forms.py:45 +msgid "password (again)" +msgstr "密码(重复)" + +#: forms.py:54 +msgid "Usernames can only contain letters, numbers and underscores" +msgstr "用户名只能包含字母、数字和下划线" + +#: forms.py:59 +msgid "This username is already taken. Please choose another." +msgstr "该用户名已被占用,请另选一个。" + +#: forms.py:68 +msgid "You must type the same password each time" +msgstr "您必须输入两遍同样的密码" + +#: forms.py:96 +msgid "I have read and agree to the Terms of Service" +msgstr "我已阅读并同意该服务条款" + +#: forms.py:105 +msgid "You must agree to the terms to register" +msgstr "您必须同意注册条款" + +#: forms.py:124 +msgid "This email address is already in use. Please supply a different email address." +msgstr "该 Email 地址已有人使用,请提供一个另外的 Email 地址。" + +#: forms.py:149 +msgid "Registration using free email addresses is prohibited. Please supply a different email address." +msgstr "禁止使用免费 Email 地址注册,请提供一个另外的 Email 地址。" + +#: models.py:188 +msgid "user" +msgstr "用户" + +#: models.py:189 +msgid "activation key" +msgstr "激活密钥" + +#: models.py:194 +msgid "registration profile" +msgstr "注册信息" + +#: models.py:195 +msgid "registration profiles" +msgstr "注册信息" + diff --git a/troggle/registration/locale/zh_TW/LC_MESSAGES/django.mo b/troggle/registration/locale/zh_TW/LC_MESSAGES/django.mo new file mode 100644 index 0000000000000000000000000000000000000000..24a3534958925d49ab1e1032f3cd2d50e28cd3e8 GIT binary patch literal 1669 zcmb7@?@t^>7{{ktt)4&AXnav$%nPGd-E)DcaMT7wBq&fq4-$Q2rhCKQ+PmG$&K#B) zlYz5_j$aFc%Reb1L)AsfCe}YehmHu4uFRqAmmMO1Z)TM;7j0N;8E~j@JaB< zgM>T*z5+f1wt_lVC-@9F1U?Je;6d!XO5#cEY;dMsv6N14oH{xtzh8IQ;=3%(@AV|vY3}YjvXY*M^qA|R zXg^AZYdZwBm`gnuIa{798RDn7l-w7uQ8$}Dg+W!btee2l@=!ea(96(#nu?Ipz zRlh1A_v?0YJOjNUw$M3dm=K?Oeu8plC8>1MoG?o|W1-@w`8a7%hwRz!59rIxMxsYa z7^!wtIE+yz#s7Cv5Uo(P(=w4k-}{7H(&$YXBPa_e9ixMtT_1GzbkmXUp_9EQ1|mZ| z$H#c^>w72sOQ_qBmKSo-SxtnqGqHEXN$XN#BmZaD)|}t zdL{)8+o_dgzTooh;rM$-Yu!%ggZpcAyOx*0KM

xabiQ%v@BrHY!(sEB~4+6_(Y) zTySo_yt)xA=GE-i!P2$hmo2ihJP}-9Ds67>Tv}06`SQjc+Fkv7)Zz_wEf@U0qNXqG z7U#-qv%&mAY3rL(A*XV)YJOS$aAoJ}xd!XIxk-Wm4QogtSUg|4eLIYCpRSNqF!P66 z$iq!}X|1$*2`ixwq)?eCgz4zOb<_Eu%V#&$+>}~aQ`f%=*7J9B6T#&I#_G$tQejqI zIJ>6+nG?Au+*9?``^mNf|~kKO|4cY^4f0YdlaqKr+1c$B-qXcH}7Cl pxp;%zs~V{pgxD?4RKCcot<~M)c@jn`ZGRU`tT#@={Oe_q{{ZHmUoijx literal 0 HcmV?d00001 diff --git a/troggle/registration/locale/zh_TW/LC_MESSAGES/django.po b/troggle/registration/locale/zh_TW/LC_MESSAGES/django.po new file mode 100644 index 000000000..7cc090d08 --- /dev/null +++ b/troggle/registration/locale/zh_TW/LC_MESSAGES/django.po @@ -0,0 +1,77 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2007-09-19 19:30-0500\n" +"PO-Revision-Date: 2008-03-20 23:22+0800\n" +"Last-Translator: hutuworm \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: forms.py:38 +msgid "username" +msgstr "用戶名" + +#: forms.py:41 +msgid "email address" +msgstr "Email 地址" + +#: forms.py:43 +msgid "password" +msgstr "密碼" + +#: forms.py:45 +msgid "password (again)" +msgstr "密碼(重復)" + +#: forms.py:54 +msgid "Usernames can only contain letters, numbers and underscores" +msgstr "用戶名只能包含字母、數字和下劃線" + +#: forms.py:59 +msgid "This username is already taken. Please choose another." +msgstr "該用戶名已被佔用,請另選一個。" + +#: forms.py:68 +msgid "You must type the same password each time" +msgstr "您必須輸入兩遍同樣的密碼" + +#: forms.py:96 +msgid "I have read and agree to the Terms of Service" +msgstr "我已閱讀並同意該服務條款" + +#: forms.py:105 +msgid "You must agree to the terms to register" +msgstr "您必須同意注冊條款" + +#: forms.py:124 +msgid "This email address is already in use. Please supply a different email address." +msgstr "該 Email 地址已有人使用,請提供一個另外的 Email 地址。" + +#: forms.py:149 +msgid "Registration using free email addresses is prohibited. Please supply a different email address." +msgstr "禁止使用免費 Email 地址注冊,請提供一個另外的 Email 地址。" + +#: models.py:188 +msgid "user" +msgstr "用戶" + +#: models.py:189 +msgid "activation key" +msgstr "激活密鑰" + +#: models.py:194 +msgid "registration profile" +msgstr "注冊信息" + +#: models.py:195 +msgid "registration profiles" +msgstr "注冊信息" + diff --git a/troggle/registration/management/__init__.py b/troggle/registration/management/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/troggle/registration/management/commands/__init__.py b/troggle/registration/management/commands/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/troggle/registration/management/commands/cleanupregistration.py b/troggle/registration/management/commands/cleanupregistration.py new file mode 100644 index 000000000..abec5aed3 --- /dev/null +++ b/troggle/registration/management/commands/cleanupregistration.py @@ -0,0 +1,19 @@ +""" +A management command which deletes expired accounts (e.g., +accounts which signed up but never activated) from the database. + +Calls ``RegistrationProfile.objects.delete_expired_users()``, which +contains the actual logic for determining which accounts are deleted. + +""" + +from django.core.management.base import NoArgsCommand + +from registration.models import RegistrationProfile + + +class Command(NoArgsCommand): + help = "Delete expired user registrations from the database" + + def handle_noargs(self, **options): + RegistrationProfile.objects.delete_expired_users() diff --git a/troggle/registration/models.py b/troggle/registration/models.py new file mode 100644 index 000000000..4a211c179 --- /dev/null +++ b/troggle/registration/models.py @@ -0,0 +1,255 @@ +import datetime +import random +import re +import sha + +from django.conf import settings +from django.contrib.auth.models import User +from django.contrib.sites.models import Site +from django.db import models +from django.db import transaction +from django.template.loader import render_to_string +from django.utils.translation import ugettext_lazy as _ + + +SHA1_RE = re.compile('^[a-f0-9]{40}$') + + +class RegistrationManager(models.Manager): + """ + Custom manager for the ``RegistrationProfile`` model. + + The methods defined here provide shortcuts for account creation + and activation (including generation and emailing of activation + keys), and for cleaning out expired inactive accounts. + + """ + def activate_user(self, activation_key): + """ + Validate an activation key and activate the corresponding + ``User`` if valid. + + If the key is valid and has not expired, return the ``User`` + after activating. + + If the key is not valid or has expired, return ``False``. + + If the key is valid but the ``User`` is already active, + return ``False``. + + To prevent reactivation of an account which has been + deactivated by site administrators, the activation key is + reset to the string constant ``RegistrationProfile.ACTIVATED`` + after successful activation. + + To execute customized logic when a ``User`` is activated, + connect a function to the signal + ``registration.signals.user_activated``; this signal will be + sent (with the ``User`` as the value of the keyword argument + ``user``) after a successful activation. + + """ + from registration.signals import user_activated + + # Make sure the key we're trying conforms to the pattern of a + # SHA1 hash; if it doesn't, no point trying to look it up in + # the database. + if SHA1_RE.search(activation_key): + try: + profile = self.get(activation_key=activation_key) + except self.model.DoesNotExist: + return False + if not profile.activation_key_expired(): + user = profile.user + user.is_active = True + user.save() + profile.activation_key = self.model.ACTIVATED + profile.save() + user_activated.send(sender=self.model, user=user) + return user + return False + + def create_inactive_user(self, username, password, email, + send_email=True): + """ + Create a new, inactive ``User``, generate a + ``RegistrationProfile`` and email its activation key to the + ``User``, returning the new ``User``. + + To disable the email, call with ``send_email=False``. + + The activation email will make use of two templates: + + ``registration/activation_email_subject.txt`` + This template will be used for the subject line of the + email. It receives one context variable, ``site``, which + is the currently-active + ``django.contrib.sites.models.Site`` instance. Because it + is used as the subject line of an email, this template's + output **must** be only a single line of text; output + longer than one line will be forcibly joined into only a + single line. + + ``registration/activation_email.txt`` + This template will be used for the body of the email. It + will receive three context variables: ``activation_key`` + will be the user's activation key (for use in constructing + a URL to activate the account), ``expiration_days`` will + be the number of days for which the key will be valid and + ``site`` will be the currently-active + ``django.contrib.sites.models.Site`` instance. + + To execute customized logic once the new ``User`` has been + created, connect a function to the signal + ``registration.signals.user_registered``; this signal will be + sent (with the new ``User`` as the value of the keyword + argument ``user``) after the ``User`` and + ``RegistrationProfile`` have been created, and the email (if + any) has been sent.. + + """ + from registration.signals import user_registered + + new_user = User.objects.create_user(username, email, password) + new_user.is_active = False + new_user.save() + + registration_profile = self.create_profile(new_user) + + if send_email: + from django.core.mail import send_mail + current_site = Site.objects.get_current() + + subject = render_to_string('registration/activation_email_subject.txt', + { 'site': current_site }) + # Email subject *must not* contain newlines + subject = ''.join(subject.splitlines()) + + message = render_to_string('registration/activation_email.txt', + { 'activation_key': registration_profile.activation_key, + 'expiration_days': settings.ACCOUNT_ACTIVATION_DAYS, + 'site': current_site }) + + send_mail(subject, message, settings.DEFAULT_FROM_EMAIL, [new_user.email]) + user_registered.send(sender=self.model, user=new_user) + return new_user + create_inactive_user = transaction.commit_on_success(create_inactive_user) + + def create_profile(self, user): + """ + Create a ``RegistrationProfile`` for a given + ``User``, and return the ``RegistrationProfile``. + + The activation key for the ``RegistrationProfile`` will be a + SHA1 hash, generated from a combination of the ``User``'s + username and a random salt. + + """ + salt = sha.new(str(random.random())).hexdigest()[:5] + activation_key = sha.new(salt+user.username).hexdigest() + return self.create(user=user, + activation_key=activation_key) + + def delete_expired_users(self): + """ + Remove expired instances of ``RegistrationProfile`` and their + associated ``User``s. + + Accounts to be deleted are identified by searching for + instances of ``RegistrationProfile`` with expired activation + keys, and then checking to see if their associated ``User`` + instances have the field ``is_active`` set to ``False``; any + ``User`` who is both inactive and has an expired activation + key will be deleted. + + It is recommended that this method be executed regularly as + part of your routine site maintenance; this application + provides a custom management command which will call this + method, accessible as ``manage.py cleanupregistration``. + + Regularly clearing out accounts which have never been + activated serves two useful purposes: + + 1. It alleviates the ocasional need to reset a + ``RegistrationProfile`` and/or re-send an activation email + when a user does not receive or does not act upon the + initial activation email; since the account will be + deleted, the user will be able to simply re-register and + receive a new activation key. + + 2. It prevents the possibility of a malicious user registering + one or more accounts and never activating them (thus + denying the use of those usernames to anyone else); since + those accounts will be deleted, the usernames will become + available for use again. + + If you have a troublesome ``User`` and wish to disable their + account while keeping it in the database, simply delete the + associated ``RegistrationProfile``; an inactive ``User`` which + does not have an associated ``RegistrationProfile`` will not + be deleted. + + """ + for profile in self.all(): + if profile.activation_key_expired(): + user = profile.user + if not user.is_active: + user.delete() + + +class RegistrationProfile(models.Model): + """ + A simple profile which stores an activation key for use during + user account registration. + + Generally, you will not want to interact directly with instances + of this model; the provided manager includes methods + for creating and activating new accounts, as well as for cleaning + out accounts which have never been activated. + + While it is possible to use this model as the value of the + ``AUTH_PROFILE_MODULE`` setting, it's not recommended that you do + so. This model's sole purpose is to store data temporarily during + account registration and activation. + + """ + ACTIVATED = u"ALREADY_ACTIVATED" + + user = models.ForeignKey(User, unique=True, verbose_name=_('user')) + activation_key = models.CharField(_('activation key'), max_length=40) + + objects = RegistrationManager() + + class Meta: + verbose_name = _('registration profile') + verbose_name_plural = _('registration profiles') + + def __unicode__(self): + return u"Registration information for %s" % self.user + + def activation_key_expired(self): + """ + Determine whether this ``RegistrationProfile``'s activation + key has expired, returning a boolean -- ``True`` if the key + has expired. + + Key expiration is determined by a two-step process: + + 1. If the user has already activated, the key will have been + reset to the string constant ``ACTIVATED``. Re-activating + is not permitted, and so this method returns ``True`` in + this case. + + 2. Otherwise, the date the user signed up is incremented by + the number of days specified in the setting + ``ACCOUNT_ACTIVATION_DAYS`` (which should be the number of + days after signup during which a user is allowed to + activate their account); if the result is less than or + equal to the current date, the key has expired and this + method returns ``True``. + + """ + expiration_date = datetime.timedelta(days=settings.ACCOUNT_ACTIVATION_DAYS) + return self.activation_key == self.ACTIVATED or \ + (self.user.date_joined + expiration_date <= datetime.datetime.now()) + activation_key_expired.boolean = True diff --git a/troggle/registration/signals.py b/troggle/registration/signals.py new file mode 100644 index 000000000..2a6eed9f3 --- /dev/null +++ b/troggle/registration/signals.py @@ -0,0 +1,8 @@ +from django.dispatch import Signal + + +# A new user has registered. +user_registered = Signal(providing_args=["user"]) + +# A user has activated his or her account. +user_activated = Signal(providing_args=["user"]) diff --git a/troggle/registration/tests.py b/troggle/registration/tests.py new file mode 100644 index 000000000..0f2655392 --- /dev/null +++ b/troggle/registration/tests.py @@ -0,0 +1,355 @@ +""" +Unit tests for django-registration. + +These tests assume that you've completed all the prerequisites for +getting django-registration running in the default setup, to wit: + +1. You have ``registration`` in your ``INSTALLED_APPS`` setting. + +2. You have created all of the templates mentioned in this + application's documentation. + +3. You have added the setting ``ACCOUNT_ACTIVATION_DAYS`` to your + settings file. + +4. You have URL patterns pointing to the registration and activation + views, with the names ``registration_register`` and + ``registration_activate``, respectively, and a URL pattern named + 'registration_complete'. + +""" + +import datetime +import sha + +from django.conf import settings +from django.contrib.auth.models import User +from django.core import mail +from django.core import management +from django.core.urlresolvers import reverse +from django.test import TestCase + +from registration import forms +from registration.models import RegistrationProfile +from registration import signals + + +class RegistrationTestCase(TestCase): + """ + Base class for the test cases; this sets up two users -- one + expired, one not -- which are used to exercise various parts of + the application. + + """ + def setUp(self): + self.sample_user = RegistrationProfile.objects.create_inactive_user(username='alice', + password='secret', + email='alice@example.com') + self.expired_user = RegistrationProfile.objects.create_inactive_user(username='bob', + password='swordfish', + email='bob@example.com') + self.expired_user.date_joined -= datetime.timedelta(days=settings.ACCOUNT_ACTIVATION_DAYS + 1) + self.expired_user.save() + + +class RegistrationModelTests(RegistrationTestCase): + """ + Tests for the model-oriented functionality of django-registration, + including ``RegistrationProfile`` and its custom manager. + + """ + def test_new_user_is_inactive(self): + """ + Test that a newly-created user is inactive. + + """ + self.failIf(self.sample_user.is_active) + + def test_registration_profile_created(self): + """ + Test that a ``RegistrationProfile`` is created for a new user. + + """ + self.assertEqual(RegistrationProfile.objects.count(), 2) + + def test_activation_email(self): + """ + Test that user signup sends an activation email. + + """ + self.assertEqual(len(mail.outbox), 2) + + def test_activation_email_disable(self): + """ + Test that activation email can be disabled. + + """ + RegistrationProfile.objects.create_inactive_user(username='noemail', + password='foo', + email='nobody@example.com', + send_email=False) + self.assertEqual(len(mail.outbox), 2) + + def test_activation(self): + """ + Test that user activation actually activates the user and + properly resets the activation key, and fails for an + already-active or expired user, or an invalid key. + + """ + # Activating a valid user returns the user. + self.failUnlessEqual(RegistrationProfile.objects.activate_user(RegistrationProfile.objects.get(user=self.sample_user).activation_key).pk, + self.sample_user.pk) + + # The activated user must now be active. + self.failUnless(User.objects.get(pk=self.sample_user.pk).is_active) + + # The activation key must now be reset to the "already activated" constant. + self.failUnlessEqual(RegistrationProfile.objects.get(user=self.sample_user).activation_key, + RegistrationProfile.ACTIVATED) + + # Activating an expired user returns False. + self.failIf(RegistrationProfile.objects.activate_user(RegistrationProfile.objects.get(user=self.expired_user).activation_key)) + + # Activating from a key that isn't a SHA1 hash returns False. + self.failIf(RegistrationProfile.objects.activate_user('foo')) + + # Activating from a key that doesn't exist returns False. + self.failIf(RegistrationProfile.objects.activate_user(sha.new('foo').hexdigest())) + + def test_account_expiration_condition(self): + """ + Test that ``RegistrationProfile.activation_key_expired()`` + returns ``True`` for expired users and for active users, and + ``False`` otherwise. + + """ + # Unexpired user returns False. + self.failIf(RegistrationProfile.objects.get(user=self.sample_user).activation_key_expired()) + + # Expired user returns True. + self.failUnless(RegistrationProfile.objects.get(user=self.expired_user).activation_key_expired()) + + # Activated user returns True. + RegistrationProfile.objects.activate_user(RegistrationProfile.objects.get(user=self.sample_user).activation_key) + self.failUnless(RegistrationProfile.objects.get(user=self.sample_user).activation_key_expired()) + + def test_expired_user_deletion(self): + """ + Test that + ``RegistrationProfile.objects.delete_expired_users()`` deletes + only inactive users whose activation window has expired. + + """ + RegistrationProfile.objects.delete_expired_users() + self.assertEqual(RegistrationProfile.objects.count(), 1) + + def test_management_command(self): + """ + Test that ``manage.py cleanupregistration`` functions + correctly. + + """ + management.call_command('cleanupregistration') + self.assertEqual(RegistrationProfile.objects.count(), 1) + + def test_signals(self): + """ + Test that the ``user_registered`` and ``user_activated`` + signals are sent, and that they send the ``User`` as an + argument. + + """ + def receiver(sender, **kwargs): + self.assert_('user' in kwargs) + self.assertEqual(kwargs['user'].username, u'signal_test') + received_signals.append(kwargs.get('signal')) + + received_signals = [] + expected_signals = [signals.user_registered, signals.user_activated] + for signal in expected_signals: + signal.connect(receiver) + + RegistrationProfile.objects.create_inactive_user(username='signal_test', + password='foo', + email='nobody@example.com', + send_email=False) + RegistrationProfile.objects.activate_user(RegistrationProfile.objects.get(user__username='signal_test').activation_key) + + self.assertEqual(received_signals, expected_signals) + + +class RegistrationFormTests(RegistrationTestCase): + """ + Tests for the forms and custom validation logic included in + django-registration. + + """ + def test_registration_form(self): + """ + Test that ``RegistrationForm`` enforces username constraints + and matching passwords. + + """ + invalid_data_dicts = [ + # Non-alphanumeric username. + { + 'data': + { 'username': 'foo/bar', + 'email': 'foo@example.com', + 'password1': 'foo', + 'password2': 'foo' }, + 'error': + ('username', [u"Enter a valid value."]) + }, + # Already-existing username. + { + 'data': + { 'username': 'alice', + 'email': 'alice@example.com', + 'password1': 'secret', + 'password2': 'secret' }, + 'error': + ('username', [u"This username is already taken. Please choose another."]) + }, + # Mismatched passwords. + { + 'data': + { 'username': 'foo', + 'email': 'foo@example.com', + 'password1': 'foo', + 'password2': 'bar' }, + 'error': + ('__all__', [u"You must type the same password each time"]) + }, + ] + + for invalid_dict in invalid_data_dicts: + form = forms.RegistrationForm(data=invalid_dict['data']) + self.failIf(form.is_valid()) + self.assertEqual(form.errors[invalid_dict['error'][0]], invalid_dict['error'][1]) + + form = forms.RegistrationForm(data={ 'username': 'foo', + 'email': 'foo@example.com', + 'password1': 'foo', + 'password2': 'foo' }) + self.failUnless(form.is_valid()) + + def test_registration_form_tos(self): + """ + Test that ``RegistrationFormTermsOfService`` requires + agreement to the terms of service. + + """ + form = forms.RegistrationFormTermsOfService(data={ 'username': 'foo', + 'email': 'foo@example.com', + 'password1': 'foo', + 'password2': 'foo' }) + self.failIf(form.is_valid()) + self.assertEqual(form.errors['tos'], [u"You must agree to the terms to register"]) + + form = forms.RegistrationFormTermsOfService(data={ 'username': 'foo', + 'email': 'foo@example.com', + 'password1': 'foo', + 'password2': 'foo', + 'tos': 'on' }) + self.failUnless(form.is_valid()) + + def test_registration_form_unique_email(self): + """ + Test that ``RegistrationFormUniqueEmail`` validates uniqueness + of email addresses. + + """ + form = forms.RegistrationFormUniqueEmail(data={ 'username': 'foo', + 'email': 'alice@example.com', + 'password1': 'foo', + 'password2': 'foo' }) + self.failIf(form.is_valid()) + self.assertEqual(form.errors['email'], [u"This email address is already in use. Please supply a different email address."]) + + form = forms.RegistrationFormUniqueEmail(data={ 'username': 'foo', + 'email': 'foo@example.com', + 'password1': 'foo', + 'password2': 'foo' }) + self.failUnless(form.is_valid()) + + def test_registration_form_no_free_email(self): + """ + Test that ``RegistrationFormNoFreeEmail`` disallows + registration with free email addresses. + + """ + base_data = { 'username': 'foo', + 'password1': 'foo', + 'password2': 'foo' } + for domain in ('aim.com', 'aol.com', 'email.com', 'gmail.com', + 'googlemail.com', 'hotmail.com', 'hushmail.com', + 'msn.com', 'mail.ru', 'mailinator.com', 'live.com'): + invalid_data = base_data.copy() + invalid_data['email'] = u"foo@%s" % domain + form = forms.RegistrationFormNoFreeEmail(data=invalid_data) + self.failIf(form.is_valid()) + self.assertEqual(form.errors['email'], [u"Registration using free email addresses is prohibited. Please supply a different email address."]) + + base_data['email'] = 'foo@example.com' + form = forms.RegistrationFormNoFreeEmail(data=base_data) + self.failUnless(form.is_valid()) + + +class RegistrationViewTests(RegistrationTestCase): + """ + Tests for the views included in django-registration. + + """ + def test_registration_view(self): + """ + Test that the registration view rejects invalid submissions, + and creates a new user and redirects after a valid submission. + + """ + # Invalid data fails. + response = self.client.post(reverse('registration_register'), + data={ 'username': 'alice', # Will fail on username uniqueness. + 'email': 'foo@example.com', + 'password1': 'foo', + 'password2': 'foo' }) + self.assertEqual(response.status_code, 200) + self.failUnless(response.context['form']) + self.failUnless(response.context['form'].errors) + + response = self.client.post(reverse('registration_register'), + data={ 'username': 'foo', + 'email': 'foo@example.com', + 'password1': 'foo', + 'password2': 'foo' }) + self.assertEqual(response.status_code, 302) + self.assertEqual(response['Location'], 'http://testserver%s' % reverse('registration_complete')) + self.assertEqual(RegistrationProfile.objects.count(), 3) + + def test_activation_view(self): + """ + Test that the activation view activates the user from a valid + key and fails if the key is invalid or has expired. + + """ + # Valid user puts the user account into the context. + response = self.client.get(reverse('registration_activate', + kwargs={ 'activation_key': RegistrationProfile.objects.get(user=self.sample_user).activation_key })) + self.assertEqual(response.status_code, 200) + self.assertEqual(response.context['account'].pk, self.sample_user.pk) + + # Expired user sets the account to False. + response = self.client.get(reverse('registration_activate', + kwargs={ 'activation_key': RegistrationProfile.objects.get(user=self.expired_user).activation_key })) + self.failIf(response.context['account']) + + # Invalid key gets to the view, but sets account to False. + response = self.client.get(reverse('registration_activate', + kwargs={ 'activation_key': 'foo' })) + self.failIf(response.context['account']) + + # Nonexistent key sets the account to False. + response = self.client.get(reverse('registration_activate', + kwargs={ 'activation_key': sha.new('foo').hexdigest() })) + self.failIf(response.context['account']) diff --git a/troggle/registration/urls.py b/troggle/registration/urls.py new file mode 100644 index 000000000..25cf2b053 --- /dev/null +++ b/troggle/registration/urls.py @@ -0,0 +1,72 @@ +""" +URLConf for Django user registration and authentication. + +If the default behavior of the registration views is acceptable to +you, simply use a line like this in your root URLConf to set up the +default URLs for registration:: + + (r'^accounts/', include('registration.urls')), + +This will also automatically set up the views in +``django.contrib.auth`` at sensible default locations. + +But if you'd like to customize the behavior (e.g., by passing extra +arguments to the various views) or split up the URLs, feel free to set +up your own URL patterns for these views instead. If you do, it's a +good idea to use the names ``registration_activate``, +``registration_complete`` and ``registration_register`` for the +various steps of the user-signup process. + +""" + +from django.conf import settings +from django.conf.urls.defaults import * +from django.views.generic.simple import direct_to_template +from django.contrib.auth import views as auth_views + +from registration.views import activate +from registration.views import register + + +urlpatterns = patterns('', + # Activation keys get matched by \w+ instead of the more specific + # [a-fA-F0-9]{40} because a bad activation key should still get to the view; + # that way it can return a sensible "invalid key" message instead of a + # confusing 404. + url(r'^activate/(?P\w+)/$', + activate, + name='registration_activate'), + url(r'^login/$', + auth_views.login, + {'template_name': 'registration/login.html'}, + name='auth_login'), + url(r'^logout/$', + auth_views.logout, + {'template_name': 'registration/logout.html'}, + name='auth_logout'), + url(r'^password/change/$', + auth_views.password_change, + name='auth_password_change'), + url(r'^password/change/done/$', + auth_views.password_change_done, + name='auth_password_change_done'), + url(r'^password/reset/$', + auth_views.password_reset, + name='auth_password_reset'), + url(r'^password/reset/confirm/(?P[0-9A-Za-z]+)-(?P.+)/$', + auth_views.password_reset_confirm, + name='auth_password_reset_confirm'), + url(r'^password/reset/complete/$', + auth_views.password_reset_complete, + name='auth_password_reset_complete'), + url(r'^password/reset/done/$', + auth_views.password_reset_done, + name='auth_password_reset_done'), + url(r'^register/$', + register, + name='registration_register'), + url(r'^register/complete/$', + direct_to_template, + {'template': 'registration/registration_complete.html','extra_context':{'settings':settings}}, + name='registration_complete'), + ) diff --git a/troggle/registration/views.py b/troggle/registration/views.py new file mode 100644 index 000000000..aac17c54d --- /dev/null +++ b/troggle/registration/views.py @@ -0,0 +1,153 @@ +""" +Views which allow users to create and activate accounts. + +""" + + +from django.conf import settings +from django.core.urlresolvers import reverse +from django.http import HttpResponseRedirect +from django.shortcuts import render_to_response +from django.template import RequestContext + +from registration.forms import RegistrationForm +from registration.models import RegistrationProfile + + +def activate(request, activation_key, + template_name='registration/activate.html', + extra_context=None): + """ + Activate a ``User``'s account from an activation key, if their key + is valid and hasn't expired. + + By default, use the template ``registration/activate.html``; to + change this, pass the name of a template as the keyword argument + ``template_name``. + + **Required arguments** + + ``activation_key`` + The activation key to validate and use for activating the + ``User``. + + **Optional arguments** + + ``extra_context`` + A dictionary of variables to add to the template context. Any + callable object in this dictionary will be called to produce + the end result which appears in the context. + + ``template_name`` + A custom template to use. + + **Context:** + + ``account`` + The ``User`` object corresponding to the account, if the + activation was successful. ``False`` if the activation was not + successful. + + ``expiration_days`` + The number of days for which activation keys stay valid after + registration. + + Any extra variables supplied in the ``extra_context`` argument + (see above). + + **Template:** + + registration/activate.html or ``template_name`` keyword argument. + + """ + activation_key = activation_key.lower() # Normalize before trying anything with it. + account = RegistrationProfile.objects.activate_user(activation_key) + if extra_context is None: + extra_context = {} + context = RequestContext(request) + for key, value in extra_context.items(): + context[key] = callable(value) and value() or value + return render_to_response(template_name, + { 'account': account, + 'expiration_days': settings.ACCOUNT_ACTIVATION_DAYS, 'settings':settings}, + context_instance=context) + + +def register(request, success_url=None, + form_class=RegistrationForm, + template_name='registration/registration_form.html', + extra_context=None): + """ + Allow a new user to register an account. + + Following successful registration, issue a redirect; by default, + this will be whatever URL corresponds to the named URL pattern + ``registration_complete``, which will be + ``/accounts/register/complete/`` if using the included URLConf. To + change this, point that named pattern at another URL, or pass your + preferred URL as the keyword argument ``success_url``. + + By default, ``registration.forms.RegistrationForm`` will be used + as the registration form; to change this, pass a different form + class as the ``form_class`` keyword argument. The form class you + specify must have a method ``save`` which will create and return + the new ``User``. + + By default, use the template + ``registration/registration_form.html``; to change this, pass the + name of a template as the keyword argument ``template_name``. + + **Required arguments** + + None. + + **Optional arguments** + + ``form_class`` + The form class to use for registration. + + ``extra_context`` + A dictionary of variables to add to the template context. Any + callable object in this dictionary will be called to produce + the end result which appears in the context. + + ``success_url`` + The URL to redirect to on successful registration. + + ``template_name`` + A custom template to use. + + **Context:** + + ``form`` + The registration form. + + Any extra variables supplied in the ``extra_context`` argument + (see above). + + **Template:** + + registration/registration_form.html or ``template_name`` keyword + argument. + + """ + if request.method == 'POST': + form = form_class(data=request.POST, files=request.FILES) + if form.is_valid(): + new_user = form.save() + # success_url needs to be dynamically generated here; setting a + # a default value using reverse() will cause circular-import + # problems with the default URLConf for this application, which + # imports this file. + return HttpResponseRedirect(success_url or reverse('registration_complete')) + else: + form = form_class() + + if extra_context is None: + extra_context = {} + context = RequestContext(request) + for key, value in extra_context.items(): + context[key] = callable(value) and value() or value + return render_to_response(template_name, + { 'form': form,'settings':settings }, + context_instance=context) diff --git a/troggle/settings.py b/troggle/settings.py index 353809d7e..9ad299d62 100644 --- a/troggle/settings.py +++ b/troggle/settings.py @@ -46,6 +46,10 @@ TEMPLATE_LOADERS = ( # 'django.template.loaders.eggs.load_template_source', ) +TEMPLATE_CONTEXT_PROCESSORS = ( "django.core.context_processors.auth", "troggle.context.settingsContext") + +LOGIN_REDIRECT_URL = '/' + MIDDLEWARE_CLASSES = ( 'django.middleware.common.CommonMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', @@ -56,6 +60,10 @@ MIDDLEWARE_CLASSES = ( ROOT_URLCONF = 'troggle.urls' +ACCOUNT_ACTIVATION_DAYS=3 + +AUTH_PROFILE_MODULE = 'expo.person' + INSTALLED_APPS = ( 'django.contrib.admin', 'django.contrib.auth', @@ -63,5 +71,7 @@ INSTALLED_APPS = ( 'django.contrib.sessions', 'django.contrib.sites', 'django.contrib.redirects', + 'troggle.registration', + 'troggle.profiles', 'troggle.expo' ) diff --git a/troggle/templates/base.html b/troggle/templates/base.html index b1fc47f33..c88ac19d4 100644 --- a/troggle/templates/base.html +++ b/troggle/templates/base.html @@ -2,7 +2,7 @@ - + {% block title %}THE TITLE{% endblock %} @@ -11,21 +11,34 @@ - -

-
+ +
+
-

CUCC Expeditions to Austria: 1976 - 2008

+

CUCC Expeditions to Austria: 1976 -

+
+

2009

+

-
- + {% block nav %} diff --git a/troggle/templates/personForm.html b/troggle/templates/personForm.html new file mode 100644 index 000000000..84ee7b79b --- /dev/null +++ b/troggle/templates/personForm.html @@ -0,0 +1,6 @@ +{% extends "base.html" %} +{% block content %} + +{{ form }} + +{% endblock %} \ No newline at end of file diff --git a/troggle/templates/profiles/create_profile.html b/troggle/templates/profiles/create_profile.html new file mode 100644 index 000000000..2eed3e480 --- /dev/null +++ b/troggle/templates/profiles/create_profile.html @@ -0,0 +1,13 @@ +{% extends "base.html" %} + +{% block content %} + +
+{{ form }} + +
+ +{% if form.errors %} +

Please correct the errors below

+{% endif %} +{% endblock %} \ No newline at end of file diff --git a/troggle/templates/profiles/profile_list.html b/troggle/templates/profiles/profile_list.html new file mode 100644 index 000000000..e69de29bb diff --git a/troggle/templates/registration/activate.html b/troggle/templates/registration/activate.html new file mode 100644 index 000000000..f87d519b3 --- /dev/null +++ b/troggle/templates/registration/activate.html @@ -0,0 +1,13 @@ +{% extends "base.html" %} + +{% block title %} +registration_form.html | {{ block.super }} +{% endblock %} + +{% block header %} +

activate.html

+{% endblock %} + +{% block content %} +You are now activated. +{% endblock %} \ No newline at end of file diff --git a/troggle/templates/registration/activation_email.txt b/troggle/templates/registration/activation_email.txt new file mode 100644 index 000000000..3047d8f32 --- /dev/null +++ b/troggle/templates/registration/activation_email.txt @@ -0,0 +1,3 @@ +Activate your account in {{ expiration_days }} days... +{{ URL_ROOT }}{% url registration_activate activation_key %} + diff --git a/troggle/templates/registration/activation_email_subject.txt b/troggle/templates/registration/activation_email_subject.txt new file mode 100644 index 000000000..78ae905dd --- /dev/null +++ b/troggle/templates/registration/activation_email_subject.txt @@ -0,0 +1 @@ +[CUCC Expo] Activation email \ No newline at end of file diff --git a/troggle/templates/registration/login.html b/troggle/templates/registration/login.html new file mode 100644 index 000000000..04b5074e8 --- /dev/null +++ b/troggle/templates/registration/login.html @@ -0,0 +1,19 @@ +{% extends "base.html" %} + +{% block content %} + +{% if form.errors %} +

Your username and password didn't match. Please try again.

+{% endif %} + +
+ + + +
{{ form.username.label_tag }}{{ form.username }}
{{ form.password.label_tag }}{{ form.password }}
+ + + +
+ +{% endblock %} diff --git a/troggle/templates/registration/logout.html b/troggle/templates/registration/logout.html new file mode 100644 index 000000000..9e40c20d3 --- /dev/null +++ b/troggle/templates/registration/logout.html @@ -0,0 +1,4 @@ +{% extends "base.html" %} +{% block content %} + You have been logged out. +{% endblock %} \ No newline at end of file diff --git a/troggle/templates/registration/registration_activate.html b/troggle/templates/registration/registration_activate.html new file mode 100644 index 000000000..cbd540e52 --- /dev/null +++ b/troggle/templates/registration/registration_activate.html @@ -0,0 +1,6 @@ +{% extends “base.html” %} +{% block body %} +Hello {{ account }}! + +Check your email to confirm the activation. There are {{ expiration_days }} days left to do it. +{% endblock %} \ No newline at end of file diff --git a/troggle/templates/registration/registration_complete.html b/troggle/templates/registration/registration_complete.html new file mode 100644 index 000000000..552fa04e6 --- /dev/null +++ b/troggle/templates/registration/registration_complete.html @@ -0,0 +1,13 @@ +{% extends "base.html" %} + +{% block title %} +registration_complete.html | {{ block.super }} +{% endblock %} + +{% block header %} +

registration_complete.html

+{% endblock %} + +{% block content %} +Thank you for signing up. An email with the activation code has been sent to your inbox. +{% endblock %} \ No newline at end of file diff --git a/troggle/templates/registration/registration_form.html b/troggle/templates/registration/registration_form.html new file mode 100644 index 000000000..17bebf263 --- /dev/null +++ b/troggle/templates/registration/registration_form.html @@ -0,0 +1,56 @@ +{% extends "base.html" %} + +{% block title %} +registration_form.html | {{ block.super }} +{% endblock %} + +{% block header %} +

registration_form.html

+{% endblock %} + +{% block content %} +
+ + + + + + + + + + + + + + + + + + + + + +
Username: + {{ form.username }}
+ {% for error in form.username.errors %} + {{ error }} + {% endfor %} +
Email: + {{ form.email }}
+ {% for error in form.email.errors %} + {{ error }} + {% endfor %} +
Password: + {{ form.password1 }}
+ {% for error in form.password1.errors %} + {{ error }} + {% endfor %} +
Password (again): + {{ form.password2 }}
+ {% for error in form.password2.errors %} + {{ error }} + {% endfor %} +
 
+
+{% endblock %} \ No newline at end of file diff --git a/troggle/urls.py b/troggle/urls.py index 36c502ebf..8c2810c51 100644 --- a/troggle/urls.py +++ b/troggle/urls.py @@ -45,6 +45,11 @@ urlpatterns = patterns('', (r'^admin/doc/?', include('django.contrib.admindocs.urls')), (r'^admin/(.*)', admin.site.root), + (r'^accounts/', include('registration.urls')), + (r'^profiles/', include('profiles.urls')), + + (r'^personform/(.*)$', personForm), + (r'^site_media/(?P.*)$', 'django.views.static.serve', {'document_root': settings.MEDIA_ROOT, 'show_indexes': True}),