[Zope3-checkins] SVN: Zope3/trunk/src/zope/app/wiki/ Changed the modified notification mail to use diffs

Eckart Hertzler eckart at hertzler.de
Tue Jun 8 08:11:49 EDT 2004


Log message for revision 25288:

Changed the modified notification mail to use diffs
(removing an 'XXX')

- fixed some errors in diff, which were not noticed before,
  because the module was not used
- add a wikipage edit event that contains the updated object and
  the previous source text
- removed some references to smptlib
- updated the subscribe directive




-=-
Modified: Zope3/trunk/src/zope/app/wiki/TODO.txt
===================================================================
--- Zope3/trunk/src/zope/app/wiki/TODO.txt	2004-06-08 11:05:21 UTC (rev 25287)
+++ Zope3/trunk/src/zope/app/wiki/TODO.txt	2004-06-08 12:11:49 UTC (rev 25288)
@@ -37,5 +37,3 @@
     Differ.
 
   - Update POT and translations
-
-  - Use MailDelivery utility
\ No newline at end of file

Modified: Zope3/trunk/src/zope/app/wiki/configure.zcml
===================================================================
--- Zope3/trunk/src/zope/app/wiki/configure.zcml	2004-06-08 11:05:21 UTC (rev 25287)
+++ Zope3/trunk/src/zope/app/wiki/configure.zcml	2004-06-08 12:11:49 UTC (rev 25288)
@@ -207,12 +207,16 @@
   <!-- Register event listener for change mails -->
   <subscriber
       factory=".wikipage.mailer"
-      for="zope.app.container.interfaces.IObjectMovedEvent"
+      for="zope.app.container.interfaces.IObjectAddedEvent"
       />
   <subscriber
       factory=".wikipage.mailer"
-      for="zope.app.event.interfaces.IObjectModifiedEvent"
+      for="zope.app.container.interfaces.IObjectRemovedEvent"
       />
+  <subscriber
+      factory=".wikipage.mailer"
+      for=".interfaces.IWikiPageEditEvent"
+      />
 
 
   <!-- Register various browser related components, including all views -->

Modified: Zope3/trunk/src/zope/app/wiki/diff.py
===================================================================
--- Zope3/trunk/src/zope/app/wiki/diff.py	2004-06-08 11:05:21 UTC (rev 25287)
+++ Zope3/trunk/src/zope/app/wiki/diff.py	2004-06-08 12:11:49 UTC (rev 25288)
@@ -15,7 +15,8 @@
 
 $Id$
 """
-from difflib import ndiff
+from difflib import SequenceMatcher
+from string import split, join
 
 MAX_OLD_LINES_DISPLAY = 40
 MAX_NEW_LINES_DISPLAY = 40
@@ -30,7 +31,7 @@
 
     old = split(old_text, '\n')
     new = split(new_text, '\n')
-    cruncher=ndiff.SequenceMatcher(
+    cruncher=SequenceMatcher(
         isjunk=lambda x: x in " \\t",
         a=old,
         b=new)
@@ -41,7 +42,7 @@
             if verbose: r.append('??changed:')
             r = r + _abbreviateDiffLines(old[old_lo:old_hi],'-',
                                          MAX_OLD_LINES_DISPLAY)
-            r = r + _abbreviateDiffLines(new[new_lo:new_hi],'',
+            r = r + _abbreviateDiffLines(new[new_lo:new_hi],'+',
                                          MAX_NEW_LINES_DISPLAY)
             r.append('')
         elif tag == 'delete':

Modified: Zope3/trunk/src/zope/app/wiki/interfaces.py
===================================================================
--- Zope3/trunk/src/zope/app/wiki/interfaces.py	2004-06-08 11:05:21 UTC (rev 25287)
+++ Zope3/trunk/src/zope/app/wiki/interfaces.py	2004-06-08 12:11:49 UTC (rev 25288)
@@ -25,6 +25,7 @@
 from zope.app.container.interfaces import IContainer, IContentContainer
 from zope.app.container.constraints import ContainerTypesConstraint
 from zope.app.container.constraints import ItemTypePrecondition
+from zope.app.event.interfaces import IObjectEvent
 from zope.app.i18n import ZopeMessageIDFactory as _ 
 
 class IComment(Interface):
@@ -140,6 +141,17 @@
         constraint = ContainerTypesConstraint(IWiki))
 
 
+class IWikiPageEditEvent(IObjectEvent):
+    """ an object event containing the old source in addition
+    to the changed object
+    """
+
+    oldSource = SourceText(
+        title=_(u"Previous Source Text"),
+        description=_(u"Previous source text of the Wiki Page."),
+        default=u"",
+        required=True)
+
 class IMailSubscriptions(Interface):
     """This interface allows you to retrieve a list of E-mails for
     mailings. In our context """

Modified: Zope3/trunk/src/zope/app/wiki/tests/test_wikimail.py
===================================================================
--- Zope3/trunk/src/zope/app/wiki/tests/test_wikimail.py	2004-06-08 11:05:21 UTC (rev 25287)
+++ Zope3/trunk/src/zope/app/wiki/tests/test_wikimail.py	2004-06-08 12:11:49 UTC (rev 25288)
@@ -17,6 +17,7 @@
 """
 import unittest
 
