source: trunk/trac-hacks/announcerplugin/announcerplugin/subscribers/ticket_compat.py @ 745

Revision 745, 8.9 KB checked in by rcorsaro, 5 years ago (diff)

merged latest announcer trac-hacks commits

Line 
1from trac.core import Component, implements
2from announcerplugin.api import IAnnouncementSubscriber, IAnnouncementPreferenceProvider, istrue
3from trac.ticket import model
4from trac.web.chrome import add_warning
5from trac.config import BoolOption
6import re
7from trac.resource import ResourceNotFound
8
9class StaticTicketSubscriber(Component):
10    """The static ticket subscriber implements a policy to -always- send an email to a
11    certain address. Controlled via the smtp_always_bcc option in the announcer
12    section of the trac.ini"""
13   
14    implements(IAnnouncementSubscriber)
15   
16    def __init__(self):
17        bcc = self.config.get('announcer', 'smtp_always_bcc')
18        if bcc:
19            self._returnval = ('*', )
20            self.bcc = bcc
21        else:
22            self._returnval = tuple()
23           
24    def get_subscription_realms(self):
25        self._returnval
26       
27    def get_subscription_categories(self, realm):
28        return self._returnval
29       
30    def get_subscriptions_for_event(self, event):
31        self.log.debug("StaticTicketSubscriber added '%s' because of rule: smtp_always_bcc" % self.bcc)
32        yield ('email', None, False, self.bcc)
33
34class LegacyTicketSubscriber(Component):
35    implements(IAnnouncementSubscriber, IAnnouncementPreferenceProvider)
36   
37    always_notify_owner = BoolOption("announcer", "always_notify_owner", False, 
38        """The always_notify_owner option mimics the option of the same name in the
39        notification section, except users can opt-out in their preferences. Used
40        only if LegacyTicketSubscriber is enabled.""")
41
42    always_notify_reporter = BoolOption("announcer", "always_notify_reporter", False, 
43        """The always_notify_reporter option mimics the option of the same name in the
44        notification section, except users can opt-out in their preferences. Used
45        only if LegacyTicketSubscriber is enabled.""")
46
47    always_notify_updater = BoolOption("announcer", "always_notify_updater", False, 
48        """The always_notify_updater option mimics the option of the same name in the
49        notification section, except users can opt-out in their preferences. Used
50        only if LegacyTicketSubscriber is enabled.""")
51
52    always_notify_component_owner = BoolOption("announcer", 
53            "always_notify_component_owner", True,
54            """Whether or not to notify the owner of the ticket's
55            component.""")
56       
57    def get_announcement_preference_boxes(self, req):
58        yield "legacy", "Ticket Notifications"
59
60    def render_announcement_preference_box(self, req, panel):
61        cfg = self.config
62        sess = req.session
63       
64        always_notify_owner = istrue(
65            cfg.get('announcer', 'always_notify_owner', None)
66        )
67        always_notify_reporter = istrue(
68            cfg.get('announcer', 'always_notify_reporter', None)
69        )
70        always_notify_updater = istrue(
71            cfg.get('announcer', 'always_notify_updater', None)
72        )
73
74        if req.method == "POST":
75            if always_notify_owner:
76                sess['announcer_legacy_notify_owner'] = unicode(req.args.get('legacy_notify_owner', False))
77            if always_notify_reporter:
78                sess['announcer_legacy_notify_reporter'] = unicode(req.args.get('legacy_notify_reporter', False))
79            if always_notify_updater:
80                sess['announcer_legacy_notify_updater'] = unicode(req.args.get('legacy_notify_updater', False))
81       
82        data = dict(
83            always_notify_owner = always_notify_owner,
84            always_notify_reporter = always_notify_reporter,
85            always_notify_updater = always_notify_updater,
86            legacy_notify_owner = istrue(sess.get('announcer_legacy_notify_owner', True), None),
87            legacy_notify_reporter = istrue(sess.get('announcer_legacy_notify_reporter', True), None),
88            legacy_notify_updater = istrue(sess.get('announcer_legacy_notify_updater', True), None),
89        )
90       
91        return "prefs_announcer_legacy.html", data
92
93    def get_subscription_realms(self):
94        return ('ticket',)
95       
96    def get_subscription_categories(self, realm):
97        if realm == 'ticket':
98            return ('created', 'changed', 'attachment added')
99        else:
100            return tuple()
101           
102    def get_subscriptions_for_event(self, event):
103        if event.realm == "ticket":
104            ticket = event.target
105           
106            if event.category in ('created', 'changed', 'attachment added'):
107                if self.always_notify_component_owner:
108                    try:
109                        # this throws an exception if the component does not exist
110                        component = model.Component(self.env, ticket['component'])
111                        if component.owner:
112                            self.log.debug("LegacyTicketSubscriber added '%s' because of rule: component owner" % (component.owner,))
113                            yield ('email', component.owner, True, None)
114                    except ResourceNotFound, message:
115                        self.log.warn("LegacyTicketSubscriber couldn't add component owner because component was not found, message: '%s'" % (message,))   
116
117                if self.always_notify_owner and ticket['owner'] and not self._check_opt_out('notify_owner', ticket['owner']):                   
118                    owner = ticket['owner']
119                    if '@' in owner:
120                        name, authenticated, address = None, False, owner
121                    else:
122                        name, authenticated, address = owner, True, None
123                   
124                    self.log.debug(
125                        "LegacyTicketSubscriber added '%s (%s)' because of rule: always_notify_owner" % (
126                            owner, authenticated and 'authenticated' or 'not authenticated'
127                        )
128                    )
129                    yield ('email', name, authenticated, address)
130                   
131                if self.always_notify_reporter and ticket['reporter'] and not self._check_opt_out('notify_reporter', ticket['reporter']):
132                    reporter = ticket['reporter']
133                    if '@' in reporter:
134                        name, authenticated, address = None, False, reporter
135                    else:
136                        name, authenticated, address = reporter, True, None
137                   
138                    self.log.debug(
139                        "LegacyTicketSubscriber added '%s (%s)' because of rule: always_notify_reporter" % (
140                            reporter, authenticated and 'authenticated' or 'not authenticated'
141                        )
142                    )
143                    yield ('email', name, authenticated, address)
144                   
145                if self.always_notify_updater and event.author and not self._check_opt_out('notify_updater', event.author):
146                    self.log.debug("LegacyTicketSubscriber added '%s (authenticated)' because of rule: always_notify_updater" % event.author)
147                    yield ('email', event.author, True, None)
148           
149        return
150       
151    def _check_opt_out(self, preference, sid):
152        db = self.env.get_db_cnx()
153        cursor = db.cursor()
154       
155        cursor.execute("""
156            SELECT value
157              FROM session_attribute
158             WHERE sid=%s
159               AND authenticated=1
160               AND name=%s
161        """, (sid, 'announcer_legacy_' + preference))
162               
163        result = cursor.fetchone()
164        if result:
165            optout = (result[0] == '0')
166            if optout:
167                self.log.debug("LegacyTicketSubscriber excluded '%s' because of opt-out rule: %s" % (sid,preference))
168                return True
169       
170        return False
171
172class CarbonCopySubscriber(Component):
173    implements(IAnnouncementSubscriber)
174   
175    def get_subscription_realms(self):
176        return ('ticket',)
177       
178    def get_subscription_categories(self, realm):
179        if realm == 'ticket':
180            return ('created', 'changed', 'attachment added')
181        else:
182            return tuple()
183       
184    def get_subscriptions_for_event(self, event):
185        if event.realm == 'ticket':
186            if event.category in ('created', 'changed', 'attachment added'):
187                cc = event.target['cc']
188                for chunk in re.split('\s|,', cc):
189                    chunk = chunk.strip()
190                    if not chunk or chunk.startswith('@'):
191                        continue
192                       
193                    if '@' in chunk:
194                        address = chunk
195                        name = None
196                    else:
197                        name = chunk
198                        address = None
199                       
200                    if name or address:
201                        self.log.debug("CarbonCopySubscriber added '%s <%s>' because of rule: carbon copied" % (name,address))
202                        yield ('email', name, name and True or False, address)
203       
Note: See TracBrowser for help on using the repository browser.