Notifications on custom fields

83 views
Skip to first unread message

Mo

unread,
Jan 4, 2017, 10:38:00 AM1/4/17
to Trac Users
Coming from https://groups.google.com/d/msg/trac-users/VTv3b5nAQNw/prTYQrGQCgAJ
I managed to add custom fields for User roles and status on tickets like this:

[ticket-custom]
test
= select
test
.label = Test
test
.options = |open|done
test
.value =
tester
= text                                                                                                                          
tester
.label = Tester
tester
.value =

Then I managed to sort all the roles and status side by side using TracTicketFieldsLayoutPlugin in a separate group "Roles".

Additionally I have a user completion on the role fields by using AutocompleteUsersPlugin and
[autocomplete]
fields
= tester

There are some issues left with that approach. One is that the AutocompleteUsersPlugin only completes 1 user, not many like the Cc field does.
But most important we would need notifications based on Roles. That would mean a tester gets a notification if he was added to a Tester role.

I looked at AnnouncerPlugin which only has a very small set of static rules and does not support any custom fields. Then I looked at XMailPlugin (or called MailPlugin), that could create any SQL filter for mail notifications, but only SQL based. That could work, any other idea to have custom filter rules for mail notifications, user based and global ones by the administrator?

Best regards,
Mo

Peter Suter

unread,
Jan 4, 2017, 1:51:59 PM1/4/17
to trac-...@googlegroups.com
On 0    4.01.2017 16:38, Mo wrote:
I managed to add custom fields for User roles
Might be nice to write up your solution as a cookbook similar to https://trac.edgewall.org/wiki/CookBook/Configuration/SignedTickets


But most important we would need notifications based on Roles. That would mean a tester gets a notification if he was added to a Tester role.

I looked at AnnouncerPlugin which only has a very small set of static rules and does not support any custom fields. Then I looked at XMailPlugin (or called MailPlugin), that could create any SQL filter for mail notifications, but only SQL based. That could work, any other idea to have custom filter rules for mail notifications, user based and global ones by the administrator?

Trac 1.2's new notification system  would allow you to write a small single-file plugin implementing INotificationSubscriber.
https://trac.edgewall.org/wiki/TracDev/Proposals/AdvancedNotification
https://trac.edgewall.org/wiki/TracDev/PluginDevelopment#Singlefileplugins
https://trac.edgewall.org/wiki/TracDev/PluginDevelopment/ExtensionPoints/trac.notification.api.INotificationSubscriber#Examples

If I understand you correctly you want notification subscriptions exactly like the CC field provides, but for a custom field.
So I think you could basically copy the component that implements the CC field notifications (CarbonCopySubscriber) and replace 'cc' by your custom field name.
https://trac.edgewall.org/browser/trunk/trac/ticket/notification.py?rev=15148&marks=712-759#L711

That could look something like this (untested):

from trac.core import Component, implements
from trac.notification.api import INotificationSubscriber, NotificationSystem
from trac.notification.mail import RecipientMatcher
from trac.notification.model import Subscription
from trac.web.chrome import Chrome

class TesterCustomFieldSubscriber(Component):
    """Subscriber for custom ticket field."""

    implements(INotificationSubscriber)
   
    field_name = 'tester'

    def matches(self, event):
        if event.realm != 'ticket':
            return
        if event.category not in ('created', 'changed', 'attachment added',
                                  'attachment deleted'):
            return

        # Custom field with comma-separated string. Parse to set.
        chrome = Chrome(self.env)
        to_set = lambda field: set(chrome.cc_list(field))
        user_set = to_set(event.target[self.field_name] or '')

        # Harvest previous field values
        if 'fields' in event.changes and self.field_name in event.changes['fields']:
            field_set.update(to_set(event.changes['fields'][self.field_name]['old']))

        matcher = RecipientMatcher(self.env)
        klass = self.__class__.__name__
        sids = set()
        for field in field_set:
            recipient = matcher.match_recipient(field)
            if not recipient:
                continue
            sid, auth, addr = recipient

            # Default subscription
            for s in self.default_subscriptions():
                yield s[0], s[1], sid, auth, addr, s[2], s[3], s[4]
            if sid:
                sids.add((sid, auth))

        for s in Subscription.find_by_sids_and_class(self.env, sids, klass):
            yield s.subscription_tuple()

    def description(self):
        return "Ticket that I'm listed in as %s is modified" % self.field_name

    def default_subscriptions(self):
        klass = self.__class__.__name__
        return NotificationSystem(self.env).default_subscriptions(klass)

    def requires_authentication(self):
        return True

