Moved LogActionRegistry into wagtailcore

Since logs are generated and stored in wagtailcore, I think it makes
sense for the list of available actions to be managed there too.
pull/7013/head
Karl Hobley 2020-08-01 19:07:59 +01:00 zatwierdzone przez Matt Westcott
rodzic 68862b5c79
commit 8a80196456
8 zmienionych plików z 238 dodań i 237 usunięć

Wyświetl plik

@ -5,8 +5,8 @@ from django.db import models
from django.utils.translation import gettext_lazy as _
from django_filters.widgets import SuffixedMultiWidget
from wagtail.admin.log_action_registry import registry as log_action_registry
from wagtail.admin.widgets import AdminDateInput, BooleanButtonSelect, ButtonSelect, FilteredSelect
from wagtail.core.logging import page_log_action_registry
from wagtail.core.models import Page, PageLogEntry, Task, TaskState, Workflow, WorkflowState
@ -185,7 +185,7 @@ def get_audit_log_users_queryset(request):
class SiteHistoryReportFilterSet(WagtailFilterSet):
action = django_filters.ChoiceFilter(choices=log_action_registry.get_choices)
action = django_filters.ChoiceFilter(choices=page_log_action_registry.get_choices)
timestamp = django_filters.DateFromToRangeFilter(label=_('Date'), widget=DateRangePickerWidget)
label = django_filters.CharFilter(label=_('Title'), lookup_expr='icontains')
user = django_filters.ModelChoiceFilter(
@ -198,7 +198,7 @@ class SiteHistoryReportFilterSet(WagtailFilterSet):
class PageHistoryReportFilterSet(WagtailFilterSet):
action = django_filters.ChoiceFilter(choices=log_action_registry.get_choices)
action = django_filters.ChoiceFilter(choices=page_log_action_registry.get_choices)
user = django_filters.ModelChoiceFilter(
field_name='user', queryset=get_audit_log_users_queryset
)

Wyświetl plik

@ -20,12 +20,12 @@ from django.utils.timesince import timesince
from django.utils.translation import gettext_lazy as _
from wagtail.admin.localization import get_js_translation_strings
from wagtail.admin.log_action_registry import registry as log_action_registry
from wagtail.admin.menu import admin_menu
from wagtail.admin.navigation import get_explorable_root_page
from wagtail.admin.search import admin_search_areas
from wagtail.admin.staticfiles import versioned_static as versioned_static_func
from wagtail.core import hooks
from wagtail.core.logging import page_log_action_registry
from wagtail.core.models import (
Collection, CollectionViewRestriction, Locale, Page, PageLogEntry, PageViewRestriction,
UserPagePermissionsProxy)
@ -583,7 +583,7 @@ def timesince_last_update(last_update, time_prefix='', use_shorthand=True):
def format_action_log_message(log_entry):
if not isinstance(log_entry, PageLogEntry):
return ''
return log_action_registry.format_message(log_entry)
return page_log_action_registry.format_message(log_entry)
@register.simple_tag

Wyświetl plik

@ -7,41 +7,11 @@ from django.urls import reverse
from django.utils import timezone
from freezegun import freeze_time
from wagtail.admin.log_action_registry import LogActionRegistry
from wagtail.core.models import GroupPagePermission, Page, PageLogEntry, PageViewRestriction
from wagtail.tests.testapp.models import SimplePage
from wagtail.tests.utils import WagtailTestUtils
def test_hook(actions):
return actions.register_action('test.custom_action', 'Custom action', 'Tested!')
class TestAuditLogHooks(TestCase, WagtailTestUtils):
def setUp(self):
self.root_page = Page.objects.get(id=2)
def test_register_log_actions_hook(self):
# testapp/wagtail_hooks.py defines a 'blockquote' rich text feature with a hallo.js
# plugin, via the register_rich_text_features hook; test that we can retrieve it here
log_actions = LogActionRegistry()
actions = log_actions.get_actions()
self.assertIn('wagtail.create', actions)
def test_action_format_message(self):
log_entry = PageLogEntry.objects.log_action(self.root_page, action='test.custom_action')
log_actions = LogActionRegistry()
self.assertEqual(log_actions.format_message(log_entry), "Unknown test.custom_action")
self.assertNotIn('test.custom_action', log_actions.get_actions())
with self.register_hook('register_log_actions', test_hook):
log_actions = LogActionRegistry()
self.assertIn('test.custom_action', log_actions.get_actions())
self.assertEqual(log_actions.format_message(log_entry), "Tested!")
self.assertEqual(log_actions.get_action_label('test.custom_action'), 'Custom action')
class TestAuditLogAdmin(TestCase, WagtailTestUtils):
def setUp(self):
self.root_page = Page.objects.get(id=2)

Wyświetl plik

@ -214,5 +214,5 @@ class LogEntriesView(ReportView):
return PageLogEntry.objects.filter(q)
def get_action_label(self, action):
from wagtail.admin.log_action_registry import registry as log_action_registry
return force_str(log_action_registry.get_action_label(action))
from wagtail.core.logging import page_log_action_registry
return force_str(page_log_action_registry.get_action_label(action))

Wyświetl plik

@ -808,202 +808,3 @@ def register_icons(icons):
@hooks.register('construct_homepage_summary_items')
def add_pages_summary_item(request, items):
items.insert(0, PagesSummaryItem(request))
@hooks.register('register_log_actions')
def register_core_log_actions(actions):
actions.register_action('wagtail.create', _('Create'), _('Created'))
actions.register_action('wagtail.edit', _('Save draft'), _('Draft saved'))
actions.register_action('wagtail.delete', _('Delete'), _('Deleted'))
actions.register_action('wagtail.publish', _('Publish'), _('Published'))
actions.register_action('wagtail.publish.scheduled', _("Publish scheduled draft"), _('Published scheduled draft'))
actions.register_action('wagtail.unpublish', _('Unpublish'), _('Unpublished'))
actions.register_action('wagtail.unpublish.scheduled', _('Unpublish scheduled draft'), _('Unpublished scheduled draft'))
actions.register_action('wagtail.lock', _('Lock'), _('Locked'))
actions.register_action('wagtail.unlock', _('Unlock'), _('Unlocked'))
actions.register_action('wagtail.moderation.approve', _('Approve'), _('Approved'))
actions.register_action('wagtail.moderation.reject', _('Reject'), _('Rejected'))
def revert_message(data):
try:
return _('Reverted to previous revision with id %(revision_id)s from %(created_at)s') % {
'revision_id': data['revision']['id'],
'created_at': data['revision']['created'],
}
except KeyError:
return _('Reverted to previous revision')
def copy_message(data):
try:
return _('Copied from %(title)s') % {
'title': data['source']['title'],
}
except KeyError:
return _("Copied")
def create_alias_message(data):
try:
return _('Created an alias of %(title)s') % {
'title': data['source']['title'],
}
except KeyError:
return _("Created an alias")
def convert_alias_message(data):
try:
return _("Converted the alias '%(title)s' into a regular page") % {
'title': data['page']['title'],
}
except KeyError:
return _("Converted an alias into a regular page")
def move_message(data):
try:
return _("Moved from '%(old_parent)s' to '%(new_parent)s'") % {
'old_parent': data['source']['title'],
'new_parent': data['destination']['title'],
}
except KeyError:
return _('Moved')
def reorder_message(data):
try:
return _("Reordered under '%(parent)s'") % {
'parent': data['destination']['title'],
}
except KeyError:
return _('Reordered')
def schedule_publish_message(data):
try:
if data['revision']['has_live_version']:
return _('Revision %(revision_id)s from %(created_at)s scheduled for publishing at %(go_live_at)s.') % {
'revision_id': data['revision']['id'],
'created_at': data['revision']['created'],
'go_live_at': data['revision']['go_live_at'],
}
else:
return _('Page scheduled for publishing at %(go_live_at)s') % {
'go_live_at': data['revision']['go_live_at'],
}
except KeyError:
return _('Page scheduled for publishing')
def unschedule_publish_message(data):
try:
if data['revision']['has_live_version']:
return _('Revision %(revision_id)s from %(created_at)s unscheduled from publishing at %(go_live_at)s.') % {
'revision_id': data['revision']['id'],
'created_at': data['revision']['created'],
'go_live_at': data['revision']['go_live_at'],
}
else:
return _('Page unscheduled for publishing at %(go_live_at)s') % {
'go_live_at': data['revision']['go_live_at'],
}
except KeyError:
return _('Page unscheduled from publishing')
def add_view_restriction(data):
try:
return _("Added the '%(restriction)s' view restriction") % {
'restriction': data['restriction']['title'],
}
except KeyError:
return _('Added view restriction')
def edit_view_restriction(data):
try:
return _("Updated the view restriction to '%(restriction)s'") % {
'restriction': data['restriction']['title'],
}
except KeyError:
return _('Updated view restriction')
def delete_view_restriction(data):
try:
return _("Removed the '%(restriction)s' view restriction") % {
'restriction': data['restriction']['title'],
}
except KeyError:
return _('Removed view restriction')
def rename_message(data):
try:
return _("Renamed from '%(old)s' to '%(new)s'") % {
'old': data['title']['old'],
'new': data['title']['new'],
}
except KeyError:
return _('Renamed')
actions.register_action('wagtail.rename', _('Rename'), rename_message)
actions.register_action('wagtail.revert', _('Revert'), revert_message)
actions.register_action('wagtail.copy', _('Copy'), copy_message)
actions.register_action('wagtail.create_alias', _('Create alias'), create_alias_message)
actions.register_action('wagtail.convert_alias', _('Convert alias into regular page'), convert_alias_message)
actions.register_action('wagtail.move', _('Move'), move_message)
actions.register_action('wagtail.reorder', _('Reorder'), reorder_message)
actions.register_action('wagtail.publish.schedule', _("Schedule publication"), schedule_publish_message)
actions.register_action('wagtail.schedule.cancel', _("Unschedule publication"), unschedule_publish_message)
actions.register_action('wagtail.view_restriction.create', _("Add view restrictions"), add_view_restriction)
actions.register_action('wagtail.view_restriction.edit', _("Update view restrictions"), edit_view_restriction)
actions.register_action('wagtail.view_restriction.delete', _("Remove view restrictions"), delete_view_restriction)
@hooks.register('register_log_actions')
def register_workflow_log_actions(actions):
def workflow_start_message(data):
try:
return _("'%(workflow)s' started. Next step '%(task)s'") % {
'workflow': data['workflow']['title'],
'task': data['workflow']['next']['title'],
}
except (KeyError, TypeError):
return _('Workflow started')
def workflow_approve_message(data):
try:
if data['workflow']['next']:
return _("Approved at '%(task)s'. Next step '%(next_task)s'") % {
'task': data['workflow']['task']['title'],
'next_task': data['workflow']['next']['title'],
}
else:
return _("Approved at '%(task)s'. '%(workflow)s' complete") % {
'task': data['workflow']['task']['title'],
'workflow': data['workflow']['title'],
}
except (KeyError, TypeError):
return _('Workflow task approved')
def workflow_reject_message(data):
try:
return _("Rejected at '%(task)s'. Changes requested") % {
'task': data['workflow']['task']['title'],
}
except (KeyError, TypeError):
return _('Workflow task rejected. Workflow complete')
def workflow_resume_message(data):
try:
return _("Resubmitted '%(task)s'. Workflow resumed'") % {
'task': data['workflow']['task']['title'],
}
except (KeyError, TypeError):
return _('Workflow task resubmitted. Workflow resumed')
def workflow_cancel_message(data):
try:
return _("Cancelled '%(workflow)s' at '%(task)s'") % {
'workflow': data['workflow']['title'],
'task': data['workflow']['task']['title'],
}
except (KeyError, TypeError):
return _('Workflow cancelled')
actions.register_action('wagtail.workflow.start', _('Workflow: start'), workflow_start_message)
actions.register_action('wagtail.workflow.approve', _('Workflow: approve task'), workflow_approve_message)
actions.register_action('wagtail.workflow.reject', _('Workflow: reject task'), workflow_reject_message)
actions.register_action('wagtail.workflow.resume', _('Workflow: resume task'), workflow_resume_message)
actions.register_action('wagtail.workflow.cancel', _('Workflow: cancel'), workflow_cancel_message)

Wyświetl plik

@ -57,4 +57,4 @@ class LogActionRegistry:
return self.get_actions()[action][0]
registry = LogActionRegistry()
page_log_action_registry = LogActionRegistry()

Wyświetl plik

@ -6,6 +6,7 @@ from django.test import TestCase
from django.utils import timezone
from freezegun import freeze_time
from wagtail.core.logging import LogActionRegistry
from wagtail.core.models import (
Page, PageLogEntry, PageViewRestriction, Task, Workflow, WorkflowTask)
from wagtail.tests.testapp.models import SimplePage
@ -307,3 +308,32 @@ class TestAuditLog(TestCase):
restriction.restriction_type = PageViewRestriction.PASSWORD
restriction.save()
self.assertEqual(PageLogEntry.objects.filter(action='wagtail.view_restriction.edit').count(), 1)
def test_hook(actions):
return actions.register_action('test.custom_action', 'Custom action', 'Tested!')
class TestAuditLogHooks(TestCase, WagtailTestUtils):
def setUp(self):
self.root_page = Page.objects.get(id=2)
def test_register_log_actions_hook(self):
# testapp/wagtail_hooks.py defines a 'blockquote' rich text feature with a hallo.js
# plugin, via the register_rich_text_features hook; test that we can retrieve it here
log_actions = LogActionRegistry()
actions = log_actions.get_actions()
self.assertIn('wagtail.create', actions)
def test_action_format_message(self):
log_entry = PageLogEntry.objects.log_action(self.root_page, action='test.custom_action')
log_actions = LogActionRegistry()
self.assertEqual(log_actions.format_message(log_entry), "Unknown test.custom_action")
self.assertNotIn('test.custom_action', log_actions.get_actions())
with self.register_hook('register_log_actions', test_hook):
log_actions = LogActionRegistry()
self.assertIn('test.custom_action', log_actions.get_actions())
self.assertEqual(log_actions.format_message(log_entry), "Tested!")
self.assertEqual(log_actions.get_action_label('test.custom_action'), 'Custom action')

Wyświetl plik

@ -2,6 +2,7 @@ from django.conf import settings
from django.contrib.auth.models import Permission
from django.contrib.auth.views import redirect_to_login
from django.urls import reverse
from django.utils.translation import gettext as _
from django.utils.translation import ngettext
from wagtail.core import hooks
@ -92,3 +93,202 @@ def describe_collection_children(collection):
) % {'count': descendant_count},
'url': url,
}
@hooks.register('register_log_actions')
def register_core_log_actions(actions):
actions.register_action('wagtail.create', _('Create'), _('Created'))
actions.register_action('wagtail.edit', _('Save draft'), _('Draft saved'))
actions.register_action('wagtail.delete', _('Delete'), _('Deleted'))
actions.register_action('wagtail.publish', _('Publish'), _('Published'))
actions.register_action('wagtail.publish.scheduled', _("Publish scheduled draft"), _('Published scheduled draft'))
actions.register_action('wagtail.unpublish', _('Unpublish'), _('Unpublished'))
actions.register_action('wagtail.unpublish.scheduled', _('Unpublish scheduled draft'), _('Unpublished scheduled draft'))
actions.register_action('wagtail.lock', _('Lock'), _('Locked'))
actions.register_action('wagtail.unlock', _('Unlock'), _('Unlocked'))
actions.register_action('wagtail.moderation.approve', _('Approve'), _('Approved'))
actions.register_action('wagtail.moderation.reject', _('Reject'), _('Rejected'))
def revert_message(data):
try:
return _('Reverted to previous revision with id %(revision_id)s from %(created_at)s') % {
'revision_id': data['revision']['id'],
'created_at': data['revision']['created'],
}
except KeyError:
return _('Reverted to previous revision')
def copy_message(data):
try:
return _('Copied from %(title)s') % {
'title': data['source']['title'],
}
except KeyError:
return _("Copied")
def create_alias_message(data):
try:
return _('Created an alias of %(title)s') % {
'title': data['source']['title'],
}
except KeyError:
return _("Created an alias")
def convert_alias_message(data):
try:
return _("Converted the alias '%(title)s' into a regular page") % {
'title': data['page']['title'],
}
except KeyError:
return _("Converted an alias into a regular page")
def move_message(data):
try:
return _("Moved from '%(old_parent)s' to '%(new_parent)s'") % {
'old_parent': data['source']['title'],
'new_parent': data['destination']['title'],
}
except KeyError:
return _('Moved')
def reorder_message(data):
try:
return _("Reordered under '%(parent)s'") % {
'parent': data['destination']['title'],
}
except KeyError:
return _('Reordered')
def schedule_publish_message(data):
try:
if data['revision']['has_live_version']:
return _('Revision %(revision_id)s from %(created_at)s scheduled for publishing at %(go_live_at)s.') % {
'revision_id': data['revision']['id'],
'created_at': data['revision']['created'],
'go_live_at': data['revision']['go_live_at'],
}
else:
return _('Page scheduled for publishing at %(go_live_at)s') % {
'go_live_at': data['revision']['go_live_at'],
}
except KeyError:
return _('Page scheduled for publishing')
def unschedule_publish_message(data):
try:
if data['revision']['has_live_version']:
return _('Revision %(revision_id)s from %(created_at)s unscheduled from publishing at %(go_live_at)s.') % {
'revision_id': data['revision']['id'],
'created_at': data['revision']['created'],
'go_live_at': data['revision']['go_live_at'],
}
else:
return _('Page unscheduled for publishing at %(go_live_at)s') % {
'go_live_at': data['revision']['go_live_at'],
}
except KeyError:
return _('Page unscheduled from publishing')
def add_view_restriction(data):
try:
return _("Added the '%(restriction)s' view restriction") % {
'restriction': data['restriction']['title'],
}
except KeyError:
return _('Added view restriction')
def edit_view_restriction(data):
try:
return _("Updated the view restriction to '%(restriction)s'") % {
'restriction': data['restriction']['title'],
}
except KeyError:
return _('Updated view restriction')
def delete_view_restriction(data):
try:
return _("Removed the '%(restriction)s' view restriction") % {
'restriction': data['restriction']['title'],
}
except KeyError:
return _('Removed view restriction')
def rename_message(data):
try:
return _("Renamed from '%(old)s' to '%(new)s'") % {
'old': data['title']['old'],
'new': data['title']['new'],
}
except KeyError:
return _('Renamed')
actions.register_action('wagtail.rename', _('Rename'), rename_message)
actions.register_action('wagtail.revert', _('Revert'), revert_message)
actions.register_action('wagtail.copy', _('Copy'), copy_message)
actions.register_action('wagtail.create_alias', _('Create alias'), create_alias_message)
actions.register_action('wagtail.convert_alias', _('Convert alias into regular page'), convert_alias_message)
actions.register_action('wagtail.move', _('Move'), move_message)
actions.register_action('wagtail.reorder', _('Reorder'), reorder_message)
actions.register_action('wagtail.publish.schedule', _("Schedule publication"), schedule_publish_message)
actions.register_action('wagtail.schedule.cancel', _("Unschedule publication"), unschedule_publish_message)
actions.register_action('wagtail.view_restriction.create', _("Add view restrictions"), add_view_restriction)
actions.register_action('wagtail.view_restriction.edit', _("Update view restrictions"), edit_view_restriction)
actions.register_action('wagtail.view_restriction.delete', _("Remove view restrictions"), delete_view_restriction)
@hooks.register('register_log_actions')
def register_workflow_log_actions(actions):
def workflow_start_message(data):
try:
return _("'%(workflow)s' started. Next step '%(task)s'") % {
'workflow': data['workflow']['title'],
'task': data['workflow']['next']['title'],
}
except (KeyError, TypeError):
return _('Workflow started')
def workflow_approve_message(data):
try:
if data['workflow']['next']:
return _("Approved at '%(task)s'. Next step '%(next_task)s'") % {
'task': data['workflow']['task']['title'],
'next_task': data['workflow']['next']['title'],
}
else:
return _("Approved at '%(task)s'. '%(workflow)s' complete") % {
'task': data['workflow']['task']['title'],
'workflow': data['workflow']['title'],
}
except (KeyError, TypeError):
return _('Workflow task approved')
def workflow_reject_message(data):
try:
return _("Rejected at '%(task)s'. Changes requested") % {
'task': data['workflow']['task']['title'],
}
except (KeyError, TypeError):
return _('Workflow task rejected. Workflow complete')
def workflow_resume_message(data):
try:
return _("Resubmitted '%(task)s'. Workflow resumed'") % {
'task': data['workflow']['task']['title'],
}
except (KeyError, TypeError):
return _('Workflow task resubmitted. Workflow resumed')
def workflow_cancel_message(data):
try:
return _("Cancelled '%(workflow)s' at '%(task)s'") % {
'workflow': data['workflow']['title'],
'task': data['workflow']['task']['title'],
}
except (KeyError, TypeError):
return _('Workflow cancelled')
actions.register_action('wagtail.workflow.start', _('Workflow: start'), workflow_start_message)
actions.register_action('wagtail.workflow.approve', _('Workflow: approve task'), workflow_approve_message)
actions.register_action('wagtail.workflow.reject', _('Workflow: reject task'), workflow_reject_message)
actions.register_action('wagtail.workflow.resume', _('Workflow: resume task'), workflow_resume_message)
actions.register_action('wagtail.workflow.cancel', _('Workflow: cancel'), workflow_cancel_message)