From d099189fee72350f719c83ef61a8a432af754d3a Mon Sep 17 00:00:00 2001
From: ShraddhaAg <shraddha.agrawal000@gmail.com>
Date: Mar 15 2019 08:23:05 +0000
Subject: Upgrade from Python 2 to Python 3


This commit upgrades FHP from Python 2 to Python 3 and Django 1.11
to Django 2.0.

---

diff --git a/Dockerfile b/Dockerfile
index 3ae4a38..86713a9 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,4 +1,5 @@
-FROM python:2-alpine
+#Issue with celery=4.2.1 with Py3.7 hence Py3.6.8 used
+FROM python:3.6.8-alpine
 
 # Set current working directory
 WORKDIR /app
diff --git a/happinesspackets/messaging/forms.py b/happinesspackets/messaging/forms.py
index 0861170..1c6e822 100644
--- a/happinesspackets/messaging/forms.py
+++ b/happinesspackets/messaging/forms.py
@@ -8,7 +8,7 @@ from crispy_forms.helper import FormHelper
 from crispy_forms.layout import Submit, Layout, Fieldset, HTML
 from django import forms
 from django.conf import settings
-from django.core.urlresolvers import reverse
+from django.urls import reverse
 from django.db.models import Q
 from django.utils import timezone
 
diff --git a/happinesspackets/messaging/models.py b/happinesspackets/messaging/models.py
index e7890f9..a50a868 100644
--- a/happinesspackets/messaging/models.py
+++ b/happinesspackets/messaging/models.py
@@ -4,7 +4,7 @@ from __future__ import unicode_literals
 import logging
 import re
 
-from django.core.urlresolvers import reverse
+from django.urls import reverse
 from django.db import models
 from django.template.loader import render_to_string
 from django.utils.crypto import salted_hmac
diff --git a/happinesspackets/messaging/tests/test_views.py b/happinesspackets/messaging/tests/test_views.py
index aa58124..d1f1b25 100644
--- a/happinesspackets/messaging/tests/test_views.py
+++ b/happinesspackets/messaging/tests/test_views.py
@@ -4,7 +4,7 @@ from __future__ import unicode_literals
 from django.conf import settings
 from django.core import mail
 from django.contrib.auth.models import User
-from django.core.urlresolvers import reverse
+from django.urls import reverse
 from django.test import TestCase
 from django.utils.crypto import salted_hmac
 from haystack.management.commands import update_index
diff --git a/happinesspackets/messaging/urls.py b/happinesspackets/messaging/urls.py
index a8ae2a6..0e89d37 100644
--- a/happinesspackets/messaging/urls.py
+++ b/happinesspackets/messaging/urls.py
@@ -1,23 +1,25 @@
 from __future__ import unicode_literals
 
-from django.conf.urls import url
+from django.urls import re_path
 
 from .views import (StartView, MessageSearchView, MessageSendView, MessageSenderConfirmationSentView, MessageSenderConfirmationView,
                     MessageSenderConfirmedView, MessageRecipientMessageUpdate, FaqView, ArchiveView, InspirationView,
                     BlacklistEmailView, ReceivedMessagesView, SentMessagesView)
 