-----
If you want to stick with Trac 1.0 and Announcer, you could try something similar with Announcer's equivalent: IAnnouncementSubscriber
/ CarbonCopySubscriber.
https://trac-hacks.org/browser/announcerplugin/trunk/announcer/subscribers.py#L55

Actually the Announcer branch 0.11 already had a TicketCustomFieldSubscriber that did something similar. I don't know why it doesn't exist in the 1.0 branch.
https://trac-hacks.org/browser/announcerplugin/branches/0.11/announcerplugin/subscribers/ticket_custom.py

Best regards,
Peter

Peter Suter

unread,
Jan 4, 2017, 2:02:09 PM1/4/17
to trac-...@googlegroups.com
On 04.01.2017 19:51, Peter Suter wrote:
Actually the Announcer branch 0.11 already had a TicketCustomFieldSubscriber that did something similar.


> I don't know why it doesn't exist in the 1.0 branch.

Actually it's there as well, but was moved to announcer.opt.subscribers: https://trac-hacks.org/browser/announcerplugin/trunk/announcer/opt/subscribers.py?rev=16128#L375

Mo

unread,
Jan 5, 2017, 5:17:12 AM1/5/17
to Trac Users
Am Mittwoch, 4. Januar 2017 19:51:59 UTC+1 schrieb Peter Suter:


Very interesting, thank you for these hints. I would prefer going for the modern way of 1.2 instead of making efforts to adapt to the old 1.0 way or plugin the plugin (adapting the adaption), that is AnnouncerPlugin. We already have that many Plugins that make core updates harder.

Any major migration issues with 1.0 to 1.2? I'll test on a snapshot anyway.
 
If I understand you correctly you want notification subscriptions exactly like the CC field provides, but for a custom field.
So I think you could basically copy the component that implements the CC field notifications (CarbonCopySubscriber) and replace 'cc' by your custom field name.
https://trac.edgewall.org/browser/trunk/trac/ticket/notification.py?rev=15148&marks=712-759#L711

That could look something like this (untested):
...

Is that code already something that would work as a single-file plugin.py in ./plugins already?



Beside from that, a rule framework configurable on the user preferences would be preferable. I checked
https://www.trac-hacks.org/wiki/MailPlugin
But it can't search for custom fields as those are not in the ticket table:

Invalid SQL-String:

select id,summary from ticket where developer='Mo'

Best regards,
Mo

Peter Suter

unread,
Jan 5, 2017, 2:10:37 PM1/5/17
to trac-...@googlegroups.com
On 05.01.2017 11:17, Mo wrote:

Any major migration issues with 1.0 to 1.2? I'll test on a snapshot anyway.

Not really, but it maybe depends on what you consider major. Make sure to check:
https://trac.edgewall.org/wiki/TracUpgrade
https://trac.edgewall.org/wiki/TracUpgrade#to1.2
https://trac.edgewall.org/wiki/TracUpgrade#KnownIssues

And especially check all your Plugins! A lot of old plugins from the Trac 0.x days had / have yet to be updated:
https://trac-hacks.org/query?release=1.2&group=status&col=id&col=summary&col=owner&col=type&col=status&col=priority&col=component&order=priority


That could look something like this (untested):
...

Is that code already something that would work as a single-file plugin.py in ./plugins already?
Yes, except I made a small mistake: Replace `user_set` by `field_set`. Then it should work.


Beside from that, a rule framework configurable on the user preferences would be preferable.
Could you explain a bit more what kind of flexibility you're looking for?
The single-file plugin subscriber actually adds a rule that can be configured in the user preferences (and / or by the site admin as overridable default).
The basics rules available by default look something like this:
https://trac.edgewall.org/attachment/wiki/TracDev/Proposals/AdvancedNotification/notification-subscription-prefs.png

But you can add more subscribers like above to get more rules in the Trac 1.2 framework.
Adding some that are similar to those in Announcer you would get this:
https://trac.edgewall.org/attachment/ticket/11870/watch-prefs.png

I'm not familiar with that plugin, but it's likely it won't work unchanged with Trac 1.2.

Best regards,
Peter

Mo

unread,
Jan 6, 2017, 5:35:02 AM1/6/17
to Trac Users

Am Donnerstag, 5. Januar 2017 20:10:37 UTC+1 schrieb Peter Suter:
 
