1
# Copyright 2011 Canonical Ltd. This software is licensed under the
2
# GNU Affero General Public License version 3 (see the file LICENSE).
3
"""Event handlers that send email notifications."""
7
from canonical.database.sqlbase import block_implicit_flushes
8
from canonical.launchpad.helpers import (
9
get_contact_email_addresses,
12
from lp.services.mail.notification import get_unified_diff
13
from canonical.launchpad.webapp.publisher import canonical_url
14
from lp.blueprints.interfaces.specification import ISpecification
15
from lp.registry.interfaces.person import IPerson
16
from lp.services.mail.mailwrapper import MailWrapper
17
from lp.services.mail.sendmail import simple_sendmail_from_person
20
def specification_notification_subject(spec):
21
"""Format the email subject line for a specification."""
22
return '[Blueprint %s] %s' % (spec.name, spec.title)
25
@block_implicit_flushes
26
def notify_specification_modified(spec, event):
27
"""Notify the related people that a specification has been modifed."""
28
user = IPerson(event.user)
29
spec_delta = spec.getDelta(event.object_before_modification, user)
30
if spec_delta is None:
31
# XXX: Bjorn Tillenius 2006-03-08:
32
# Ideally, if an IObjectModifiedEvent event is generated,
33
# spec_delta shouldn't be None. I'm not confident that we
34
# have enough test yet to assert this, though.
37
subject = specification_notification_subject(spec)
40
for dbitem_name in ('definition_status', 'priority'):
41
title = ISpecification[dbitem_name].title
42
assert ISpecification[dbitem_name].required, (
43
"The mail notification assumes %s can't be None" % dbitem_name)
44
dbitem_delta = getattr(spec_delta, dbitem_name)
45
if dbitem_delta is not None:
46
old_item = dbitem_delta['old']
47
new_item = dbitem_delta['new']
48
info_lines.append("%s%s: %s => %s" % (
49
indent, title, old_item.title, new_item.title))
51
for person_attrname in ('approver', 'assignee', 'drafter'):
52
title = ISpecification[person_attrname].title
53
person_delta = getattr(spec_delta, person_attrname)
54
if person_delta is not None:
55
old_person = person_delta['old']
56
if old_person is None:
59
old_value = old_person.displayname
60
new_person = person_delta['new']
61
if new_person is None:
64
new_value = new_person.displayname
66
"%s%s: %s => %s" % (indent, title, old_value, new_value))
68
mail_wrapper = MailWrapper(width=72)
69
if spec_delta.whiteboard is not None:
72
whiteboard_delta = spec_delta.whiteboard
73
if whiteboard_delta['old'] is None:
74
info_lines.append('Whiteboard set to:')
75
info_lines.append(mail_wrapper.format(whiteboard_delta['new']))
77
whiteboard_diff = get_unified_diff(
78
whiteboard_delta['old'], whiteboard_delta['new'], 72)
79
info_lines.append('Whiteboard changed:')
80
info_lines.append(whiteboard_diff)
83
# The specification was modified, but we don't yet support
84
# sending notification for the change.
86
body = get_email_template('specification-modified.txt', 'blueprints') % {
87
'editor': user.displayname,
88
'info_fields': '\n'.join(info_lines),
89
'spec_title': spec.title,
90
'spec_url': canonical_url(spec)}
92
for address in spec.notificationRecipientAddresses():
93
simple_sendmail_from_person(user, address, subject, body)
96
@block_implicit_flushes
97
def notify_specification_subscription_created(specsub, event):
98
"""Notify a user that they have been subscribed to a blueprint."""
99
user = IPerson(event.user)
100
spec = specsub.specification
101
person = specsub.person
102
subject = specification_notification_subject(spec)
103
mailwrapper = MailWrapper(width=72)
104
body = mailwrapper.format(
105
'You are now subscribed to the blueprint '
106
'%(blueprint_name)s - %(blueprint_title)s.\n\n'
107
'-- \n%(blueprint_url)s' %
108
{'blueprint_name': spec.name,
109
'blueprint_title': spec.title,
110
'blueprint_url': canonical_url(spec)})
111
for address in get_contact_email_addresses(person):
112
simple_sendmail_from_person(user, address, subject, body)
115
@block_implicit_flushes
116
def notify_specification_subscription_modified(specsub, event):
117
"""Notify a subscriber to a blueprint that their
118
subscription has changed.
120
user = IPerson(event.user)
121
spec = specsub.specification
122
person = specsub.person
123
# Only send a notification if the
124
# subscription changed by someone else.
127
subject = specification_notification_subject(spec)
128
if specsub.essential:
129
specsub_type = 'Participation essential'
131
specsub_type = 'Participation non-essential'
132
mailwrapper = MailWrapper(width=72)
133
body = mailwrapper.format(
134
'Your subscription to the blueprint '
135
'%(blueprint_name)s - %(blueprint_title)s '
136
'has changed to [%(specsub_type)s].\n\n'
137
'--\n %(blueprint_url)s' %
138
{'blueprint_name': spec.name,
139
'blueprint_title': spec.title,
140
'specsub_type': specsub_type,
141
'blueprint_url': canonical_url(spec)})
142
for address in get_contact_email_addresses(person):
143
simple_sendmail_from_person(user, address, subject, body)