+from zope.event import subscribers
 from zope.interface import classImplements, implements 
 from zope.app.tests import ztapi
 from zope.app.tests.placelesssetup import PlacelessSetup
@@ -27,6 +28,7 @@
 from zope.app.mail.interfaces import IMailDelivery
 
 from zope.app.wiki.interfaces import IWikiPage, IWiki, IMailSubscriptions
+from zope.app.wiki.interfaces import IWikiPageEditEvent
 from zope.app.wiki.wikipage import WikiPage
 from zope.app.wiki.wikipage import MailSubscriptions, WikiMailer, mailer
 from zope.app.wiki.wiki import Wiki
@@ -108,10 +110,6 @@
 
 class WikiMailerTest(PlacefulSetup, unittest.TestCase):
 
-    # Note: There are several other methods in this class, but they require
-    #       mail to be sent out. One way to still write tests for these would
-    #       be to implement a dummy smtplib.SMTP class...not now though. ;)
-
     def setUp(self):
         PlacefulSetup.setUp(self)
         # This needs to be done, since the IAttributeAnnotable interface
@@ -127,7 +125,12 @@
         delivery = MailDeliveryStub()
         ztapi.provideUtility(IMailDelivery, delivery,
                              name='wiki-delivery')
+        subscribers.append(mailer)
 
+    def tearDown(self):
+        mail_result=[]
+        subscribers.remove(mailer)
+
     def test_getAllSubscribers(self):
         wiki = Wiki()
         wiki_sub = MailSubscriptions(wiki)
@@ -150,13 +153,23 @@
         page_sub.context.__annotations__[SubscriberKey] = ('blah at bar.com',)
         wiki['page1'] = page
         page.source = 'Hello World!'
-        event = ObjectModifiedEvent(page)
-        mailer(event)
         self.assertEqual('wiki at zope3.org', 
-                         mail_result[0][0])
-        self.assertEqual(('blah at bar.com', 'foo at bar.com'), mail_result[0][1])
-        self.assertEqual('Subject: Modified: page1\n\n\nHello World!',
-                         mail_result[0][2])
+                         mail_result[-1][0])
+        self.assertEqual(('blah at bar.com', 'foo at bar.com'), mail_result[-1][1])
+        self.assertEqual(
+            u'''Subject: Modified: page1\n\n\n\n??changed:\n'''
+            u'''-\n'''
+            u'''+Hello World!\n''',
+            mail_result[-1][2])
+        page.source = 'Hello New World!'
+        self.assertEqual('wiki at zope3.org', 
+                         mail_result[-1][0])
+        self.assertEqual(('blah at bar.com', 'foo at bar.com'), mail_result[-1][1])
+        self.assertEqual(
+            u'''Subject: Modified: page1\n\n\n\n??changed:\n'''
+            u'''-Hello World!\n'''
+            u'''+Hello New World!\n''',
+            mail_result[-1][2])
   
 
 

