[Zope3-checkins] CVS: Zope3/src/zope/event - __init__.py:1.2 eventchannel.py:1.2 subscribable.py:1.2

Jim Fulton jim@zope.com
Wed, 25 Dec 2002 09:14:08 -0500


Update of /cvs-repository/Zope3/src/zope/event
In directory cvs.zope.org:/tmp/cvs-serv15352/src/zope/event

Added Files:
	__init__.py eventchannel.py subscribable.py 
Log Message:
Grand renaming:

- Renamed most files (especially python modules) to lower case.

- Moved views and interfaces into separate hierarchies within each
  project, where each top-level directory under the zope package
  is a separate project.

- Moved everything to src from lib/python.

  lib/python will eventually go away. I need access to the cvs
  repository to make this happen, however.

There are probably some bits that are broken. All tests pass
and zope runs, but I haven't tried everything. There are a number
of cleanups I'll work on tomorrow.



=== Zope3/src/zope/event/__init__.py 1.1 => 1.2 ===
--- /dev/null	Wed Dec 25 09:14:08 2002
+++ Zope3/src/zope/event/__init__.py	Wed Dec 25 09:13:37 2002
@@ -0,0 +1,52 @@
+##############################################################################
+#
+# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""
+
+Revision information:
+$Id$
+"""
+
+from zope.component import getService
+from zope.interfaces.event import IEvent
+
+
+def getEventService(context):
+    return getService(context, 'Events')
+
+def publish(context, event):
+    return getEventService(context).publish(event)
+
+def subscribe(subscriber, event_type=IEvent, filter=None, context=None):
+    if context is None:
+        context = subscriber
+    return getEventService(context).subscribe(
+        subscriber, event_type, filter)
+
+def subscribeMany(subscriber, event_types=(IEvent,),
+                  filter=None, context=None):
+    if context is None:
+        context = subscriber
+    subscribe = getEventService(context).subscribe
+    for event_type in event_types:
+        subscribe(subscriber, event_type, filter)
+
+def unsubscribe(subscriber, event_type=None, filter=None, context=None):
+    if context is None: context=subscriber
+    return getEventService(context).unsubscribe(
+        subscriber, event_type, filter)
+
+def listSubscriptions(subscriber, event_type=None, context=None):
+    if context is None: context=subscriber
+    return getEventService(context).listSubscriptions(
+        subscriber, event_type)


=== Zope3/src/zope/event/eventchannel.py 1.1 => 1.2 ===
--- /dev/null	Wed Dec 25 09:14:08 2002
+++ Zope3/src/zope/event/eventchannel.py	Wed Dec 25 09:13:37 2002
@@ -0,0 +1,34 @@
+##############################################################################
+#
+# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""
+
+Revision information:
+$Id$
+"""
+
+from zope.event.subscribable import Subscribable
+from zope.interfaces.event import IEventChannel
+
+class EventChannel(Subscribable):
+
+    __implements__ = IEventChannel
+
+    def notify(self, event):
+
+        for subscriptions in self.subscriptionsForEvent(event):
+
+            for subscriber, filter in subscriptions:
+                if filter is not None and not filter(event):
+                    continue
+                subscriber.notify(event)


