1. Olemis Lang
  2. trac-mq

Commits

Olemis Lang  committed 02877e2

Trac #11148 : 'IWikiChangeListener' notifications powered by 'ListenerNotifier.notify' [ok]

  • Participants
  • Parent commits e944ce9
  • Branches trac_t11148

Comments (0)

Files changed (5)

File t11148/t11148_r11782_IEntityChangeListener_v2.diff

View file
 
 diff -r 8d0c3223a818 trac/core.py
 --- a/trac/core.py	Thu Apr 18 14:30:21 2013 +0000
-+++ b/trac/core.py	Sat Apr 27 16:41:49 2013 -0500
++++ b/trac/core.py	Sat Apr 27 23:56:40 2013 -0500
 @@ -165,7 +165,6 @@
  
          locals_.setdefault('_implements', []).extend(interfaces)
  implements = Component.implements
  
  
-@@ -236,3 +235,107 @@
+@@ -236,3 +235,115 @@
          with the given class will not be available.
          """
          return True
 +        Called when an entity is created.
 +        """
 +
-+    def entity_changed(entity, old_values, changeinfo = None):
++    def entity_changed(entity, old_values=None, changeinfo = None):
 +        """Called when an entity is modified.
 +
 +        :param old_values: is a dictionary containing the previous values of
 +                           the entity properties that changed. Properties
 +                           specific for entity type.
++                           May be `None` if the entity-specific interface
++                           does not support old entity state
 +        """
 +
 +    def entity_deleted(entity, changeinfo = None):
 +        if generic_listeners:
 +            kwargs['entity'] = entity
 +            #TODO : Include `interface` in kwargs ?
-+            parts = method_name.split('_', 1)
-+            action = parts[-1]
++            try:
++                prefix = interface._entity_listener_prefix
++            except AttributeError:
++                parts = method_name.split('_', 1)
++                action = parts[-1]
++            else:
++                action = method_name[len(prefix) + 1:] \
++                         if method_name.startswith(prefix) else method_name
 +            changeinfo = kwargs.setdefault('changeinfo', 
 +                                           NotificationChangeInfo())
 +            target_args = set(('changeinfo', 'entity'))
 +                getattr(listener, method_name)(**kwargs)
 diff -r 8d0c3223a818 trac/tests/core.py
 --- a/trac/tests/core.py	Thu Apr 18 14:30:21 2013 +0000
-+++ b/trac/tests/core.py	Sat Apr 27 16:41:49 2013 -0500
++++ b/trac/tests/core.py	Sat Apr 27 23:56:40 2013 -0500
 @@ -15,7 +15,7 @@
  # Author: Christopher Lenz <cmlenz@gmx.de>
  
 +        kwargs.update(action='created')
 +        self._handle(kwargs)
 +
-+    def entity_changed(self, entity, old_values, changeinfo = None):
++    def entity_changed(self, entity, old_values=None, changeinfo = None):
 +        kwargs = locals()
 +        kwargs.update(action='changed')
 +        self._handle(kwargs)
  
 diff -r 8d0c3223a818 trac/ticket/api.py
 --- a/trac/ticket/api.py	Thu Apr 18 14:30:21 2013 +0000
-+++ b/trac/ticket/api.py	Sat Apr 27 16:41:49 2013 -0500
-@@ -179,6 +179,146 @@
++++ b/trac/ticket/api.py	Sat Apr 27 23:56:40 2013 -0500
+@@ -179,6 +179,152 @@
          """Called when a milestone is deleted."""
  
  
 +    :param     entity: target ticket type.
 +    :param changeinfo: always set to None.
 +    """
++
 +    _entity_listener_prefix = 'type'
 +
 +    def type_created(entity, changeinfo = None):
 +    :param     entity: target ticket resolution.
 +    :param changeinfo: always set to None.
 +    """
++
 +    _entity_listener_prefix = 'resolution'
 +
 +    def resolution_created(entity, changeinfo = None):
 +    :param     entity: target ticket priority.
 +    :param changeinfo: always set to None.
 +    """
++
 +    _entity_listener_prefix = 'priority'
 +
 +    def priority_created(entity, changeinfo = None):
 +    :param     entity: target ticket severity.
 +    :param changeinfo: always set to None.
 +    """
++
 +    _entity_listener_prefix = 'severity'
 +
 +    def severity_created(entity, changeinfo = None):
 +    :param     entity: target ticket component.
 +    :param changeinfo: always set to None.
 +    """
++
 +    _entity_listener_prefix = 'component'
 +
 +    def component_created(entity, changeinfo = None):
 +    :param     entity: target ticket version.
 +    :param changeinfo: always set to None.
 +    """
