Merge pull request #228 from nephila/feature/should_knock
Add option to customize the knocker behavior
This commit is contained in:
commit
746e5ec8af
7 changed files with 96 additions and 0 deletions
|
@ -16,6 +16,7 @@ env:
|
||||||
- TOXENV='pep8'
|
- TOXENV='pep8'
|
||||||
- TOXENV='isort'
|
- TOXENV='isort'
|
||||||
- DJANGO='django19' CMS='cms32'
|
- DJANGO='django19' CMS='cms32'
|
||||||
|
- DJANGO='django19' CMS='knocker'
|
||||||
- DJANGO='django18' CMS='cms32'
|
- DJANGO='django18' CMS='cms32'
|
||||||
- DJANGO='django18' CMS='cms31'
|
- DJANGO='django18' CMS='cms31'
|
||||||
- DJANGO='django17' CMS='cms32'
|
- DJANGO='django17' CMS='cms32'
|
||||||
|
@ -74,8 +75,12 @@ matrix:
|
||||||
env: DJANGO='django18' CMS='cms32'
|
env: DJANGO='django18' CMS='cms32'
|
||||||
- python: 2.6
|
- python: 2.6
|
||||||
env: DJANGO='django19' CMS='cms32'
|
env: DJANGO='django19' CMS='cms32'
|
||||||
|
- python: 2.6
|
||||||
|
env: DJANGO='django19' CMS='knocker'
|
||||||
- python: 3.3
|
- python: 3.3
|
||||||
env: DJANGO='django19' CMS='cms32'
|
env: DJANGO='django19' CMS='cms32'
|
||||||
|
- python: 3.3
|
||||||
|
env: DJANGO='django19' CMS='knocker'
|
||||||
- python: 3.5
|
- python: 3.5
|
||||||
env: DJANGO='django16' CMS='cms30'
|
env: DJANGO='django16' CMS='cms30'
|
||||||
- python: 3.5
|
- python: 3.5
|
||||||
|
|
|
@ -494,6 +494,8 @@ Per-Apphook settings
|
||||||
* Twitter author handle: Per-Apphook setting for BLOG_TWITTER_AUTHOR
|
* Twitter author handle: Per-Apphook setting for BLOG_TWITTER_AUTHOR
|
||||||
* Google+ type: Per-Apphook setting for BLOG_GPLUS_TYPE
|
* Google+ type: Per-Apphook setting for BLOG_GPLUS_TYPE
|
||||||
* Google+ author name: Per-Apphook setting for BLOG_GPLUS_AUTHOR
|
* Google+ author name: Per-Apphook setting for BLOG_GPLUS_AUTHOR
|
||||||
|
* Send notifications on post publish: Send desktop notifications when a post is published
|
||||||
|
* Send notifications on post update: Send desktop notifications when a post is updated
|
||||||
|
|
||||||
|
|
||||||
Import from Wordpress
|
Import from Wordpress
|
||||||
|
|
|
@ -191,6 +191,12 @@ class BlogConfigAdmin(BaseAppHookConfig, TranslatableAdmin):
|
||||||
),
|
),
|
||||||
'classes': ('collapse',)
|
'classes': ('collapse',)
|
||||||
}),
|
}),
|
||||||
|
('Notifications', {
|
||||||
|
'fields': (
|
||||||
|
'config.send_knock_create', 'config.send_knock_update'
|
||||||
|
),
|
||||||
|
'classes': ('collapse',)
|
||||||
|
}),
|
||||||
('Sitemap', {
|
('Sitemap', {
|
||||||
'fields': (
|
'fields': (
|
||||||
'config.sitemap_changefreq', 'config.sitemap_priority',
|
'config.sitemap_changefreq', 'config.sitemap_priority',
|
||||||
|
|
|
@ -125,4 +125,13 @@ class BlogConfigForm(AppDataForm):
|
||||||
max_length=200, label=_('Google+ author name'), required=False,
|
max_length=200, label=_('Google+ author name'), required=False,
|
||||||
initial=get_setting('GPLUS_AUTHOR')
|
initial=get_setting('GPLUS_AUTHOR')
|
||||||
)
|
)
|
||||||
|
|
||||||
|
send_knock_create = forms.BooleanField(
|
||||||
|
label=_('Send notifications on post publish'), required=False, initial=False,
|
||||||
|
help_text=_('Emits a desktop notification -if enabled- when publishing a new post')
|
||||||
|
)
|
||||||
|
send_knock_update = forms.BooleanField(
|
||||||
|
label=_('Send notifications on post update'), required=False, initial=False,
|
||||||
|
help_text=_('Emits a desktop notification -if enabled- when editing a published post')
|
||||||
|
)
|
||||||
setup_config(BlogConfigForm, BlogConfig)
|
setup_config(BlogConfigForm, BlogConfig)
|
||||||
|
|
|
@ -265,6 +265,10 @@ class Post(KnockerModel, ModelMeta, TranslatableModel):
|
||||||
return title.strip()
|
return title.strip()
|
||||||
|
|
||||||
def get_keywords(self):
|
def get_keywords(self):
|
||||||
|
"""
|
||||||
|
Returns the list of keywords (as python list)
|
||||||
|
:return: list
|
||||||
|
"""
|
||||||
return self.safe_translation_getter('meta_keywords', default='').strip().split(',')
|
return self.safe_translation_getter('meta_keywords', default='').strip().split(',')
|
||||||
|
|
||||||
def get_locale(self):
|
def get_locale(self):
|
||||||
|
@ -282,10 +286,16 @@ class Post(KnockerModel, ModelMeta, TranslatableModel):
|
||||||
return ''
|
return ''
|
||||||
|
|
||||||
def get_tags(self):
|
def get_tags(self):
|
||||||
|
"""
|
||||||
|
Returns the list of object tags as comma separated list
|
||||||
|
"""
|
||||||
taglist = [tag.name for tag in self.tags.all()]
|
taglist = [tag.name for tag in self.tags.all()]
|
||||||
return ','.join(taglist)
|
return ','.join(taglist)
|
||||||
|
|
||||||
def get_author(self):
|
def get_author(self):
|
||||||
|
"""
|
||||||
|
Return the author (user) objects
|
||||||
|
"""
|
||||||
return self.author
|
return self.author
|
||||||
|
|
||||||
def _set_default_author(self, current_user):
|
def _set_default_author(self, current_user):
|
||||||
|
@ -309,6 +319,9 @@ class Post(KnockerModel, ModelMeta, TranslatableModel):
|
||||||
return get_setting('IMAGE_FULL_SIZE')
|
return get_setting('IMAGE_FULL_SIZE')
|
||||||
|
|
||||||
def get_full_url(self):
|
def get_full_url(self):
|
||||||
|
"""
|
||||||
|
Return the url with protocol and domain url
|
||||||
|
"""
|
||||||
return self.build_absolute_uri(self.get_absolute_url())
|
return self.build_absolute_uri(self.get_absolute_url())
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
@ -321,6 +334,15 @@ class Post(KnockerModel, ModelMeta, TranslatableModel):
|
||||||
(self.date_published_end is None or self.date_published_end > timezone.now())
|
(self.date_published_end is None or self.date_published_end > timezone.now())
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def should_knock(self, 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
|
||||||
|
|
||||||
|
|
||||||
class BasePostPlugin(CMSPlugin):
|
class BasePostPlugin(CMSPlugin):
|
||||||
app_config = AppHookConfigField(
|
app_config = AppHookConfigField(
|
||||||
|
|
|
@ -117,8 +117,12 @@ class BaseTest(BaseTestCase):
|
||||||
namespace='sample_app2', app_title='app2', object_name='Article'
|
namespace='sample_app2', app_title='app2', object_name='Article'
|
||||||
)
|
)
|
||||||
cls.app_config_1.app_data.config.paginate_by = 1
|
cls.app_config_1.app_data.config.paginate_by = 1
|
||||||
|
cls.app_config_1.app_data.config.send_knock_create = True
|
||||||
|
cls.app_config_1.app_data.config.send_knock_update = True
|
||||||
cls.app_config_1.save()
|
cls.app_config_1.save()
|
||||||
cls.app_config_2.app_data.config.paginate_by = 2
|
cls.app_config_2.app_data.config.paginate_by = 2
|
||||||
|
cls.app_config_2.app_data.config.send_knock_create = True
|
||||||
|
cls.app_config_2.app_data.config.send_knock_update = True
|
||||||
cls.app_config_2.save()
|
cls.app_config_2.save()
|
||||||
cls.app_configs = {
|
cls.app_configs = {
|
||||||
'sample_app': cls.app_config_1,
|
'sample_app': cls.app_config_1,
|
||||||
|
|
|
@ -666,3 +666,51 @@ class KnockerTest(BaseTest):
|
||||||
'new {0}'.format(posts[0]._meta.verbose_name))
|
'new {0}'.format(posts[0]._meta.verbose_name))
|
||||||
self.assertEqual(knock_create['message'], posts[0].title)
|
self.assertEqual(knock_create['message'], posts[0].title)
|
||||||
self.assertEqual(knock_create['language'], language)
|
self.assertEqual(knock_create['language'], language)
|
||||||
|
|
||||||
|
def test_should_knock(self):
|
||||||
|
self.get_pages()
|
||||||
|
|
||||||
|
post_data = {
|
||||||
|
'author': self.user,
|
||||||
|
'title': 'post 1',
|
||||||
|
'abstract': 'post 1',
|
||||||
|
'meta_description': 'post 1',
|
||||||
|
'meta_keywords': 'post 1',
|
||||||
|
'app_config': self.app_config_1
|
||||||
|
}
|
||||||
|
post = Post.objects.create(**post_data)
|
||||||
|
# Object is not published, no knock
|
||||||
|
self.assertFalse(post.should_knock())
|
||||||
|
post.publish = True
|
||||||
|
post.save()
|
||||||
|
# Object is published, send knock
|
||||||
|
self.assertTrue(post.should_knock())
|
||||||
|
|
||||||
|
# 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())
|
||||||
|
|
||||||
|
# Knock disabled for publishing
|
||||||
|
self.app_config_1.app_data.config.send_knock_create = False
|
||||||
|
self.app_config_1.save()
|
||||||
|
post_data = {
|
||||||
|
'author': self.user,
|
||||||
|
'title': 'post 2',
|
||||||
|
'abstract': 'post 2',
|
||||||
|
'meta_description': 'post 2',
|
||||||
|
'meta_keywords': 'post 2',
|
||||||
|
'app_config': self.app_config_1
|
||||||
|
}
|
||||||
|
post = Post.objects.create(**post_data)
|
||||||
|
self.assertFalse(post.should_knock())
|
||||||
|
post.publish = True
|
||||||
|
post.save()
|
||||||
|
self.assertFalse(post.should_knock())
|
||||||
|
|
||||||
|
# Restore default values
|
||||||
|
self.app_config_1.app_data.config.send_knock_create = True
|
||||||
|
self.app_config_1.app_data.config.send_knock_update = True
|
||||||
|
self.app_config_1.save()
|
||||||
|
|
Loading…
Add table
Reference in a new issue