From 37e0591a6509eaa4af3bf4656b32aa7b7df92646 Mon Sep 17 00:00:00 2001 From: elhassane <elhassanegargem@gmail.com> Date: Tue, 25 Aug 2020 15:25:32 +0200 Subject: [PATCH 1/5] contact us page --- app/apps/bootstrap/forms.py | 2 +- app/apps/users/admin.py | 4 +- app/apps/users/forms.py | 10 ++++- app/apps/users/migrations/0009_contactus.py | 23 +++++++++++ app/apps/users/models.py | 40 +++++++++++++++++++ app/apps/users/urls.py | 3 +- app/apps/users/views.py | 18 +++++++-- app/escriptorium/static/css/escriptorium.css | 4 ++ app/escriptorium/templates/base.html | 2 +- .../templates/users/email/contactus_html.html | 5 +++ .../users/email/contactus_message.txt | 5 +++ .../users/email/contactus_subject.txt | 1 + 12 files changed, 109 insertions(+), 8 deletions(-) create mode 100644 app/apps/users/migrations/0009_contactus.py create mode 100644 app/escriptorium/templates/users/email/contactus_html.html create mode 100644 app/escriptorium/templates/users/email/contactus_message.txt create mode 100644 app/escriptorium/templates/users/email/contactus_subject.txt diff --git a/app/apps/bootstrap/forms.py b/app/apps/bootstrap/forms.py index 88208250..f9071dd2 100644 --- a/app/apps/bootstrap/forms.py +++ b/app/apps/bootstrap/forms.py @@ -26,7 +26,7 @@ class BootstrapFormMixin(): class_ += ' form-control' if issubclass(field.widget.__class__, forms.Select): class_ += ' custom-select' - if field.widget.input_type == 'select': + if hasattr(field.widget,'input_type') and field.widget.input_type == 'select': field.widget.need_label = True field.widget.attrs['class'] = class_ diff --git a/app/apps/users/admin.py b/app/apps/users/admin.py index b0b29f67..d052098e 100644 --- a/app/apps/users/admin.py +++ b/app/apps/users/admin.py @@ -6,7 +6,7 @@ from django.contrib import messages from django.utils.translation import ngettext -from users.models import User, ResearchField, Invitation +from users.models import User, ResearchField, Invitation, ContactUs class MyUserChangeForm(UserChangeForm): @@ -62,3 +62,5 @@ class InvitationAdmin(admin.ModelAdmin): admin.site.register(User, MyUserAdmin) admin.site.register(ResearchField) admin.site.register(Invitation, InvitationAdmin) +admin.site.register(ContactUs) + diff --git a/app/apps/users/forms.py b/app/apps/users/forms.py index ebd31ff9..ccb220e5 100644 --- a/app/apps/users/forms.py +++ b/app/apps/users/forms.py @@ -3,7 +3,7 @@ from django.contrib.auth.forms import UserChangeForm, UserCreationForm from django.utils.translation import gettext as _ from bootstrap.forms import BootstrapFormMixin -from users.models import Invitation, User +from users.models import Invitation, User, ContactUs class InvitationForm(BootstrapFormMixin, forms.ModelForm): @@ -52,3 +52,11 @@ class ProfileForm(BootstrapFormMixin, forms.ModelForm): class Meta: model = User fields = ('email', 'first_name', 'last_name') + + +class ContactUsForm(BootstrapFormMixin, forms.ModelForm): + + class Meta: + model = ContactUs + fields = ('name','subject','email','message') + diff --git a/app/apps/users/migrations/0009_contactus.py b/app/apps/users/migrations/0009_contactus.py new file mode 100644 index 00000000..0bea23d8 --- /dev/null +++ b/app/apps/users/migrations/0009_contactus.py @@ -0,0 +1,23 @@ +# Generated by Django 2.1.4 on 2020-08-20 16:18 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('users', '0008_auto_20200520_1007'), + ] + + operations = [ + migrations.CreateModel( + name='ContactUs', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=255)), + ('subject', models.CharField(max_length=255)), + ('email', models.EmailField(max_length=255, verbose_name='email address')), + ('message', models.TextField()), + ], + ), + ] diff --git a/app/apps/users/models.py b/app/apps/users/models.py index 9dc9af23..42d004bd 100644 --- a/app/apps/users/models.py +++ b/app/apps/users/models.py @@ -133,3 +133,43 @@ class Invitation(models.Model): _('{username} accepted your invitation!').format( username=self.recipient.username), level='success') + +class ContactUs(models.Model): + """ + Represents Contact Us form + """ + name = models.CharField(max_length=255) + subject = models.CharField(max_length=255) + email = models.EmailField( + verbose_name=_('email address'), + max_length=255, + ) + message = models.TextField() + + class Meta: + verbose_name ="message" + verbose_name_plural = "messages" + + + def __str__(self): + + return "from {}({})".format(self.name,self.email) + + def save(self, *args, **kwargs): + context = { + "sender_name": self.name, + "sender_email": self.email, + "message": self.message, + "subject": self.subject + } + + send_email( + 'users/email/contactus_subject.txt', + 'users/email/contactus_message.txt', + 'users/email/contactus_html.html', + 'elhassanegargem@gmail.com', + context=context, + result_interface=None + ) + + super().save(*args, **kwargs) diff --git a/app/apps/users/urls.py b/app/apps/users/urls.py index 7259741b..a90f1c5f 100644 --- a/app/apps/users/urls.py +++ b/app/apps/users/urls.py @@ -1,11 +1,12 @@ from django.urls import path, include -from users.views import SendInvitation, AcceptInvitation, Profile +from users.views import SendInvitation, AcceptInvitation, Profile, ContactUsView from django.contrib.auth.decorators import permission_required urlpatterns = [ path('', include('django.contrib.auth.urls')), path('profile/', Profile.as_view(), name='user_profile'), + path('contact/', ContactUsView.as_view(), name='contactus'), path('invite/', permission_required('users.can_invite', raise_exception=True)(SendInvitation.as_view()), name='send-invitation'), diff --git a/app/apps/users/views.py b/app/apps/users/views.py index c624e15f..ea62e6f4 100644 --- a/app/apps/users/views.py +++ b/app/apps/users/views.py @@ -1,6 +1,6 @@ from os import listdir, stat from os.path import isfile, join, relpath - +from django.shortcuts import reverse from django.conf import settings from django.contrib.auth.mixins import LoginRequiredMixin from django.contrib.messages.views import SuccessMessageMixin @@ -12,8 +12,8 @@ from django.views.generic.edit import CreateView, UpdateView from rest_framework.authtoken.models import Token -from users.models import User, Invitation -from users.forms import InvitationForm, InvitationAcceptForm, ProfileForm +from users.models import User, Invitation, ContactUs +from users.forms import InvitationForm, InvitationAcceptForm, ProfileForm, ContactUsForm class SendInvitation(LoginRequiredMixin, SuccessMessageMixin, CreateView): @@ -103,3 +103,15 @@ class Profile(SuccessMessageMixin, UpdateView): context['is_paginated'] = paginator.count != 0 context['page_obj'] = paginator.get_page(page_number) return context + +class ContactUsView(SuccessMessageMixin, CreateView): + + model = ContactUs + form_class = ContactUsForm + + success_message = _('Your message successfully sent.') + + template_name = 'users/contactus.html' + + def get_success_url(self): + return reverse('home') diff --git a/app/escriptorium/static/css/escriptorium.css b/app/escriptorium/static/css/escriptorium.css index 0ae2817a..e2d55eb2 100644 --- a/app/escriptorium/static/css/escriptorium.css +++ b/app/escriptorium/static/css/escriptorium.css @@ -616,3 +616,7 @@ i.panel-icon { .cmp-del { color: red; } + +#contact-form{ + width: 100%; +} \ No newline at end of file diff --git a/app/escriptorium/templates/base.html b/app/escriptorium/templates/base.html index 3167a746..cf925d36 100644 --- a/app/escriptorium/templates/base.html +++ b/app/escriptorium/templates/base.html @@ -47,7 +47,7 @@ <a class="nav-link" href="#">{% trans 'About' %}</a> </li> <li class="nav-item"> - <a class="nav-link" href="#">{% trans 'Contact' %}</a> + <a class="nav-link" href="{% url 'contactus' %}">{% trans 'Contact' %}</a> </li> {% comment %} diff --git a/app/escriptorium/templates/users/email/contactus_html.html b/app/escriptorium/templates/users/email/contactus_html.html new file mode 100644 index 00000000..8266ab4d --- /dev/null +++ b/app/escriptorium/templates/users/email/contactus_html.html @@ -0,0 +1,5 @@ +<p>Hello escriptorium Admin</p> +<p>{{sender_name}} wants to send you a message, you will find it bellow.</br> +{{message}} +<p>You can contact him on this email : {{ sender_email }}</p> +<p>Sincerely, the eScriptorium team.</p> diff --git a/app/escriptorium/templates/users/email/contactus_message.txt b/app/escriptorium/templates/users/email/contactus_message.txt new file mode 100644 index 00000000..245a7491 --- /dev/null +++ b/app/escriptorium/templates/users/email/contactus_message.txt @@ -0,0 +1,5 @@ +Dear escriptorium Admin, +{{sender_name}} wants to send you a message, you will find it bellow. +{{message}} +You can contact him on this email : {{ sender_email }} +Sincerely, the eScriptorium team. diff --git a/app/escriptorium/templates/users/email/contactus_subject.txt b/app/escriptorium/templates/users/email/contactus_subject.txt new file mode 100644 index 00000000..cdbd58a6 --- /dev/null +++ b/app/escriptorium/templates/users/email/contactus_subject.txt @@ -0,0 +1 @@ +{{ subject }} \ No newline at end of file -- GitLab From 8b8233df232cce04b5e36cc7da8c9bb28b43b4cd Mon Sep 17 00:00:00 2001 From: elhassane <elhassanegargem@gmail.com> Date: Thu, 27 Aug 2020 12:17:16 +0200 Subject: [PATCH 2/5] change success url --- app/apps/users/views.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/apps/users/views.py b/app/apps/users/views.py index ea62e6f4..e594848a 100644 --- a/app/apps/users/views.py +++ b/app/apps/users/views.py @@ -113,5 +113,4 @@ class ContactUsView(SuccessMessageMixin, CreateView): template_name = 'users/contactus.html' - def get_success_url(self): - return reverse('home') + success_url = '/contact/' -- GitLab From d25173a3c8673aacc048e0651eab2548b40efefb Mon Sep 17 00:00:00 2001 From: elhassane <elhassanegargem@gmail.com> Date: Thu, 27 Aug 2020 13:19:35 +0200 Subject: [PATCH 3/5] forget to push template --- app/apps/users/models.py | 2 +- .../templates/users/contactus.html | 32 +++++++++++++++++++ 2 files changed, 33 insertions(+), 1 deletion(-) create mode 100644 app/escriptorium/templates/users/contactus.html diff --git a/app/apps/users/models.py b/app/apps/users/models.py index 42d004bd..aa6aada1 100644 --- a/app/apps/users/models.py +++ b/app/apps/users/models.py @@ -167,7 +167,7 @@ class ContactUs(models.Model): 'users/email/contactus_subject.txt', 'users/email/contactus_message.txt', 'users/email/contactus_html.html', - 'elhassanegargem@gmail.com', + settings.ADMINS, context=context, result_interface=None ) diff --git a/app/escriptorium/templates/users/contactus.html b/app/escriptorium/templates/users/contactus.html new file mode 100644 index 00000000..6e5d6ae2 --- /dev/null +++ b/app/escriptorium/templates/users/contactus.html @@ -0,0 +1,32 @@ +{% extends "base.html" %} +{% load i18n bootstrap static %} + +{% block body %} +<div class="container"> + <div class="row"> + <form id="contact-form" method="post"> + {% csrf_token %} + <fieldset> + <div class="form-group"> + {% for error in form.errors %} + <p class="error">{{ error }}</p> + {% endfor %} + </div> + <div class="form-group"> + {{ form.name }} + </div> + <div class="form-group"> + {{ form.email }} + </div> + <div class="form-group"> + {{ form.subject }} + </div> + <div class="form-group"> + {{ form.message }} + </div> + <input type="submit" value="{% trans 'Send' %}" class="btn btn-success btn-block my-3" {% if object %}autofocus{% endif %}> + </fieldset> + </form> + </div> +</div> +{% endblock %} \ No newline at end of file -- GitLab From d1d83a078e56326263b839791c03e7fddc6eb2b1 Mon Sep 17 00:00:00 2001 From: elhassane <elhassanegargem@gmail.com> Date: Fri, 28 Aug 2020 13:41:06 +0200 Subject: [PATCH 4/5] remove subject and edit template --- app/apps/users/forms.py | 2 +- app/apps/users/models.py | 2 -- app/escriptorium/templates/users/contactus.html | 17 ++++------------- .../templates/users/email/contactus_subject.txt | 2 +- 4 files changed, 6 insertions(+), 17 deletions(-) diff --git a/app/apps/users/forms.py b/app/apps/users/forms.py index ccb220e5..6867f44c 100644 --- a/app/apps/users/forms.py +++ b/app/apps/users/forms.py @@ -58,5 +58,5 @@ class ContactUsForm(BootstrapFormMixin, forms.ModelForm): class Meta: model = ContactUs - fields = ('name','subject','email','message') + fields = ('name','email','message') diff --git a/app/apps/users/models.py b/app/apps/users/models.py index aa6aada1..95acf464 100644 --- a/app/apps/users/models.py +++ b/app/apps/users/models.py @@ -139,7 +139,6 @@ class ContactUs(models.Model): Represents Contact Us form """ name = models.CharField(max_length=255) - subject = models.CharField(max_length=255) email = models.EmailField( verbose_name=_('email address'), max_length=255, @@ -160,7 +159,6 @@ class ContactUs(models.Model): "sender_name": self.name, "sender_email": self.email, "message": self.message, - "subject": self.subject } send_email( diff --git a/app/escriptorium/templates/users/contactus.html b/app/escriptorium/templates/users/contactus.html index 6e5d6ae2..84b102cb 100644 --- a/app/escriptorium/templates/users/contactus.html +++ b/app/escriptorium/templates/users/contactus.html @@ -8,22 +8,13 @@ {% csrf_token %} <fieldset> <div class="form-group"> - {% for error in form.errors %} + {% for error in form.non_field_errors %} <p class="error">{{ error }}</p> {% endfor %} </div> - <div class="form-group"> - {{ form.name }} - </div> - <div class="form-group"> - {{ form.email }} - </div> - <div class="form-group"> - {{ form.subject }} - </div> - <div class="form-group"> - {{ form.message }} - </div> + {% render_field form.name %} + {% render_field form.email %} + {% render_field form.message %} <input type="submit" value="{% trans 'Send' %}" class="btn btn-success btn-block my-3" {% if object %}autofocus{% endif %}> </fieldset> </form> diff --git a/app/escriptorium/templates/users/email/contactus_subject.txt b/app/escriptorium/templates/users/email/contactus_subject.txt index cdbd58a6..1484af58 100644 --- a/app/escriptorium/templates/users/email/contactus_subject.txt +++ b/app/escriptorium/templates/users/email/contactus_subject.txt @@ -1 +1 @@ -{{ subject }} \ No newline at end of file +message from : {{ sender_name }}({{sender_email }}) \ No newline at end of file -- GitLab From cd6d05703c1141bcf49c528e1eff22ae4158a8ac Mon Sep 17 00:00:00 2001 From: elhassane <elhassanegargem@gmail.com> Date: Fri, 28 Aug 2020 15:15:33 +0200 Subject: [PATCH 5/5] add captcha to contact --- app/apps/users/forms.py | 6 +++++- app/escriptorium/settings.py | 1 + app/escriptorium/templates/users/contactus.html | 1 + app/escriptorium/urls.py | 3 ++- app/requirements.txt | 1 + 5 files changed, 10 insertions(+), 2 deletions(-) diff --git a/app/apps/users/forms.py b/app/apps/users/forms.py index 6867f44c..cdf2d6a3 100644 --- a/app/apps/users/forms.py +++ b/app/apps/users/forms.py @@ -1,6 +1,7 @@ from django import forms from django.contrib.auth.forms import UserChangeForm, UserCreationForm from django.utils.translation import gettext as _ +from captcha.fields import CaptchaField from bootstrap.forms import BootstrapFormMixin from users.models import Invitation, User, ContactUs @@ -56,7 +57,10 @@ class ProfileForm(BootstrapFormMixin, forms.ModelForm): class ContactUsForm(BootstrapFormMixin, forms.ModelForm): + message = forms.CharField(label="Message : Please precise your institution or research center if applicable", widget=forms.Textarea(attrs={'placeholder':'Message : Please precise your institution or research center if applicable' })) + captcha = CaptchaField() + class Meta: model = ContactUs - fields = ('name','email','message') + fields = ('name','email','message','captcha') diff --git a/app/escriptorium/settings.py b/app/escriptorium/settings.py index 41ba0568..a331cd01 100644 --- a/app/escriptorium/settings.py +++ b/app/escriptorium/settings.py @@ -62,6 +62,7 @@ INSTALLED_APPS = [ 'rest_framework', 'rest_framework.authtoken', 'compressor', + 'captcha', 'bootstrap', 'versioning', diff --git a/app/escriptorium/templates/users/contactus.html b/app/escriptorium/templates/users/contactus.html index 84b102cb..c3d701d8 100644 --- a/app/escriptorium/templates/users/contactus.html +++ b/app/escriptorium/templates/users/contactus.html @@ -15,6 +15,7 @@ {% render_field form.name %} {% render_field form.email %} {% render_field form.message %} + {{ form.captcha }} <input type="submit" value="{% trans 'Send' %}" class="btn btn-success btn-block my-3" {% if object %}autofocus{% endif %}> </fieldset> </form> diff --git a/app/escriptorium/urls.py b/app/escriptorium/urls.py index d548cc10..9b279341 100644 --- a/app/escriptorium/urls.py +++ b/app/escriptorium/urls.py @@ -26,7 +26,8 @@ urlpatterns = [ path('api/', include('api.urls', namespace='api')), # sandbox - path('baseline-editor/', TemplateView.as_view(template_name='baseline_editor.html')) + path('baseline-editor/', TemplateView.as_view(template_name='baseline_editor.html')), + path(r'captcha/', include('captcha.urls')), ] if settings.DEBUG: diff --git a/app/requirements.txt b/app/requirements.txt index ade37044..494e3f5c 100644 --- a/app/requirements.txt +++ b/app/requirements.txt @@ -22,3 +22,4 @@ requests==2.21.0 numpy>=1.17 django-compressor==2.4 albumentations +django-simple-captcha==0.5.12 -- GitLab