++
 +    _entity_listener_prefix = 'version'
 +
 +    def version_created(entity, changeinfo = None):
  
 diff -r 8d0c3223a818 trac/ticket/model.py
 --- a/trac/ticket/model.py	Thu Apr 18 14:30:21 2013 +0000
-+++ b/trac/ticket/model.py	Sat Apr 27 16:41:49 2013 -0500
++++ b/trac/ticket/model.py	Sat Apr 27 23:56:40 2013 -0500
 @@ -25,9 +25,13 @@
  from trac.attachment import Attachment
  from trac import core
          """
 diff -r 8d0c3223a818 trac/ticket/tests/model.py
 --- a/trac/ticket/tests/model.py	Thu Apr 18 14:30:21 2013 +0000
-+++ b/trac/ticket/tests/model.py	Sat Apr 27 16:41:49 2013 -0500
++++ b/trac/ticket/tests/model.py	Sat Apr 27 23:56:40 2013 -0500
 @@ -9,15 +9,16 @@
  
  from trac import core

File t11148/t11148_r11784_IEntityListener_compat_attachment.diff

View file
 
 diff -r 2d08b51bc080 trac/attachment.py
 --- a/trac/attachment.py	Sat Apr 27 16:41:50 2013 -0500
-+++ b/trac/attachment.py	Sat Apr 27 16:50:19 2013 -0500
++++ b/trac/attachment.py	Sat Apr 27 23:05:24 2013 -0500
 @@ -34,6 +34,7 @@
                         console_datetime_format, get_dir_list
  from trac.config import BoolOption, IntOption
  from trac.mimeview import *
  from trac.perm import PermissionError, IPermissionPolicy
  from trac.resource import *
-@@ -235,8 +236,8 @@
+@@ -61,6 +62,8 @@
+     """Extension point interface for components that require
+     notification when attachments are created or deleted."""
+ 
++    _entity_listener_prefix = 'attachment'
++
+     def attachment_added(attachment):
+         """Called when an attachment is added."""
+ 
+@@ -235,8 +238,8 @@
  
          self.env.log.info("Attachment removed: %s" % self.title)
  
  
      def reparent(self, new_realm, new_id):
          assert self.filename, "Cannot reparent non-existent attachment"
-@@ -284,9 +285,10 @@
+@@ -284,9 +287,10 @@
  
          self.env.log.info("Attachment reparented: %s" % self.title)
  
  
      def insert(self, filename, fileobj, size, t=None, db=None):
          """Create a new Attachment record and save the file content.
-@@ -330,8 +332,8 @@
+@@ -330,8 +334,8 @@
                  self.env.log.info("New attachment: %s by %s", self.title,
                                    self.author)
  
      @classmethod
 diff -r 2d08b51bc080 trac/tests/attachment.py
 --- a/trac/tests/attachment.py	Sat Apr 27 16:41:50 2013 -0500
-+++ b/trac/tests/attachment.py	Sat Apr 27 16:50:19 2013 -0500
++++ b/trac/tests/attachment.py	Sat Apr 27 23:05:24 2013 -0500
 @@ -6,11 +6,13 @@
  import tempfile
  import unittest

File t11148/t11148_r11784_IEntityListener_compat_ticket.diff

View file
 # Parent 2c0e5eb15b91dc6952dcb8c0866631ff7cb9fcab
 Trac #11148 : 'ITicketChangeListener' , 'IMilestoneChangeListener' notifications powered by 'ListenerNotifier.notify'
 
+diff -r 2c0e5eb15b91 trac/ticket/api.py
+--- a/trac/ticket/api.py	Sat Apr 27 16:50:19 2013 -0500
++++ b/trac/ticket/api.py	Sat Apr 27 23:03:14 2013 -0500
+@@ -131,6 +131,8 @@
+     """Extension point interface for components that require notification
+     when tickets are created, modified, or deleted."""
+ 
++    _entity_listener_prefix = 'ticket'
++
+     def ticket_created(ticket):
+         """Called when a ticket is created."""
+ 
+@@ -164,6 +166,8 @@
+     """Extension point interface for components that require notification
+     when milestones are created, modified, or deleted."""
+ 
++    _entity_listener_prefix = 'milestone'
++
+     def milestone_created(milestone):
+         """Called when a milestone is created."""
+ 
 diff -r 2c0e5eb15b91 trac/ticket/model.py
 --- a/trac/ticket/model.py	Sat Apr 27 16:50:19 2013 -0500