Modified: Zope3/trunk/src/zope/app/wiki/wikipage.py
===================================================================
--- Zope3/trunk/src/zope/app/wiki/wikipage.py	2004-06-08 11:05:21 UTC (rev 25287)
+++ Zope3/trunk/src/zope/app/wiki/wikipage.py	2004-06-08 12:11:49 UTC (rev 25288)
@@ -15,24 +15,26 @@
 
 $Id$
 """
-import smtplib
 from persistent import Persistent
 
 from zope.interface import implements
+from zope.event import notify
 
 from zope.app import zapi
 from zope.app.container.btree import BTreeContainer
 from zope.app.dublincore.interfaces import ICMFDublinCore
 from zope.app.filerepresentation.interfaces import IReadFile, IWriteFile
 from zope.app.annotation.interfaces import IAnnotations
-from zope.app.event.interfaces import IObjectModifiedEvent
+from zope.app.event.objectevent import ObjectEvent
 from zope.app.container.interfaces import \
-     IObjectAddedEvent, IObjectRemovedEvent, IObjectMovedEvent
+     IObjectAddedEvent, IObjectRemovedEvent
 from zope.app.mail.interfaces import IMailDelivery
 
 from zope.app.wiki.interfaces import IWiki, IWikiPage, IComment
 from zope.app.wiki.interfaces import IWikiContained, IWikiPageContained
 from zope.app.wiki.interfaces import IWikiPageHierarchy, IMailSubscriptions
+from zope.app.wiki.interfaces import IWikiPageEditEvent
+from zope.app.wiki.diff import textdiff
 
 __metaclass__ = type
 
@@ -48,9 +50,21 @@
     # See zope.app.container.interfaces.IContained
     __parent__ = __name__ = None
 
+    def __init__(self, source=u''):
+        super(WikiPage, self).__init__()
+        self._source = source
+
+    def _getSource(self):
+        return self._source
+
+    def _setSource(self, source):
+        old_source = self._source 
+        self._source = source
+        notify(WikiPageEditEvent(self, old_source))
+
     # See zope.app.wiki.interfaces.IWikiPage
-    source = u''
-    
+    source = property(_getSource, _setSource)
+
     # See zope.app.wiki.interfaces.IWikiPage
     type = u'zope.source.rest'
 
@@ -167,6 +181,17 @@
         self.context.source = unicode(data)
 
 
+# An edit event containing the source before the update
+
+class WikiPageEditEvent(ObjectEvent):
+    implements(IWikiPageEditEvent)
+
+    oldSource = u''
+
+    def __init__(self, object, old_source):
+        super(WikiPageEditEvent, self).__init__(object)
+        self.oldSource = old_source
+
 # Component to fullfill mail subscriptions
 
 class MailSubscriptions:
@@ -208,19 +233,14 @@
 class WikiMailer:
     """Class to handle all outgoing mail."""
 
-    def __init__(self, host="localhost", port="25"):
-        """Initialize the the object.""" 
-        self.host = host
-        self.port = port
-
     def __call__(self, event):
         # XXX event handling should be separated from mailing
         if IWikiPage.providedBy(event.object):
             if IObjectAddedEvent.providedBy(event):
                 self.handleAdded(event.object)
 
-            elif IObjectModifiedEvent.providedBy(event):
-                self.handleModified(event.object)
+            elif IWikiPageEditEvent.providedBy(event):
+                self.handleModified(event)
 
             elif IObjectRemovedEvent.providedBy(event):
                 self.handleRemoved(event.object)
@@ -231,13 +251,13 @@
         body = object.source
         self.mail(emails, subject, body)        
 
-    def handleModified(self, object):
-        # XXX: Should have some nice diff code here.
-        # from diff import textdiff
-        subject = 'Modified: '+zapi.name(object)
-        emails = self.getAllSubscribers(object)
-        body = object.source
-        self.mail(emails, subject, body)
+    def handleModified(self, event):
+        object = event.object
+        if zapi.name(object) is not None:
+            subject = 'Modified: '+zapi.name(object)
+            emails = self.getAllSubscribers(object)
+            body = textdiff(event.oldSource, object.source)
+            self.mail(emails, subject, body)
 
     def handleRemoved(self, object):
         subject = 'Removed: '+zapi.name(object)




More information about the Zope3-Checkins mailing list