From d798aee693f1ae94af22bf5cd8f31487e63836fc Mon Sep 17 00:00:00 2001 From: Mark Longair Date: Wed, 28 Sep 2016 20:13:49 +0100 Subject: [PATCH 01/14] Django 1.8: formtools is now a separate package --- nuntium/views.py | 2 +- requirements.txt | 1 + writeit/settings.py | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/nuntium/views.py b/nuntium/views.py index ebf9d8fc..0606809d 100644 --- a/nuntium/views.py +++ b/nuntium/views.py @@ -3,7 +3,7 @@ from django.views.generic import TemplateView, DetailView, RedirectView, ListView from subdomains.utils import reverse from django.http import Http404, HttpResponseRedirect -from django.contrib.formtools.wizard.views import NamedUrlSessionWizardView +from formtools.wizard.views import NamedUrlSessionWizardView from django.shortcuts import get_object_or_404, redirect from haystack.views import SearchView diff --git a/requirements.txt b/requirements.txt index 1d987e25..4ed8149b 100644 --- a/requirements.txt +++ b/requirements.txt @@ -19,6 +19,7 @@ django-celery-transactions==0.1.3 django-dirtyfields==1.0 django-downloadview==1.6 django-extensions==1.6.7 +django-formtools==1.0 django-haystack==2.4.0 django-markdown-deux==1.0.5 django-nose==1.4.3 diff --git a/writeit/settings.py b/writeit/settings.py index 200bcff1..9a229099 100644 --- a/writeit/settings.py +++ b/writeit/settings.py @@ -235,7 +235,7 @@ # 'django.contrib.admindocs', # Multi-page form wizard - 'django.contrib.formtools', + 'formtools', 'subdomains', ) From 111eb0e1c97e25bd725c8bb64414fea5145ec1cf Mon Sep 17 00:00:00 2001 From: Mark Longair Date: Wed, 28 Sep 2016 20:17:30 +0100 Subject: [PATCH 02/14] Django 1.8: fix the django.utils.importlib warning in celery-haystack --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 4ed8149b..121536b5 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,7 +3,7 @@ anyjson==0.3.3 backport-collections==0.1 billiard==3.3.0.19 celery==3.1.23 -celery-haystack==0.8 +celery-haystack==0.10 cffi==1.7.0 contextlib2==0.5.3 cryptography==1.4 From 6e289418979921e1870bd070599b8413e224d5a4 Mon Sep 17 00:00:00 2001 From: Mark Longair Date: Wed, 28 Sep 2016 20:22:18 +0100 Subject: [PATCH 03/14] Django 1.8: fix python-social-auth deprecation warnings This should fix the warnings of the form: "Model class social.apps.django_app.default.models.[some class] doesn't declare an explicit app_label and either isn't in an application in INSTALLED_APPS or else was imported before its application was loaded. This will no longer be supported in Django 1.9." --- requirements.txt | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/requirements.txt b/requirements.txt index 121536b5..24b82719 100644 --- a/requirements.txt +++ b/requirements.txt @@ -44,21 +44,21 @@ mock==1.0.1 mysociety-django-popolo==0.0.8 ndg-httpsclient==0.4.1 nose==1.3.7 -oauthlib==1.1.2 +oauthlib==2.0.0 -e git://github.com/mysociety/popit-django.git@django-1.7#egg=popit-django multiple-django-popolo-sources==0.0.3 pyasn1==0.1.9 pycparser==2.14 -PyJWT==1.4.0 +PyJWT==1.4.2 pyOpenSSL==16.0.0 python-dateutil==2.5.3 python-mimeparse==1.5.2 python-openid==2.2.5 -python-social-auth==0.2.3 +python-social-auth==0.2.21 pytz==2016.4 PyYAML==3.11 -requests==2.10.0 -requests-oauthlib==0.6.1 +requests==2.11.1 +requests-oauthlib==0.7.0 simplejson==3.8.2 six==1.10.0 slumber==0.7.1 From 68cb657027eff8ebd4c63b4c81a0c937553c73c1 Mon Sep 17 00:00:00 2001 From: Mark Longair Date: Wed, 28 Sep 2016 20:31:20 +0100 Subject: [PATCH 04/14] Django 1.8: remove South (now unneeded) and causes deprecations warnings --- requirements.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 24b82719..dfa223bb 100644 --- a/requirements.txt +++ b/requirements.txt @@ -62,7 +62,6 @@ requests-oauthlib==0.7.0 simplejson==3.8.2 six==1.10.0 slumber==0.7.1 -South==1.0.2 static==0.4 static3==0.7.0 transifex-client==0.12.1 From fb16da52af2c4f1e656cba16b66f44bcde8478b2 Mon Sep 17 00:00:00 2001 From: Mark Longair Date: Wed, 28 Sep 2016 20:34:12 +0100 Subject: [PATCH 05/14] Django 1.8: the contenttypes fields have moved --- nuntium/models.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nuntium/models.py b/nuntium/models.py index fd2fd529..ee2135a7 100644 --- a/nuntium/models.py +++ b/nuntium/models.py @@ -8,7 +8,7 @@ from contactos.models import Contact from .plugins import OutputPlugin from django.contrib.contenttypes.models import ContentType -from django.contrib.contenttypes import generic +from django.contrib.contenttypes.fields import GenericForeignKey import datetime from djangoplugins.models import Plugin from django.core.mail import EmailMultiAlternatives @@ -52,7 +52,7 @@ class MessageRecord(models.Model): datetime = models.DateField(default=now) content_type = models.ForeignKey(ContentType) object_id = models.PositiveIntegerField() - content_object = generic.GenericForeignKey('content_type', 'object_id') + content_object = GenericForeignKey('content_type', 'object_id') def __unicode__(self): outbound_message = self.content_object From c21674f8269153ef6c05928944b33edb39e887c1 Mon Sep 17 00:00:00 2001 From: Mark Longair Date: Wed, 28 Sep 2016 20:39:56 +0100 Subject: [PATCH 06/14] Django 1.8: fix 'django.utils.unittest will be removed in Django 1.9' --- global_test_case.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/global_test_case.py b/global_test_case.py index 7c88e34f..50a2ae75 100644 --- a/global_test_case.py +++ b/global_test_case.py @@ -1,7 +1,7 @@ import re from django.test import TestCase -from django.utils.unittest import skipUnless +from unittest import skipUnless from django.core.management import call_command from tastypie.test import ResourceTestCase from django.conf import settings From 3b55604da9b3f7a899afd78ac96eec073caf9ce3 Mon Sep 17 00:00:00 2001 From: Mark Longair Date: Mon, 6 Feb 2017 16:32:11 +0000 Subject: [PATCH 07/14] Django 1.8: update Django version to 1.8.17 --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index dfa223bb..5f697b5d 100644 --- a/requirements.txt +++ b/requirements.txt @@ -9,7 +9,7 @@ contextlib2==0.5.3 cryptography==1.4 dj-database-url==0.2.2 dj-static==0.0.6 -Django==1.7.11 +Django==1.8.17 django-admin-bootstrapped==2.3.6 django-annoying==0.8.1 django-appconf==1.0.2 From 235c9378296bcf51e65a9b8e50f9c9316aec3406 Mon Sep 17 00:00:00 2001 From: Mark Longair Date: Wed, 28 Sep 2016 20:37:50 +0100 Subject: [PATCH 08/14] Django 1.8: get Celery working with the new Django version We switch to using Celery in the manner recommended in Celery 3.1 and later. We wouldn't need django-celery any more, except that we're using it provides a Django ORM-based results backend for Celery. We upgrade django-celery to avoid some deprecation warnings. The celery worker and beat are no longer invoked using manage.py but with the celery script. --- README.md | 4 ++-- config_examples/email_sender.sh.example | 2 +- nuntium/tasks.py | 16 +++++++++------- requirements.txt | 4 ++-- scripts/provision.sh | 4 ++-- writeit/celery.py | 22 ++++++++++++++++++++++ writeit/settings.py | 17 ++++++++++++----- 7 files changed, 50 insertions(+), 19 deletions(-) create mode 100644 writeit/celery.py diff --git a/README.md b/README.md index 1dbf216d..183c78e3 100644 --- a/README.md +++ b/README.md @@ -39,7 +39,7 @@ And visit http://127.0.0.1.xip.io:8000 on your host machine to use WriteIt. ### Background jobs - ./manage.py celery worker + celery -A writeit worker This handles syncing contact details from remote sources. If you have created a new instance and the contacts do not seem to be syncing @@ -47,7 +47,7 @@ it is probably because a celery worker is not running. ### Scheduled jobs - ./manage.py celery beat + celery -A writeit beat This sends emails to recipients and periodically re-sync contacts from remote sources. diff --git a/config_examples/email_sender.sh.example b/config_examples/email_sender.sh.example index fac6ae4a..9bc8b87e 100644 --- a/config_examples/email_sender.sh.example +++ b/config_examples/email_sender.sh.example @@ -6,4 +6,4 @@ LOGDIR=$(dirname $LOGFILE) cd /home/ubuntu/writeit/write-it/ source /home/ubuntu/.virtualenvs/writeit/bin/activate test -d $LOGDIR || mkdir -p $LOGDIR -exec python manage.py celery beat --logfile=$LOGFILE \ No newline at end of file +exec celery -A writeit beat --logfile=$LOGFILE diff --git a/nuntium/tasks.py b/nuntium/tasks.py index e05a2e25..e7677906 100644 --- a/nuntium/tasks.py +++ b/nuntium/tasks.py @@ -1,19 +1,21 @@ -from celery import task +from __future__ import absolute_import, unicode_literals + +import logging + +from celery import shared_task + from .management.commands.send_mails import send_mails from instance.models import WriteitInstancePopitInstanceRecord from popolo_sources.models import PopoloSource -import logging - logger = logging.getLogger(__name__) - -@task() +@shared_task() def send_mails_task(): send_mails() -@task() +@shared_task() def pull_from_popolo_json(writeitinstance, popolo_source): result = writeitinstance._load_persons_from_popolo_json(popolo_source) logger.info(u'Resyncing {0} with {1}'.format( @@ -21,7 +23,7 @@ def pull_from_popolo_json(writeitinstance, popolo_source): return result -@task() +@shared_task() def update_all_instances(periodicity='1W'): all_records = WriteitInstancePopitInstanceRecord.objects.filter(periodicity=periodicity) logger.info(u'Complete resync of all instances') diff --git a/requirements.txt b/requirements.txt index 5f697b5d..49bc1419 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,7 +2,7 @@ amqp==1.4.9 anyjson==0.3.3 backport-collections==0.1 billiard==3.3.0.19 -celery==3.1.23 +celery==3.1.25 celery-haystack==0.10 cffi==1.7.0 contextlib2==0.5.3 @@ -14,7 +14,7 @@ django-admin-bootstrapped==2.3.6 django-annoying==0.8.1 django-appconf==1.0.2 django-autoslug==1.9.3 -django-celery==3.1.17 +django-celery==3.2.1 django-celery-transactions==0.1.3 django-dirtyfields==1.0 django-downloadview==1.6 diff --git a/scripts/provision.sh b/scripts/provision.sh index ee5070fe..bb1ae8c1 100755 --- a/scripts/provision.sh +++ b/scripts/provision.sh @@ -61,10 +61,10 @@ Add some seed data to your instance with: ./manage.py loaddata example_data.yaml Run a celery worker with: - ./manage.py celery worker + celery -A writeit worker Run celery beat with: - ./manage.py celery beat + celery -A writeit beat Run the tests with: ./manage.py test nuntium contactos mailit diff --git a/writeit/celery.py b/writeit/celery.py new file mode 100644 index 00000000..c976f0ad --- /dev/null +++ b/writeit/celery.py @@ -0,0 +1,22 @@ +from __future__ import absolute_import + +import os + +from celery import Celery + +# set the default Django settings module for the 'celery' program. +os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'writeit.settings') + +from django.conf import settings # noqa + +app = Celery('writeit') + +# Using a string here means the worker will not have to +# pickle the object when using Windows. +app.config_from_object('django.conf:settings') +app.autodiscover_tasks(lambda: settings.INSTALLED_APPS) + + +@app.task(bind=True) +def debug_task(self): + print('Request: {0!r}'.format(self.request)) diff --git a/writeit/settings.py b/writeit/settings.py index 9a229099..7409e8bc 100644 --- a/writeit/settings.py +++ b/writeit/settings.py @@ -1,4 +1,7 @@ # -*- coding: utf-8 -*- + +from __future__ import absolute_import + # Django settings for writeit project. import sys import os @@ -206,6 +209,7 @@ 'social.apps.django_app.default', 'annoying', 'celery_haystack', + 'djcelery', 'instance', 'nuntium', @@ -225,7 +229,6 @@ 'django_extensions', # Searching. 'haystack', - 'djcelery', 'pipeline', # Uncomment the next line to enable the admin: 'django_admin_bootstrapped', @@ -335,9 +338,13 @@ # CELERY CONFIGURATION -import djcelery + +CELERY_BROKER_URL = 'amqp://guest:guest@localhost//' +CELERY_ACCEPT_CONTENT = ['pickle'] +CELERY_TASK_SERIALIZER = 'pickle' +CELERY_RESULT_BACKEND='djcelery.backends.database:DatabaseBackend' + from celery.schedules import crontab -djcelery.setup_loader() CELERYBEAT_SCHEDULE = { # Sends emails every 2 minutes @@ -410,10 +417,10 @@ API_BASED = False if TESTING: - from testing_settings import * # noqa + from .testing_settings import * # noqa try: - from local_settings import * # noqa + from .local_settings import * # noqa INSTALLED_APPS += EXTRA_APPS except ImportError: pass From 640527ff8212371774278607d01c55f3c69ea3b9 Mon Sep 17 00:00:00 2001 From: Mark Longair Date: Mon, 6 Feb 2017 18:29:47 +0000 Subject: [PATCH 09/14] Django 1.8: upgrade django-annoying so AutoOneToOneField still works --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 49bc1419..77114e97 100644 --- a/requirements.txt +++ b/requirements.txt @@ -11,7 +11,7 @@ dj-database-url==0.2.2 dj-static==0.0.6 Django==1.8.17 django-admin-bootstrapped==2.3.6 -django-annoying==0.8.1 +django-annoying==0.10.3 django-appconf==1.0.2 django-autoslug==1.9.3 django-celery==3.2.1 From e1f70c211793182bcf5dceb48a2f4de2a17844ef Mon Sep 17 00:00:00 2001 From: Mark Longair Date: Mon, 6 Feb 2017 18:50:54 +0000 Subject: [PATCH 10/14] Django 1.8: fix an assertion relating to which template is used This test was failing because of this error: ValueError: assertTemplateUsed() and assertTemplateNotUsed() are only usable on responses fetched using the Django test Client. However, I'm a bit unclear on how this ever worked, since the template parameter for WriteItDeleteView was never being overridden? --- nuntium/user_section/tests/delete_an_instance_tests.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/nuntium/user_section/tests/delete_an_instance_tests.py b/nuntium/user_section/tests/delete_an_instance_tests.py index fab19aeb..3addb5a9 100644 --- a/nuntium/user_section/tests/delete_an_instance_tests.py +++ b/nuntium/user_section/tests/delete_an_instance_tests.py @@ -21,10 +21,14 @@ def test_get_to_url(self): url = reverse('delete_an_instance', subdomain=self.writeitinstance.slug) request = self.factory.get(url) request.user = self.writeitinstance.owner - response = WriteItDeleteView.as_view()(request) + view = WriteItDeleteView.as_view( + template_name="nuntium/profiles/writeitinstance_check_delete.html") + response = view(request) self.assertEquals(response.status_code, 200) - self.assertTemplateUsed(response, 'nuntium/profiles/writeitinstance_check_delete.html') + self.assertEqual( + response.template_name, + ['nuntium/profiles/writeitinstance_check_delete.html']) # It's not yet deleted self.assertTrue(WriteItInstance.objects.get(id=self.writeitinstance.id)) From deebe5e01e50d6686f6bae7de61f984249fc46dd Mon Sep 17 00:00:00 2001 From: Mark Longair Date: Mon, 6 Feb 2017 19:17:55 +0000 Subject: [PATCH 11/14] Django 1.8: remove an apparently unused argument to handleemail These tests are now erroring with the stricter argument parsing in Django 1.8. I can't see that this arguement was ever used for anything anyway. --- mailit/tests/email_logging_tests.py | 4 ++-- mailit/tests/handle_mails_management_command_test.py | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/mailit/tests/email_logging_tests.py b/mailit/tests/email_logging_tests.py index 6649bf60..5543e108 100644 --- a/mailit/tests/email_logging_tests.py +++ b/mailit/tests/email_logging_tests.py @@ -28,7 +28,7 @@ def test_it_sends_a_mail_to_the_admins_when_receiving_a_mail(self): with patch('sys.stdin') as stdin: stdin.attach_mock(readlines1_mock, 'readlines') - call_command('handleemail', 'mailit.tests.handle_mails_management_command.StdinMock', verbosity=0) + call_command('handleemail', verbosity=0) self.assertEquals(len(mail.outbox), 1) self.assertEquals(mail.outbox[0].to[0], 'falvarez@admins.org') @@ -46,6 +46,6 @@ def test_if_there_are_no_admins_does_not_send_emails(self): with patch('sys.stdin') as stdin: stdin.attach_mock(readlines1_mock, 'readlines') - call_command('handleemail', 'mailit.tests.handle_mails_management_command.StdinMock', verbosity=0) + call_command('handleemail', verbosity=0) self.assertEquals(len(mail.outbox), 0) diff --git a/mailit/tests/handle_mails_management_command_test.py b/mailit/tests/handle_mails_management_command_test.py index d1b00757..e5f9b513 100644 --- a/mailit/tests/handle_mails_management_command_test.py +++ b/mailit/tests/handle_mails_management_command_test.py @@ -123,7 +123,7 @@ def test_call_command(self): with patch('sys.stdin') as stdin: stdin.attach_mock(readlines1_mock, 'readlines') - call_command('handleemail', 'mailit.tests.handle_mails_management_command.StdinMock', verbosity=0) + call_command('handleemail', verbosity=0) the_answers = Answer.objects.filter(message=identifier.outbound_message.message) self.assertEquals(the_answers.count(), 1) @@ -137,7 +137,7 @@ def test_call_command_does_not_include_identifier_in_content(self): with patch('sys.stdin') as stdin: stdin.attach_mock(readlines2_mock, 'readlines') - call_command('handleemail', 'mailit.tests.handle_mails_management_command.StdinMock', verbosity=0) + call_command('handleemail', verbosity=0) the_answers = Answer.objects.filter(message=identifier.outbound_message.message) self.assertEquals(the_answers.count(), 1) @@ -147,7 +147,7 @@ def test_call_command_does_not_include_identifier_in_content(self): def test_it_sends_an_email_to_the_admin_if_any_failure(self): with patch('sys.stdin') as stdin: stdin.attach_mock(readlines3_mock, 'readlines') - call_command('handleemail', 'mailit.tests.handle_mails_management_command.StdinMock', verbosity=0) + call_command('handleemail', verbosity=0) content_text = '' for line in readlines3_mock(): content_text += line @@ -161,7 +161,7 @@ def test_it_sends_an_email_to_the_admin_if_any_failure(self): def test_mail_admins_if_theres_a_problem(self): with patch('sys.stdin') as stdin: stdin.attach_mock(killer_mail, 'readlines') - call_command('handleemail', 'mailit.tests.handle_mails_management_command.StdinMock', verbosity=0) + call_command('handleemail', verbosity=0) self.assertEquals(len(mail.outbox), 1) self.assertNotIn(killer_mail(), mail.outbox[0].body) self.assertEquals(mail.outbox[0].to[0], 'falvarez@admins.org') @@ -174,7 +174,7 @@ def test_it_correctly_parses_the_to_email(self): identifier.save() with patch('sys.stdin') as stdin: stdin.attach_mock(readlines4_mock, 'readlines') - call_command('handleemail', 'mailit.tests.handle_mails_management_command.StdinMock', verbosity=0) + call_command('handleemail', verbosity=0) the_answer = Answer.objects.get(message=identifier.outbound_message.message) self.assertNotIn('Tony', the_answer.content) self.assertNotIn(' Date: Mon, 6 Feb 2017 19:18:51 +0000 Subject: [PATCH 12/14] Django 1.8: fix two tests of exception handling when sending email It looks as if django.core.mail.mail_admins now uses django.core.mail.EmailMultiAlternatives.send whereas it didn't in earlier versions of Django. mail_admins is used in the handling of an exception, so we need to patch that to stop our test exception being raised in the exception handling as well. --- mailit/tests/plugin_test.py | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/mailit/tests/plugin_test.py b/mailit/tests/plugin_test.py index a6b0546a..963c28c2 100644 --- a/mailit/tests/plugin_test.py +++ b/mailit/tests/plugin_test.py @@ -407,12 +407,16 @@ def test_smpt_error_code_500(self): # I'm taking it as if we should not try to send this # message again, but for example - def test_any_other_exception(self): + @patch('mailit.mail_admins') + def test_any_other_exception(self, mail_admins): with patch("django.core.mail.EmailMultiAlternatives.send") as send_mail: send_mail.side_effect = Exception(401, "Something very bad") result_of_sending, fatal_error = self.channel.send(self.outbound_message1) self.assertFalse(result_of_sending) self.assertTrue(fatal_error) + mail_admins.assert_called_with( + 'Problem sending an email', + u"Error with outbound id 1, contact 'pdaire@ciudadanointeligente.org' and message 'Subject 1 at instance 1' and the error was '(401, 'Something very bad')'") def test_smpt_error_code_501(self): # to handle this kind of error @@ -493,14 +497,16 @@ def test_smpt_error_code_552(self): self.assertFalse(result_of_sending) self.assertFalse(fatal_error) - def test_extra_logging(self): + @patch('logging.info') + @patch('mailit.mail_admins') + def test_extra_logging(self, mail_admins, info): with patch("django.core.mail.EmailMultiAlternatives.send") as send_mail: send_mail.side_effect = Exception("Hey this is an exception") - with patch('logging.info') as info: - expected_log = u"Error with outbound id 1, contact 'pdaire@ciudadanointeligente.org' and message 'Subject 1 at instance 1' and the error was 'Hey this is an exception'" - self.channel.send(self.outbound_message1) + expected_log = u"Error with outbound id 1, contact 'pdaire@ciudadanointeligente.org' and message 'Subject 1 at instance 1' and the error was 'Hey this is an exception'" + self.channel.send(self.outbound_message1) - info.assert_called_with(expected_log) + info.assert_called_with(expected_log) + mail_admins.assert_called_with('Problem sending an email', expected_log) class MailitTemplateUpdateTestCase(UserSectionTestCase): From 9b07a40f106b2a58d506a45259791eec1acf92a6 Mon Sep 17 00:00:00 2001 From: Mark Longair Date: Thu, 9 Feb 2017 14:13:52 +0000 Subject: [PATCH 13/14] Django 1.8: update billiard and kombu for Celery 3.1.25 "pip check" picked up that Celery 3.1.25 requires upgraded versions of these packages. --- requirements.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/requirements.txt b/requirements.txt index 77114e97..0b994fb5 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,7 +1,7 @@ amqp==1.4.9 anyjson==0.3.3 backport-collections==0.1 -billiard==3.3.0.19 +billiard==3.3.0.23 celery==3.1.25 celery-haystack==0.10 cffi==1.7.0 @@ -37,7 +37,7 @@ futures==3.0.5 gunicorn==19.6.0 idna==2.1 ipaddress==1.0.16 -kombu==3.0.35 +kombu==3.0.37 libsass==0.11.1 markdown2==2.3.1 mock==1.0.1 From 8efd1df8ad640ee430deae5c14afbeaec3c94f28 Mon Sep 17 00:00:00 2001 From: Mark Longair Date: Thu, 9 Feb 2017 14:50:37 +0000 Subject: [PATCH 14/14] Upgrade the Python cryptography package to the latest version The version in use had security issue: CVE-2016-9243 --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 0b994fb5..eaa5aa76 100644 --- a/requirements.txt +++ b/requirements.txt @@ -6,7 +6,7 @@ celery==3.1.25 celery-haystack==0.10 cffi==1.7.0 contextlib2==0.5.3 -cryptography==1.4 +cryptography==1.7.2 dj-database-url==0.2.2 dj-static==0.0.6 Django==1.8.17