[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