Back to index

moin  1.9.0~rc2
jabbernotify.py
Go to the documentation of this file.
00001 # -*- coding: iso-8859-1 -*-
00002 """
00003     MoinMoin - jabber notification plugin for event system
00004 
00005     This code sends notifications using a separate daemon.
00006 
00007     @copyright: 2007 by Karol Nowak <grywacz@gmail.com>
00008     @license: GNU GPL, see COPYING for details.
00009 """
00010 
00011 import xmlrpclib
00012 
00013 from MoinMoin import log
00014 logging = log.getLogger(__name__)
00015 
00016 from MoinMoin.Page import Page
00017 from MoinMoin.user import User, getUserList
00018 from MoinMoin.support.python_compatibility import set
00019 from MoinMoin.action.AttachFile import getAttachUrl
00020 
00021 import MoinMoin.events.notification as notification
00022 import MoinMoin.events as ev
00023 
00024 
00025 def handle(event):
00026     """An event handler"""
00027 
00028     cfg = event.request.cfg
00029 
00030     # Check for desired event type and if notification bot is configured
00031     if not cfg.jabber_enabled:
00032         return
00033 
00034     if isinstance(event, (ev.PageChangedEvent, ev.TrivialPageChangedEvent)):
00035         return handle_page_changed(event)
00036     elif isinstance(event, (ev.JabberIDSetEvent, ev.JabberIDUnsetEvent)):
00037         return handle_jid_changed(event)
00038     elif isinstance(event, ev.FileAttachedEvent):
00039         return handle_file_attached(event)
00040     # TODO (needs also corresponding changes in xmppbot + testing)
00041     #elif isinstance(event, ev.FileRemovedEvent):
00042     #    return handle_file_removed(event)
00043     elif isinstance(event, ev.PageDeletedEvent):
00044         return handle_page_deleted(event)
00045     elif isinstance(event, ev.PageRenamedEvent):
00046         return handle_page_renamed(event)
00047     elif isinstance(event, ev.UserCreatedEvent):
00048         return handle_user_created(event)
00049 
00050 
00051 def handle_jid_changed(event):
00052     """ Handles events sent when user's JID changes """
00053 
00054     request = event.request
00055     server = request.cfg.notification_server
00056     secret = request.cfg.secrets['jabberbot']
00057     try:
00058         if isinstance(event, ev.JabberIDSetEvent):
00059             server.addJIDToRoster(secret, event.jid)
00060         else:
00061             server.removeJIDFromRoster(secret, event.jid)
00062     except xmlrpclib.Error, err:
00063         logging.error("XML RPC error: %s" % str(err))
00064     except Exception, err:
00065         logging.error("Low-level communication error: %s" % str(err))
00066 
00067 
00068 def handle_file_attached(event):
00069     """Handles event sent when a file is attached to a page"""
00070 
00071     names = set()
00072     request = event.request
00073     page = Page(request, event.pagename)
00074     subscribers = page.getSubscribers(request, return_users=1)
00075     notification.filter_subscriber_list(event, subscribers, True)
00076     recipients = []
00077 
00078     for lang in subscribers:
00079         recipients.extend(subscribers[lang])
00080 
00081     attachlink = request.getQualifiedURL(getAttachUrl(event.pagename, event.filename, request))
00082     pagelink = request.getQualifiedURL(page.url(request, {}))
00083 
00084     for lang in subscribers.keys():
00085         _ = lambda text: request.getText(text, lang=lang)
00086         data = notification.attachment_added(request, _, event.pagename, event.filename, event.size)
00087         links = [{'url': attachlink, 'description': _("Attachment link")},
00088                   {'url': pagelink, 'description': _("Page link")}]
00089 
00090         jids = [usr.jid for usr in subscribers[lang]]
00091         data['url_list'] = links
00092         data['action'] = "file_attached"
00093 
00094         if send_notification(request, jids, data):
00095             names.update(recipients)
00096 
00097     return notification.Success(names)
00098 
00099 
00100 def handle_page_changed(event):
00101     """ Handles events related to page changes """
00102     request = event.request
00103     page = event.page
00104 
00105     subscribers = page.getSubscribers(request, return_users=1)
00106     notification.filter_subscriber_list(event, subscribers, True)
00107     return page_change("page_changed", request, page, subscribers, \
00108                        revisions=page.getRevList(), comment=event.comment)
00109 
00110 
00111 def handle_page_deleted(event):
00112     """Handles event sent when a page is deleted"""
00113 
00114     request = event.request
00115     page = event.page
00116 
00117     subscribers = page.getSubscribers(request, return_users=1)
00118     notification.filter_subscriber_list(event, subscribers, True)
00119     return page_change("page_deleted", request, page, subscribers)
00120 
00121 
00122 def handle_page_renamed(event):
00123     """Handles event sent when a page is renamed"""
00124 
00125     request = event.request
00126     page = event.page
00127     old_name = event.old_page.page_name
00128 
00129     subscribers = page.getSubscribers(request, return_users=1)
00130 
00131     # Change request's page so that we filter subscribers of the OLD page
00132     request.page = event.old_page
00133     notification.filter_subscriber_list(event, subscribers, True)
00134     request.page = page
00135     return page_change("page_renamed", request, page, subscribers, old_name=old_name)
00136 
00137 
00138 def handle_user_created(event):
00139     """Handles an event sent when a new user is being created"""
00140     request = event.request
00141     sitename = request.cfg.sitename
00142     event_name = event.name
00143     email = event.user.email or u"NOT SET"
00144     username = event.user.name
00145 
00146     user_ids = getUserList(request)
00147     for id in user_ids:
00148         usr = User(request, id=id)
00149         # Currently send this only to super users
00150         if usr.isSuperUser() and usr.jid and event_name in usr.jabber_subscribed_events:
00151             _ = lambda text: request.getText(text, lang=usr.language or 'en')
00152             msg = notification.user_created_message(request, _, sitename, username, email)
00153             data = {'action': "user_created", 'subject': msg['subject'], 'text': msg['text'],
00154                     'url_list': []}
00155             send_notification(request, [usr.jid], data)
00156 
00157 
00158 def page_change(change_type, request, page, subscribers, **kwargs):
00159     """Sends notification about page being changed in some way"""
00160 
00161     # send notifications to all subscribers
00162     if subscribers:
00163         recipients = set()
00164 
00165         for lang in subscribers:
00166             _ = lambda text: request.getText(text, lang=lang)
00167             jids = [u.jid for u in subscribers[lang] if u.jid]
00168             names = [u.name for u in subscribers[lang] if u.jid]
00169             msg = notification.page_change_message(change_type, request, page, lang, **kwargs)
00170             page_url = request.getQualifiedURL(page.url(request))
00171             url = {'url': page_url, 'description': _("Changed page")}
00172             data = {'action': change_type, 'subject': _('Page changed'),
00173                             'url_list': [url], 'text': msg['text'], 'diff': msg.get('diff', ''),
00174                             'comment': msg.get('comment', ''), 'editor': msg['editor'],
00175                             'old_name': msg.get('old_name', ''), 'page_name': msg.get('page_name', ''),
00176                             'revision': msg.get('revision', '')}
00177 
00178             result = send_notification(request, jids, data)
00179 
00180             if result:
00181                 recipients.update(names)
00182 
00183         if recipients:
00184             return notification.Success(recipients)
00185 
00186 
00187 def send_notification(request, jids, notification):
00188     """ Send notifications for a single language.
00189 
00190     @param jids: an iterable of Jabber IDs to send the message to
00191     @param message: message text
00192     @param subject: subject of the message, makes little sense for chats
00193     @param url_list: a list of dicts containing URLs and their descriptions
00194     @type url_list: list
00195 
00196     """
00197     server = request.cfg.notification_server
00198 
00199     if type(notification) != dict:
00200         raise ValueError("notification must be of type dict!")
00201 
00202     if type(notification['url_list']) != list:
00203         raise ValueError("url_list must be of type list!")
00204 
00205     try:
00206         server.send_notification(request.cfg.secrets['jabberbot'], jids, notification)
00207         return True
00208     except xmlrpclib.Error, err:
00209         logging.error("XML RPC error: %s" % str(err))
00210     except Exception, err:
00211         logging.error("Low-level communication error: %s" % str(err))
00212