1
# -*- coding: iso-8859-1 -*-
3
MoinMoin - event (notification) framework
5
This code abstracts event handling in MoinMoin,
6
currently for notifications. It implements the observer pattern.
8
@copyright: 2007 by Karol Nowak <grywacz@gmail.com>
9
@license: GNU GPL, see COPYING for details.
12
from MoinMoin import log
13
logging = log.getLogger(__name__)
15
from MoinMoin import wikiutil
16
from MoinMoin.util import pysupport
17
from MoinMoin.wikiutil import PluginAttributeError
19
# Create a list of extension actions from the package directory
20
modules = pysupport.getPackageModules(__file__)
22
# Dummy pseudo-getText function used in event descriptions,
23
# so that they get into .po files
28
"""A class handling information common to all events."""
30
# NOTE: each Event subclass must have a unique name attribute
33
def __init__(self, request):
34
self.request = request
37
class PageEvent(Event):
38
"""An event related to a page change"""
42
def __init__(self, request):
43
Event.__init__(self, request)
46
class PageChangedEvent(PageEvent):
48
name = u"PageChangedEvent"
49
description = _(u"""Page has been modified""")
52
def __init__(self, request, page, comment):
53
PageEvent.__init__(self, request)
55
self.comment = comment
58
class TrivialPageChangedEvent(PageEvent):
60
name = u"TrivialPageChangedEvent"
61
description = _(u"Page has been modified in a trivial fashion")
64
def __init__(self, request, page, comment):
65
PageEvent.__init__(self, request)
67
self.comment = comment
70
class PageRenamedEvent(PageEvent):
72
name = u"PageRenamedEvent"
73
description = _(u"""Page has been renamed""")
76
def __init__(self, request, page, old_page, comment=""):
77
PageEvent.__init__(self, request)
79
self.old_page = old_page
80
self.comment = comment
83
class PageDeletedEvent(PageEvent):
85
name = u"PageDeletedEvent"
86
description = _(u"""Page has been deleted""")
89
def __init__(self, request, page, comment):
90
PageEvent.__init__(self, request)
92
self.comment = comment
95
class PageCopiedEvent(PageEvent):
97
name = u"PageCopiedEvent"
98
description = _(u"""Page has been copied""")
101
def __init__(self, request, page, old_page, comment):
102
PageEvent.__init__(self, request)
104
self.old_page = old_page
105
self.comment = comment
108
class FileAttachedEvent(PageEvent):
110
name = u"FileAttachedEvent"
111
description = _(u"""A new attachment has been added""")
112
req_superuser = False
114
def __init__(self, request, pagename, filename, size):
115
PageEvent.__init__(self, request)
116
self.request = request
117
self.pagename = pagename
118
self.filename = filename
122
class PageRevertedEvent(PageEvent):
124
name = u"PageRevertedEvent"
125
description = _(u"""A page has been reverted to a previous state""")
126
req_superuser = False
128
def __init__(self, request, pagename, previous, current):
129
PageEvent.__init__(self, request)
130
self.pagename = pagename
131
self.previous = previous
132
self.current = current
135
class SubscribedToPageEvent(PageEvent):
137
name = u"SubscribedToPageEvent"
138
description = _(u"""A user has subscribed to a page""")
141
def __init__(self, request, pagename, username):
142
PageEvent.__init__(self, request)
143
self.pagename = pagename
144
self.username = username
147
class JabberIDSetEvent(Event):
148
""" Sent when user changes her Jabber ID """
150
def __init__(self, request, jid):
151
Event.__init__(self, request)
154
class JabberIDUnsetEvent(Event):
155
""" Sent when Jabber ID is no longer used
157
Obviously this will be usually sent along with JabberIDSetEvent,
158
because we require user's jabber id to be unique by default.
161
def __init__(self, request, jid):
162
Event.__init__(self, request)
165
class UserCreatedEvent(Event):
166
""" Sent when a new user has been created """
168
name = u"UserCreatedEvent"
169
description = _(u"""A new account has been created""")
172
def __init__(self, request, user):
173
Event.__init__(self, request)
176
class PagePreSaveEvent(Event):
177
""" Event sent when a page is about to be saved
179
This can be used to abort a save, for instance,
184
name = u"PagePreSaveEvent"
186
def __init__(self, request, page_editor, new_text):
187
Event.__init__(self, request)
188
self.page_editor = page_editor
189
self.new_text = new_text
193
""" This is a base class for messages passed from event handlers """
196
class Abort(EventResult):
197
""" Result returned if handler wants to abort operation that sent the event """
198
def __init__(self, reason):
200
@param reason: human-readable reason of failure
205
def get_handlers(cfg):
206
"""Create a list of available event handlers.
208
Each handler is a handle() function defined in an plugin,
209
pretty much like in case of actions.
211
TODO: maybe make it less dumb? ;-)
215
names = wikiutil.getPlugins("events", cfg)
219
handler = wikiutil.importPlugin(cfg, "events", name, "handle")
220
except PluginAttributeError:
223
if handler is not None:
224
event_handlers.append(handler)
226
return event_handlers
229
def send_event(event):
230
"""Function called from outside to process an event
232
@return: a list of messages returned by handlers
236
# A list of messages generated by event handlers, passed back to caller
238
cfg = event.request.cfg
240
# Try to handle the event with each available handler (for now)
241
for handle in cfg.event_handlers:
242
retval = handle(event)
244
assert retval is None or isinstance(retval, EventResult)
251
def get_subscribable_events():
252
"""Create and return a list of user-visible events
254
@return: A list of user-visible events described by dictionaries
258
subscribable_events = {}
260
for ev in defs.values():
261
if type(ev) is type and issubclass(ev, Event) and ev.__dict__.has_key("description") and ev.__dict__.has_key("name"):
262
subscribable_events[ev.name] = {'desc': ev.description, 'superuser': ev.req_superuser}
264
return subscribable_events
266
# Get rid of the dummy getText so that it doesn't get imported with *