From 9d21af92973c55892526fdc8a76ce1152088df7d Mon Sep 17 00:00:00 2001 From: Fabian Braun Date: Fri, 24 Mar 2017 21:27:37 +0100 Subject: [PATCH 1/7] Add bulk actions for posts: publish, unpublish, allow/disallow comments, and enable/disable liveblog (if installed) --- AUTHORS.rst | 1 + cms_helper.py | 2 + djangocms_blog/admin.py | 63 ++++++++++++++++++++++++++ djangocms_blog/cms_appconfig.py | 2 + djangocms_blog/cms_apps.py | 2 + djangocms_blog/cms_menus.py | 3 ++ djangocms_blog/liveblog/cms_plugins.py | 1 + djangocms_blog/urls.py | 1 + 8 files changed, 75 insertions(+) diff --git a/AUTHORS.rst b/AUTHORS.rst index 64dfb75..53e4ba9 100644 --- a/AUTHORS.rst +++ b/AUTHORS.rst @@ -16,6 +16,7 @@ Contributors * cluster-master * danra * Davide Truffo +* Fabian Braun * frnhr * furiousdave * Georgiy Kutsurua diff --git a/cms_helper.py b/cms_helper.py index fd63480..76404b6 100755 --- a/cms_helper.py +++ b/cms_helper.py @@ -9,6 +9,7 @@ from tempfile import mkdtemp def gettext(s): return s + HELPER_SETTINGS = dict( ROOT_URLCONF='tests.test_utils.urls', INSTALLED_APPS=[ @@ -139,5 +140,6 @@ def setup(): from djangocms_helper import runner runner.setup('djangocms_blog', sys.modules[__name__], use_cms=True) + if __name__ == '__main__': run() diff --git a/djangocms_blog/admin.py b/djangocms_blog/admin.py index ce10d10..2230256 100755 --- a/djangocms_blog/admin.py +++ b/djangocms_blog/admin.py @@ -14,6 +14,7 @@ from django.contrib import admin from django.contrib.sites.models import Site from django.core.urlresolvers import reverse from django.http import HttpResponseRedirect +from django.utils import timezone from django.utils.six import callable from django.utils.translation import get_language_from_request, ugettext_lazy as _ from parler.admin import TranslatableAdmin @@ -30,6 +31,59 @@ except ImportError: pass +# Bulk actions for post admin +def make_published(modeladmin, request, queryset): + """ Bulk action to mark selected posts as published. If + the date_published field is empty the current time is + saved as date_published. + """ + for post in queryset: + if not post.publish: + if not post.date_published: + post.date_published = timezone.now() + post.publish = True + post.save() + + +def make_unpublished(modeladmin, request, queryset): + """ Bulk action to mark selected posts as UNpublished. + """ + queryset.update(publish=False) + + +def enable_comments(modeladmin, request, queryset): + """ Bulk action to enable comments for selected posts. + """ + queryset.update(enable_comments=True) + + +def disable_comments(modeladmin, request, queryset): + """ Bulk action to disable comments for selected posts. + """ + queryset.update(enable_comments=False) + + +def enable_liveblog(modeladmin, request, queryset): + """ Bulk action to enable comments for selected posts. + """ + queryset.update(enable_liveblog=True) + + +def disable_liveblog(modeladmin, request, queryset): + """ Bulk action to disable comments for selected posts. + """ + queryset.update(enable_liveblog=False) + + +# Make bulk action menu entries localizable +make_published.short_description = _("Publish selection") +make_unpublished.short_description = _("Unpublish selection") +enable_comments.short_description = _("Enable comments for selection") +disable_comments.short_description = _("Disable comments for selection ") +enable_liveblog.short_description = _("Enable liveblog for selection") +disable_liveblog.short_description = _("Disable liveblog for selection ") + + class BlogCategoryAdmin(EnhancedModelAdminMixin, ModelAppHookConfig, TranslatableAdmin): form = CategoryAdminForm list_display = [ @@ -58,6 +112,14 @@ class PostAdmin(PlaceholderAdminMixin, FrontendEditableAdminMixin, list_filter = ('app_config',) date_hierarchy = 'date_published' raw_id_fields = ['author'] + actions = [ + make_published, + make_unpublished, + enable_comments, + disable_comments, + ] + if 'djangocms_blog.liveblog' in settings.INSTALLED_APPS: + actions += [enable_liveblog, disable_liveblog] frontend_editable_fields = ('title', 'abstract', 'post_text') enhance_exclude = ('main_image', 'tags') _fieldsets = [ @@ -329,6 +391,7 @@ class BlogConfigAdmin(BaseAppHookConfig, TranslatableAdmin): menu_pool.clear(all=True) return super(BlogConfigAdmin, self).save_model(request, obj, form, change) + admin.site.register(BlogCategory, BlogCategoryAdmin) admin.site.register(Post, PostAdmin) admin.site.register(BlogConfig, BlogConfigAdmin) diff --git a/djangocms_blog/cms_appconfig.py b/djangocms_blog/cms_appconfig.py index 0ac4542..36ff2cc 100644 --- a/djangocms_blog/cms_appconfig.py +++ b/djangocms_blog/cms_appconfig.py @@ -139,4 +139,6 @@ class BlogConfigForm(AppDataForm): 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) diff --git a/djangocms_blog/cms_apps.py b/djangocms_blog/cms_apps.py index c6e25ae..aad2a18 100644 --- a/djangocms_blog/cms_apps.py +++ b/djangocms_blog/cms_apps.py @@ -28,5 +28,7 @@ class BlogApp(AutoCMSAppMixin, CMSConfigApp): 'object_name': get_setting('DEFAULT_OBJECT_NAME') }, } + + apphook_pool.register(BlogApp) BlogApp.setup() diff --git a/djangocms_blog/cms_menus.py b/djangocms_blog/cms_menus.py index 9cd6e20..89e2b98 100644 --- a/djangocms_blog/cms_menus.py +++ b/djangocms_blog/cms_menus.py @@ -106,6 +106,7 @@ class BlogCategoryMenu(CMSAttachMenu): return nodes + menu_pool.register_menu(BlogCategoryMenu) @@ -161,6 +162,7 @@ class BlogNavModifier(Modifier): node.selected = True return nodes + menu_pool.register_modifier(BlogNavModifier) @@ -170,5 +172,6 @@ def clear_menu_cache(**kwargs): """ menu_pool.clear(all=True) + post_save.connect(clear_menu_cache, sender=BlogCategory) post_delete.connect(clear_menu_cache, sender=BlogCategory) diff --git a/djangocms_blog/liveblog/cms_plugins.py b/djangocms_blog/liveblog/cms_plugins.py index 7e0d9fa..c351679 100644 --- a/djangocms_blog/liveblog/cms_plugins.py +++ b/djangocms_blog/liveblog/cms_plugins.py @@ -28,4 +28,5 @@ class LiveblogPlugin(TextPlugin): context['instance'] = instance return context + plugin_pool.register_plugin(LiveblogPlugin) diff --git a/djangocms_blog/urls.py b/djangocms_blog/urls.py index 84b9db2..2d68439 100644 --- a/djangocms_blog/urls.py +++ b/djangocms_blog/urls.py @@ -20,6 +20,7 @@ def get_urls(): ) return details + detail_urls = get_urls() urlpatterns = [ From 3f7e3275d5094c2c837a092b1a7ff1cb8433ab79 Mon Sep 17 00:00:00 2001 From: Fabian Braun Date: Fri, 24 Mar 2017 21:41:30 +0100 Subject: [PATCH 2/7] Merge for adding bulk actions for posts: publish, unpublish, allow/disallow comments, and enable/disable liveblog (if installed) --- djangocms_blog/admin.py | 1 - 1 file changed, 1 deletion(-) diff --git a/djangocms_blog/admin.py b/djangocms_blog/admin.py index e1dcd8a..fd4e4e2 100755 --- a/djangocms_blog/admin.py +++ b/djangocms_blog/admin.py @@ -133,7 +133,6 @@ class PostAdmin(PlaceholderAdminMixin, FrontendEditableAdminMixin, 'title', 'author', 'date_published', 'app_config', 'all_languages_column', 'date_published_end' ] - list_filter = ('app_config',) search_fields = ('translations__title',) date_hierarchy = 'date_published' raw_id_fields = ['author'] From 41cf73e9a151f706a92c725cefb75d84f539e54d Mon Sep 17 00:00:00 2001 From: Fabian Braun Date: Fri, 24 Mar 2017 21:43:44 +0100 Subject: [PATCH 3/7] Updated AUTHORS.rst --- AUTHORS.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/AUTHORS.rst b/AUTHORS.rst index 64dfb75..53e4ba9 100644 --- a/AUTHORS.rst +++ b/AUTHORS.rst @@ -16,6 +16,7 @@ Contributors * cluster-master * danra * Davide Truffo +* Fabian Braun * frnhr * furiousdave * Georgiy Kutsurua From c079a86582ffbe5bb00f50a2b231b415722c9aa9 Mon Sep 17 00:00:00 2001 From: Fabian Braun Date: Fri, 24 Mar 2017 21:50:47 +0100 Subject: [PATCH 4/7] Currect wrong merge --- djangocms_blog/cms_menus.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/djangocms_blog/cms_menus.py b/djangocms_blog/cms_menus.py index 89e2b98..26a6143 100644 --- a/djangocms_blog/cms_menus.py +++ b/djangocms_blog/cms_menus.py @@ -107,9 +107,6 @@ class BlogCategoryMenu(CMSAttachMenu): return nodes -menu_pool.register_menu(BlogCategoryMenu) - - class BlogNavModifier(Modifier): """ This navigation modifier makes sure that when @@ -164,6 +161,7 @@ class BlogNavModifier(Modifier): menu_pool.register_modifier(BlogNavModifier) +menu_pool.register_menu(BlogCategoryMenu) def clear_menu_cache(**kwargs): From 13ac239576bfc40fb4d41c6b9acda3fb7fb42de6 Mon Sep 17 00:00:00 2001 From: Fabian Braun Date: Sun, 26 Mar 2017 19:07:15 +0200 Subject: [PATCH 5/7] Messages for bulk cations, bulk actions as staticmethods of PostAdmin --- djangocms_blog/admin.py | 168 +++++++++++++++++++++++++--------------- 1 file changed, 107 insertions(+), 61 deletions(-) diff --git a/djangocms_blog/admin.py b/djangocms_blog/admin.py index fd4e4e2..f218ff4 100755 --- a/djangocms_blog/admin.py +++ b/djangocms_blog/admin.py @@ -11,12 +11,15 @@ from django.apps import apps from django.conf import settings from django.conf.urls import url from django.contrib import admin +from django.contrib import messages from django.contrib.sites.models import Site from django.core.urlresolvers import reverse from django.http import HttpResponseRedirect 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 _ +from django.utils.translation import ungettext as __ + from parler.admin import TranslatableAdmin from .cms_appconfig import BlogConfig @@ -31,59 +34,6 @@ except ImportError: pass -# Bulk actions for post admin -def make_published(modeladmin, request, queryset): - """ Bulk action to mark selected posts as published. If - the date_published field is empty the current time is - saved as date_published. - """ - for post in queryset: - if not post.publish: - if not post.date_published: - post.date_published = timezone.now() - post.publish = True - post.save() - - -def make_unpublished(modeladmin, request, queryset): - """ Bulk action to mark selected posts as UNpublished. - """ - queryset.update(publish=False) - - -def enable_comments(modeladmin, request, queryset): - """ Bulk action to enable comments for selected posts. - """ - queryset.update(enable_comments=True) - - -def disable_comments(modeladmin, request, queryset): - """ Bulk action to disable comments for selected posts. - """ - queryset.update(enable_comments=False) - - -def enable_liveblog(modeladmin, request, queryset): - """ Bulk action to enable comments for selected posts. - """ - queryset.update(enable_liveblog=True) - - -def disable_liveblog(modeladmin, request, queryset): - """ Bulk action to disable comments for selected posts. - """ - queryset.update(enable_liveblog=False) - - -# Make bulk action menu entries localizable -make_published.short_description = _("Publish selection") -make_unpublished.short_description = _("Unpublish selection") -enable_comments.short_description = _("Enable comments for selection") -disable_comments.short_description = _("Disable comments for selection ") -enable_liveblog.short_description = _("Enable liveblog for selection") -disable_liveblog.short_description = _("Disable liveblog for selection ") - - class SiteListFilter(admin.SimpleListFilter): title = _('site') parameter_name = 'sites' @@ -136,14 +86,6 @@ class PostAdmin(PlaceholderAdminMixin, FrontendEditableAdminMixin, search_fields = ('translations__title',) date_hierarchy = 'date_published' raw_id_fields = ['author'] - actions = [ - make_published, - make_unpublished, - enable_comments, - disable_comments, - ] - if 'djangocms_blog.liveblog' in settings.INSTALLED_APPS: - actions += [enable_liveblog, disable_liveblog] frontend_editable_fields = ('title', 'abstract', 'post_text') enhance_exclude = ('main_image', 'tags') _fieldsets = [ @@ -171,6 +113,110 @@ class PostAdmin(PlaceholderAdminMixin, FrontendEditableAdminMixin, } _sites = None + # Bulk actions for post admin + @staticmethod + def make_published(modeladmin, request, queryset): + """ Bulk action to mark selected posts as published. If + the date_published field is empty the current time is + saved as date_published. + queryset must not be empty (ensured by DjangoCMS). + """ + cnt1 = queryset.filter( + date_published__isnull=True, + publish=False, + ).update(date_published=timezone.now(), publish=True) + cnt2 = queryset.filter( + date_published__isnull=False, + publish=False, + ).update(publish=True) + messages.add_message( + request, messages.INFO, + __('%(updates)d entry published.', + '%(updates)d entries published.', cnt1+cnt2) % { + 'updates': cnt1+cnt2, }) + + @staticmethod + def make_unpublished(modeladmin, request, queryset): + """ Bulk action to mark selected posts as UNpublished. + queryset must not be empty (ensured by DjangoCMS). + """ + updates = queryset.filter(publish=True)\ + .update(publish=False) + messages.add_message( + request, messages.INFO, + __('%(updates)d entry unpublished.', + '%(updates)d entries unpublished.', updates) % { + 'updates': updates, }) + + @staticmethod + def enable_comments(modeladmin, request, queryset): + """ Bulk action to enable comments for selected posts. + queryset must not be empty (ensured by DjangoCMS). + """ + updates = queryset.filter(enable_comments=False)\ + .update(enable_comments=True) + messages.add_message( + request, messages.INFO, + __('Comments for %(updates)d entry enabled.', + 'Comments for %(updates)d entries enabled', updates) % { + 'updates': updates, }) + + @staticmethod + def disable_comments(modeladmin, request, queryset): + """ Bulk action to disable comments for selected posts. + queryset must not be empty (ensured by DjangoCMS). + """ + updates = queryset.filter(enable_comments=True)\ + .update(enable_comments=False) + messages.add_message( + request, messages.INFO, + __('Comments for %(updates)d entry disabled.', + 'Comments for %(updates)d entries disabled.', updates) % { + 'updates': updates, }) + + @staticmethod + def enable_liveblog(modeladmin, request, queryset): + """ Bulk action to enable comments for selected posts. + queryset must not be empty (ensured by DjangoCMS). + """ + updates = queryset.filter(enable_liveblog=False)\ + .update(enable_liveblog=True) + messages.add_message( + request, messages.INFO, + __('Liveblog for %(updates)d entry enabled.', + 'Liveblog for %(updates)d entries enabled.', updates) % { + 'updates': updates, }) + + @staticmethod + def disable_liveblog(modeladmin, request, queryset): + """ Bulk action to disable comments for selected posts. + queryset must not be empty (ensured by DjangoCMS). + """ + updates = queryset.filter(enable_liveblog=True)\ + .update(enable_liveblog=False) + messages.add_message( + request, messages.INFO, + __('Liveblog for %(updates)d entry enabled.', + 'Liveblog for %(updates)d entries enabled.') % { + 'updates': updates, }) + + # Make bulk action menu entries localizable + make_published.__func__.short_description = _("Publish selection") + make_unpublished.__func__.short_description = _("Unpublish selection") + enable_comments.__func__.short_description = _("Enable comments for selection") + disable_comments.__func__.short_description = _("Disable comments for selection ") + enable_liveblog.__func__.short_description = _("Enable liveblog for selection") + disable_liveblog.__func__.short_description = _("Disable liveblog for selection ") + + actions = [ + make_published.__func__, + make_unpublished.__func__, + enable_comments.__func__, + disable_comments.__func__, + ] + if 'djangocms_blog.liveblog' in settings.INSTALLED_APPS: + actions += [enable_liveblog.__func__, disable_liveblog.__func__] + def get_list_filter(self, request): filters = ['app_config', 'publish', 'date_published'] if get_setting('MULTISITE'): From bce9d56afe58ad4bbe8435bbc9204ca0f3dfcc04 Mon Sep 17 00:00:00 2001 From: Fabian Braun Date: Sun, 26 Mar 2017 20:07:55 +0200 Subject: [PATCH 6/7] Fix isort and pep8 issues --- cms_helper.py | 1 - djangocms_blog/admin.py | 6 ++---- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/cms_helper.py b/cms_helper.py index 8c838ef..8f28c53 100755 --- a/cms_helper.py +++ b/cms_helper.py @@ -11,7 +11,6 @@ def gettext(s): return s - HELPER_SETTINGS = dict( ROOT_URLCONF='tests.test_utils.urls', INSTALLED_APPS=[ diff --git a/djangocms_blog/admin.py b/djangocms_blog/admin.py index f218ff4..bfafe2a 100755 --- a/djangocms_blog/admin.py +++ b/djangocms_blog/admin.py @@ -10,15 +10,13 @@ from django import forms from django.apps import apps from django.conf import settings from django.conf.urls import url -from django.contrib import admin -from django.contrib import messages +from django.contrib import admin, messages from django.contrib.sites.models import Site from django.core.urlresolvers import reverse from django.http import HttpResponseRedirect 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 _ -from django.utils.translation import ungettext as __ +from django.utils.translation import get_language_from_request, ugettext_lazy as _, ungettext as __ from parler.admin import TranslatableAdmin From 92780aa4b089bcb77cf3fb773d116f548055c63c Mon Sep 17 00:00:00 2001 From: Fabian Braun Date: Mon, 27 Mar 2017 09:49:57 +0200 Subject: [PATCH 7/7] Replace @staticmethod by method-based admin actions. --- djangocms_blog/admin.py | 47 ++++++++++++++++++----------------------- 1 file changed, 20 insertions(+), 27 deletions(-) diff --git a/djangocms_blog/admin.py b/djangocms_blog/admin.py index bfafe2a..f7cbb8b 100755 --- a/djangocms_blog/admin.py +++ b/djangocms_blog/admin.py @@ -86,6 +86,14 @@ class PostAdmin(PlaceholderAdminMixin, FrontendEditableAdminMixin, raw_id_fields = ['author'] frontend_editable_fields = ('title', 'abstract', 'post_text') enhance_exclude = ('main_image', 'tags') + actions = [ + 'make_published', + 'make_unpublished', + 'enable_comments', + 'disable_comments', + ] + if 'djangocms_blog.liveblog' in settings.INSTALLED_APPS: + actions += ['enable_liveblog', 'disable_liveblog'] _fieldsets = [ (None, { 'fields': [['title', 'categories', 'publish', 'app_config']] @@ -112,8 +120,7 @@ class PostAdmin(PlaceholderAdminMixin, FrontendEditableAdminMixin, _sites = None # Bulk actions for post admin - @staticmethod - def make_published(modeladmin, request, queryset): + def make_published(self, request, queryset): """ Bulk action to mark selected posts as published. If the date_published field is empty the current time is saved as date_published. @@ -133,8 +140,7 @@ class PostAdmin(PlaceholderAdminMixin, FrontendEditableAdminMixin, '%(updates)d entries published.', cnt1+cnt2) % { 'updates': cnt1+cnt2, }) - @staticmethod - def make_unpublished(modeladmin, request, queryset): + def make_unpublished(self, request, queryset): """ Bulk action to mark selected posts as UNpublished. queryset must not be empty (ensured by DjangoCMS). """ @@ -146,8 +152,7 @@ class PostAdmin(PlaceholderAdminMixin, FrontendEditableAdminMixin, '%(updates)d entries unpublished.', updates) % { 'updates': updates, }) - @staticmethod - def enable_comments(modeladmin, request, queryset): + def enable_comments(self, request, queryset): """ Bulk action to enable comments for selected posts. queryset must not be empty (ensured by DjangoCMS). """ @@ -159,8 +164,7 @@ class PostAdmin(PlaceholderAdminMixin, FrontendEditableAdminMixin, 'Comments for %(updates)d entries enabled', updates) % { 'updates': updates, }) - @staticmethod - def disable_comments(modeladmin, request, queryset): + def disable_comments(self, request, queryset): """ Bulk action to disable comments for selected posts. queryset must not be empty (ensured by DjangoCMS). """ @@ -172,8 +176,7 @@ class PostAdmin(PlaceholderAdminMixin, FrontendEditableAdminMixin, 'Comments for %(updates)d entries disabled.', updates) % { 'updates': updates, }) - @staticmethod - def enable_liveblog(modeladmin, request, queryset): + def enable_liveblog(self, request, queryset): """ Bulk action to enable comments for selected posts. queryset must not be empty (ensured by DjangoCMS). """ @@ -185,8 +188,7 @@ class PostAdmin(PlaceholderAdminMixin, FrontendEditableAdminMixin, 'Liveblog for %(updates)d entries enabled.', updates) % { 'updates': updates, }) - @staticmethod - def disable_liveblog(modeladmin, request, queryset): + def disable_liveblog(self, request, queryset): """ Bulk action to disable comments for selected posts. queryset must not be empty (ensured by DjangoCMS). """ @@ -199,21 +201,12 @@ class PostAdmin(PlaceholderAdminMixin, FrontendEditableAdminMixin, 'updates': updates, }) # Make bulk action menu entries localizable - make_published.__func__.short_description = _("Publish selection") - make_unpublished.__func__.short_description = _("Unpublish selection") - enable_comments.__func__.short_description = _("Enable comments for selection") - disable_comments.__func__.short_description = _("Disable comments for selection ") - enable_liveblog.__func__.short_description = _("Enable liveblog for selection") - disable_liveblog.__func__.short_description = _("Disable liveblog for selection ") - - actions = [ - make_published.__func__, - make_unpublished.__func__, - enable_comments.__func__, - disable_comments.__func__, - ] - if 'djangocms_blog.liveblog' in settings.INSTALLED_APPS: - actions += [enable_liveblog.__func__, disable_liveblog.__func__] + make_published.short_description = _("Publish selection") + make_unpublished.short_description = _("Unpublish selection") + enable_comments.short_description = _("Enable comments for selection") + disable_comments.short_description = _("Disable comments for selection ") + enable_liveblog.short_description = _("Enable liveblog for selection") + disable_liveblog.short_description = _("Disable liveblog for selection ") def get_list_filter(self, request): filters = ['app_config', 'publish', 'date_published']