+app_name = 'messaging'
+
 urlpatterns = [
-    url(r'^$', StartView.as_view(), name='start'),
-    url(r'^faq/$', FaqView.as_view(), name='faq'),
-    url(r'^archive/$', ArchiveView.as_view(), name='archive'),
-    url(r'^inspiration/$', InspirationView.as_view(), name='inspiration'),
-    url(r'^received-messages/$', ReceivedMessagesView.as_view(), name='received_messages'),
-    url(r'^sent-messages/$', SentMessagesView.as_view(), name='sent_messages'),
-    url(r'^blacklist-email/(?P<email>[\w\.@\+-]+)/(?P<digest>\w+)/$', BlacklistEmailView.as_view(), name='blacklist_email'),
-    url(r'^send/$', MessageSendView.as_view(), name='send'),
-    url(r'^send/confirmation-sent/$', MessageSenderConfirmationSentView.as_view(), name='sender_confirmation_sent'),
-    url(r'^send/confirmation/(?P<identifier>[\w-]+)/(?P<token>[\w-]+)/$', MessageSenderConfirmationView.as_view(), name='sender_confirm'),
-    url(r'^send/confirmed/$', MessageSenderConfirmedView.as_view(), name='sender_confirmed'),
-    url(r'^recipient/(?P<identifier>[\w-]+)/(?P<token>[\w-]+)/$', MessageRecipientMessageUpdate.as_view(), name='recipient_message_update'),
-    url(r'^search/?$', MessageSearchView.as_view(), name='search'),
+    re_path(r'^$', StartView.as_view(), name='start'),
+    re_path(r'^faq/$', FaqView.as_view(), name='faq'),
+    re_path(r'^archive/$', ArchiveView.as_view(), name='archive'),
+    re_path(r'^inspiration/$', InspirationView.as_view(), name='inspiration'),
+    re_path(r'^received-messages/$', ReceivedMessagesView.as_view(), name='received_messages'),
+    re_path(r'^sent-messages/$', SentMessagesView.as_view(), name='sent_messages'),
+    re_path(r'^blacklist-email/(?P<email>[\w\.@\+-]+)/(?P<digest>\w+)/$', BlacklistEmailView.as_view(), name='blacklist_email'),
+    re_path(r'^send/$', MessageSendView.as_view(), name='send'),
+    re_path(r'^send/confirmation-sent/$', MessageSenderConfirmationSentView.as_view(), name='sender_confirmation_sent'),
+    re_path(r'^send/confirmation/(?P<identifier>[\w-]+)/(?P<token>[\w-]+)/$', MessageSenderConfirmationView.as_view(), name='sender_confirm'),
+    re_path(r'^send/confirmed/$', MessageSenderConfirmedView.as_view(), name='sender_confirmed'),
+    re_path(r'^recipient/(?P<identifier>[\w-]+)/(?P<token>[\w-]+)/$', MessageRecipientMessageUpdate.as_view(), name='recipient_message_update'),
+    re_path(r'^search/?$', MessageSearchView.as_view(), name='search'),
 ]
diff --git a/happinesspackets/messaging/views.py b/happinesspackets/messaging/views.py
index a5a0d62..597e9b5 100644
--- a/happinesspackets/messaging/views.py
+++ b/happinesspackets/messaging/views.py
@@ -4,7 +4,7 @@ from __future__ import unicode_literals
 import logging
 
 from django.contrib import messages
-from django.core.urlresolvers import reverse, reverse_lazy
+from django.urls import reverse, reverse_lazy
 from django.http import HttpResponseRedirect, Http404
 from django.utils.crypto import salted_hmac, constant_time_compare
 from django.utils.decorators import method_decorator
@@ -13,6 +13,7 @@ from django.views.decorators.debug import sensitive_post_parameters
 from django.views.generic import FormView, TemplateView, UpdateView, ListView
 from django.contrib.auth.mixins import LoginRequiredMixin
 from django.db.models import Q
+from django.shortcuts import render
 
 from haystack.generic_views import SearchView
 from haystack.forms import SearchForm
@@ -126,10 +127,10 @@ class MessageSenderConfirmationView(TemplateView):
         try:
             message = Message.objects.get(identifier=kwargs['identifier'], sender_email_token=kwargs['token'])
         except Message.DoesNotExist:
-            return self.render_to_response({'not_found': True})
+            return render(request, self.template_name, {'not_found': True})
 
         if message.status != Message.STATUS.pending_sender_confirmation:
-            return self.render_to_response({'already_confirmed': True})
+            return render(request, self.template_name, {'already_confirmed': True})
 
         message.send_to_recipient(self.request.is_secure(), self.request.get_host())
 
@@ -145,9 +146,9 @@ class MessageSenderConfirmationView(TemplateView):
         try:
             publish(message)
         except PublishReturned:
