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

Revision 559, 8.7 KB checked in by dgynn, 5 years ago (diff)

updating announcerplugin to  th:changeset:4427

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    def get_announcement_preference_boxes(self, req):
53        yield "legacy", "Legacy Notification (Opt-Out)"
54
55    def render_announcement_preference_box(self, req, panel):
56        cfg = self.config
57        sess = req.session
58       
59        always_notify_owner = istrue(
60            cfg.get('announcer', 'always_notify_owner', None)
61        )
62        always_notify_reporter = istrue(
63            cfg.get('announcer', 'always_notify_reporter', None)
64        )
65        always_notify_updater = istrue(
66            cfg.get('announcer', 'always_notify_updater', None)
67        )
68
69        if req.method == "POST":
70            if always_notify_owner:
71                sess['announcer_legacy_notify_owner'] = req.args.get('legacy_notify_owner', False)
72            if always_notify_reporter:
73                sess['announcer_legacy_notify_reporter'] = req.args.get('legacy_notify_reporter', False)
74            if always_notify_updater:
75                sess['announcer_legacy_notify_updater'] = req.args.get('legacy_notify_updater', False)
76       
77        data = dict(
78            always_notify_owner = always_notify_owner,
79            always_notify_reporter = always_notify_reporter,
80            always_notify_updater = always_notify_updater,
81            legacy_notify_owner = istrue(sess.get('announcer_legacy_notify_owner', True), None),
82            legacy_notify_reporter = istrue(sess.get('announcer_legacy_notify_reporter', True), None),
83            legacy_notify_updater = istrue(sess.get('announcer_legacy_notify_updater', True), None),
84        )
85       
86        return "prefs_announcer_legacy.html", data
87
88    def get_subscription_realms(self):
89        return ('ticket',)
90       
91    def get_subscription_categories(self, realm):
92        if realm == 'ticket':
93            return ('created', 'changed', 'attachment added')
94        else:
95            return tuple()
96           
97    def get_subscriptions_for_event(self, event):
98        if event.realm == "ticket":
99            ticket = event.target
100           
101            if event.category in ('created', 'changed', 'attachment added'):
102                try:
103                    # this throws an exception if the component does not exist
104                    component = model.Component(self.env, ticket['component'])
105                    if component.owner:
106                        ## TODO: Is this an option?
107                        self.log.debug("LegacyTicketSubscriber added '%s' because of rule: component owner" % (component.owner,))
108                        yield ('email', component.owner, True, None)
109                except ResourceNotFound, message:
110                    self.log.warn("LegacyTicketSubscriber couldn't add component owner because component was not found, message: '%s'" % (message,))   
111
112                if self.always_notify_owner and ticket['owner'] and not self._check_opt_out('notify_owner', ticket['owner']):                   
113                    owner = ticket['owner']
114                    if '@' in owner:
115                        name, authenticated, address = None, False, owner
116                    else:
117                        name, authenticated, address = owner, True, None
118                   
119                    self.log.debug(
120                        "LegacyTicketSubscriber added '%s (%s)' because of rule: always_notify_owner" % (
121                            owner, authenticated and 'authenticated' or 'not authenticated'
122                        )
123                    )
124                    yield ('email', name, authenticated, address)
125                   
126                if self.always_notify_reporter and ticket['reporter'] and not self._check_opt_out('notify_reporter', ticket['reporter']):
127                    reporter = ticket['reporter']
128                    if '@' in reporter:
129                        name, authenticated, address = None, False, reporter
130                    else:
131                        name, authenticated, address = reporter, True, None
132                   
133                    self.log.debug(
134                        "LegacyTicketSubscriber added '%s (%s)' because of rule: always_notify_reporter" % (
135                            reporter, authenticated and 'authenticated' or 'not authenticated'
136                        )
137                    )
138                    yield ('email', name, authenticated, address)
139                   
140                if self.always_notify_updater and event.author and not self._check_opt_out('notify_updater', event.author):
141                    self.log.debug("LegacyTicketSubscriber added '%s (authenticated)' because of rule: always_notify_updater" % event.author)
142                    yield ('email', event.author, True, None)
143           
144        return
145       
146    def _check_opt_out(self, preference, sid):
147        db = self.env.get_db_cnx()
148        cursor = db.cursor()
149       
150        cursor.execute("""
151            SELECT value
152              FROM session_attribute
153             WHERE sid=%s
154               AND authenticated=1
155               AND name=%s
156        """, (sid, 'announcer_legacy_' + preference))
157               
158        result = cursor.fetchone()
159        if result:
160            optout = (result[0] == '0')
161            if optout:
162                self.log.debug("LegacyTicketSubscriber excluded '%s' because of opt-out rule: %s" % (sid,preference))
163                return True
164       
165        return False
166
167class CarbonCopySubscriber(Component):
168    implements(IAnnouncementSubscriber)
169   
170    def get_subscription_realms(self):
171        return ('ticket',)
172       
173    def get_subscription_categories(self, realm):
174        if realm == 'ticket':
175            return ('created', 'changed', 'attachment added')
176        else:
177            return tuple()
178       
179    def get_subscriptions_for_event(self, event):
180        if event.realm == 'ticket':
181            if event.category in ('created', 'changed', 'attachment added'):
182                cc = event.target['cc']
183                for chunk in re.split('\s|,', cc):
184                    chunk = chunk.strip()
185                    if not chunk or chunk.startswith('@'):
186                        continue
187                       
188                    if '@' in chunk:
189                        address = chunk
190                        name = None
191                    else:
192                        name = chunk
193                        address = None
194                       
195                    if name or address:
196                        self.log.debug("CarbonCopySubscriber added '%s <%s>' because of rule: carbon copied" % (name,address))
197                        yield ('email', name, name and True or False, address)
198       
Note: See TracBrowser for help on using the repository browser.