[wp-meta] [Making WordPress.org] #3594: Email notifications not sent for updates to watched tickets and still sent for blocked tickets

Making WordPress.org noreply at wordpress.org
Mon May 27 02:39:45 UTC 2019


#3594: Email notifications not sent for updates to watched tickets and still sent
for blocked tickets
-----------------------+---------------------
 Reporter:  iandunn    |       Owner:  (none)
     Type:  defect     |      Status:  new
 Priority:  high       |   Milestone:
Component:  Trac       |  Resolution:
 Keywords:  has-patch  |
-----------------------+---------------------
Changes (by nacin):

 * keywords:  needs-patch => has-patch


Comment:

 I only learned about this a few weeks ago, and made some time this weekend
 to look.

 This appears to have broken when Trac was upgraded to 1.2.2 last year. We
 were running a core patch, and while that patch was updated for 1.2.2, it
 ran against deprecated code because the entire notifications process was
 refactored. The most relevant link upstream is probably
 https://trac.edgewall.org/changeset/13469.

 The refactoring gives Trac some proper support for managing how you wish
 to be notified. If we wanted, we may be able to move to Trac's UI and DB
 schema, but it seems not worth the effort (and probably requires some work
 from https://trac.edgewall.org/ticket/11871 that is not complete).

 In practice, at the very least, we can use the new API and extension
 points to inject our own subscription logic pretty easily. I've lightly
 tested this code below. If installed as a plugin, it should work. I'll do
 some more testing and talk with the systems team.

 {{{#!python
 from trac.core import Component, implements
 from trac.notification.mail import RecipientMatcher
 from trac.notification.api import INotificationSubscriber


 class WordPressNotificationSubscriber(Component):
     implements(INotificationSubscriber)

     def matches(self, event):
         print("YAY IT RUNS")
         if not self.env.config.getbool('wordpress',
 'fine_grained_notifications'):
             return
         if event.realm != 'ticket':
             return
         if event.category not in ('created', 'changed', 'attachment
 added'):
             return

         ticket = event.target

         matcher = RecipientMatcher(self.env)
         klass = self.__class__.__name__
         format = None

         priority = 2
         for username in self.get_subscribers(ticket, event):
             recipient = matcher.match_recipient(username)
             if recipient:
                 sid, authenticated, address = recipient
                 yield (klass, 'email', sid, authenticated, address,
 format,
                        priority, 'always')

         priority = 1
         for username in self.get_unsubscribers(ticket, event):
             recipient = matcher.match_recipient(username)
             if recipient:
                 sid, authenticated, address = recipient
                 yield (klass, 'email', sid, authenticated, address,
 format,
                        priority, 'never')

     def get_subscribers(self, ticket, event):
         # People can subscribe to new tickets
         if event.category == 'created':
             for row in self.env.db_query("""
                     SELECT username FROM _notifications
                     WHERE type = 'newticket' AND value = '1'
                     """):
                 yield row[0]

         # People can subscribe to components, milestones, and focuses
         component = old_component = ticket['component']
         milestone = old_milestone = ticket['milestone']
         if 'focuses' in ticket:
             focuses = set(ticket['focuses'].split(', '))
         else:
             focuses = None

         # Make sure we include the previous component, milestone, or focus
 too
         if 'fields' in event.changes:
             if 'component' in event.changes['fields']:
                 old_component =
 event.changes['fields']['component']['old']

             if 'milestone' in event.changes['fields']:
                 old_milestone =
 event.changes['fields']['milestone']['old']

             if 'focuses' in ticket and 'focuses' in
 event.changes['fields']:
                 focuses |=
 set(event.changes['fields']['focuses']['old'].split(', '))

         # Add component subscribers
         for row in self.env.db_query("""
                 SELECT username FROM _notifications
                 WHERE type = 'component' AND value IN ( %s, %s )
                 """, (component, old_component)):
             yield row[0]

         # Add milestone subscribers
         for row in self.env.db_query("""
                 SELECT username FROM _notifications
                 WHERE type = 'milestone' AND value IN ( %s, %s )
                 """, (milestone, old_milestone)):
             yield row[0]

         # Add focus subscribers
         if focuses:
             focuses = list(focuses)
             for row in self.env.db_query("""
                     SELECT username FROM _notifications
                     WHERE type = 'focus' AND value IN ( %s )
                     """ % ','.join(['%s'] * len(focuses)), focuses):
                 yield row[0]

         # Add individual ticket subscribers
         for row in self.env.db_query("""
                 SELECT username FROM _ticket_subs
                 WHERE ticket = %s AND status > 0
                 """, (ticket.id,)):
             yield row[0]

     def get_unsubscribers(self, ticket):
         # If a user has specifically blocked notifications for a ticket,
         # remove them (even if they are a reporter, owner, or updater).
         for row in self.env.db_query("""
                 SELECT username FROM _ticket_subs
                 WHERE ticket = %s AND status = 0
                 """, (ticket.id,)):
             yield row[0]

     def description(self):
         return None  # not configurable

     def requires_authentication(self):
         return False

     def default_subscriptions(self):
         return ()
 }}}

-- 
Ticket URL: <https://meta.trac.wordpress.org/ticket/3594#comment:10>
Making WordPress.org <https://meta.trac.wordpress.org/>
Making WordPress.org


More information about the wp-meta mailing list