-            return self.render_to_response({'publish_returned': True})
+            return render(request, self.template_name, {'publish_returned': True})
         except ConnectionException:
-            return self.render_to_response({'connection_exception': True})
+            return render(request, self.template_name, {'connection_exception': True})
         return HttpResponseRedirect(reverse('messaging:sender_confirmed'))
 
 
diff --git a/happinesspackets/settings/base.py b/happinesspackets/settings/base.py
index 34dc815..141eadd 100644
--- a/happinesspackets/settings/base.py
+++ b/happinesspackets/settings/base.py
@@ -60,7 +60,7 @@ STATICFILES_DIRS = (
 )
 
 # noinspection PyUnresolvedReferences
-MIDDLEWARE_CLASSES = [
+MIDDLEWARE = [
     'django.contrib.sessions.middleware.SessionMiddleware',
     'happinesspackets.utils.middleware.SetRemoteAddrFromForwardedFor',
     'opbeat.contrib.django.middleware.OpbeatAPMMiddleware',
diff --git a/happinesspackets/settings/dev.py b/happinesspackets/settings/dev.py
index 7e577cc..cdfe56e 100644
--- a/happinesspackets/settings/dev.py
+++ b/happinesspackets/settings/dev.py
@@ -1,6 +1,7 @@
 # -*- coding: utf-8 -*-
 # noinspection PyUnresolvedReferences
 import json
+import sys
 
 from .base import *  # noqa
 
@@ -39,7 +40,7 @@ CSRF_COOKIE_SECURE = False
 
 ADMIN_ENABLED = True
 
-MIDDLEWARE_CLASSES = [
+MIDDLEWARE = [
     'django.contrib.sessions.middleware.SessionMiddleware',
     'django.contrib.auth.middleware.AuthenticationMiddleware',
     'happinesspackets.utils.middleware.SetRemoteAddrFromForwardedFor',
@@ -47,12 +48,16 @@ MIDDLEWARE_CLASSES = [
     'django.middleware.common.CommonMiddleware',
     'django.middleware.csrf.CsrfViewMiddleware',
     'django.contrib.messages.middleware.MessageMiddleware',
-    'debug_toolbar.middleware.DebugToolbarMiddleware',
 ]
 
-INSTALLED_APPS += (
-    'debug_toolbar',
-)
+TESTING = 'test' in sys.argv
+
+if not TESTING:
+
+    MIDDLEWARE += ('debug_toolbar.middleware.DebugToolbarMiddleware',)
+    INSTALLED_APPS += (
+        'debug_toolbar',
+    )
 
 SELENIUM_SCREENSHOT_DIR = PROJECT_DIR.child('selenium-screenshots')
 
diff --git a/happinesspackets/tasks.py b/happinesspackets/tasks.py
index 396a924..c899b62 100644
--- a/happinesspackets/tasks.py
+++ b/happinesspackets/tasks.py
@@ -10,7 +10,7 @@ def send_html_mail(subject, body_txt, body_html, recipient):
     message.attach_alternative(body_html, 'text/html')
     message.mixed_subtype = 'related'
 
-    logo_file = open(settings.STATIC_ROOT.child('images').child('logo.png'))
+    logo_file = open(settings.STATIC_ROOT.child('images').child('logo.png'), 'rb')
     logo_mime = MIMEImage(logo_file.read())
     logo_file.close()
     logo_mime.add_header('Content-ID', '<logo.png@happinesspackets.io>')
diff --git a/happinesspackets/urls.py b/happinesspackets/urls.py
index 375f4d3..7cb90be 100644
--- a/happinesspackets/urls.py
+++ b/happinesspackets/urls.py
@@ -2,16 +2,21 @@ from __future__ import unicode_literals
 
 import django
 from django.conf import settings
-from django.conf.urls import include, url
+from django.urls import include, re_path, path
+from django.conf.urls.static import static
 from django.contrib import admin
 
 urlpatterns = [
-    url(r'^oidc/', include('mozilla_django_oidc.urls')),
-    url(r'^', include('happinesspackets.messaging.urls', namespace="messaging")),
+    re_path(r'^oidc/', include('mozilla_django_oidc.urls')),
+    re_path(r'^', include('happinesspackets.messaging.urls')),
 ]
 
 if settings.ADMIN_ENABLED or settings.DEBUG:
-    urlpatterns.append(url(r'^drunken-octo-lama/', include(admin.site.urls)))
+    urlpatterns.append(re_path(r'^drunken-octo-lama/', admin.site.urls))
 
 if settings.DEBUG:
-    urlpatterns.append(url(r'^media/(?P<path>.*)$', django.views.static.serve, {'document_root': settings.MEDIA_ROOT}))
+    import debug_toolbar
+    urlpatterns += [
+        path('__debug__/', include(debug_toolbar.urls))
+        ] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
+
diff --git a/happinesspackets/utils/middleware.py b/happinesspackets/utils/middleware.py
index 2899329..7ff845f 100644
--- a/happinesspackets/utils/middleware.py
+++ b/happinesspackets/utils/middleware.py
@@ -1,7 +1,7 @@
 from __future__ import unicode_literals
+from django.utils.deprecation import MiddlewareMixin
 
-
-class SetRemoteAddrFromForwardedFor(object):
+class SetRemoteAddrFromForwardedFor(MiddlewareMixin):
     """
     Middleware that sets REMOTE_ADDR based on HTTP_X_FORWARDED_FOR, if the
     latter is set. This is useful if you're sitting behind a reverse proxy that
diff --git a/requirements/base.txt b/requirements/base.txt
index 666f1de..218c91e 100644
--- a/requirements/base.txt
+++ b/requirements/base.txt
@@ -1,19 +1,18 @@
-Django==1.11.5
+#django-haystack doesn't have support for django2.1 yet
+Django==2.0
 
 # Basic Django extensions
 django-extensions==1.6.1
 django-braces==1.8.1
-django-crispy-forms==1.6.0
+django-crispy-forms==1.7.2
 django-model-utils==2.4
-dogslow==0.9.7                       # For logging details about very slow requests
+dogslow==1.2                       # For logging details about very slow requests
 six>=1.11.0                          # Dependency of django-extensions
 
 # Basic Python libraries
 Unipath==1.1          # Better path handling
-wsgiref==0.1.2        # ???
 pytz==2015.7          # Timezone data
-ipython==4.1.1        # Prettier python prompt
-gnureadline==6.3.3    # Dependency of ipython
+ipython==7.3.0        # Prettier python prompt
 
 # For generating docs - sphinx and dependencies
 Sphinx==1.3.6
@@ -31,8 +30,8 @@ pep8==1.7.0
 # Misc
 python-dateutil==2.5.0
 factory-boy==2.9.2
-opbeat==3.3
-mozilla-django-oidc==1.0.0
+opbeat==3.6.1
+mozilla-django-oidc==1.2.1
 fedora-messaging>=1.4.0
 happinesspacket-schema>=0.1.2
 celery[redis]==4.2.1
diff --git a/requirements/dev.txt b/requirements/dev.txt
index 64759f5..d54bac5 100644
--- a/requirements/dev.txt
+++ b/requirements/dev.txt
@@ -1,7 +1,6 @@
 -r base.txt
 coverage==4.0.3
 django-coverage==1.2.4
-django-debug-toolbar==1.4
+django-debug-toolbar==1.11
 mock==1.3.0
 selenium==2.52
-sqlparse==0.1.18  # Dependency of debug-toolbar
diff --git a/templates/base.html b/templates/base.html
index a08af60..eb9a271 100644
--- a/templates/base.html
+++ b/templates/base.html
@@ -1,4 +1,4 @@
-{% load static from staticfiles %}
+{% load static %}
 <!DOCTYPE html>
 <html lang="en">
 <head>

