diff --git a/cfp/forms.py b/cfp/forms.py index ce36d02..946265f 100644 --- a/cfp/forms.py +++ b/cfp/forms.py @@ -2,6 +2,8 @@ from django import forms from django.forms.models import modelform_factory from django.contrib.auth.admin import UserAdmin from django.contrib.auth.models import User +from django.contrib.auth.forms import UsernameField +from django.utils.translation import ugettext as _ from django_select2.forms import ModelSelect2MultipleWidget @@ -31,3 +33,22 @@ class UsersWidget(ModelSelect2MultipleWidget): ConferenceForm = modelform_factory(Conference, fields=['name', 'home', 'venue', 'city', 'contact_email', 'staff',], widgets={'staff': UsersWidget(),}) + + +class CreateUserForm(forms.ModelForm): + class Meta: + model = User + fields = ("username", "email") + field_classes = {'username': UsernameField} + + def clean_email(self): + email = self.cleaned_data.get('email') + if email and User.objects.filter(email=email).exists(): + raise forms.ValidationError(_('A user with that email already exists.')) + + def save(self, commit=True): + user = super().save(commit=False) + user.set_unusable_password() + if commit: + user.save() + return user diff --git a/cfp/templates/cfp/staff/conference.html b/cfp/templates/cfp/staff/conference.html index a336cb9..852c44c 100644 --- a/cfp/templates/cfp/staff/conference.html +++ b/cfp/templates/cfp/staff/conference.html @@ -10,6 +10,7 @@
{% csrf_token %} {{ form|crispy }} + {% trans "Add a new user" %}
diff --git a/cfp/templates/cfp/staff/create_user.html b/cfp/templates/cfp/staff/create_user.html new file mode 100644 index 0000000..7e433cc --- /dev/null +++ b/cfp/templates/cfp/staff/create_user.html @@ -0,0 +1,17 @@ +{% extends 'cfp/staff/base.html' %} +{% load i18n crispy_forms_tags %} + +{% block conferencetab %} class="active"{% endblock %} + +{% block content %} + +

{% trans "Add a new user" %}

+ +
+ {% csrf_token %} + {{ form|crispy }} + + {% trans "Cancel" %} +
+ +{% endblock %} diff --git a/cfp/templates/cfp/staff/talk_decide.html b/cfp/templates/cfp/staff/talk_decide.html index 1fcd04b..50f1724 100644 --- a/cfp/templates/cfp/staff/talk_decide.html +++ b/cfp/templates/cfp/staff/talk_decide.html @@ -13,7 +13,7 @@
{% comment %}

{% trans "Information for the proposer" %}

