[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