Repository: Cloud-CV/EvalAI

Issue:
Add Feature to notify users about new challenge on EvalAI.



Discussion:

Resolving patch:
diff --git a/apps/web/urls.py b/apps/web/urls.py
--- a/apps/web/urls.py
+++ b/apps/web/urls.py
@@ -5,4 +5,5 @@
 urlpatterns = [
     url(r'^contact/$', views.contact_us, name='contact_us'),
     url(r'^team/$', views.our_team, name='our_team'),
+    url(r'^notify_users/$', views.notify_users_about_challenge, name='notify_users_about_challenge'),
 ]
diff --git a/apps/web/views.py b/apps/web/views.py
--- a/apps/web/views.py
+++ b/apps/web/views.py
@@ -1,7 +1,14 @@
 from django.contrib.auth.models import User
+from django.conf import settings
+from django.core.mail import EmailMultiAlternatives
 from django.shortcuts import render
+from django.template.loader import get_template
+from django.template import Context
+
+from email.MIMEImage import MIMEImage
 
 from .models import Team
+from .serializers import ContactSerializer, TeamSerializer
 
 from rest_framework import permissions, status
 from rest_framework.decorators import (api_view,
@@ -10,8 +17,6 @@
 from rest_framework.response import Response
 from rest_framework.throttling import AnonRateThrottle
 
-from .serializers import ContactSerializer, TeamSerializer
-
 
 def home(request, template_name="index.html"):
     """
@@ -34,6 +39,57 @@ def internal_server_error(request):
     return response
 
 
+def notify_users_about_challenge(request):
+    """
+    Email New Challenge Details to EvalAI Users
+    """
+    if request.user.is_authenticated() and request.user.is_superuser:
+        if request.method == 'GET':
+            template_name = 'notification_email_data.html'
+            return render(request, template_name)
+
+        elif request.method == 'POST':
+            template_name = 'notification_email.html'
+            emails = User.objects.all().exclude(email__isnull=True, email__exact='').values_list('email', flat=True)
+            htmly = get_template('notification_email.html')
+
+            subject = request.POST.get('subject')
+            body = request.POST.get('body')
+
+            try:
+                challenge_image = request.FILES['challenge_image']
+            except:
+                challenge_image = None
+
+            if challenge_image:
+                image = MIMEImage(challenge_image.read())
+                image.add_header('Content-ID', '<{}>'.format(challenge_image))
+
+            context = Context({'body': body,
+                               'image': challenge_image})
+
+            for email in emails:
+                from_email = settings.EMAIL_HOST_USER
+                to = [email]
+                html_content = htmly.render(context)
+
+                msg = EmailMultiAlternatives(subject, html_content, from_email, to)
+                msg.attach_alternative(html_content, "text/html")
+                msg.mixed_subtype = 'related'
+
+                if challenge_image:
+                    msg.attach(image)
+
+                msg.send()
+            return render(request,
+                          'notification_email_conformation.html',
+                          {'message': 'All the emails are sent successfully!'})
+        else:
+            return render(request, 'error404.html')
+    else:
+        return render(request, 'error404.html')
+
+
 @throttle_classes([AnonRateThrottle, ])
 @api_view(['GET', 'POST'])
 @permission_classes((permissions.AllowAny,))


Test patch:
diff --git a/tests/unit/web/test_views.py b/tests/unit/web/test_views.py
--- a/tests/unit/web/test_views.py
+++ b/tests/unit/web/test_views.py
@@ -169,3 +169,90 @@ def test_error_handlers(self):
         response = internal_server_error(request)
         self.assertEqual(response.status_code, 500)
         self.assertIn('Error 500', unicode(response))
+
+
+class TestNotifyUsersAboutChallenge(TestCase):
+
+    def setUp(self):
+        self.client = Client()
+
+        self.superuser = User.objects.create_superuser(
+            'superuser',
+            "superuser@test.com",
+            'secret_password')
+
+        self.user = User.objects.create(
+            username='someuser',
+            email="user@test.com",
+            password='secret_password')
+
+        self.url = reverse_lazy('web:notify_users_about_challenge')
+
+        self.email_data = {'subject': 'Subject of the Email',
+                           'body': 'Body of the Email'}
+
+    def test_if_user_isnt_authenticated(self):
+        response = self.client.get(self.url)
+        html = response.content.decode('utf8')
+        self.assertTrue(html.startswith('<!DOCTYPE html>'))
+        self.assertTrue(html.endswith(''))
+        self.assertEqual(response.status_code, 200)
+
+    def test_if_user_is_authenticated_but_not_superuser(self):
+        self.data = {'username': self.user.username, 'password': self.user.password}
+        response = self.client.post(self.url, self.data)
+        html = response.content.decode('utf8')
+        self.assertTrue(html.startswith('<!DOCTYPE html>'))
+        self.assertTrue(html.endswith(''))
+        self.assertEqual(response.status_code, 200)
+
+    def test_if_user_is_authenticated_and_superuser(self):
+        request = self.client.get('/admin/', follow=True)
+        response = self.client.login(username='superuser', password='secret_password')
+        self.assertEqual(request.status_code, 200)
+        self.assertTrue(response)
+
+    def test_notification_email_data_page(self):
+        request = self.client.get('/admin/', follow=True)
+        response = self.client.login(username='superuser', password='secret_password', follow=True)
+        request = self.client.get(self.url)
+        html = request.content.decode('utf8')
+        self.assertTrue(html.startswith(''))
+        self.assertTrue(html.endswith(''))
+        self.assertEqual(request.status_code, 200)
+        self.assertTrue(response)
+
+    def test_notification_email_without_challenge_image(self):
+        request = self.client.get('/admin/', follow=True)
+        response = self.client.login(username='superuser', password='secret_password', follow=True)
+        request = self.client.post(self.url, self.email_data)
+        html = request.content.decode('utf8')
+        self.assertTrue(html.startswith(''))
+        self.assertTrue(html.endswith(''))
+        self.assertEqual(request.status_code, 200)
+        self.assertTrue(response)
+
+    def test_notification_email_with_challenge_image(self):
+        request = self.client.get('/admin/', follow=True)
+        response = self.client.login(username='superuser', password='secret_password', follow=True)
+        self.email_data['challenge_image'] = SimpleUploadedFile(
+                                                name='test_background_image.jpg',
+                                                content=open('frontend/src/images/rocket.png', 'rb').read(),
+                                                content_type='image/jpg'
+            )
+        request = self.client.post(self.url, self.email_data)
+        html = request.content.decode('utf8')
+        self.assertTrue(html.startswith(''))
+        self.assertTrue(html.endswith(''))
+        self.assertTrue(response)
+        self.assertEqual(request.status_code, 200)
+
+    def test_notification_with_put_request(self):
+        request = self.client.get('/admin/', follow=True)
+        response = self.client.login(username='superuser', password='secret_password', follow=True)
+        request = self.client.put(self.url, self.email_data)
+        html = request.content.decode('utf8')
+        self.assertTrue(html.startswith('<!DOCTYPE html>'))
+        self.assertTrue(html.endswith(''))
+        self.assertTrue(response)
+        self.assertEqual(request.status_code, 200)