1# -*- coding: iso-8859-1 -*-
2"""
3    MoinMoin - common functions for notification framework
4
5    Code for building messages informing about events (changes)
6    happening in the wiki.
7
8    @copyright: 2007 by Karol Nowak <grywacz@gmail.com>
9    @license: GNU GPL, see COPYING for details.
10"""
11
12from MoinMoin import user, wikiutil
13from MoinMoin.events import EventResult
14
15
16class Result(EventResult):
17    """ A base class for results of notification handlers"""
18    pass
19
20
21class Failure(Result):
22    """ Used to report a failure in sending notifications """
23    def __init__(self, reason, recipients = None):
24        """
25        @param recipients: a set of recipients
26        @type recipients: set
27        """
28        self.reason = reason
29        self.recipient = None
30
31    def __str__(self):
32        return self.reason or u""
33
34
35class Success(Result):
36    """ Used to indicate successfull notifications """
37
38    def __init__(self, recipients):
39        """
40        @param recipients: a set of recipients
41        @type recipients: set
42        """
43        self.recipients = recipients
44
45
46class UnknownChangeType(Exception):
47    """ Used to signal an invalid change event """
48    pass
49
50
51def page_change_message(msgtype, request, page, lang, **kwargs):
52    """Prepare a notification text for a page change of given type
53
54    @param msgtype: a type of message to send (page_changed, page_renamed, ...)
55    @type msgtype: str or unicode
56    @param **kwargs: a dictionary of additional parameters, which depend on msgtype
57
58    @return: dictionary containing data about the changed page
59    @rtype: dict
60
61    """
62    _ = lambda text: request.getText(text, lang=lang)
63    cfg = request.cfg
64    data = {}
65    data['revision'] = str(page.getRevList()[0])
66    data['page_name'] = pagename = page.page_name
67    sitename = page.cfg.sitename or request.url_root
68    data['editor'] = editor = username = page.uid_override or user.getUserIdentification(request)
69
70    trivial = (kwargs.get('trivial') and _("Trivial ")) or ""
71
72    if msgtype == "page_changed":
73        data['subject'] = _(cfg.mail_notify_page_changed_subject) % locals()
74        data['text'] = _(cfg.mail_notify_page_changed_intro) % locals()
75
76        revisions = kwargs['revisions']
77        # append a diff (or append full page text if there is no diff)
78        if len(revisions) < 2:
79            data['diff'] = _("New page:\n") + page.get_raw_body()
80        else:
81            lines = wikiutil.pagediff(request, page.page_name, revisions[1],
82                                      page.page_name, revisions[0])
83            if lines:
84                data['diff'] = '\n'.join(lines)
85            else:
86                data['diff'] = _("No differences found!\n")
87
88    elif msgtype == "page_deleted":
89        data['subject'] = _(cfg.mail_notify_page_deleted_subject) % locals()
90        data['text'] = _(cfg.mail_notify_page_deleted_intro) % locals()
91
92        revisions = kwargs['revisions']
93        latest_existing = revisions[0]
94        lines = wikiutil.pagediff(request, page.page_name, latest_existing,
95                                  page.page_name, latest_existing + 1)
96        if lines:
97            data['diff'] = '\n'.join(lines)
98        else:
99            data['diff'] = _("No differences found!\n")
100
101    elif msgtype == "page_renamed":
102        data['old_name'] = oldname = kwargs['old_name']
103        data['subject'] = _(cfg.mail_notify_page_renamed_subject) % locals()
104        data['text'] = _(cfg.mail_notify_page_renamed_intro) % locals()
105        data['diff'] = ''
106
107    else:
108        raise UnknownChangeType()
109
110    if 'comment' in kwargs and kwargs['comment']:
111        data['comment'] = kwargs['comment']
112
113    return data
114
115
116def user_created_message(request, _, sitename, username, email):
117    """Formats a message used to notify about accounts being created
118
119    @return: a dict containing message body and subject
120    """
121    cfg = request.cfg
122    sitename = sitename or "Wiki"
123    useremail = email
124
125    data = {}
126    data['subject'] = _(cfg.mail_notify_user_created_subject) % locals()
127    data['text'] = _(cfg.mail_notify_user_created_intro) % locals()
128    return data
129
130
131def attachment_added(request, _, page_name, attach_name, attach_size):
132    return _attachment_changed(request, _, page_name, attach_name, attach_size, change="added")
133
134
135def attachment_removed(request, _, page_name, attach_name, attach_size):
136    return _attachment_changed(request, _, page_name, attach_name, attach_size, change="removed")
137
138
139def _attachment_changed(request, _, page_name, attach_name, attach_size, change):
140    """Formats a message used to notify about new / removed attachments
141
142    @param _: a gettext function
143    @return: a dict with notification data
144    """
145    cfg = request.cfg
146    pagename = page_name
147    sitename = cfg.sitename or request.url_root
148    editor = user.getUserIdentification(request)
149    data = {}
150    data['editor'] = editor
151    data['page_name'] = page_name
152    data['attach_size'] = attach_size
153    data['attach_name'] = attach_name
154    if change == "added":
155        data['subject'] = _(cfg.mail_notify_att_added_subject) % locals()
156        data['text'] = _(cfg.mail_notify_att_added_intro) % locals()
157    elif change == "removed":
158        data['subject'] = _(cfg.mail_notify_att_removed_subject) % locals()
159        data['text'] = _(cfg.mail_notify_att_removed_intro) % locals()
160    else:
161        raise UnknownChangeType()
162    return data
163
164
165# XXX: clean up this method to take a notification type instead of bool for_jabber
166def filter_subscriber_list(event, subscribers, for_jabber):
167    """Filter a list of page subscribers to honor event subscriptions
168
169    @param subscribers: list of subscribers (dict of lists, language is the key)
170    @param for_jabber: require jid
171    @type subscribers: dict
172
173    """
174    event_name = event.name
175
176    # Filter the list by removing users who don't want to receive
177    # notifications about this type of event
178    for lang in subscribers.keys():
179        userlist = []
180
181        if for_jabber:
182            for usr in subscribers[lang]:
183                if usr.jid and event_name in usr.jabber_subscribed_events:
184                    userlist.append(usr)
185        else:
186            for usr in subscribers[lang]:
187                if usr.email and event_name in usr.email_subscribed_events:
188                    userlist.append(usr)
189
190        subscribers[lang] = userlist
191