
shansen at advpubtech
Jul 22, 2004, 10:36 PM
Post #1 of 3
(358 views)
Permalink
|
|
Notification (Proposed patch too)
|
|
Sooo. The only thing reeeally preventing me from making use of this wonderful system is notifications. And, since I think I have some fairly specific needs, I wrote a notification module. I also modified the ticket.py to make use of it. Using it is easy; customizing it is even easier. Basically, I wrote a base notification class which does nothing, and wrote a bunch of mixins or plug-ins. Then, one generates a 'TicketNotifier' class with whatever base classes they want to get their desired behavior. E.g: class TicketNotifier(BaseTicketNotifier, TicketFieldDiscoveryMixin, TicketCcDiscoveryMixin, DomainResolverMixin, SMTPTransportMixin): def __init__(self, *args, **kwargs): BaseTicketNotifier.__init__(self, *args, **kwargs) self.setTicketFields("owner", "reporter") self.setSender("Trac <trac [at] ixokai>") self.setServer("localhost", 25) self.setDomain("ixokai.net") I know that looks really complicated, but its not so much :) There are basically three stages of events that occur after you .send() from in Ticket.py. The first stage is discovery of who to send the notifications to. - The TicketFieldDiscovery will grab names from arbitrary fields in the ticket table. setTicketFields("owner", "reporter") controls which fields. - TicketCcDiscovery does the same thing, but splits names up out of the 'CC' field. - The ComponentOwnerDiscovery will include the owner of the tickets component. (Not used above) - The TicketAuthorDiscovery will include the name of the person making the change. Er, this should probably be ChangeAuthor. Or some other name. (Not used above) Note that all discovery mixins will be called in turn Next comes the Resolver stage, where it takes a name and makes it into an address. I left in two resolvers and took out my wacky one. - DomainResolver simply appends a domain name to the end of the user. - EmailResolver simply returns the name if its an email address. Note that all the resolvers are tried in turn until one returns a valid name. If they all fail, no mail will be sent to that name. Finally, the Transport happens. This actually formats the message and sends it. I included two. - SendmailTransport -- calls /usr/bin/sendmail and pipes the message to them. - SMTPTransport -- uses smtplib to connect to a server. All Transports are called in turn, so you could have an IM or IRC transport and they would all send messages as appropriate. Different plug-ins may have different options, my __init__ up there calls them. Anyways: you can fully customize the behavior by just using different plugins or writing your own. Its entirely possible this is more complicated then you want to include, and that's cool. But it was fun to do and it solves my problem for now :) --Stephen -------------- next part -------------- A non-text attachment was scrubbed... Name: Ticket.py.patch Type: application/octet-stream Size: 3330 bytes Desc: not available Url : /archive/trac/attachments/20040311/00771ea3/Ticket.py.a -------------- next part -------------- A non-text attachment was scrubbed... Name: notify.tgz Type: application/octet-stream Size: 10124 bytes Desc: not available Url : /archive/trac/attachments/20040311/00771ea3/notify.a
|