-+++ b/trac/ticket/model.py	Sat Apr 27 18:22:51 2013 -0500
++++ b/trac/ticket/model.py	Sat Apr 27 23:03:14 2013 -0500
 @@ -28,10 +28,11 @@
  from trac.core import (Interface, IEntityChangeListener, ListenerNotifier,
                         TracError)
      def select(cls, env, include_completed=True, db=None):
 diff -r 2c0e5eb15b91 trac/ticket/tests/model.py
 --- a/trac/ticket/tests/model.py	Sat Apr 27 16:50:19 2013 -0500
-+++ b/trac/ticket/tests/model.py	Sat Apr 27 18:22:51 2013 -0500
++++ b/trac/ticket/tests/model.py	Sat Apr 27 23:03:14 2013 -0500
 @@ -402,14 +402,21 @@
  
      def test_change_listener_created(self):

File t11148/t11148_r11784_IEntityListener_compat_versioncontrol.diff

View file
 
 diff -r 97ded291445a trac/versioncontrol/api.py
 --- a/trac/versioncontrol/api.py	Sat Apr 27 18:22:51 2013 -0500
-+++ b/trac/versioncontrol/api.py	Sat Apr 27 18:57:04 2013 -0500
++++ b/trac/versioncontrol/api.py	Sat Apr 27 20:00:19 2013 -0500
 @@ -22,6 +22,7 @@
  from trac.admin import AdminCommandError, IAdminCommandProvider, get_dir_list
  from trac.config import ConfigSection, ListOption, Option
  from trac.resource import IResourceManager, Resource, ResourceNotFound
  from trac.util.concurrency import threading
  from trac.util.text import printout, to_unicode
-@@ -657,9 +658,9 @@
+@@ -94,6 +95,8 @@
+ class IRepositoryChangeListener(Interface):
+     """Listen for changes in repositories."""
+ 
++    _entity_listener_prefix = 'changeset'
++
+     def changeset_added(repos, changeset):
+         """Called after a changeset has been added to a repository."""
+ 
+@@ -657,9 +660,9 @@
          for repos in sorted(repositories, key=lambda r: r.reponame):
              repos.sync()
              for rev in revs:
                  try:
                      changeset = repos.get_changeset(rev)
                  except NoSuchChangeset:
-@@ -670,8 +671,10 @@
+@@ -670,8 +673,10 @@
                          continue
                  self.log.debug("Event %s on %s for revision %s",
                                 event, repos.reponame or '(default)', rev)

File t11148/t11148_r11784_IEntityListener_compat_wiki.diff

View file
 # HG changeset patch
-# Parent e4ab81782045017e600aa19b5323665f9f3e9524
+# Parent b40d09fa09786188ad2a4aa37c92705b1a50fdc8
 Trac #11148 : 'IWikiChangeListener' notifications powered by 'ListenerNotifier.notify' [ok]
 
-diff --git a/trac/wiki/model.py b/trac/wiki/model.py
---- a/trac/wiki/model.py
-+++ b/trac/wiki/model.py
+diff -r b40d09fa0978 trac/wiki/api.py
+--- a/trac/wiki/api.py	Sat Apr 27 23:56:47 2013 -0500
++++ b/trac/wiki/api.py	Sun Apr 28 00:00:24 2013 -0500
+@@ -36,6 +36,8 @@
+     interface.
+     """
+ 
++    _entity_listener_prefix = 'wiki_page'
++
+     def wiki_page_added(page):
+         """Called whenever a new Wiki page is added."""
+ 
+diff -r b40d09fa0978 trac/wiki/model.py
+--- a/trac/wiki/model.py	Sat Apr 27 23:56:47 2013 -0500
++++ b/trac/wiki/model.py	Sun Apr 28 00:00:24 2013 -0500
 @@ -21,10 +21,11 @@
  from datetime import datetime
  
  
      def get_history(self, db=None):
          """Retrieve the edit history of a wiki page.