Could you explain a bit more what kind of flexibility you're looking for?
The single-file plugin subscriber actually adds a rule that can be configured in the user preferences (and / or by the site admin as overridable default).
The basics rules available by default look something like this:
https://trac.edgewall.org/attachment/wiki/TracDev/Proposals/AdvancedNotification/notification-subscription-prefs.png

Thank you, I wasn't aware this adds anothers rule to the set that every user can configure. I thought it just implements a static global rule. This is very flexible.

Concerning the Trac 1.2 update. I got all plugins updated and working except these issue:
Major blocker is https://trac-hacks.org/ticket/13031 as no user can login anymore by the AccountManagerPlugin.

Then I had some minor issues on thos plugin that I temporarilly just disabled:
WatchListPlugin: https://trac-hacks.org/ticket/13030

Best regards,
Mo

Mo

unread,
Jan 9, 2017, 3:22:37 AM1/9/17
to Trac Users
Am Freitag, 6. Januar 2017 11:35:02 UTC+1 schrieb Mo:

Concerning the Trac 1.2 update. I got all plugins updated and working except these issue:
...
Additionally:
FieldToolTip Plugin: https://trac-hacks.org/ticket/13033

I should rather start a 1.2 migration thread..

Best regards,
Mo

Mo

unread,
Jan 16, 2017, 9:51:41 AM1/16/17
to Trac Users
Am Mittwoch, 4. Januar 2017 19:51:59 UTC+1 schrieb Peter Suter:

    def description(self):
        return "Ticket that I'm listed in as %s is modified" % self.field_name

Learning Python and INotificationSubscriber...
How would I replace that field_name by the real label text configured in trac.ini?

Mo

unread,
Jan 16, 2017, 10:10:21 AM1/16/17
to Trac Users
When subscribing to my custom rule, I get this error message:

Warning: The change has been saved, but an error occurred while sending notifications: Cannot find implementation(s) of the IEmailAddressResolver interface named DefaultDomainEmailResolver, SpecifiedEmailResolver. Please check that the Component is enabled or update the option [notification] email_address_resolvers in trac.ini.
 
I did not set email_address_resolvers, so having the default it should be set to SessionEmailResolver, according https://trac.edgewall.org/wiki/TracIni#notification-email_address_resolvers-option.
There is no other option.
When I was using AnnouncerPlugin on Trac 1.0.9 I had email_address_resolvers = SpecifiedEmailResolver,SessionEmailResolver,DefaultDomainEmailResolver.

Now without AccountManagerPlugin I can't even set some Email-Adresses anymore, but Trac still knows them somehow.

Best regards,
Mo

Mo

unread,
Jan 16, 2017, 10:25:22 AM1/16/17
to Trac Users
Am Montag, 16. Januar 2017 16:10:21 UTC+1 schrieb Mo:

I did not set email_address_resolvers, so having the default it should be set to SessionEmailResolver, according https://trac.edgewall.org/wiki/TracIni#notification-email_address_resolvers-option.
There is no other option.
When I was using AnnouncerPlugin on Trac 1.0.9 I had email_address_resolvers = SpecifiedEmailResolver,SessionEmailResolver,DefaultDomainEmailResolver.

Sorry, the old setting was still enabled when I copy-pasted from old [announcer] to [notification]. I deleted that line, and it's working now.
Still the question, which resolvers are there and how are email adresses determined without AccountManagerPlugin and basic auth via webserver only.

BR, Mo

Peter Suter

unread,
Jan 16, 2017, 2:51:01 PM1/16/17
to trac-...@googlegroups.com

Try:

from trac.ticket.api import
TicketSystem

def description(self):
    ticket_system = TicketSystem(self.env)
    ticket_field_labels = ticket_system.get_ticket_field_labels()
    field_label = ticket_field_labels[self.field_name]
    return "Ticket that I'm listed in as %s is modified" % field_label

(Untested)

Peter Suter

unread,
Jan 16, 2017, 2:59:33 PM1/16/17
to trac-...@googlegroups.com

Sorry, I don't fully understand your question.

SessionEmailResolver is the only one by default. AccountManagerPlugin is not involved in this I think.

Possibly your problem is related to https://trac.edgewall.org/ticket/12660?
All active IEmailAddressResolver components are always used in Trac 1.2, even if not listed in email_address_resolvers. (This will be fixed in Trac 1.2.1.)

Reply all
Reply to author
Forward
0 new messages