""" Event.py
Module for dispatching Straw-related events.
"""
__copyright__ = "Copyright (c) 2002-2005 Free Software Foundation, Inc."
__license__ = """ GNU General Public License
This program is free software; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any later
version.
This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place - Suite 330, Boston, MA 02111-1307, USA. """
import traceback
import sys
import error
_base_cache = dict()
def find_bases(klass):
def _find_bases(klass, d = None):
if d is None:
d = dict()
for b in klass.__bases__:
if issubclass(b, BaseSignal):
d[b] = 1
_find_bases(b, d)
return tuple(d.keys())
bases = _base_cache.get(klass, None)
if bases is not None:
return bases
bases = _find_bases(klass)
_base_cache[klass] = bases
return bases
class BaseSignal:
def __init__(self, sender):
self.sender = sender
return
class SignalEmitter:
recorder = None
"""Base class for signal emitters"""
def __init__(self):
self._slots = dict()
def initialize_slots(self, *signals):
"""Initialize signal slots.
signals should be a list of signals this emitter is going to send."""
for s in signals:
self._slots[s] = dict()
bs = find_bases(s)
for k in bs:
self._slots[k] = dict()
def signal_connect(self, signal, handler, data=None):
"""Connect a handler to a signal in this emitter, and associate
data with the callback. This will override previous bindings of
signal to handler."""
self._slots[signal][handler] = data
return
def signal_disconnect(self, signal, handler):
"""Disconnect handler from signal."""
self._slots[signal][handler] = None
del self._slots[signal][handler]
return
def emit_signal(self, signal):
"""Emit a signal object. Signal should be an instance of BaseSignal or
a subclass."""
sclasses = find_bases(signal.__class__)
for sc in sclasses + (signal.__class__,):
for handler, data in self._slots.get(sc, {}).items():
if data is not None:
args = (signal, data)
else:
args = (signal,)
try:
#if self.recorder is not None:
# self.recorder.record(sc, handler)
apply(handler, args)
except:
error.log_exc("Caught an exception when trying to "
"call a signal handler for "
"signal %s\n" %
str(signal))
traceback.print_exc()
"""
def start_recording(klass, recorder):
klass.recorder = recorder
start_recording = classmethod(start_recording)
def stop_recording(klass):
if klass.recorder is not None:
klass.recorder.stop()
klass.recorder = None
stop_recording = classmethod(stop_recording)
"""
# Feed creation and feed list management events
class FeedsChangedSignal(BaseSignal):
def __init__(self, sender, feed=None):
BaseSignal.__init__(self, sender)
self.feed = feed
class FeedsEmptySignal(BaseSignal):
pass
class FeedsImportedSignal(FeedsChangedSignal):
"""
A signal for importing huge amount of feeds from OPML.
"""
def __init__(self, sender, feeds,
parent=None, from_sub=False):
FeedsChangedSignal.__init__(self, sender)
self.feeds = feeds
self.category = parent
self.from_sub = from_sub
class FeedDeletedSignal(FeedsChangedSignal):
def __init__(self, sender, feed):
FeedsChangedSignal.__init__(self, sender, feed)
self.feed = feed
class FeedCreatedSignal(FeedsChangedSignal):
def __init__(self, sender, feed, category=None, index=None):
FeedsChangedSignal.__init__(self, sender)
self.feed = feed
self.category = category
self.index = index
# Feed detail Specific
class FeedDetailChangedSignal(BaseSignal):
def __init__(self, sender):
BaseSignal.__init__(self, sender)
class ItemOrderChangedSignal(FeedDetailChangedSignal):
pass
class FeedPollFrequencyChangedSignal(FeedDetailChangedSignal):
def __init__(self, sender):
BaseSignal.__init__(self, sender)
class FeedNumOfItemsStoredChangedSignal(FeedDetailChangedSignal):
def __init__(self, sender):
BaseSignal.__init__(self, sender)
class FeedErrorStatusChangedSignal(FeedDetailChangedSignal):
pass
class FeedInfoUpdatedSignal(FeedDetailChangedSignal):
"""
Feed information like title, description, copyright, etc...
"""
def __init__(self, sender):
BaseSignal.__init__(self, sender)
class FeedUnreadChangedSignal(FeedDetailChangedSignal):
def __init__(self, sender):
BaseSignal.__init__(self, sender)
# Feed category specific
class FeedCategoriesChangedSignal(BaseSignal):
pass
class FeedCategoryListChangedSignal(FeedCategoriesChangedSignal):
pass
class FeedCategoryListLoadedSignal(FeedCategoriesChangedSignal):
pass
class FeedCategoryAddedSignal(FeedCategoryListChangedSignal):
def __init__(self, sender, category):
FeedCategoryListChangedSignal.__init__(self, sender)
self.category = category
class FeedCategoryRemovedSignal(FeedCategoryListChangedSignal):
def __init__(self, sender, category):
FeedCategoryListChangedSignal.__init__(self, sender)
self.category = category
class FeedCategoryChangedSignal(FeedCategoriesChangedSignal):
""" Called when a Feed Category was modified (i.e. feed added, feed
removed, category title changed, etc...
"""
def __init__(self, sender, feed=None):
FeedCategoriesChangedSignal.__init__(self, sender)
self.feed = feed
class FeedCategorySortedSignal(FeedCategoryChangedSignal):
""" Called when a Feed Category has been sorted. """
def __init__(self, sender, reverse=False):
FeedCategoryChangedSignal.__init__(self, sender)
self.descending = reverse
class SubscriptionContentsUpdatedSignal(BaseSignal):
pass
# Item specific
class ItemsAddedSignal(BaseSignal):
def __init__(self, sender, items):
BaseSignal.__init__(self, sender)
self.items = items
class ItemDeletedSignal(BaseSignal):
def __init__(self, sender, item):
BaseSignal.__init__(self, sender)
self.item = item
class NewItemsSignal(BaseSignal):
def __init__(self, sender, items):
BaseSignal.__init__(self, sender)
self.items = items
class ItemStickySignal(BaseSignal):
def __init__(self, sender, item=None):
BaseSignal.__init__(self, sender)
if item is None:
item = sender
self.item = item
class AllItemsReadSignal(BaseSignal):
def __init__(self, sender, changed):
BaseSignal.__init__(self, sender)
self.changed = changed
# Other events ...
class FeedLastPollChangedSignal(BaseSignal):
pass
class PollChangedSignal(BaseSignal):
def __init__(self, sender):
BaseSignal.__init__(self, sender)
class FeedPolledSignal(BaseSignal):
pass
class FeedStatusChangedSignal(BaseSignal):
"""
Provides a signal for denoting that the polling process
has begun or finished.
"""
pass
class ImageUpdatedSignal(BaseSignal):
def __init__(self, sender, url, data):
BaseSignal.__init__(self, sender)
self.url = url
self.data = data
class NumberOfItemsStoredChangedSignal(BaseSignal):
pass
class PollFrequencyChangedSignal(PollChangedSignal):
""" Global poll frequency """
def __init__(self, sender, value):
PollChangedSignal.__init__(self, sender)
self.value = value
class PollingStoppedSignal(BaseSignal):
pass
class FeedSelectionChangedSignal(BaseSignal):
"""
Emitted when a feed has been selected in the feeds tree view.
"""
def __init__(self, sender, old, new):
BaseSignal.__init__(self, sender)
self.old = old
self.new = new
class ItemSelectionChangedSignal(BaseSignal):
""" Called when an item has been selected in the item list.
Normally this should display the content of the item
"""
def __init__(self, sender, item):
BaseSignal.__init__(self, sender)
self.item = item
class ItemReadSignal(BaseSignal):
""" Called when an item's 'seen' property has been changed
(i.e. marked as read)
"""
def __init__(self, sender, item=None):
BaseSignal.__init__(self, sender)
if item is None:
item = sender
self.item = item
class CategorySelectionChangedSignal(BaseSignal):
"""
Emitted when a the user changes categories
"""
def __init__(self, sender, newcat):
BaseSignal.__init__(self, sender)
self.current = newcat
class OfflineModeChangedSignal(BaseSignal):
pass
class RefreshFeedDisplaySignal(BaseSignal):
pass
class StatusDisplaySignal(BaseSignal):
pass
class FindInterruptSignal(BaseSignal):
pass
if __name__ == '__main__':
print find_bases(ItemReadSignal)
syntax highlighted by Code2HTML, v. 0.9.1