-diff --git a/trac/wiki/tests/model.py b/trac/wiki/tests/model.py
---- a/trac/wiki/tests/model.py
-+++ b/trac/wiki/tests/model.py
+diff -r b40d09fa0978 trac/wiki/tests/model.py
+--- a/trac/wiki/tests/model.py	Sat Apr 27 23:56:47 2013 -0500
++++ b/trac/wiki/tests/model.py	Sun Apr 28 00:00:24 2013 -0500
 @@ -12,6 +12,7 @@
  from trac.attachment import Attachment
  from trac.core import *
          self.assertEqual(page, listener.added[0])
  
 +        generic_listener = GenericEntitiesChangeListenerMock(self.env)
-+        self.assertEqual([{'action' : 'created', 'entity' : page}], 
++        self.assertEqual([{'action' : 'added', 'entity' : page}], 
 +                         generic_listener.details)
 +
      def test_update_page(self):
          t = datetime(2001, 1, 1, 1, 1, 1, 0, utc)
          t2 = datetime(2002, 1, 1, 1, 1, 1, 0, utc)
-@@ -149,6 +154,12 @@
+@@ -149,6 +154,13 @@
          self.assertEqual((page, 2, t2, 'Changing', 'kate', '192.168.0.101'),
                           listener.changed[0])
  
 +        generic_listener = GenericEntitiesChangeListenerMock(self.env)
 +        self.assertEqual([{'action' : 'changed', 'entity' : page,
 +                           'version' : 2, 't' : t2 , 'comment' : 'Changing',
-+                           'author' : 'kate', 'ipnr' : '192.168.0.101'}], 
++                           'author' : 'kate', 'ipnr' : '192.168.0.101',
++                            'old_values': None}], 
 +                         generic_listener.details)
 +
          page = WikiPage(self.env, 'TestPage')
          history = list(page.get_history())
          self.assertEqual(2, len(history))
-@@ -174,6 +185,10 @@
+@@ -174,6 +186,10 @@
          listener = TestWikiChangeListener(self.env)
          self.assertEqual(page, listener.deleted[0])
  
      def test_delete_page_version(self):
          self.env.db_transaction.executemany(
              "INSERT INTO wiki VALUES(%s,%s,%s,%s,%s,%s,%s,%s)",
-@@ -194,6 +209,10 @@
+@@ -194,6 +210,10 @@
          listener = TestWikiChangeListener(self.env)
          self.assertEqual(page, listener.deleted_version[0])
  
      def test_delete_page_last_version(self):
          self.env.db_transaction(
              "INSERT INTO wiki VALUES(%s,%s,%s,%s,%s,%s,%s,%s)",
-@@ -212,6 +231,10 @@
+@@ -212,6 +232,10 @@
          listener = TestWikiChangeListener(self.env)
          self.assertEqual(page, listener.deleted[0])
  
      def test_rename_page(self):
          data = (1, 42, 'joe', '::1', 'Bla bla', 'Testing', 0)
          self.env.db_transaction(
-@@ -247,6 +270,17 @@
+@@ -247,6 +271,33 @@
          listener = TestWikiChangeListener(self.env)
          self.assertEqual((page, 'TestPage'), listener.renamed[0])
  
 +        generic_listener = GenericEntitiesChangeListenerMock(self.env)
-+        self.assertEqual([{'action' : 'added', 'entity' : attachment},
-+                          {'action' : 'reparented', 'entity' : attachment,
-+                           'old_parent_realm' : 'wiki', 
-+                           'old_parent_id' : 'TestPage'},
-+                          {'action' : 'renamed', 'entity' : page,
-+                           'old_name' : 'TestPage'},
-+                          {'action' : 'deleted', 'entity' : attachment}], 
-+                         generic_listener.details)
++        self.assertEqual({'action' : 'added', 'entity' : attachment},
++                         generic_listener.details[0])
++
++        from trac.resource import Resource
++
++        # Match everything but attachment
++        event_args = generic_listener.details[1]
++        expected_resource = Resource('wiki', 'PageRenamed').child('attachment',
++                                                                  'foo.txt')
++        resource = event_args.pop('entity').resource
++        self.assertEqual({'action' : 'reparented', 'old_parent_realm' : 'wiki', 
++                          'old_parent_id' : 'TestPage'}, 
++                         event_args)
++        self.assertEqual(expected_resource, resource)
++
++        self.assertEqual({'action' : 'renamed', 'entity' : page,
++                          'old_name' : 'TestPage'},
++                         generic_listener.details[2])
++
++        # Match everything but attachment
++        event_args = generic_listener.details[3]
++        resource = event_args.pop('entity').resource
++        self.assertEqual({'action' : 'deleted'}, event_args)
++        self.assertEqual(expected_resource, resource)
 +
 +
      def test_invalid_page_name(self):