{% endcomment %} -
+ {% csrf_token %} {% comment %}
diff --git a/cfp/urls.py b/cfp/urls.py index 5cad1d3..c3a7fd3 100644 --- a/cfp/urls.py +++ b/cfp/urls.py @@ -17,6 +17,7 @@ urlpatterns = [ url(r'^staff/talks/(?P[\w\-]+)/decline/$', views.talk_decide, {'accept': False}, name='talk-decline'), url(r'^staff/speakers/$', views.participant_list, name='participant-list'), url(r'^staff/speakers/(?P[\w\-]+)/$', views.participant_details, name='participant-details'), + url(r'^staff/add-user/$', views.create_user, name='create-user'), url(r'^staff/select2/$', views.Select2View.as_view(), name='django_select2-json'), #url(r'^markdown/$', views.markdown_preview, name='markdown'), diff --git a/cfp/views.py b/cfp/views.py index 22f0fab..aea9241 100644 --- a/cfp/views.py +++ b/cfp/views.py @@ -12,7 +12,7 @@ from cfp.decorators import staff_required from .mixins import StaffRequiredMixin from .utils import is_staff from .models import Participant, Talk, TalkCategory, Vote -from .forms import TalkForm, ParticipantForm, ConferenceForm +from .forms import TalkForm, ParticipantForm, ConferenceForm, CreateUserForm def home(request, conference): @@ -203,6 +203,7 @@ def conference(request, conference): form = ConferenceForm(request.POST or None, instance=conference) if request.method == 'POST' and form.is_valid(): + # TODO mail notifications to new staff members form.save() messages.success(request, _('Modifications successfully saved.')) return redirect(reverse('conference')) @@ -212,5 +213,19 @@ def conference(request, conference): }) +@staff_required +def create_user(request, conference): + form = CreateUserForm(request.POST or None) + + if request.method == 'POST' and form.is_valid(): + form.save() + messages.success(request, _('User created successfully.')) + return redirect(reverse('create-user')) + + return render(request, 'cfp/staff/create_user.html', { + 'form': form, + }) + + class Select2View(StaffRequiredMixin, AutoResponseView): pass diff --git a/locale/fr/LC_MESSAGES/django.mo b/locale/fr/LC_MESSAGES/django.mo index 5d68ec2..f2a230b 100644 Binary files a/locale/fr/LC_MESSAGES/django.mo and b/locale/fr/LC_MESSAGES/django.mo differ diff --git a/locale/fr/LC_MESSAGES/django.po b/locale/fr/LC_MESSAGES/django.po index e8c8006..a8e55ba 100644 --- a/locale/fr/LC_MESSAGES/django.po +++ b/locale/fr/LC_MESSAGES/django.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2017-07-30 18:07+0000\n" +"POT-Creation-Date: 2017-07-30 19:44+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -105,7 +105,7 @@ msgid "Biography" msgstr "Biographie" #: accounts/templates/accounts/participant_details.html:27 -#: cfp/templates/cfp/staff/base.html:20 +#: cfp/templates/cfp/staff/base.html:19 #: cfp/templates/cfp/staff/participant_details.html:31 #: cfp/templates/cfp/staff/talk_list.html:8 #: proposals/templates/proposals/talk_list.html:9 @@ -215,6 +215,7 @@ msgid "Submit" msgstr "Envoyer" #: accounts/templates/accounts/profile.html:36 +#: cfp/templates/cfp/staff/create_user.html:14 #: cfp/templates/cfp/staff/talk_decide.html:27 ponyconf/templates/_form.html:16 #: proposals/templates/proposals/talk_decide.html:23 msgid "Cancel" @@ -287,6 +288,10 @@ msgstr "%(name)s a été ajouté aux participants" msgid "%(name)s is already a participant" msgstr "%(name)s est déjà participant" +#: cfp/forms.py:47 +msgid "A user with that email already exists." +msgstr "Un utilisateur avec cet email existe déjà." + #: cfp/models.py:36 msgid "Conference name" msgstr "Nom de la conférence" @@ -343,7 +348,7 @@ msgstr "Couleur sur le programme" msgid "Label on program" msgstr "Label dans le xml du programme" -#: cfp/models.py:229 cfp/templates/cfp/staff/base.html:21 +#: cfp/models.py:229 cfp/templates/cfp/staff/base.html:20 #: cfp/templates/cfp/staff/participant_list.html:8 #: cfp/templates/cfp/staff/talk_details.html:75 #: cfp/templates/cfp/staff/talk_list.html:18 proposals/models.py:154 @@ -444,10 +449,11 @@ msgstr "Un mail vous a été envoyé avec toutes les URLs" #: cfp/templates/cfp/propose.html:22 cfp/templates/cfp/speaker.html:21 #: cfp/templates/cfp/staff/conference.html:13 +#: cfp/templates/cfp/staff/create_user.html:13 msgid "Save" msgstr "Envoyer" -#: cfp/templates/cfp/staff/base.html:19 +#: cfp/templates/cfp/staff/base.html:21 #: cfp/templates/cfp/staff/conference.html:8 msgid "Conference" msgstr "Conférence" @@ -456,6 +462,10 @@ msgstr "Conférence" msgid "Please select a category." msgstr "Veuillez sélectionner une catégorie." +#: cfp/templates/cfp/staff/create_user.html:8 +msgid "Add a new user" +msgstr "Ajouter un nouvel utilisateur" + #: cfp/templates/cfp/staff/participant_details.html:18 msgid "Informations" msgstr "Informations" @@ -735,11 +745,13 @@ msgstr "Vote mis à jour" msgid "Decision taken in account" msgstr "Décision enregistrée" -#: cfp/views.py:207 -#, fuzzy -#| msgid "Vote successfully created" +#: cfp/views.py:208 msgid "Modifications successfully saved." -msgstr "A voté !" +msgstr "Modification enregistrée avec succès." + +#: cfp/views.py:222 +msgid "User created successfully." +msgstr "Utilisateur créé avec succès." #: conversations/templates/conversations/_message_form.html:4 msgid "Send a message" @@ -836,7 +848,7 @@ msgstr "Appel à participation" #: ponyconf/templates/base.html:36 msgid "Staff" -msgstr "" +msgstr "Staff" #: ponyconf/templates/base.html:50 #: ponyconf/templates/registration/login.html:10 diff --git a/ponyconf/urls.py b/ponyconf/urls.py index 9c93505..a17e402 100644 --- a/ponyconf/urls.py +++ b/ponyconf/urls.py @@ -15,17 +15,10 @@ Including another URLconf """ from django.conf.urls import include, url from django.contrib import admin -#from django.conf.urls.static import static -#from django.conf import settings urlpatterns = [ url(r'^admin/', admin.site.urls), - url(r'^accounts/', include('accounts.urls')), + url(r'accounts/', include('django.contrib.auth.urls')), url(r'^', include('cfp.urls')), - #url(r'', include('proposals.urls')), - #url(r'', include('planning.urls')), - #url(r'^volunteers/', include('volunteers.urls')), - #url(r'^conversations/', include('conversations.urls')), - #url(r'^select2/', include('django_select2.urls')), -]# + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) +]