136
116
for line in text_diff]
137
117
text_diff = '\n'.join(text_diff)
141
def specification_notification_subject(spec):
142
"""Format the email subject line for a specification."""
143
return '[Blueprint %s] %s' % (spec.name, spec.title)
146
@block_implicit_flushes
147
def notify_specification_modified(spec, event):
148
"""Notify the related people that a specification has been modifed."""
149
user = IPerson(event.user)
150
spec_delta = spec.getDelta(event.object_before_modification, user)
151
if spec_delta is None:
152
# XXX: Bjorn Tillenius 2006-03-08:
153
# Ideally, if an IObjectModifiedEvent event is generated,
154
# spec_delta shouldn't be None. I'm not confident that we
155
# have enough test yet to assert this, though.
158
subject = specification_notification_subject(spec)
161
for dbitem_name in ('definition_status', 'priority'):
162
title = ISpecification[dbitem_name].title
163
assert ISpecification[dbitem_name].required, (
164
"The mail notification assumes %s can't be None" % dbitem_name)
165
dbitem_delta = getattr(spec_delta, dbitem_name)
166
if dbitem_delta is not None:
167
old_item = dbitem_delta['old']
168
new_item = dbitem_delta['new']
169
info_lines.append("%s%s: %s => %s" % (
170
indent, title, old_item.title, new_item.title))
172
for person_attrname in ('approver', 'assignee', 'drafter'):
173
title = ISpecification[person_attrname].title
174
person_delta = getattr(spec_delta, person_attrname)
175
if person_delta is not None:
176
old_person = person_delta['old']
177
if old_person is None:
180
old_value = old_person.displayname
181
new_person = person_delta['new']
182
if new_person is None:
185
new_value = new_person.displayname
187
"%s%s: %s => %s" % (indent, title, old_value, new_value))
189
mail_wrapper = MailWrapper(width=72)
190
if spec_delta.whiteboard is not None:
192
info_lines.append('')
193
whiteboard_delta = spec_delta.whiteboard
194
if whiteboard_delta['old'] is None:
195
info_lines.append('Whiteboard set to:')
196
info_lines.append(mail_wrapper.format(whiteboard_delta['new']))
198
whiteboard_diff = get_unified_diff(
199
whiteboard_delta['old'], whiteboard_delta['new'], 72)
200
info_lines.append('Whiteboard changed:')
201
info_lines.append(whiteboard_diff)
204
# The specification was modified, but we don't yet support
205
# sending notification for the change.
207
body = get_email_template('specification-modified.txt', 'blueprints') % {
208
'editor': user.displayname,
209
'info_fields': '\n'.join(info_lines),
210
'spec_title': spec.title,
211
'spec_url': canonical_url(spec)}
213
for address in spec.notificationRecipientAddresses():
214
simple_sendmail_from_person(user, address, subject, body)
217
@block_implicit_flushes
218
def notify_specification_subscription_created(specsub, event):
219
"""Notify a user that they have been subscribed to a blueprint."""
220
user = IPerson(event.user)
221
spec = specsub.specification
222
person = specsub.person
223
subject = specification_notification_subject(spec)
224
mailwrapper = MailWrapper(width=72)
225
body = mailwrapper.format(
226
'You are now subscribed to the blueprint '
227
'%(blueprint_name)s - %(blueprint_title)s.\n\n'
228
'-- \n%(blueprint_url)s' %
229
{'blueprint_name': spec.name,
230
'blueprint_title': spec.title,
231
'blueprint_url': canonical_url(spec)})
232
for address in get_contact_email_addresses(person):
233
simple_sendmail_from_person(user, address, subject, body)
236
@block_implicit_flushes
237
def notify_specification_subscription_modified(specsub, event):
238
"""Notify a subscriber to a blueprint that their
239
subscription has changed.
241
user = IPerson(event.user)
242
spec = specsub.specification
243
person = specsub.person
244
# Only send a notification if the
245
# subscription changed by someone else.
248
subject = specification_notification_subject(spec)
249
if specsub.essential:
250
specsub_type = 'Participation essential'
252
specsub_type = 'Participation non-essential'
253
mailwrapper = MailWrapper(width=72)
254
body = mailwrapper.format(
255
'Your subscription to the blueprint '
256
'%(blueprint_name)s - %(blueprint_title)s '
257
'has changed to [%(specsub_type)s].\n\n'
258
'--\n %(blueprint_url)s' %
259
{'blueprint_name': spec.name,
260
'blueprint_title': spec.title,
261
'specsub_type': specsub_type,
262
'blueprint_url': canonical_url(spec)})
263
for address in get_contact_email_addresses(person):
264
simple_sendmail_from_person(user, address, subject, body)
267
@block_implicit_flushes
268
def notify_new_ppa_subscription(subscription, event):
269
"""Notification that a new PPA subscription can be activated."""
270
non_active_subscribers = subscription.getNonActiveSubscribers()
272
archive = subscription.archive
274
# We don't send notification emails for commercial PPAs as these
275
# are purchased via software center (and do not mention Launchpad).
276
if archive.commercial:
279
registrant_name = subscription.registrant.displayname
280
ppa_displayname = archive.displayname
281
ppa_reference = "ppa:%s/%s" % (
282
archive.owner.name, archive.name)
283
ppa_description = archive.description
284
subject = 'PPA access granted for ' + ppa_displayname
286
template = get_email_template('ppa-subscription-new.txt', app='soyuz')
288
for person, preferred_email in non_active_subscribers:
289
to_address = [preferred_email.email]
290
root = getUtility(ILaunchpadRoot)
291
recipient_subscriptions_url = "%s~/+archivesubscriptions" % (
293
description_blurb = '.'
294
if ppa_description is not None and ppa_description != '':
295
description_blurb = (
296
' and has the following description:\n\n%s' % ppa_description)
298
'recipient_name': person.displayname,
299
'registrant_name': registrant_name,
300
'registrant_profile_url': canonical_url(subscription.registrant),
301
'ppa_displayname': ppa_displayname,
302
'ppa_reference': ppa_reference,
303
'ppa_description_blurb': description_blurb,
304
'recipient_subscriptions_url': recipient_subscriptions_url,
306
body = MailWrapper(72).format(template % replacements,
309
from_address = format_address(
310
registrant_name, config.canonical.noreply_from_address)
313
'Sender': config.canonical.bounce_address,
316
# If the registrant has a preferred email, then use it for the
318
if subscription.registrant.preferredemail:
319
headers['Reply-To'] = format_address(
321
subscription.registrant.preferredemail.email)
323
simple_sendmail(from_address, to_address, subject, body, headers)