Skip to content

Commit

Permalink
Add support for django 3.0 (#553)
Browse files Browse the repository at this point in the history
* Add support for django-knocker 0.4 / channels 2
* Add support for django 3.0
  • Loading branch information
yakky committed May 4, 2020
1 parent 13665e5 commit bc0833d
Show file tree
Hide file tree
Showing 9 changed files with 76 additions and 45 deletions.
7 changes: 7 additions & 0 deletions .travis.yml
Expand Up @@ -12,6 +12,7 @@ env:
- TOXENV='pep8'
- TOXENV='isort'
- TOXENV='docs'
- DJANGO='django30' CMS='cms37'
- DJANGO='django22' CMS='cms37'
- DJANGO='django21' CMS='cms37'
- DJANGO='django21' CMS='cms36'
Expand All @@ -20,6 +21,8 @@ env:
- DJANGO='django111' CMS='cms36'
- DJANGO='django111' CMS='cms35'

services:
- redis-server

# command to install dependencies, e.g. pip install -r requirements.txt --use-mirrors
install:
Expand All @@ -40,6 +43,8 @@ after_success:

matrix:
exclude:
- python: 2.7
env: DJANGO='django30' CMS='cms37'
- python: 2.7
env: DJANGO='django22' CMS='cms37'
- python: 2.7
Expand All @@ -54,6 +59,8 @@ matrix:
env: DJANGO='django20' CMS='cms36'
- python: 2.7
env: DJANGO='django20' CMS='cms35'
- python: 3.5
env: DJANGO='django30' CMS='cms37'
- python: 2.7
env: TOXENV='docs'
- python: 2.7
Expand Down
7 changes: 5 additions & 2 deletions cms_helper.py
Expand Up @@ -125,10 +125,13 @@ def gettext(s):
HELPER_SETTINGS['INSTALLED_APPS'].append('knocker')
HELPER_SETTINGS['INSTALLED_APPS'].append('channels')
HELPER_SETTINGS['INSTALLED_APPS'].append('djangocms_blog.liveblog', )
HELPER_SETTINGS['ASGI_APPLICATION'] = 'tests.test_utils.routing.channel_routing',
HELPER_SETTINGS['CHANNEL_LAYERS'] = {
'default': {
'BACKEND': 'asgiref.inmemory.ChannelLayer',
'ROUTING': 'tests.test_utils.routing.channel_routing',
'BACKEND': 'channels_redis.core.RedisChannelLayer',
'CONFIG': {
'hosts': [('localhost', 6379)],
},
},
}
except ImportError:
Expand Down
2 changes: 1 addition & 1 deletion djangocms_blog/admin.py
Expand Up @@ -14,9 +14,9 @@
from django.http import HttpResponseRedirect
from django.urls import reverse
from django.utils import timezone
from django.utils.six import callable, text_type
from django.utils.translation import get_language_from_request, ugettext_lazy as _, ungettext as __
from parler.admin import TranslatableAdmin
from six import callable, text_type

from .cms_appconfig import BlogConfig
from .forms import CategoryAdminForm, PostAdminForm
Expand Down
2 changes: 1 addition & 1 deletion djangocms_blog/feeds.py
Expand Up @@ -10,10 +10,10 @@
from django.utils.feedgenerator import Rss201rev2Feed
from django.utils.html import strip_tags
from django.utils.safestring import mark_safe
from django.utils.six import BytesIO
from django.utils.text import normalize_newlines
from django.utils.translation import get_language_from_request, ugettext as _
from lxml import etree
from six import BytesIO

from djangocms_blog.settings import get_setting
from djangocms_blog.views import PostDetailView
Expand Down
23 changes: 12 additions & 11 deletions djangocms_blog/liveblog/models.py
Expand Up @@ -4,17 +4,17 @@
import json
from operator import itemgetter

import django
from channels import Group
from asgiref.sync import async_to_sync
from channels.layers import get_channel_layer
from cms.models import CMSPlugin
from cms.utils.plugins import reorder_plugins
from django.db import models
from django.template import Context
from django.utils.six import python_2_unicode_compatible
from django.utils.timezone import now
from django.utils.translation import ugettext_lazy as _
from djangocms_text_ckeditor.models import AbstractText
from filer.fields.image import FilerImageField
from six import python_2_unicode_compatible

from djangocms_blog.models import Post, thumbnail_model
from djangocms_blog.settings import DATE_FORMAT
Expand Down Expand Up @@ -86,21 +86,22 @@ def send(self, request):
'creation_date': self.post_date.strftime(DATE_FORMAT),
'changed_date': self.changed_date.strftime(DATE_FORMAT),
}
Group(self.liveblog_group).send({
'text': json.dumps(notification),
channel_layer = get_channel_layer()
async_to_sync(channel_layer.group_send)(self.liveblog_group, {
'type': 'knocker.saved',
'message': json.dumps(notification)
})


class Liveblog(LiveblogInterface, AbstractText):
"""
Basic liveblog plugin model
"""
if django.VERSION >= (1, 10):
cmsplugin_ptr = models.OneToOneField(
CMSPlugin,
related_name='%(app_label)s_%(class)s', primary_key=True,
parent_link=True, on_delete=models.CASCADE
)
cmsplugin_ptr = models.OneToOneField(
CMSPlugin,
related_name='%(app_label)s_%(class)s', primary_key=True,
parent_link=True, on_delete=models.CASCADE
)
title = models.CharField(_('title'), max_length=255)
image = FilerImageField(
verbose_name=_('image'), blank=True, null=True, on_delete=models.SET_NULL,
Expand Down
7 changes: 4 additions & 3 deletions djangocms_blog/models.py
Expand Up @@ -15,7 +15,7 @@
from django.dispatch import receiver
from django.urls import reverse
from django.utils import timezone
from django.utils.encoding import force_bytes, force_text, python_2_unicode_compatible
from django.utils.encoding import force_bytes, force_text
from django.utils.functional import cached_property
from django.utils.html import escape, strip_tags
from django.utils.translation import get_language, ugettext, ugettext_lazy as _
Expand All @@ -25,6 +25,7 @@
from meta.models import ModelMeta
from parler.models import TranslatableModel, TranslatedFields
from parler.utils.context import switch_language
from six import python_2_unicode_compatible
from sortedm2m.fields import SortedManyToManyField
from taggit_autosuggest.managers import TaggableManager

Expand Down Expand Up @@ -434,14 +435,14 @@ def is_published(self):
(self.date_published_end is None or self.date_published_end > timezone.now())
)

def should_knock(self, created=False):
def should_knock(self, signal_type, created=False):
"""
Returns whether to emit knocks according to the post state
"""
new = (self.app_config.send_knock_create and self.is_published and
self.date_published == self.date_modified)
updated = self.app_config.send_knock_update and self.is_published
return new or updated
return (new or updated) and signal_type in ('post_save', 'post_delete')

def get_cache_key(self, language, prefix):
return 'djangocms-blog:{2}:{0}:{1}'.format(language, self.guid, prefix)
Expand Down
24 changes: 12 additions & 12 deletions docs/features/channels.rst
Expand Up @@ -11,7 +11,7 @@ djangocms-blog implements some channels related features:

For detailed information on channels setup, please refer to `channels documentation`_.

.. warning:: liveblog does not currently work on django 2.0 and up
.. warning:: channels support works only on Django 2.2 and up

.. _knocker:

Expand Down Expand Up @@ -40,13 +40,13 @@ To enable notifications:

.. code-block:: python
ASGI_APPLICATION = 'myproject.routing.channel_routing'
CHANNEL_LAYERS={
'default': {
'BACKEND': 'asgi_redis.RedisChannelLayer',
'BACKEND': 'channels_redis.core.RedisChannelLayer',
'CONFIG': {
'hosts': [os.environ.get('REDIS_URL', 'redis://localhost:6379')],
},
'ROUTING': 'myproject.routing.channel_routing',
},
}
Expand Down Expand Up @@ -131,15 +131,15 @@ To enable liveblog features:

.. code-block:: python
CHANNEL_LAYERS={
'default': {
'BACKEND': 'asgi_redis.RedisChannelLayer',
'CONFIG': {
'hosts': [os.environ.get('REDIS_URL', 'redis://localhost:6379')],
},
'ROUTING': 'myproject.routing.channel_routing',
},
}
ASGI_APPLICATION = 'myproject.routing.channel_routing'
CHANNEL_LAYERS={
'default': {
'BACKEND': 'channels_redis.core.RedisChannelLayer',
'CONFIG': {
'hosts': [os.environ.get('REDIS_URL', 'redis://localhost:6379')],
},
},
}
.. note:: Check `channels documentation`_ for more detailed information on ``CHANNEL_LAYERS`` setup.

Expand Down
14 changes: 7 additions & 7 deletions tests/test_models.py
Expand Up @@ -1267,7 +1267,7 @@ def test_model_attributes(self):
for language in posts[0].get_available_languages():
with smart_override(language):
posts[0].set_current_language(language)
knock_create = posts[0].as_knock(True)
knock_create = posts[0].as_knock(signal_type='post_save', created=True)
self.assertEqual(knock_create['title'],
'new {0}'.format(posts[0]._meta.verbose_name))
self.assertEqual(knock_create['message'], posts[0].title)
Expand All @@ -1276,7 +1276,7 @@ def test_model_attributes(self):
for language in posts[0].get_available_languages():
with smart_override(language):
posts[0].set_current_language(language)
knock_create = posts[0].as_knock(False)
knock_create = posts[0].as_knock(signal_type='post_save', created=False)
self.assertEqual(knock_create['title'],
'new {0}'.format(posts[0]._meta.verbose_name))
self.assertEqual(knock_create['message'], posts[0].title)
Expand All @@ -1295,18 +1295,18 @@ def test_should_knock(self):
}
post = Post.objects.create(**post_data)
# Object is not published, no knock
self.assertFalse(post.should_knock())
self.assertFalse(post.should_knock(signal_type='post_save'))
post.publish = True
post.save()
# Object is published, send knock
self.assertTrue(post.should_knock())
self.assertTrue(post.should_knock(signal_type='post_save'))

# Knock disabled for updates
self.app_config_1.app_data.config.send_knock_update = False
self.app_config_1.save()
post.abstract = 'what'
post.save()
self.assertFalse(post.should_knock())
self.assertFalse(post.should_knock(signal_type='post_save'))

# Knock disabled for publishing
self.app_config_1.app_data.config.send_knock_create = False
Expand All @@ -1320,10 +1320,10 @@ def test_should_knock(self):
'app_config': self.app_config_1
}
post = Post.objects.create(**post_data)
self.assertFalse(post.should_knock())
self.assertFalse(post.should_knock(signal_type='post_save'))
post.publish = True
post.save()
self.assertFalse(post.should_knock())
self.assertFalse(post.should_knock(signal_type='post_save'))

