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