Index: tracdiscussion/api.py
===================================================================
--- tracdiscussion/api.py (revision 17855)
+++ tracdiscussion/api.py (working copy)
@@ -424,6 +424,12 @@
# Determine if user has e-mail set.
context.authemail = req.session.get('email')
+ # ... or Trac can make up an e-mail address (?) ...
+ # (see notification:smtp_default_domain)
+ if not context.authemail:
+ if req.is_authenticated:
+ context.authemail = req.authname
+
# Prepare other general context attributes.
context.redirect_url = None
context.format = req.args.get('format')
Index: tracdiscussion/notification.py
===================================================================
--- tracdiscussion/notification.py (revision 17855)
+++ tracdiscussion/notification.py (working copy)
@@ -12,258 +12,696 @@
from trac.core import *
from trac.config import ListOption
from trac.web.chrome import Chrome
-from trac.notification import NotifyEmail
from tracdiscussion.api import *
+try:
+ from trac.notification import NotifyEmail
-class DiscussionNotifyEmail(NotifyEmail):
- template_name = 'topic-notify-body.txt'
- forum = None
- topic = None
- message = None
- from_email = 'trac+discussion@localhost'
- to_recipients = []
- cc_recipients = []
- COLS = 75
+ class DiscussionNotifyEmail(NotifyEmail):
+ template_name = 'topic-notify-body.txt'
+ forum = None
+ topic = None
+ message = None
+ from_email = 'trac+discussion@localhost'
+ to_recipients = []
+ cc_recipients = []
+ COLS = 75
- def __init__(self, env):
- NotifyEmail.__init__(self, env)
- self.prev_cc = []
+ def __init__(self, env):
+ NotifyEmail.__init__(self, env)
+ self.prev_cc = []
- def notify(self, context, forum=None, topic=None, message=None):
- req = context.req
- # Store link to currently notifying forum, topic and message.
- self.forum = forum
- self.topic = topic
- self.message = message
+ def notify(self, context, forum=None, topic=None, message=None):
+ req = context.req
+ # Store link to currently notifying forum, topic and message.
+ self.forum = forum
+ self.topic = topic
+ self.message = message
- # Initialize template data.
- data = {
- 'forum': self.forum,
- 'topic': self.topic,
- 'message': self.message,
- 'prefix': self.config.get('notification',
- 'smtp_subject_prefix')
- }
- if data['prefix'] == '__default__':
- data['prefix'] = self.env.project_name
- self.data.update({'discussion': data})
+ # Initialize template data.
+ data = {
+ 'forum': self.forum,
+ 'topic': self.topic,
+ 'message': self.message,
+ 'prefix': self.config.get('notification',
+ 'smtp_subject_prefix')
+ }
+ if data['prefix'] == '__default__':
+ data['prefix'] = self.env.project_name
+ self.data.update({'discussion': data})
- # Which item notify about?
- if self.message:
- self.message['link'] = \
- self.env.abs_href.discussion('message', self.message['id'])
- self.template_name = 'message-notify-body.txt'
- elif self.topic:
- self.topic['link'] = \
- self.env.abs_href.discussion('topic', self.topic['id'])
- self.template_name = 'topic-notify-body.txt'
+ # Which item notify about?
+ if self.message:
+ self.message['link'] = \
+ self.env.abs_href.discussion('message', self.message['id'])
+ self.template_name = 'message-notify-body.txt'
+ elif self.topic:
+ self.topic['link'] = \
+ self.env.abs_href.discussion('topic', self.topic['id'])
+ self.template_name = 'topic-notify-body.txt'
- # Send e-mail to all subscribers.
- self.cc_recipients = forum['subscribers'] + topic['subscribers'] + \
- self.config.getlist('discussion',
- 'smtp_always_cc')
+ # Send e-mail to all subscribers.
+ self.cc_recipients = forum['subscribers'] + topic['subscribers'] + \
+ self.config.getlist('discussion',
+ 'smtp_always_cc')
- # Render subject template and send notification.
- message = 'message-notify-subject.txt' if self.message \
- else 'topic-notify-subject.txt'
- template = Chrome(self.env).render_template(req, message, self.data,
- 'text/plain')
- subject = (to_unicode(template)).strip()
- NotifyEmail.notify(self, id, subject)
+ # Render subject template and send notification.
+ message = 'message-notify-subject.txt' if self.message \
+ else 'topic-notify-subject.txt'
+ template = Chrome(self.env).render_template(req, message, self.data,
+ 'text/plain')
+ subject = (to_unicode(template)).strip()
+ NotifyEmail.notify(self, id, subject)
- def invite(self, forum=None, topic=None, recipients=None):
- # Store link to currently notifying forum.
- recipients = recipients or []
- self.forum = forum
- self.topic = topic
+ def invite(self, forum=None, topic=None, recipients=None):
+ # Store link to currently notifying forum.
+ recipients = recipients or []
+ self.forum = forum
+ self.topic = topic
- # Initialize template data.
- data = {
- 'forum': self.forum,
- 'topic': self.topic,
- 'prefix': self.config.get('notification', 'smtp_subject_prefix')
- }
- if data['prefix'] == '__default__':
- data['prefix'] = self.env.project_name
- self.data.update({'discussion': data})
+ # Initialize template data.
+ data = {
+ 'forum': self.forum,
+ 'topic': self.topic,
+ 'prefix': self.config.get('notification', 'smtp_subject_prefix')
+ }
+ if data['prefix'] == '__default__':
+ data['prefix'] = self.env.project_name
+ self.data.update({'discussion': data})
- # Which item notify about?
- if self.topic:
- self.topic['link'] = \
- self.env.abs_href.discussion('topic', self.topic['id'])
- self.template_name = 'topic-invite-body.txt'
- elif self.forum:
- self.forum['link'] = \
- self.env.abs_href.discussion('forum', self.forum['id'])
- self.template_name = 'forum-invite-body.txt'
+ # Which item notify about?
+ if self.topic:
+ self.topic['link'] = \
+ self.env.abs_href.discussion('topic', self.topic['id'])
+ self.template_name = 'topic-invite-body.txt'
+ elif self.forum:
+ self.forum['link'] = \
+ self.env.abs_href.discussion('forum', self.forum['id'])
+ self.template_name = 'forum-invite-body.txt'
- # Send e-mail to all subscribers.
- self.cc_recipients = recipients + \
- self.config.getlist('discussion',
- 'smtp_always_cc')
+ # Send e-mail to all subscribers.
+ self.cc_recipients = recipients + \
+ self.config.getlist('discussion',
+ 'smtp_always_cc')
- # Render subject template and send notification.
- topic = 'topic-invite-subject.txt' if self.topic \
- else 'forum-invite-subject.txt'
- template = Chrome(self.env).render_template(topic, self.data,
- 'text/plain')
- subject = (to_unicode(template)).strip()
- NotifyEmail.notify(self, id, subject)
+ # Render subject template and send notification.
+ topic = 'topic-invite-subject.txt' if self.topic \
+ else 'forum-invite-subject.txt'
+ template = Chrome(self.env).render_template(topic, self.data,
+ 'text/plain')
+ subject = (to_unicode(template)).strip()
+ NotifyEmail.notify(self, id, subject)
- def send(self, to_recipients, cc_recipients):
- header = {}
+ def send(self, to_recipients, cc_recipients):
+ header = {}
- # Add item specific e-mail header fields.
- if self.message:
- # ID of the message.
- header['Message-ID'] = self.get_message_email_id(
- self.message['id'])
- header['X-Trac-Message-ID'] = to_unicode(self.message['id'])
- header['X-Trac-Discussion-URL'] = self.message['link']
+ # Add item specific e-mail header fields.
+ if self.message:
+ # ID of the message.
+ header['Message-ID'] = self.get_message_email_id(
+ self.message['id'])
+ header['X-Trac-Message-ID'] = to_unicode(self.message['id'])
+ header['X-Trac-Discussion-URL'] = self.message['link']
- # ID of replied message.
- if self.message['replyto'] != -1:
- reply_id = self.get_message_email_id(self.message['replyto'])
+ # ID of replied message.
+ if self.message['replyto'] != -1:
+ reply_id = self.get_message_email_id(self.message['replyto'])
+ else:
+ reply_id = self.get_topic_email_id(self.message['topic'])
+ header['In-Reply-To'] = reply_id
+ header['References'] = reply_id
+ elif self.topic:
+ # ID of the message.
+ header['Message-ID'] = self.get_topic_email_id(self.topic['id'])
+ header['X-Trac-Topic-ID'] = to_unicode(self.topic['id'])
+ header['X-Trac-Discussion-URL'] = self.topic['link']
+ elif self.forum:
+ # ID of the message.
+ header['Message-ID'] = self.get_forum_email_id(self.forum['id'])
+ header['X-Trac-Forum-ID'] = to_unicode(self.forum['id'])
+ header['X-Trac-Discussion-URL'] = self.forum['link']
else:
- reply_id = self.get_topic_email_id(self.message['topic'])
- header['In-Reply-To'] = reply_id
- header['References'] = reply_id
- elif self.topic:
- # ID of the message.
- header['Message-ID'] = self.get_topic_email_id(self.topic['id'])
- header['X-Trac-Topic-ID'] = to_unicode(self.topic['id'])
- header['X-Trac-Discussion-URL'] = self.topic['link']
- elif self.forum:
- # ID of the message.
- header['Message-ID'] = self.get_forum_email_id(self.forum['id'])
- header['X-Trac-Forum-ID'] = to_unicode(self.forum['id'])
- header['X-Trac-Discussion-URL'] = self.forum['link']
- else:
- # Should not happen.
- raise TracError('DiscussionPlugin internal error.')
+ # Should not happen.
+ raise TracError('DiscussionPlugin internal error.')
- # Send e-mail.
- self.template = Chrome(self.env).load_template(self.template_name,
- method='text')
- self.env.log.debug('to_recipients: %s cc_recipients: %s',
- to_recipients, cc_recipients)
- NotifyEmail.send(self, to_recipients, cc_recipients, header)
+ # Send e-mail.
+ self.template = Chrome(self.env).load_template(self.template_name,
+ method='text')
+ self.env.log.debug('to_recipients: %s cc_recipients: %s',
+ to_recipients, cc_recipients)
+ NotifyEmail.send(self, to_recipients, cc_recipients, header)
- def get_recipients(self, item_id):
- return self.to_recipients, self.cc_recipients
+ def get_recipients(self, item_id):
+ return self.to_recipients, self.cc_recipients
- def get_message_email_id(self, message_id):
- # Generate a predictable, but sufficiently unique message ID.
- s = 'm.%s.%08d' % (self.config.get('project', 'url'), int(message_id))
- digest = hashlib.md5(s).hexdigest()
- host = self.from_email[self.from_email.find('@') + 1:]
- email_id = '<%03d.%s@%s>' % (len(s), digest, host)
- return email_id
+ def get_message_email_id(self, message_id):
+ # Generate a predictable, but sufficiently unique message ID.
+ s = 'm.%s.%08d' % (self.config.get('project', 'url'), int(message_id))
+ digest = hashlib.md5(s).hexdigest()
+ host = self.from_email[self.from_email.find('@') + 1:]
+ email_id = '<%03d.%s@%s>' % (len(s), digest, host)
+ return email_id
- def get_topic_email_id(self, topic_id):
- # Generate a predictable, but sufficiently unique topic ID.
- s = 't.%s.%08d' % (self.config.get('project', 'url'), int(topic_id))
- digest = hashlib.md5(s).hexdigest()
- host = self.from_email[self.from_email.find('@') + 1:]
- email_id = '<%03d.%s@%s>' % (len(s), digest, host)
- return email_id
+ def get_topic_email_id(self, topic_id):
+ # Generate a predictable, but sufficiently unique topic ID.
+ s = 't.%s.%08d' % (self.config.get('project', 'url'), int(topic_id))
+ digest = hashlib.md5(s).hexdigest()
+ host = self.from_email[self.from_email.find('@') + 1:]
+ email_id = '<%03d.%s@%s>' % (len(s), digest, host)
+ return email_id
- def get_forum_email_id(self, forum_id):
- # Generate a predictable, but sufficiently unique topic ID.
- s = 'f.%s.%08d' % (self.config.get('project', 'url'), int(forum_id))
- digest = hashlib.md5(s).hexdigest()
- host = self.from_email[self.from_email.find('@') + 1:]
- email_id = '<%03d.%s@%s>' % (len(s), digest, host)
- return email_id
+ def get_forum_email_id(self, forum_id):
+ # Generate a predictable, but sufficiently unique topic ID.
+ s = 'f.%s.%08d' % (self.config.get('project', 'url'), int(forum_id))
+ digest = hashlib.md5(s).hexdigest()
+ host = self.from_email[self.from_email.find('@') + 1:]
+ email_id = '<%03d.%s@%s>' % (len(s), digest, host)
+ return email_id
-class DiscussionEmailNotification(Component):
- """
- The e-mail notification component implements topic and message change
- listener interfaces and send e-mail notifications when topics and
- messages are created.
- """
- implements(IForumChangeListener, IMessageChangeListener,
- ITopicChangeListener)
+ class DiscussionEmailNotification(Component):
+ """
+ The e-mail notification component implements topic and message change
+ listener interfaces and send e-mail notifications when topics and
+ messages are created.
+ """
+ implements(IForumChangeListener, IMessageChangeListener,
+ ITopicChangeListener)
- # Configuration options.
+ # Configuration options.
- smtp_always_cc = ListOption('discussion', 'smtp_always_cc', [],
- doc="""Always send discussion notifications to the listed e-mail
- addresses.
- """)
+ smtp_always_cc = ListOption('discussion', 'smtp_always_cc', [],
+ doc="""Always send discussion notifications to the listed e-mail
+ addresses.
+ """)
- # IForumChangeListener methods.
+ # IForumChangeListener methods.
- def forum_created(self, context, forum):
- # Send e-mail invitation.
- notifier = DiscussionNotifyEmail(self.env)
- notifier.invite(forum, None, forum['subscribers'])
+ def forum_created(self, context, forum):
+ # Send e-mail invitation.
+ notifier = DiscussionNotifyEmail(self.env)
+ notifier.invite(forum, None, forum['subscribers'])
- def forum_changed(self, context, forum, old_forum):
- # Get new subscribers to topic.
- new_subscribers = [subscriber
- for subscriber in forum['subscribers']
- if subscriber not in old_forum['subscribers']]
+ def forum_changed(self, context, forum, old_forum):
+ # Get new subscribers to topic.
+ new_subscribers = [subscriber
+ for subscriber in forum['subscribers']
+ if subscriber not in old_forum['subscribers']]
- # We need to use complete forum dictionary.
- old_forum.update(forum)
+ # We need to use complete forum dictionary.
+ old_forum.update(forum)
- # Send e-mail invitation.
- notifier = DiscussionNotifyEmail(self.env)
- notifier.invite(old_forum, None, new_subscribers)
+ # Send e-mail invitation.
+ notifier = DiscussionNotifyEmail(self.env)
+ notifier.invite(old_forum, None, new_subscribers)
- def forum_deleted(self, forum):
- self.log.debug('DiscussionEmailNotification.forum_deleted()')
+ def forum_deleted(self, forum):
+ self.log.debug('DiscussionEmailNotification.forum_deleted()')
- # ITopicChangeListener methods.
+ # ITopicChangeListener methods.
- def topic_created(self, context, topic):
- # Get forum of the topic.
- api = self.env[DiscussionApi]
- forum = api.get_forum(context, topic['forum'])
+ def topic_created(self, context, topic):
+ # Get forum of the topic.
+ api = self.env[DiscussionApi]
+ forum = api.get_forum(context, topic['forum'])
- # Send e-mail notification.
- notifier = DiscussionNotifyEmail(self.env)
- notifier.notify(context, forum, topic, None)
+ # Send e-mail notification.
+ notifier = DiscussionNotifyEmail(self.env)
+ notifier.notify(context, forum, topic, None)
- def topic_changed(self, context, topic, old_topic):
- if 'subscribers' in topic:
+ def topic_changed(self, context, topic, old_topic):
+ if 'subscribers' in topic:
+ # Get new subscribers to topic.
+ new_subscribers = [subscriber
+ for subscriber in topic['subscribers']
+ if subscriber not in old_topic['subscribers']]
+
+ # We need to use complete topic dictionary.
+ old_topic.update(topic)
+
+ # Get forum of the topic.
+ api = self.env[DiscussionApi]
+ forum = api.get_forum(context, old_topic['forum'])
+
+ # Send e-mail invitation.
+ notifier = DiscussionNotifyEmail(self.env)
+ notifier.invite(forum, old_topic, new_subscribers)
+
+ def topic_deleted(self, context, topic):
+ pass
+
+ # IMessageChangeListener methods.
+
+ def message_created(self, context, message):
+ # Get access to api component.
+ api = self.env[DiscussionApi]
+ forum = api.get_forum(context, message['forum'])
+ topic = api.get_topic(context, message['topic'])
+
+ # Send e-mail notification.
+ notifier = DiscussionNotifyEmail(self.env)
+ notifier.notify(context, forum, topic, message)
+
+ def message_changed(self, context, message, old_message):
+ pass
+
+ def message_deleted(self, context, message):
+ pass
+
+
+ ###############################################################
+ ###############################################################
+except:
+ ###############################################################
+ ###############################################################
+
+
+ from trac.notification.api import (
+ IEmailDecorator, INotificationFormatter, NotificationEvent,
+ NotificationSystem)
+ from trac.notification.mail import RecipientMatcher, set_header
+ from trac.util.text import exception_to_unicode
+
+ #from trac.util.translation import deactivate, reactivate
+
+
+ class NotificationError(TracError):
+ pass
+
+
+ class SubscriberNotifyEvent(NotificationEvent):
+
+ myrealm = 'discussion'
+
+ def __init__(self, category, username, parms):
+ super(SubscriberNotifyEvent, self).__init__(self.myrealm, category, None,
+ None, username)
+ self.parms = parms
+
+
+ class DiscussionEmailNotification(Component):
+ """
+ The e-mail notification component implements topic and message change
+ listener interfaces and send e-mail notifications when topics and
+ messages are created.
+ """
+ implements(IForumChangeListener, IMessageChangeListener,
+ ITopicChangeListener,
+ IEmailDecorator, INotificationFormatter)
+
+ myrealm = 'discussion'
+
+ # Configuration options.
+
+ smtp_always_cc = ListOption('discussion', 'smtp_always_cc', [],
+ doc="""Always send discussion notifications to the listed e-mail
+ addresses.
+ """)
+
+ # IForumChangeListener methods.
+
+ def forum_created(self, context, forum):
+ # Send e-mail invitation.
+
+ category = "forum created"
+ username = ""
+ parms = {
+ 'forum' : forum,
+ 'topic' : None,
+ 'req' : context.req
+ }
+ event = SubscriberNotifyEvent(category, username, parms)
+
+ subnames = forum['subscribers'] or []
+ subscriptions_names = subnames + \
+ self.config.getlist('discussion',
+ 'smtp_always_cc')
+ subscriptions = self._get_subscriptions( subscriptions_names )
+
+ try:
+ NotificationSystem(self.env).distribute_event(event, subscriptions)
+ except Exception as e:
+ self.log.error("Failure sending notification: %s", exception_to_unicode(e))
+ raise NotificationError(e)
+ return
+
+ def forum_changed(self, context, forum, old_forum):
# Get new subscribers to topic.
new_subscribers = [subscriber
- for subscriber in topic['subscribers']
- if subscriber not in old_topic['subscribers']]
+ for subscriber in forum['subscribers']
+ if subscriber not in old_forum['subscribers']]
- # We need to use complete topic dictionary.
- old_topic.update(topic)
+ # We need to use complete forum dictionary.
+ old_forum.update(forum)
+ # Send e-mail invitation.
+
+ category = "forum changed"
+ username = ""
+ parms = {
+ 'forum' : old_forum,
+ 'topic' : None,
+ 'req' : context.req
+ }
+ event = SubscriberNotifyEvent(category, username, parms)
+
+ subnames = new_subscribers or []
+ subscriptions_names = subnames + \
+ self.config.getlist('discussion',
+ 'smtp_always_cc')
+ subscriptions = self._get_subscriptions( subscriptions_names )
+
+ try:
+ NotificationSystem(self.env).distribute_event(event, subscriptions)
+ except Exception as e:
+ self.log.error("Failure sending notification: %s", exception_to_unicode(e))
+ raise NotificationError(e)
+ return
+
+ def forum_deleted(self, forum):
+ self.log.debug('DiscussionEmailNotification.forum_deleted()')
+
+ # ITopicChangeListener methods.
+
+ def topic_created(self, context, topic):
# Get forum of the topic.
api = self.env[DiscussionApi]
- forum = api.get_forum(context, old_topic['forum'])
+ forum = api.get_forum(context, topic['forum'])
- # Send e-mail invitation.
- notifier = DiscussionNotifyEmail(self.env)
- notifier.invite(forum, old_topic, new_subscribers)
+ # Send e-mail notification.
- def topic_deleted(self, context, topic):
- pass
+ category = "topic created"
+ username = ""
+ parms = {
+ 'forum' : forum,
+ 'topic' : topic,
+ 'message' : None,
+ 'req' : context.req
+ }
+ event = SubscriberNotifyEvent(category, username, parms)
- # IMessageChangeListener methods.
+ subscriptions_names = forum['subscribers'] + topic['subscribers'] + \
+ self.config.getlist('discussion',
+ 'smtp_always_cc')
+ subscriptions = self._get_subscriptions( subscriptions_names )
- def message_created(self, context, message):
- # Get access to api component.
- api = self.env[DiscussionApi]
- forum = api.get_forum(context, message['forum'])
- topic = api.get_topic(context, message['topic'])
+ try:
+ NotificationSystem(self.env).distribute_event(event, subscriptions)
+ except Exception as e:
+ self.log.error("Failure sending notification: %s", exception_to_unicode(e))
+ raise NotificationError(e)
+ return
- # Send e-mail notification.
- notifier = DiscussionNotifyEmail(self.env)
- notifier.notify(context, forum, topic, message)
+ def topic_changed(self, context, topic, old_topic):
+ if 'subscribers' in topic:
+ # Get new subscribers to topic.
+ new_subscribers = [subscriber
+ for subscriber in topic['subscribers']
+ if subscriber not in old_topic['subscribers']]
- def message_changed(self, context, message, old_message):
- pass
+ # We need to use complete topic dictionary.
+ old_topic.update(topic)
- def message_deleted(self, context, message):
- pass
+ # Get forum of the topic.
+ api = self.env[DiscussionApi]
+ forum = api.get_forum(context, old_topic['forum'])
+
+ # Send e-mail invitation.
+
+ category = "topic changed"
+ username = ""
+ parms = {
+ 'forum' : forum,
+ 'topic' : old_topic,
+ 'req' : context.req
+ }
+ event = SubscriberNotifyEvent(category, username, parms)
+
+ subnames = new_subscribers or []
+ subscriptions_names = subnames + \
+ self.config.getlist('discussion',
+ 'smtp_always_cc')
+ subscriptions = self._get_subscriptions( subscriptions_names )
+
+ try:
+ NotificationSystem(self.env).distribute_event(event, subscriptions)
+ except Exception as e:
+ self.log.error("Failure sending notification: %s", exception_to_unicode(e))
+ raise NotificationError(e)
+ return
+
+ def topic_deleted(self, context, topic):
+ pass
+
+ # IMessageChangeListener methods.
+
+ def message_created(self, context, message):
+ # Get access to api component.
+ api = self.env[DiscussionApi]
+ forum = api.get_forum(context, message['forum'])
+ topic = api.get_topic(context, message['topic'])
+
+ # Send e-mail notification.
+
+ category = "message created"
+ username = ""
+ parms = {
+ 'forum' : forum,
+ 'topic' : topic,
+ 'message' : message,
+ 'req' : context.req
+ }
+ event = SubscriberNotifyEvent(category, username, parms)
+
+ subscriptions_names = forum['subscribers'] + topic['subscribers'] + \
+ self.config.getlist('discussion',
+ 'smtp_always_cc')
+ subscriptions = self._get_subscriptions( subscriptions_names )
+
+ try:
+ NotificationSystem(self.env).distribute_event(event, subscriptions)
+ except Exception as e:
+ self.log.error("Failure sending notification: %s", exception_to_unicode(e))
+ raise NotificationError(e)
+ return
+
+ def message_changed(self, context, message, old_message):
+ pass
+
+ def message_deleted(self, context, message):
+ pass
+
+ def _get_subscriptions( self, subscriptions_names ):
+ """Convert names to recipients"""
+
+ subscriptions = []
+
+ matcher = RecipientMatcher(self.env)
+ transport_and_format = ('email', 'text/plain')
+ for sn in subscriptions_names:
+ recipient = matcher.match_recipient(sn)
+ if recipient:
+ subscriptions.append( recipient + transport_and_format )
+
+ #self.log.debug("subscriptions " + str(subscriptions))
+
+ return subscriptions
+
+
+ # IEmailDecorator methods
+
+ def decorate_message(self, event, message, charset):
+ if event.realm != self.myrealm:
+ return
+
+ #self.log.debug("Decorating message " + event.category)
+
+ # Someday replace with method added in trac:#13208
+ prefix = self.config.get('notification', 'smtp_subject_prefix')
+ subject = '[%s]' % self.env.project_name \
+ if prefix == '__default__' else prefix
+
+ if event.category in ("topic created", "message created"):
+ # Known as "notify" ...
+
+ # Store link to currently notifying forum, topic and message.
+ parm_forum = event.parms['forum']
+ parm_topic = event.parms['topic']
+ parm_message = event.parms['message']
+ parm_req = event.parms['req']
+
+ # Initialize template data.
+ discussion_data = {
+ 'forum': parm_forum,
+ 'topic': parm_topic,
+ 'message': parm_message,
+ 'prefix': self.config.get('notification',
+ 'smtp_subject_prefix')
+ }
+ if discussion_data['prefix'] == '__default__':
+ discussion_data['prefix'] = self.env.project_name
+ templater_data = {'discussion': discussion_data}
+
+ # Which item notify about?
+ body_template_name = 'topic-notify-body.txt'
+ if parm_message:
+ parm_message['link'] = \
+ self.env.abs_href.discussion('message', parm_message['id'])
+ body_template_name = 'message-notify-body.txt'
+ elif parm_topic:
+ parm_topic['link'] = \
+ self.env.abs_href.discussion('topic', parm_topic['id'])
+ body_template_name = 'topic-notify-body.txt'
+
+ subject_template_name = 'message-notify-subject.txt' if parm_message \
+ else 'topic-notify-subject.txt'
+
+ # Render template
+ template = Chrome(self.env).render_template(parm_req, subject_template_name, templater_data,
+ 'text/plain')
+ subject = (to_unicode(template)).strip()
+
+ elif event.category in ("forum created", "forum changed", "topic changed"):
+ # Known as "invite" ...
+
+ # Store link to currently notifying forum.
+ parm_forum = event.parms['forum']
+ parm_topic = event.parms['topic']
+ parm_req = event.parms['req']
+
+ # Initialize template data.
+ discussion_data = {
+ 'forum': parm_forum,
+ 'topic': parm_topic,
+ 'prefix': self.config.get('notification', 'smtp_subject_prefix')
+ }
+ if discussion_data['prefix'] == '__default__':
+ discussion_data['prefix'] = self.env.project_name
+ templater_data = {'discussion': discussion_data}
+
+ # Which item notify about?
+ body_template_name = 'topic-invite-body.txt'
+ if parm_topic:
+ parm_topic['link'] = \
+ self.env.abs_href.discussion('topic', parm_topic['id'])
+ body_template_name = 'topic-invite-body.txt'
+ elif parm_forum:
+ parm_forum['link'] = \
+ self.env.abs_href.discussion('forum', parm_forum['id'])
+ body_template_name = 'forum-invite-body.txt'
+
+ subject_template_name = 'topic-invite-subject.txt' if parm_topic \
+ else 'forum-invite-subject.txt'
+
+ # Render template
+ template = Chrome(self.env).render_template(parm_req, subject_template_name, templater_data,
+ 'text/plain')
+ subject = (to_unicode(template)).strip()
+
+ else:
+ # invalid / unknown
+ subject += "Unknown event category" + event.category
+
+ #self.log.debug("SUBJECT: (" + event.category + ") " + str(subject))
+
+ set_header(message, 'Subject', subject, charset)
+ return
+
+ # INotificationFormatter methods
+
+ def get_supported_styles(self, transport):
+ yield 'text/plain', self.myrealm
+
+ def format(self, transport, style, event):
+ if event.realm != self.myrealm:
+ return
+
+ #self.log.debug("Formatting notification " + event.category)
+
+ body = None
+
+ if event.category in ("topic created", "message created"):
+ # Known as "notify" ...
+
+ # Store link to currently notifying forum, topic and message.
+ parm_forum = event.parms['forum']
+ parm_topic = event.parms['topic']
+ parm_message = event.parms['message']
+ parm_req = event.parms['req']
+
+ # Initialize template data.
+ discussion_data = {
+ 'forum': parm_forum,
+ 'topic': parm_topic,
+ 'message': parm_message,
+ 'prefix': self.config.get('notification',
+ 'smtp_subject_prefix')
+ }
+ if discussion_data['prefix'] == '__default__':
+ discussion_data['prefix'] = self.env.project_name
+ templater_data = {'discussion': discussion_data}
+
+ # Which item notify about?
+ body_template_name = 'topic-notify-body.txt'
+ if parm_message:
+ parm_message['link'] = \
+ self.env.abs_href.discussion('message', parm_message['id'])
+ body_template_name = 'message-notify-body.txt'
+ elif parm_topic:
+ parm_topic['link'] = \
+ self.env.abs_href.discussion('topic', parm_topic['id'])
+ body_template_name = 'topic-notify-body.txt'
+
+ subject_template_name = 'message-notify-subject.txt' if parm_message \
+ else 'topic-notify-subject.txt'
+
+ # Render template
+ template = Chrome(self.env).render_template(parm_req, body_template_name, templater_data,
+ 'text/plain')
+ body = (to_unicode(template)).strip()
+
+ elif event.category in ("forum created", "forum changed", "topic changed"):
+ # Known as "invite" ...
+
+ # Store link to currently notifying forum.
+ parm_forum = event.parms['forum']
+ parm_topic = event.parms['topic']
+ parm_req = event.parms['req']
+
+ # Initialize template data.
+ discussion_data = {
+ 'forum': parm_forum,
+ 'topic': parm_topic,
+ 'prefix': self.config.get('notification', 'smtp_subject_prefix')
+ }
+ if discussion_data['prefix'] == '__default__':
+ discussion_data['prefix'] = self.env.project_name
+ templater_data = {'discussion': discussion_data}
+
+ # Which item notify about?
+ body_template_name = 'topic-invite-body.txt'
+ if parm_topic:
+ parm_topic['link'] = \
+ self.env.abs_href.discussion('topic', parm_topic['id'])
+ body_template_name = 'topic-invite-body.txt'
+ elif parm_forum:
+ parm_forum['link'] = \
+ self.env.abs_href.discussion('forum', parm_forum['id'])
+ body_template_name = 'forum-invite-body.txt'
+
+ subject_template_name = 'topic-invite-subject.txt' if parm_topic \
+ else 'forum-invite-subject.txt'
+
+ # Render template
+ template = Chrome(self.env).render_template(parm_req, body_template_name, templater_data,
+ 'text/plain')
+ body = (to_unicode(template)).strip()
+
+ else:
+ # invalid / unknown
+ body = "Unknown event category" + event.category
+
+ #self.log.debug("BODY: (" + event.category + ") " + str(body))
+
+ return body.encode('utf-8')
Index: tracdiscussion/templates/admin-forum-list.html
===================================================================
--- tracdiscussion/templates/admin-forum-list.html (revision 17855)
+++ tracdiscussion/templates/admin-forum-list.html (working copy)
@@ -128,6 +128,8 @@
+