# Restore default values
self.app_config_1.app_data.config.send_knock_create = True
Expand Down
35 changes: 27 additions & 8 deletions tox.ini
@@ -1,5 +1,12 @@
[tox]
envlist = docs,pep8,isort,py{37,36,35}-django{22}-cms{37},py{37,36,35}-django{21}-cms{37,36},py{37,36,35,27}-django{111}-cms{37,36,35}
envlist =
docs
pep8
isort
py{37,36}-django{30}-cms{37}
py{37,36,35}-django{22}-cms{37}
py{37,36,35}-django{21}-cms{37,36}
py{37,36,35,27}-django{111}-cms{37,36,35}

[testenv]
commands = {env:COMMAND:python} cms_helper.py djangocms_blog test {posargs}
Expand All @@ -14,27 +21,39 @@ deps =
django20: django-mptt>=0.8
django20: django-filer>=1.4,<1.6
django20: https://github.com/ella/django-appdata/archive/master.zip
django20: channels<2.4
django20: https://github.com/nephila/django-knocker/archive/master.zip
django20: channels-redis
django21: Django>=2.1,<2.2
django21: django-mptt>=0.8
django21: django-filer>=1.4,<1.6
django21: https://github.com/ella/django-appdata/archive/master.zip
django21: channels<2.4
django21: https://github.com/nephila/django-knocker/archive/master.zip
django21: channels-redis
django22: Django>=2.2,<3.0
django22: django-mptt>=0.8
django22: django-filer>=1.5,<1.6
django22: https://github.com/ella/django-appdata/archive/master.zip
django22: channels>2
django22: https://github.com/nephila/django-knocker/archive/master.zip
django22: channels-redis
django30: Django>=3.0,<3.1
django30: django-mptt>=0.9
django30: django-filer>=1.6
django30: https://github.com/yakky/django-appdata/archive/feature/django-3.0.zip
django30: django-haystack==3.0b2
django30: https://github.com/yakky/djangocms-text-ckeditor/archive/master.zip
django30: channels>2
django30: https://github.com/nephila/django-knocker/archive/master.zip
django30: channels-redis
cms35: https://github.com/divio/django-cms/archive/release/3.5.x.zip
cms35: djangocms-text-ckeditor>=3.5
cms35: aldryn-apphooks-config>=0.4.0
cms36: https://github.com/divio/django-cms/archive/release/3.6.x.zip
cms36: djangocms-text-ckeditor>=3.6
cms36: aldryn-apphooks-config>=0.5.2
py27-django111-cms37: django-cms==3.7.1
cms37: https://github.com/divio/django-cms/archive/release/3.7.x.zip
cms37: djangocms-text-ckeditor>=3.6
cms37: aldryn-apphooks-config>=0.5.2
channels<2.0
https://github.com/nephila/django-knocker/archive/master.zip?0.1.1
html5lib<0.99999999
cms37: https://github.com/yakky/aldryn-apphooks-config/archive/feature/django-3.0.zip
-r{toxinidir}/requirements-test.txt

[testenv:isort]
Expand Down

0 comments on commit bc0833d

Please sign in to comment.