=== Zope3/src/zope/event/subscribable.py 1.1 => 1.2 ===
--- /dev/null	Wed Dec 25 09:14:08 2002
+++ Zope3/src/zope/event/subscribable.py	Wed Dec 25 09:13:37 2002
@@ -0,0 +1,152 @@
+##############################################################################
+#
+# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""
+
+Revision information:
+$Id$
+"""
+__metaclass__ = type
+
+from zope.interface.type import TypeRegistry
+from zope.exceptions import NotFoundError
+from zope.interfaces.event import ISubscribable
+from zope.interfaces.event import ISubscriptionAware
+from zope.interfaces.event import IEvent
+from zope.proxy.introspection import removeAllProxies
+
+class Subscribable:
+    """a global mix-in"""
+
+    __implements__ = ISubscribable
+        # plus has subscriptionsForEvent
+
+    def __init__(self):
+        self._registry = TypeRegistry()
+        self._subscribers = [] # using a list rather than a dict so
+        # that subscribers may define custom __eq__ methods
+
+    _clear = __init__
+
+    def subscribe(self, subscriber, event_type=IEvent, filter=None):
+        clean_subscriber = removeAllProxies(subscriber)
+
+        if ISubscriptionAware.isImplementedBy(subscriber):
+            subscriber.subscribedTo(self, event_type, filter)
+
+        if event_type is IEvent:
+            event_type = None # optimization
+
+        subscribers = self._registry.setdefault(event_type, [])
+        subscribers.append((clean_subscriber, filter))
+
+        for sub in self._subscribers:
+            if sub[0] == clean_subscriber:
+                sub[1][event_type] = 1
+                break
+        else:
+            self._subscribers.append((clean_subscriber, {event_type: 1}))
+
+        self._registry = self._registry #trigger persistence, if pertinent
+
+
+    def unsubscribe(self, subscriber, event_type=None, filter=None):
+
+        clean_subscriber=removeAllProxies(subscriber)
+
+        for subscriber_index in range(len(self._subscribers)):
+            sub=self._subscribers[subscriber_index]
+            if sub[0]==clean_subscriber:
+                ev_set=sub[1]
+                break
+        else:
+            if event_type: raise NotFoundError(subscriber)
+            else: return # this was a generic unsubscribe all request;
+            # work may have been done by a local service
+
+
+        do_alert=ISubscriptionAware.isImplementedBy(clean_subscriber)
+
+        if event_type:
+            ev_type=event_type
+            if event_type is IEvent:
+                ev_type=None # handle optimization
+            if ev_type not in ev_set:
+                raise NotFoundError(subscriber, event_type, filter)
+            subscriptions = self._registry.get(ev_type)
+            if not subscriptions:
+                raise NotFoundError(subscriber, event_type, filter)
+            try:
+                subscriptions.remove((clean_subscriber, filter))
+            except ValueError:
+                raise NotFoundError(subscriber, event_type, filter)
+            if do_alert:
+                subscriber.unsubscribedFrom(self, event_type, filter)
+            if len(ev_set)==1:
+                for sub in subscriptions:
+                    if sub[0]==clean_subscriber:
+                        break
+                else:
+                    del self._subscribers[subscriber_index]
+        else:
+            for ev_type in ev_set:
+                subscriptions = self._registry.get(ev_type)
+                subs=subscriptions[:]
+                subscriptions[:] = []
+                for sub in subs:
+                    if sub[0] == clean_subscriber: # deleted (not added back)
+                        if do_alert:
+                            subscriber.unsubscribedFrom(
+                                self, ev_type or IEvent, sub[1])
+                            # IEvent switch is to make optimization transparent
+                    else: # kept (added back)
+                        subscriptions.append(sub)
+            del self._subscribers[subscriber_index]
+        self._registry=self._registry #trigger persistence, if pertinent
+
+    def subscriptionsForEvent(self, event):
+        # XXX currently a non-interface method:
+        # just a more readable prettification
+        # used only for notify methods now.  Could this be replaced
+        # with an explanatory comment in the code that uses it?
+        return self._registry.getAllForObject(event)
+
+    def listSubscriptions(self, subscriber, event_type=None):
+
+        subscriber=removeAllProxies(subscriber)
+
+        result=[]
+        if event_type:
+            ev_type=event_type
+            if event_type is IEvent:
+                ev_type=None # handle optimization
+            subscriptions = self._registry.get(ev_type)
+            if subscriptions:
+                for sub in subscriptions:
+                    if sub[0]==subscriber:
+                        result.append((event_type, sub[1]))
+        else:
+            for subscriber_index in range(len(self._subscribers)):
+                sub=self._subscribers[subscriber_index]
+                if sub[0]==subscriber:
+                    ev_set=sub[1]
+                    break
+            else:
+                return result
+            for ev_type in ev_set:
+                subscriptions = self._registry.get(ev_type)
+                if subscriptions:
+                    for sub in subscriptions:
+                        if sub[0]==subscriber:
+                            result.append((ev_type or IEvent, sub[1]))
+        return result