コード例 #1
0
 def _validate_mimebody(self, mime, ticket, newtk):
     """Body of a ticket notification message"""
     (mime_decoder, mime_name, mime_charset) = mime
     tn = TicketNotifyEmail(self.env)
     tn.notify(ticket, newticket=newtk)
     message = notifysuite.smtpd.get_message()
     (headers, body) = parse_smtp_message(message)
     self.failIf('MIME-Version' not in headers)
     self.failIf('Content-Type' not in headers)
     self.failIf('Content-Transfer-Encoding' not in headers)
     self.failIf(not re.compile(r"1.\d").match(headers['MIME-Version']))
     type_re = re.compile(r'^text/plain;\scharset="([\w\-\d]+)"$')
     charset = type_re.match(headers['Content-Type'])
     self.failIf(not charset)
     charset = charset.group(1)
     self.assertEqual(charset, mime_charset)
     self.assertEqual(headers['Content-Transfer-Encoding'], mime_name)
     # checks the width of each body line
     for line in body.splitlines():
         self.failIf(len(line) > MAXBODYWIDTH)
     # attempts to decode the body, following the specified MIME endoding 
     # and charset
     try:
         if mime_decoder:
             body = mime_decoder.decodestring(body)
         body = unicode(body, charset)
     except Exception, e:
         raise AssertionError, e
コード例 #2
0
 def _test_updater(disable):
     if disable:
         self.env.config.set('notification','always_notify_updater',
                             'false')
     ticket = Ticket(self.env)
     ticket['reporter'] = '*****@*****.**'
     ticket['summary'] = u'This is a súmmäry'
     ticket['cc'] = '*****@*****.**'
     ticket.insert()
     ticket['component'] = 'dummy'
     now = time.time()
     ticket.save_changes('*****@*****.**', 'This is a change',
                         when=now)
     tn = TicketNotifyEmail(self.env)
     tn.notify(ticket, newticket=False, modtime=now)
     message = notifysuite.smtpd.get_message()
     (headers, body) = parse_smtp_message(message)
     # checks for header existence
     self.failIf(not headers)
     # checks for updater in the 'To' recipient list
     self.failIf('To' not in headers)
     tolist = [addr.strip() for addr in headers['To'].split(',')]
     if disable:
         self.failIf('*****@*****.**' in tolist)
     else:
         self.failIf('*****@*****.**' not in tolist)
コード例 #3
0
 def test_recipients(self):
     """To/Cc recipients"""
     ticket = Ticket(self.env)
     ticket['reporter'] = '"Joe User" <*****@*****.**>'
     ticket['owner']    = '*****@*****.**'
     ticket['cc']       = '[email protected], [email protected], ' \
                          '*****@*****.**'
     ticket['summary'] = 'Foo'
     ticket.insert()
     tn = TicketNotifyEmail(self.env)
     tn.notify(ticket, newticket=True)
     recipients = notifysuite.smtpd.get_recipients()
     # checks there is no duplicate in the recipient list
     rcpts = []
     for r in recipients:
         self.failIf(r in rcpts)
         rcpts.append(r)
     # checks that all cc recipients have been notified
     cc_list = self.env.config.get('notification', 'smtp_always_cc')
     cc_list = "%s, %s" % (cc_list, ticket['cc'])
     for r in cc_list.replace(',', ' ').split():
         self.failIf(r not in recipients)
     # checks that owner has been notified
     self.failIf(smtp_address(ticket['owner']) not in recipients)
     # checks that reporter has been notified
     self.failIf(smtp_address(ticket['reporter']) not in recipients)
コード例 #4
0
ファイル: manager.py プロジェクト: pombredanne/trachacks
    def save_ticket(self, tckt, msg):
        # determine sequence number...
        cnum = 0
        tm = TicketModule(self.env)
        for change in tm.grouped_changelog_entries(tckt, None):
            if change['permanent']:
                cnum += 1
        nowdt = self.now
        nowdt = to_datetime(nowdt)
        tckt.save_changes(self.authname, msg, nowdt, cnum=str(cnum + 1))
        ## Often the time overlaps and causes a db error,
        ## especially when the trac integration post-commit hook is used.
        ## NOTE TO SELF. I DON'T THINK THIS IS NECESSARY RIGHT NOW...
        #count = 0
        #while count < 10:
        #    try:
        #        tckt.save_changes(self.authname, msg, self.now, cnum=cnum+1)
        #        count = 42
        #    except Exception, e:
        #        self.now += 1
        #        count += 1

        tn = TicketNotifyEmail(self.env)
        tn.notify(tckt, newticket=0, modtime=nowdt)
        # We fudge time as it has to be unique
        self.now += 1
コード例 #5
0
def handle_commit(commit, env):
    from trac.ticket.notification import TicketNotifyEmail
    from trac.ticket import Ticket
    from trac.util.text import to_unicode
    from trac.util.datefmt import utc

    msg = to_unicode(call_git('rev-list', ['-n', '1', commit, '--pretty=medium']).rstrip())
    eml = to_unicode(call_git('rev-list', ['-n', '1', commit, '--pretty=format:%ae']).splitlines()[1])
    now = datetime.now(utc)

    tickets = {}
    for cmd, tkts in command_re.findall(msg.split('\n\n', 1)[1]):
        action = COMMANDS.get(cmd.lower())
        if action:
            for tkt_id in ticket_re.findall(tkts):
                tickets.setdefault(tkt_id, []).append(action)

    for tkt_id, actions in tickets.iteritems():
        try:
            db = env.get_db_cnx()
            ticket = Ticket(env, int(tkt_id), db)

            if 'close' in actions:
                ticket['status'] = 'closed'
                ticket['resolution'] = 'fixed'

            # trac 1.0: `db` parameter is no longer needed and will be removed in 1.1.1
            # trac 1.0: `cnum` parameter is deprecated
            ticket.save_changes(eml, msg, now)
            db.commit()

            tn = TicketNotifyEmail(env)
            tn.notify(ticket, newticket=0, modtime=now)
        except Exception, e:
            print >>sys.stderr, 'Unexpected error while processing ticket ID %s: %s' % (tkt_id, e)
コード例 #6
0
ファイル: theme.py プロジェクト: domaemon/bloodhound-qa
    def create(self, req, summary, description, attributes = {}, notify=False):
        """ Create a new ticket, returning the ticket ID. 

        PS: Borrowed from XmlRpcPlugin.
        """
        t = Ticket(self.env)
        t['summary'] = summary
        t['description'] = description
        t['reporter'] = req.authname
        for k, v in attributes.iteritems():
            t[k] = v
        t['status'] = 'new'
        t['resolution'] = ''
        t.insert()
        # Call ticket change listeners
        ts = TicketSystem(self.env)
        for listener in ts.change_listeners:
            listener.ticket_created(t)
        if notify:
            try:
                tn = TicketNotifyEmail(self.env)
                tn.notify(t, newticket=True)
            except Exception, e:
                self.log.exception("Failure sending notification on creation "
                                   "of ticket #%s: %s" % (t.id, e))
コード例 #7
0
    def apply_action_side_effects(self, req, ticket, action):
        """Add a cross-reference comment to the other ticket"""
        # TODO: This needs a lot more error checking.
        id = 'action_%s_xref' % action
        ticketnum = req.args.get(id).strip('#')
        actions = self.get_configurable_workflow().actions
        author = req.authname

        # Add a comment to the "remote" ticket to indicate this ticket is
        # related to it.
        format_string = actions[action].get(
            'xref', 'Ticket %s is related to this ticket')
        comment = format_string % ('#%s' % ticket.id)
        # FIXME: we need a cnum to avoid messing up
        xticket = model.Ticket(self.env, ticketnum)
        # FIXME: We _assume_ we have sufficient permissions to comment on the
        # other ticket.
        now = datetime.now(utc)
        xticket.save_changes(author, comment, now)

        #Send notification on the other ticket
        try:
            tn = TicketNotifyEmail(self.env)
            tn.notify(xticket, newticket=False, modtime=now)
        except Exception, e:
            self.log.exception("Failure sending notification on change to "
                               "ticket #%s: %s" % (ticketnum, e))
コード例 #8
0
 def _test_default_domain(enabled):
     self.env.config.set('notification', 'always_notify_owner',
                         'false')
     self.env.config.set('notification', 'always_notify_reporter',
                         'false')
     self.env.config.set('notification', 'smtp_always_cc', '')
     ticket = Ticket(self.env)
     ticket['cc'] = 'joenodom, [email protected]'
     ticket['summary'] = 'This is a summary'
     ticket.insert()
     # Be sure that at least one email address is valid, so that we 
     # send a notification even if other addresses are not valid
     self.env.config.set('notification', 'smtp_always_cc',
                         '*****@*****.**')
     if enabled:
         self.env.config.set('notification', 'smtp_default_domain',
                             'example.org')
     tn = TicketNotifyEmail(self.env)
     tn.notify(ticket, newticket=True)
     message = notifysuite.smtpd.get_message()
     (headers, body) = parse_smtp_message(message)
     # Msg should always have a 'Cc' field
     self.failIf('Cc' not in headers)
     cclist = [addr.strip() for addr in headers['Cc'].split(',')]
     self.failIf('*****@*****.**' not in cclist)
     self.failIf('*****@*****.**' not in cclist)
     if not enabled:
         self.failIf(len(cclist) != 2)
         self.failIf('joenodom' in cclist)
     else:
         self.failIf(len(cclist) != 3)
         self.failIf('*****@*****.**' not in cclist)
コード例 #9
0
ファイル: notification.py プロジェクト: gdgkyoto/kyoto-gtug
 def test_ignore_domains(self):
     """Non-SMTP domain exclusion"""
     self.env.config.set('notification', 'ignore_domains',
                         'example.com, example.org')
     self.env.known_users = \
         [('*****@*****.**', 'No Email', ''), 
          ('*****@*****.**', 'With Email', '*****@*****.**')]
     ticket = Ticket(self.env)
     ticket['reporter'] = '*****@*****.**'
     ticket['owner'] = '*****@*****.**'
     ticket['summary'] = 'This is a summary'
     ticket.insert()
     tn = TicketNotifyEmail(self.env)
     tn.notify(ticket, newticket=True)
     message = notifysuite.smtpd.get_message()
     (headers, body) = parse_smtp_message(message)
     # Msg should always have a 'To' field
     self.failIf('To' not in headers)
     tolist = [addr.strip() for addr in headers['To'].split(',')]
     # 'To' list should not contain addresses with non-SMTP domains
     self.failIf('*****@*****.**' in tolist)
     self.failIf('*****@*****.**' in tolist)
     # 'To' list should have been resolved to the actual email address
     self.failIf('*****@*****.**' not in tolist)
     self.failIf(len(tolist) != 1)
コード例 #10
0
ファイル: svn_hooks.py プロジェクト: djangsters/agilo
 def execute(self):
     """Execute the parsed commands"""
     #print "Commands: %s" % self.commands
     # Now parse the command in the ticket, and react accordingly
     # Cannnot produce error messages, as the pre-commit-hook would have failed already
     parser = CommitMessageCommandParser(self.env, self.changeset.message)
     parsed_commands = parser.validate_and_parse_commit_message()
     self.commands = dict()
     for command, ticket_id, remaining_time in parsed_commands:
         # REFACT: the parser should give the ids as ints already
         ticket_id = int(ticket_id)
         self.commands.setdefault(ticket_id, list())
         self.commands.get(ticket_id).append(
             self.findCommand(command, remaining=remaining_time[:-1]))
     # Sort the ticket in reverse order by id, it will be most likely
     # that a task is existing after a User Story has been created, 
     # in which case it will be possible to execute multiple command in
     # a hierarchy. TODO: Check hierarchy, but very expensive
     keys = self.commands.keys()
     keys.sort(reverse=True)
     for t_id, cmds in [(key, self.commands[key]) for key in keys]:
         ticket = self.tm.get(tkt_id=t_id)
         for cmd in cmds:
             cmd(ticket)
         self.tm.save(ticket, author=self.author, comment=self.message)
         from trac.ticket.notification import TicketNotifyEmail
         tn = TicketNotifyEmail(self.env)
         tn.notify(ticket, newticket=False, modtime=ticket.time_changed)
     # We need to invalidate the chart cache here because some tickets may
     # have been closed through commit comments. Unfortunately there is 
     # no way to access the shared memory right now, see #565
     return True
コード例 #11
0
ファイル: controller.py プロジェクト: lkraav/trachacks
    def apply_action_side_effects(self, req, ticket, action):
        """Add a cross-reference comment to the other ticket"""
        # TODO: This needs a lot more error checking.
        id = 'action_%s_xref' % action
        ticketnum = req.args.get(id).strip('#')
        actions = self.get_configurable_workflow().actions
        author = req.authname

        # Add a comment to the "remote" ticket to indicate this ticket is
        # related to it.
        format_string = actions[action].get('xref',
                                        'Ticket %s is related to this ticket')
        comment = format_string % ('#%s' % ticket.id)
        # FIXME: we need a cnum to avoid messing up 
        xticket = model.Ticket(self.env, ticketnum)
        # FIXME: We _assume_ we have sufficient permissions to comment on the
        # other ticket.
        now = datetime.now(utc)
        xticket.save_changes(author, comment, now)

        #Send notification on the other ticket
        try:
            tn = TicketNotifyEmail(self.env)
            tn.notify(xticket, newticket=False, modtime=now)
        except Exception, e:
            self.log.exception("Failure sending notification on change to "
                               "ticket #%s: %s" % (ticketnum, e))
コード例 #12
0
 def _validate_mimebody(self, mime, ticket, newtk):
     """Body of a ticket notification message"""
     (mime_decoder, mime_name, mime_charset) = mime
     tn = TicketNotifyEmail(self.env)
     tn.notify(ticket, newticket=newtk)
     message = notifysuite.smtpd.get_message()
     (headers, body) = parse_smtp_message(message)
     self.failIf('MIME-Version' not in headers)
     self.failIf('Content-Type' not in headers)
     self.failIf('Content-Transfer-Encoding' not in headers)
     self.failIf(not re.compile(r"1.\d").match(headers['MIME-Version']))
     type_re = re.compile(r'^text/plain;\scharset="([\w\-\d]+)"$')
     charset = type_re.match(headers['Content-Type'])
     self.failIf(not charset)
     charset = charset.group(1)
     self.assertEqual(charset, mime_charset)
     self.assertEqual(headers['Content-Transfer-Encoding'], mime_name)
     # checks the width of each body line
     for line in body.splitlines():
         self.failIf(len(line) > MAXBODYWIDTH)
     # attempts to decode the body, following the specified MIME endoding
     # and charset
     try:
         if mime_decoder:
             body = mime_decoder.decodestring(body)
         body = unicode(body, charset)
     except Exception, e:
         raise AssertionError, e
コード例 #13
0
 def test_date(self):
     """Date format compliance (RFC822) 
        we do not support 'military' format""" 
     date_str = r"^((?P<day>\w{3}),\s*)*(?P<dm>\d{2})\s+" \
                r"(?P<month>\w{3})\s+(?P<year>200\d)\s+" \
                r"(?P<hour>\d{2}):(?P<min>[0-5][0-9])" \
                r"(:(?P<sec>[0-5][0-9]))*\s" \
                r"((?P<tz>\w{2,3})|(?P<offset>[+\-]\d{4}))$"
     date_re = re.compile(date_str)
     # python time module does not detect incorrect time values
     days = ['Mon','Tue','Wed','Thu','Fri','Sat','Sun']
     months = ['Jan','Feb','Mar','Apr','May','Jun', \
               'Jul','Aug','Sep','Oct','Nov','Dec']
     tz = ['UT','GMT','EST','EDT','CST','CDT','MST','MDT''PST','PDT']
     ticket = Ticket(self.env)
     ticket['reporter'] = '"Joe User" <*****@*****.**>'
     ticket['summary'] = 'This is a summary'
     ticket.insert()
     tn = TicketNotifyEmail(self.env)
     tn.notify(ticket, newticket=True)
     message = notifysuite.smtpd.get_message()
     (headers, body) = parse_smtp_message(message)
     self.failIf('Date' not in headers)
     mo = date_re.match(headers['Date'])
     self.failIf(not mo)
     if mo.group('day'):
         self.failIf(mo.group('day') not in days)
     self.failIf(int(mo.group('dm')) not in range(1,32))
     self.failIf(mo.group('month') not in months)
     self.failIf(int(mo.group('hour')) not in range(0,24))
     if mo.group('tz'):
         self.failIf(mo.group('tz') not in tz)
コード例 #14
0
 def _test_updater(disable):
     if disable:
         self.env.config.set('notification', 'always_notify_updater',
                             'false')
     ticket = Ticket(self.env)
     ticket['reporter'] = '*****@*****.**'
     ticket['summary'] = u'This is a súmmäry'
     ticket['cc'] = '*****@*****.**'
     ticket.insert()
     ticket['component'] = 'dummy'
     now = datetime.now(utc)
     ticket.save_changes('*****@*****.**',
                         'This is a change',
                         when=now)
     tn = TicketNotifyEmail(self.env)
     tn.notify(ticket, newticket=False, modtime=now)
     message = notifysuite.smtpd.get_message()
     (headers, body) = parse_smtp_message(message)
     # checks for header existence
     self.failIf(not headers)
     # checks for updater in the 'To' recipient list
     self.failIf('To' not in headers)
     tolist = [addr.strip() for addr in headers['To'].split(',')]
     if disable:
         self.failIf('*****@*****.**' in tolist)
     else:
         self.failIf('*****@*****.**' not in tolist)
コード例 #15
0
 def test_recipients(self):
     """To/Cc recipients"""
     ticket = Ticket(self.env)
     ticket['reporter'] = '"Joe User" < *****@*****.** >'
     ticket['owner'] = '*****@*****.**'
     ticket['cc']       = '[email protected], [email protected], ' \
                          '*****@*****.**'
     ticket['summary'] = 'Foo'
     ticket.insert()
     tn = TicketNotifyEmail(self.env)
     tn.notify(ticket, newticket=True)
     recipients = notifysuite.smtpd.get_recipients()
     # checks there is no duplicate in the recipient list
     rcpts = []
     for r in recipients:
         self.failIf(r in rcpts)
         rcpts.append(r)
     # checks that all cc recipients have been notified
     cc_list = self.env.config.get('notification', 'smtp_always_cc')
     cc_list = "%s, %s" % (cc_list, ticket['cc'])
     for r in cc_list.replace(',', ' ').split():
         self.failIf(r not in recipients)
     # checks that owner has been notified
     self.failIf(smtp_address(ticket['owner']) not in recipients)
     # checks that reporter has been notified
     self.failIf(smtp_address(ticket['reporter']) not in recipients)
コード例 #16
0
 def test_ignore_domains(self):
     """Non-SMTP domain exclusion"""
     self.env.config.set('notification', 'ignore_domains',
                         'example.com, example.org')
     self.env.known_users = \
         [('*****@*****.**', 'No Email', ''),
          ('*****@*****.**', 'With Email', '*****@*****.**')]
     ticket = Ticket(self.env)
     ticket['reporter'] = '*****@*****.**'
     ticket['owner'] = '*****@*****.**'
     ticket['summary'] = 'This is a summary'
     ticket.insert()
     tn = TicketNotifyEmail(self.env)
     tn.notify(ticket, newticket=True)
     message = notifysuite.smtpd.get_message()
     (headers, body) = parse_smtp_message(message)
     # Msg should always have a 'To' field
     self.failIf('To' not in headers)
     tolist = [addr.strip() for addr in headers['To'].split(',')]
     # 'To' list should not contain addresses with non-SMTP domains
     self.failIf('*****@*****.**' in tolist)
     self.failIf('*****@*****.**' in tolist)
     # 'To' list should have been resolved to the actual email address
     self.failIf('*****@*****.**' not in tolist)
     self.failIf(len(tolist) != 1)
コード例 #17
0
 def _test_short_login(enabled):
     ticket = Ticket(self.env)
     ticket['reporter'] = 'joeuser'
     ticket['summary'] = 'This is a summary'
     ticket.insert()
     # Be sure that at least one email address is valid, so that we 
     # send a notification even if other addresses are not valid
     self.env.config.set('notification', 'smtp_always_cc',
                         '*****@*****.**')
     if enabled:
         self.env.config.set('notification', 'use_short_addr', 'true')
     tn = TicketNotifyEmail(self.env)
     tn.notify(ticket, newticket=True)
     message = notifysuite.smtpd.get_message()
     (headers, body) = parse_smtp_message(message)
     # Msg should not have a 'To' header
     if not enabled:
         self.failIf('To' in headers)
     else:
         tolist = [addr.strip() for addr in headers['To'].split(',')]
     # Msg should have a 'Cc' field
     self.failIf('Cc' not in headers)
     cclist = [addr.strip() for addr in headers['Cc'].split(',')]
     if enabled:
         # Msg should be delivered to the reporter
         self.failIf(ticket['reporter'] not in tolist)
     else:
         # Msg should not be delivered to joeuser
         self.failIf(ticket['reporter'] in cclist)
     # Msg should still be delivered to the always_cc list
     self.failIf(self.env.config.get('notification',
                 'smtp_always_cc') not in cclist)
コード例 #18
0
 def test_email_map(self):
     """Login-to-email mapping"""
     self.env.config.set('notification', 'always_notify_owner', 'true')
     self.env.config.set('notification', 'always_notify_reporter', 'true')
     self.env.config.set('notification', 'smtp_always_cc',
                         '*****@*****.**')
     self.env.known_users = [
         ('joeuser', 'Joe User', '*****@*****.**'),
         ('jim@domain', 'Jim User', '*****@*****.**')
     ]
     ticket = Ticket(self.env)
     ticket['reporter'] = 'joeuser'
     ticket['owner'] = 'jim@domain'
     ticket['summary'] = 'This is a summary'
     ticket.insert()
     tn = TicketNotifyEmail(self.env)
     tn.notify(ticket, newticket=True)
     message = notifysuite.smtpd.get_message()
     (headers, body) = parse_smtp_message(message)
     # Msg should always have a 'To' field
     self.failIf('To' not in headers)
     tolist = [addr.strip() for addr in headers['To'].split(',')]
     # 'To' list should have been resolved to the real email address
     self.failIf('*****@*****.**' not in tolist)
     self.failIf('*****@*****.**' not in tolist)
     self.failIf('joeuser' in tolist)
     self.failIf('jim@domain' in tolist)
コード例 #19
0
 def _test_default_domain(enabled):
     self.env.config.set('notification', 'always_notify_owner', 'false')
     self.env.config.set('notification', 'always_notify_reporter',
                         'false')
     self.env.config.set('notification', 'smtp_always_cc', '')
     ticket = Ticket(self.env)
     ticket['cc'] = 'joenodom, [email protected]'
     ticket['summary'] = 'This is a summary'
     ticket.insert()
     # Be sure that at least one email address is valid, so that we
     # send a notification even if other addresses are not valid
     self.env.config.set('notification', 'smtp_always_cc',
                         '*****@*****.**')
     if enabled:
         self.env.config.set('notification', 'smtp_default_domain',
                             'example.org')
     tn = TicketNotifyEmail(self.env)
     tn.notify(ticket, newticket=True)
     message = notifysuite.smtpd.get_message()
     (headers, body) = parse_smtp_message(message)
     # Msg should always have a 'Cc' field
     self.failIf('Cc' not in headers)
     cclist = [addr.strip() for addr in headers['Cc'].split(',')]
     self.failIf('*****@*****.**' not in cclist)
     self.failIf('*****@*****.**' not in cclist)
     if not enabled:
         self.failIf(len(cclist) != 2)
         self.failIf('joenodom' in cclist)
     else:
         self.failIf(len(cclist) != 3)
         self.failIf('*****@*****.**' not in cclist)
コード例 #20
0
 def _test_short_login(enabled):
     ticket = Ticket(self.env)
     ticket['reporter'] = 'joeuser'
     ticket['summary'] = 'This is a summary'
     ticket.insert()
     # Be sure that at least one email address is valid, so that we
     # send a notification even if other addresses are not valid
     self.env.config.set('notification', 'smtp_always_cc',
                         '*****@*****.**')
     if enabled:
         self.env.config.set('notification', 'use_short_addr', 'true')
     tn = TicketNotifyEmail(self.env)
     tn.notify(ticket, newticket=True)
     message = notifysuite.smtpd.get_message()
     (headers, body) = parse_smtp_message(message)
     # Msg should not have a 'To' header
     if not enabled:
         self.failIf('To' in headers)
     else:
         tolist = [addr.strip() for addr in headers['To'].split(',')]
     # Msg should have a 'Cc' field
     self.failIf('Cc' not in headers)
     cclist = [addr.strip() for addr in headers['Cc'].split(',')]
     if enabled:
         # Msg should be delivered to the reporter
         self.failIf(ticket['reporter'] not in tolist)
     else:
         # Msg should not be delivered to joeuser
         self.failIf(ticket['reporter'] in cclist)
     # Msg should still be delivered to the always_cc list
     self.failIf(
         self.env.config.get('notification', 'smtp_always_cc') not in
         cclist)
コード例 #21
0
 def create(self,
            req,
            summary,
            description,
            attributes={},
            notify=False,
            when=None):
     """ Create a new ticket, returning the ticket ID.
     Overriding 'when' requires admin permission. """
     t = model.Ticket(self.env)
     t['summary'] = summary
     t['description'] = description
     t['reporter'] = req.authname
     for k, v in attributes.iteritems():
         t[k] = v
     t['status'] = 'new'
     t['resolution'] = ''
     # custom create timestamp?
     if when and not 'TICKET_ADMIN' in req.perm:
         self.log.warn(
             "RPC ticket.create: %r not allowed to create with "
             "non-current timestamp (%r)", req.authname, when)
         when = None
     t.insert(when=when)
     if notify:
         try:
             tn = TicketNotifyEmail(self.env)
             tn.notify(t, newticket=True)
         except Exception, e:
             self.log.exception("Failure sending notification on creation "
                                "of ticket #%s: %s" % (t.id, e))
コード例 #22
0
ファイル: notification.py プロジェクト: moreati/trac-gitsvn
 def _test_default_domain(enabled):
     self.env.config.set("notification", "always_notify_owner", "false")
     self.env.config.set("notification", "always_notify_reporter", "false")
     self.env.config.set("notification", "smtp_always_cc", "")
     ticket = Ticket(self.env)
     ticket["cc"] = "joenodom, [email protected]"
     ticket["summary"] = "This is a summary"
     ticket.insert()
     # Be sure that at least one email address is valid, so that we
     # send a notification even if other addresses are not valid
     self.env.config.set("notification", "smtp_always_cc", "*****@*****.**")
     if enabled:
         self.env.config.set("notification", "smtp_default_domain", "example.org")
     tn = TicketNotifyEmail(self.env)
     tn.notify(ticket, newticket=True)
     message = notifysuite.smtpd.get_message()
     (headers, body) = parse_smtp_message(message)
     # Msg should always have a 'Cc' field
     self.failIf("Cc" not in headers)
     cclist = [addr.strip() for addr in headers["Cc"].split(",")]
     self.failIf("*****@*****.**" not in cclist)
     self.failIf("*****@*****.**" not in cclist)
     if not enabled:
         self.failIf(len(cclist) != 2)
         self.failIf("joenodom" in cclist)
     else:
         self.failIf(len(cclist) != 3)
         self.failIf("*****@*****.**" not in cclist)
コード例 #23
0
ファイル: notification.py プロジェクト: moreati/trac-gitsvn
 def test_ignore_domains(self):
     """Non-SMTP domain exclusion"""
     self.env.config.set("notification", "ignore_domains", "example.com, example.org")
     self.env.known_users = [
         ("*****@*****.**", "No Email", ""),
         ("*****@*****.**", "With Email", "*****@*****.**"),
     ]
     ticket = Ticket(self.env)
     ticket["reporter"] = "*****@*****.**"
     ticket["owner"] = "*****@*****.**"
     ticket["summary"] = "This is a summary"
     ticket.insert()
     tn = TicketNotifyEmail(self.env)
     tn.notify(ticket, newticket=True)
     message = notifysuite.smtpd.get_message()
     (headers, body) = parse_smtp_message(message)
     # Msg should always have a 'To' field
     self.failIf("To" not in headers)
     tolist = [addr.strip() for addr in headers["To"].split(",")]
     # 'To' list should not contain addresses with non-SMTP domains
     self.failIf("*****@*****.**" in tolist)
     self.failIf("*****@*****.**" in tolist)
     # 'To' list should have been resolved to the actual email address
     self.failIf("*****@*****.**" not in tolist)
     self.failIf(len(tolist) != 1)
コード例 #24
0
 def test_date(self):
     """Date format compliance (RFC822) 
        we do not support 'military' format"""
     date_str = r"^((?P<day>\w{3}),\s*)*(?P<dm>\d{2})\s+" \
                r"(?P<month>\w{3})\s+(?P<year>\d{4})\s+" \
                r"(?P<hour>\d{2}):(?P<min>[0-5][0-9])" \
                r"(:(?P<sec>[0-5][0-9]))*\s" \
                r"((?P<tz>\w{2,3})|(?P<offset>[+\-]\d{4}))$"
     date_re = re.compile(date_str)
     # python time module does not detect incorrect time values
     days = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
     months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', \
               'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
     tz = [
         'UT', 'GMT', 'EST', 'EDT', 'CST', 'CDT', 'MST', 'MDT', 'PST', 'PDT'
     ]
     ticket = Ticket(self.env)
     ticket['reporter'] = '"Joe User" <*****@*****.**>'
     ticket['summary'] = 'This is a summary'
     ticket.insert()
     tn = TicketNotifyEmail(self.env)
     tn.notify(ticket, newticket=True)
     message = notifysuite.smtpd.get_message()
     (headers, body) = parse_smtp_message(message)
     self.failIf('Date' not in headers)
     mo = date_re.match(headers['Date'])
     self.failIf(not mo)
     if mo.group('day'):
         self.failIf(mo.group('day') not in days)
     self.failIf(int(mo.group('dm')) not in range(1, 32))
     self.failIf(mo.group('month') not in months)
     self.failIf(int(mo.group('hour')) not in range(0, 24))
     if mo.group('tz'):
         self.failIf(mo.group('tz') not in tz)
コード例 #25
0
ファイル: notification.py プロジェクト: moreati/trac-gitsvn
 def test_email_map(self):
     """Login-to-email mapping"""
     self.env.config.set("notification", "always_notify_owner", "true")
     self.env.config.set("notification", "always_notify_reporter", "true")
     self.env.config.set("notification", "smtp_always_cc", "*****@*****.**")
     self.env.known_users = [
         ("joeuser", "Joe User", "*****@*****.**"),
         ("jim@domain", "Jim User", "*****@*****.**"),
     ]
     ticket = Ticket(self.env)
     ticket["reporter"] = "joeuser"
     ticket["owner"] = "jim@domain"
     ticket["summary"] = "This is a summary"
     ticket.insert()
     tn = TicketNotifyEmail(self.env)
     tn.notify(ticket, newticket=True)
     message = notifysuite.smtpd.get_message()
     (headers, body) = parse_smtp_message(message)
     # Msg should always have a 'To' field
     self.failIf("To" not in headers)
     tolist = [addr.strip() for addr in headers["To"].split(",")]
     # 'To' list should have been resolved to the real email address
     self.failIf("*****@*****.**" not in tolist)
     self.failIf("*****@*****.**" not in tolist)
     self.failIf("joeuser" in tolist)
     self.failIf("jim@domain" in tolist)
コード例 #26
0
ファイル: notification.py プロジェクト: moreati/trac-gitsvn
 def _test_short_login(enabled):
     ticket = Ticket(self.env)
     ticket["reporter"] = "joeuser"
     ticket["summary"] = "This is a summary"
     ticket.insert()
     # Be sure that at least one email address is valid, so that we
     # send a notification even if other addresses are not valid
     self.env.config.set("notification", "smtp_always_cc", "*****@*****.**")
     if enabled:
         self.env.config.set("notification", "use_short_addr", "true")
     tn = TicketNotifyEmail(self.env)
     tn.notify(ticket, newticket=True)
     message = notifysuite.smtpd.get_message()
     (headers, body) = parse_smtp_message(message)
     # Msg should not have a 'To' header
     if not enabled:
         self.failIf("To" in headers)
     else:
         tolist = [addr.strip() for addr in headers["To"].split(",")]
     # Msg should have a 'Cc' field
     self.failIf("Cc" not in headers)
     cclist = [addr.strip() for addr in headers["Cc"].split(",")]
     if enabled:
         # Msg should be delivered to the reporter
         self.failIf(ticket["reporter"] not in tolist)
     else:
         # Msg should not be delivered to joeuser
         self.failIf(ticket["reporter"] in cclist)
     # Msg should still be delivered to the always_cc list
     self.failIf(self.env.config.get("notification", "smtp_always_cc") not in cclist)
コード例 #27
0
ファイル: web_ui.py プロジェクト: lkraav/trachacks
    def _save_ticket_changes(self, req, env, log, selectedTickets, tickets,
                             values, comment, modify_changetime, send_notifications):
        for id in selectedTickets:
            if id in tickets:
                t = Ticket(env, int(id))
                new_changetime = datetime.now(utc)
                
                log_msg = ""
                if not modify_changetime:
                    original_changetime = to_timestamp(t.time_changed)
                
                _values = values.copy()
                for field in [f for f in values.keys() \
                              if f in self._fields_as_list]:
                    _values[field] = self._merge_keywords(t.values[field], 
                                                          values[field],
                                                          log)
                
                t.populate(_values)
                t.save_changes(req.authname, comment, when=new_changetime)
  
                if send_notifications:
                    tn = TicketNotifyEmail(env)
                    tn.notify(t, newticket=0, modtime=new_changetime)

                if not modify_changetime:
                    self._reset_changetime(env, original_changetime, t)
                    log_msg = "(changetime not modified)"

                log.debug('BatchModifyPlugin: saved changes to #%s %s' % 
                          (id, log_msg))
コード例 #28
0
ファイル: theme.py プロジェクト: tsanov/bloodhound
    def create(self, req, summary, description, attributes={}, notify=False):
        """ Create a new ticket, returning the ticket ID.

        PS: Borrowed from XmlRpcPlugin.
        """
        if 'product' in attributes:
            env = self.env.parent or self.env
            if attributes['product']:
                env = ProductEnvironment(env, attributes['product'])
        else:
            env = self.env

        t = Ticket(env)
        t['summary'] = summary
        t['description'] = description
        t['reporter'] = req.authname
        for k, v in attributes.iteritems():
            t[k] = v
        t['status'] = 'new'
        t['resolution'] = ''
        t.insert()

        if notify:
            try:
                tn = TicketNotifyEmail(env)
                tn.notify(t, newticket=True)
            except Exception, e:
                self.log.exception("Failure sending notification on creation "
                                   "of ticket #%s: %s" % (t.id, e))
コード例 #29
0
        def _implementation(db):
            for id in selectedTickets:
                if id in tickets:
                    t = Ticket(env, int(id))
                    new_changetime = datetime.now(utc)

                    log_msg = ""
                    if not modify_changetime:
                        original_changetime = to_utimestamp(t.time_changed)

                    _values = new_values.copy()
                    for field in [f for f in new_values.keys() \
                                  if f in self._fields_as_list]:
                        _values[field] = self._merge_keywords(
                            t.values[field], new_values[field], log)

                    t.populate(_values)
                    t.save_changes(req.authname, comment, when=new_changetime)

                    if send_notifications:
                        tn = TicketNotifyEmail(env)
                        tn.notify(t, newticket=0, modtime=new_changetime)

                    if not modify_changetime:
                        self._reset_changetime(env, original_changetime, t)
                        log_msg = "(changetime not modified)"

                    log.debug('BatchModifyPlugin: saved changes to #%s %s' %
                              (id, log_msg))
コード例 #30
0
def post_to_ticket(msg, author, tkt_id, env):
    """Post the message to the ticket and send a notify email."""
    from trac.ticket.notification import TicketNotifyEmail
    from trac.ticket import Ticket
    from trac.ticket.web_ui import TicketModule
    from trac.util.datefmt import utc

    now = datetime.now(utc)

    try:
        db = env.get_db_cnx()
        # Get the related trac ticket object
        ticket = Ticket(env, tkt_id, db)

        # determine sequence number...
        cnum = 0
        tm = TicketModule(env)
        for change in tm.grouped_changelog_entries(ticket, db):
            if change['permanent']:
                cnum += 1

        ticket.save_changes(author, msg, now, db, cnum + 1)
        db.commit()

        tn = TicketNotifyEmail(env)
        tn.notify(ticket, newticket=0, modtime=now)
    except Exception, e:
        msg = 'Unexpected error processing ticket ID %s: %s' % (tkt_id, e)
        print >>sys.stderr, msg
コード例 #31
0
ファイル: manager.py プロジェクト: nyuhuhuu/trachacks
 def save_ticket(self, tckt, db, msg):
     # determine sequence number... 
     cnum = 0
     tm = TicketModule(self.env)
     for change in tm.grouped_changelog_entries(tckt, db):
         if change['permanent']:
             cnum += 1
     tckt.save_changes(self.authname, msg, self.now, db, cnum+1)
     ## Often the time overlaps and causes a db error,
     ## especially when the trac integration post-commit hook is used.
     ## NOTE TO SELF. I DON'T THINK THIS IS NECESSARY RIGHT NOW...
     #count = 0
     #while count < 10:
     #    try:
     #        tckt.save_changes(self.authname, msg, self.now, db, cnum+1)
     #        count = 42
     #    except Exception, e:
     #        self.now += 1
     #        count += 1
     db.commit()
     
     tn = TicketNotifyEmail(self.env)
     tn.notify(tckt, newticket=0, modtime=self.now)
     # We fudge time as it has to be unique
     self.now += 1
コード例 #32
0
ファイル: sms.py プロジェクト: michela/TracShot
	def ticket_changed(self,ticket,comment,author,old_values):
		self.env.log.debug("ticket_change - TicketNotifySMS: %s" % author)
		# Q) why does debug work on DEBUG setting but not INFO?
		db = self.env.get_db_cnx()
		cursor = db.cursor()
		sql = "select field, newvalue from ticket_change where ticket = %s ORDER BY time DESC LIMIT 1" % ticket.id
		cursor.execute(sql)
		data = cursor.fetchall()
		msg = ''
		for row in data:
			# TODO check alerts aren't needed on other fields
			if row[0] == 'comment':
				patt = re.compile('{{{(.+)}}}')
				mobj = patt.match(row[1])
				self.env.log.debug('comment value: ' + row[1])
				body = ''
				try:
					body = mobj.group(0)
				except AttributeError:
					self.env.log.debug('no brackets')
					body = row[1]
				msg = "Re: shot %s - %s" % (ticket.values['summary'], body )
				# ticket.id if necessary
		tne = TicketNotifyEmail(self.env)
		peeps = tne.get_recipients(ticket.id)
		list = {}
		for person in peeps:
			for p in person:
				list[p] = 1
		for k in list.keys():
			self.env.log.debug("recepient: %s" % k)
			if k != None:
				self.sms(k, str(ticket.time_changed), ticket.values['summary'], msg)
コード例 #33
0
ファイル: tickets.py プロジェクト: getpenelope/penelope.core
    def add_tickets(self, project, customerrequest, tickets, reporter, notify=False):
        from trac.ticket.notification import TicketNotifyEmail
        from trac.util.text import exception_to_unicode
        from penelope.core.models.dashboard import User

        settings = get_current_registry().settings
        tracenvs = settings.get('penelope.trac.envs')
        request = get_current_request()

        for trac in project.tracs:
            for t in tickets:
                owner = DBSession.query(User).get(t['owner'])
                ticket = {'summary': t['summary'],
                        'description': t['description'],
                        'customerrequest': customerrequest.id,
                        'reporter': reporter.email,
                        'type': 'task',
                        'priority': 'major',
                        'milestone': 'Backlog',
                        'owner': owner.email,
                        'status': 'new'}
                tracenv = Environment('%s/%s' % (tracenvs, trac.trac_name))
                tracenv.abs_href.base = trac.api_uri
                t = Ticket(tracenv)
                t.populate(ticket)
                t.insert()
                if notify:
                    try:
                        tn = TicketNotifyEmail(tracenv)
                        tn.notify(t, newticket=True)
                    except Exception, e:
                        request.add_message('Failure sending notification on creation '
                        'of a ticket #%s: %s' % (t.id, exception_to_unicode(e)), 'error')
コード例 #34
0
ファイル: notification.py プロジェクト: moreati/trac-gitsvn
 def test_date(self):
     """Date format compliance (RFC822) 
        we do not support 'military' format"""
     date_str = (
         r"^((?P<day>\w{3}),\s*)*(?P<dm>\d{2})\s+"
         r"(?P<month>\w{3})\s+(?P<year>\d{4})\s+"
         r"(?P<hour>\d{2}):(?P<min>[0-5][0-9])"
         r"(:(?P<sec>[0-5][0-9]))*\s"
         r"((?P<tz>\w{2,3})|(?P<offset>[+\-]\d{4}))$"
     )
     date_re = re.compile(date_str)
     # python time module does not detect incorrect time values
     days = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]
     months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
     tz = ["UT", "GMT", "EST", "EDT", "CST", "CDT", "MST", "MDT", "PST", "PDT"]
     ticket = Ticket(self.env)
     ticket["reporter"] = '"Joe User" <*****@*****.**>'
     ticket["summary"] = "This is a summary"
     ticket.insert()
     tn = TicketNotifyEmail(self.env)
     tn.notify(ticket, newticket=True)
     message = notifysuite.smtpd.get_message()
     (headers, body) = parse_smtp_message(message)
     self.failIf("Date" not in headers)
     mo = date_re.match(headers["Date"])
     self.failIf(not mo)
     if mo.group("day"):
         self.failIf(mo.group("day") not in days)
     self.failIf(int(mo.group("dm")) not in range(1, 32))
     self.failIf(mo.group("month") not in months)
     self.failIf(int(mo.group("hour")) not in range(0, 24))
     if mo.group("tz"):
         self.failIf(mo.group("tz") not in tz)
コード例 #35
0
ファイル: svn_hooks.py プロジェクト: nagyist/agilo
 def execute(self):
     """Execute the parsed commands"""
     #print "Commands: %s" % self.commands
     # Now parse the command in the ticket, and react accordingly
     # Cannnot produce error messages, as the pre-commit-hook would have failed already
     parser = CommitMessageCommandParser(self.env, self.changeset.message)
     parsed_commands = parser.validate_and_parse_commit_message()
     self.commands = dict()
     for command, ticket_id, remaining_time in parsed_commands:
         # REFACT: the parser should give the ids as ints already
         ticket_id = int(ticket_id)
         self.commands.setdefault(ticket_id, list())
         self.commands.get(ticket_id).append(
             self.findCommand(command, remaining=remaining_time[:-1]))
     # Sort the ticket in reverse order by id, it will be most likely
     # that a task is existing after a User Story has been created,
     # in which case it will be possible to execute multiple command in
     # a hierarchy. TODO: Check hierarchy, but very expensive
     keys = self.commands.keys()
     keys.sort(reverse=True)
     for t_id, cmds in [(key, self.commands[key]) for key in keys]:
         ticket = self.tm.get(tkt_id=t_id)
         for cmd in cmds:
             cmd(ticket)
         self.tm.save(ticket, author=self.author, comment=self.message)
         from trac.ticket.notification import TicketNotifyEmail
         tn = TicketNotifyEmail(self.env)
         tn.notify(ticket, newticket=False, modtime=ticket.time_changed)
     # We need to invalidate the chart cache here because some tickets may
     # have been closed through commit comments. Unfortunately there is
     # no way to access the shared memory right now, see #565
     return True
コード例 #36
0
    def attachment_added(self, attachment):
        # Check whether we're dealing with a ticket resource
        resource = attachment.resource
        while resource:
            if resource.realm == 'ticket':
                break
            resource = resource.parent

        if (resource and resource.realm == 'ticket' and resource.id is not None):
            with self.env.db_transaction as db:
                ticket = Ticket(attachment.env, resource.id, db)
                if (attachment.author == ticket['reporter'] and ticket['status'] == 'pending'):
                    self.env.log.info('Removing Pending status for ticket %s due to attachment' % (ticket.id))

                    comment = 'Attachment (%s) added by ticket reporter.' % (attachment.filename)
                    ticket['status'] = self.config.get('ticket', 'pending_removal_status')

                    # determine sequence number...
                    cnum = 0
                    tm = TicketModule(self.env)
                    for change in tm.grouped_changelog_entries(ticket, db):
                        c_cnum = change.get('cnum', None)
                        if c_cnum and int(c_cnum) > cnum:
                            cnum = int(c_cnum)

                    #We can't just use attachment.date as it screws up event sequencing
                    now = datetime.now(utc)

                    ticket.save_changes(attachment.author, comment, now, db, str(cnum + 1))

                    #trigger notification since we've changed the ticket
                    tn = TicketNotifyEmail(self.env)
                    tn.notify(ticket, newticket=False, modtime=now)
コード例 #37
0
ファイル: hook.py プロジェクト: willat8/extras
    def process(self, commit, status, branch):
        self.closestatus = status

        milestones = [
            m.name for m in Milestone.select(self.env) if m.name != 'unknown'
        ]
        if branch.startswith('fixes/'):
            branch = branch[6:]
            milestones = [m for m in milestones if m.startswith(branch)]
        self.milestone = sorted(milestones)[-1]

        msg = commit['message']
        self.env.log.debug("Processing Commit: %s", msg)
        msg = "%s \n Branch:    %s \n Changeset: %s" % (msg, branch,
                                                        commit['id'])
        #        author = commit['author']['name']
        author = 'Github'
        timestamp = datetime.now(utc)

        cmd_groups = command_re.findall(msg)
        self.env.log.debug("Function Handlers: %s" % cmd_groups)

        tickets = {}
        for cmd, tkts in cmd_groups:
            funcname = self.__class__._supported_cmds.get(cmd.lower(), '')
            self.env.log.debug("Function Handler: %s" % funcname)
            if funcname:
                for tkt_id in ticket_re.findall(tkts):
                    if (branch == "master") or branch.startswith("fixes/"):
                        tickets.setdefault(tkt_id,
                                           []).append(getattr(self, funcname))
#                    disable this stuff for now, it causes duplicates on merges
#                    proper implementation of this will require tracking commit hashes
#                    else:
#                        tickets.setdefault(tkt_id, []).append(self._cmdRefs)

        for tkt_id, cmds in tickets.iteritems():
            try:
                db = self.env.get_db_cnx()

                ticket = Ticket(self.env, int(tkt_id), db)
                for cmd in cmds:
                    cmd(ticket)

                # determine sequence number...
                cnum = 0
                tm = TicketModule(self.env)
                for change in tm.grouped_changelog_entries(ticket, db):
                    if change['permanent']:
                        cnum += 1

                ticket.save_changes(author, msg, timestamp, db, cnum + 1)
                db.commit()

                tn = TicketNotifyEmail(self.env)
                tn.notify(ticket, newticket=0, modtime=timestamp)
            except Exception, e:
                import traceback
                traceback.print_exc(file=sys.stderr)
コード例 #38
0
ファイル: web_ui.py プロジェクト: nyuhuhuu/trachacks
    def _do_save(self, req, db, ticket):
        if req.perm.has_permission('TICKET_CHGPROP'):
            # TICKET_CHGPROP gives permission to edit the ticket
            if not req.args.get('summary'):
                raise TracError(u'Les tickets doivent contenir un intitulé.')

            if req.args.has_key('description') or req.args.has_key('reporter'):
                req.perm.assert_permission('TICKET_ADMIN')

            ticket.populate(req.args)
        else:
            req.perm.assert_permission('TICKET_APPEND')

        # Mid air collision?
        if int(req.args.get('ts')) != ticket.time_changed:
            raise TracError(u"Désolé, impossible d'enregistrer vos modifications. "
                            u"Ce ticket a été modifié par quelqu'un d'autre "
                            u"depuis que vous avez commencé", u'Collision en plein vol')

        # Do any action on the ticket?
        action = req.args.get('action')
        actions = TicketSystem(self.env).get_available_actions(ticket, req.perm)
        if action not in actions:
            raise TracError(u'Action invalide')

        # TODO: this should not be hard-coded like this
        if action == 'accept':
            ticket['status'] =  'assigned'
            ticket['owner'] = req.authname
        if action == 'resolve':
            ticket['status'] = 'closed'
            ticket['resolution'] = req.args.get('resolve_resolution')
        elif action == 'reassign':
            ticket['owner'] = req.args.get('reassign_owner')
            ticket['status'] = 'new'
        elif action == 'reopen':
            ticket['status'] = 'reopened'
            ticket['resolution'] = ''

        self._validate_ticket(req, ticket)

        now = int(time.time())
        cnum = req.args.get('cnum')        
        replyto = req.args.get('replyto')
        internal_cnum = cnum
        if cnum and replyto: # record parent.child relationship
            internal_cnum = '%s.%s' % (replyto, cnum)
        if ticket.save_changes(get_reporter_id(req, 'author'),
                               req.args.get('comment'), when=now, db=db,
                               cnum=internal_cnum):
            db.commit()

            try:
                tn = TicketNotifyEmail(self.env)
                tn.notify(ticket, newticket=False, modtime=now)
            except Exception, e:
                self.log.exception("Failure sending notification on change to "
                                   "ticket #%s: %s" % (ticket.id, e))
コード例 #39
0
ファイル: web_ui.py プロジェクト: pombredanne/trachacks
    def _do_save(self, req, db, ticket):
        if req.perm.has_permission('TICKET_CHGPROP'):
            # TICKET_CHGPROP gives permission to edit the ticket
            if not req.args.get('summary'):
                raise TracError('Tickets must contain summary.')

            if req.args.has_key('description') or req.args.has_key('reporter'):
                req.perm.assert_permission('TICKET_ADMIN')

            ticket.populate(req.args)
        else:
            req.perm.assert_permission('TICKET_APPEND')

        # Mid air collision?
        if int(req.args.get('ts')) != ticket.time_changed:
            raise TracError("Sorry, can not save your changes. "
                            "This ticket has been modified by someone else "
                            "since you started", 'Mid Air Collision')

        # Do any action on the ticket?
        action = req.args.get('action')
        actions = TicketSystem(self.env).get_available_actions(ticket, req.perm)
        if action not in actions:
            raise TracError('Invalid action')

        # TODO: this should not be hard-coded like this
        if action == 'accept':
            ticket['status'] =  'assigned'
            ticket['owner'] = req.authname
        if action == 'resolve':
            ticket['status'] = 'closed'
            ticket['resolution'] = req.args.get('resolve_resolution')
        elif action == 'reassign':
            ticket['owner'] = req.args.get('reassign_owner')
            ticket['status'] = 'new'
        elif action == 'reopen':
            ticket['status'] = 'reopened'
            ticket['resolution'] = ''

        self._validate_ticket(req, ticket)

        now = int(time.time())
        cnum = req.args.get('cnum')        
        replyto = req.args.get('replyto')
        internal_cnum = cnum
        if cnum and replyto: # record parent.child relationship
            internal_cnum = '%s.%s' % (replyto, cnum)
        if ticket.save_changes(get_reporter_id(req, 'author'),
                               req.args.get('comment'), when=now, db=db,
                               cnum=internal_cnum):
            db.commit()

            try:
                tn = TicketNotifyEmail(self.env)
                tn.notify(ticket, newticket=False, modtime=now)
            except Exception, e:
                self.log.exception("Failure sending notification on change to "
                                   "ticket #%s: %s" % (ticket.id, e))
コード例 #40
0
ファイル: core.py プロジェクト: spscream/old_code
    def notify(self, env, tkt, new=True, modtime=0):
	""" A Wrapper for TRAC notify function """
        try:
            # create false {abs_}href properties, to trick Notify()
            #
    	    tn = TicketNotifyEmail(env)
            tn.notify(tkt, new, modtime)
        except Exception, e:
            print 'TD: Failure sending notification on creation of ticket #%s: %s' %(tkt['id'], e)
コード例 #41
0
 def test_notification_get_message_id_unicode(self):
     ticket = Ticket(self.env)
     ticket['summary'] = 'My Summary'
     ticket['description'] = 'Some description'
     ticket.insert()
     self.env.config.set('project', 'url', u"пиво Müller ")
     tn = TicketNotifyEmail(self.env)
     tn.ticket = ticket
     tn.get_message_id('foo')
コード例 #42
0
ファイル: notification.py プロジェクト: moreati/trac-gitsvn
 def test_notification_get_message_id_unicode(self):
     ticket = Ticket(self.env)
     ticket["summary"] = "My Summary"
     ticket["description"] = "Some description"
     ticket.insert()
     self.env.config.set("project", "url", u"пиво Müller ")
     tn = TicketNotifyEmail(self.env)
     tn.ticket = ticket
     tn.get_message_id("foo")
コード例 #43
0
ファイル: notification.py プロジェクト: wiraqutra/photrackjp
 def test_notification_get_message_id_unicode(self):
     ticket = Ticket(self.env)
     ticket['summary'] = 'My Summary'
     ticket['description'] = 'Some description'
     ticket.insert()
     self.env.config.set('project', 'url', u"пиво Müller ")
     tn = TicketNotifyEmail(self.env)
     tn.ticket = ticket
     tn.get_message_id('foo')
コード例 #44
0
    def __init__(self,
                 project=options.project,
                 author=AUTHOR,
                 maxage=options.maxage,
                 url=options.url):

        self.env = open_environment(project)
        db = self.env.get_db_cnx()
        cursor = db.cursor()

        if url is None:
            url = self.env.config.get('trac', 'base_url')

        self.env.href = Href(url)
        self.env.abs_href = Href(url)

        self.msg = MESSAGE % (maxage)
        self.now = int(time.time())

        maxtime = int(time.time()) - (60 * 60 * 24 * maxage)

        cursor.execute("SELECT id FROM ticket t, ticket_custom c " \
                       "WHERE t.status <> %s " \
                "AND t.changetime < %s " \
                       "AND t.id = c.ticket " \
                       "AND c.name = %s " \
                       "AND c.value = %s ", ('closed', maxtime, 'pending', '1'))

        rows = cursor.fetchall()

        for row in rows:
            id = row[0]
            try:
                ticket = Ticket(self.env, id, db)

                ticket['status'] = 'closed'
                ticket['pending'] = '0'

                # determine sequence number...
                cnum = 0
                tm = TicketModule(self.env)
                for change in tm.grouped_changelog_entries(ticket, db):
                    if change['permanent']:
                        cnum += 1

                ticket.save_changes(author, self.msg, self.now, db, cnum + 1)
                db.commit()

                print 'Closing Ticket %s (%s)\n' % (id, ticket['summary'])

                tn = TicketNotifyEmail(self.env)
                tn.notify(ticket, newticket=0, modtime=self.now)
            except Exception, e:
                import traceback
                traceback.print_exc(file=sys.stderr)
                print>>sys.stderr, 'Unexpected error while processing ticket ' \
                                   'ID %s: %s' % (id, e)
コード例 #45
0
    def __init__(self,
                 project=options.project,
                 author=options.user,
                 rev=options.rev,
                 url=options.url):
        self.env = open_environment(project)
        repos = self.env.get_repository()
        repos.sync()

        # Instead of bothering with the encoding, we'll use unicode data
        # as provided by the Trac versioncontrol API (#1310).
        try:
            chgset = repos.get_changeset(rev)
        except NoSuchChangeset:
            return  # out of scope changesets are not cached
        self.author = chgset.author
        self.rev = rev
        self.msg = "(In [%s]) %s" % (rev, chgset.message)
        self.now = datetime.now(utc)

        cmd_groups = command_re.findall(self.msg)

        tickets = {}
        for cmd, tkts in cmd_groups:
            funcname = CommitHook._supported_cmds.get(cmd.lower(), '')
            if funcname:
                for tkt_id in ticket_re.findall(tkts):
                    func = getattr(self, funcname)
                    tickets.setdefault(tkt_id, []).append(func)

        for tkt_id, cmds in tickets.iteritems():
            try:
                db = self.env.get_db_cnx()

                ticket = Ticket(self.env, int(tkt_id), db)
                for cmd in cmds:
                    cmd(ticket)

                # determine sequence number...
                cnum = 0
                tm = TicketModule(self.env)
                for change in tm.grouped_changelog_entries(ticket, db):
                    if change['permanent']:
                        cnum += 1

                ticket.save_changes(self.author, self.msg, self.now, db,
                                    cnum + 1)
                db.commit()

                tn = TicketNotifyEmail(self.env)
                tn.notify(ticket, newticket=0, modtime=self.now)
            except Exception, e:
                # import traceback
                # traceback.print_exc(file=sys.stderr)
                print>>sys.stderr, 'Unexpected error while processing ticket ' \
                                   'ID %s: %s' % (tkt_id, e)
コード例 #46
0
ファイル: hook.py プロジェクト: nilknarf0/extras
    def process(self, commit, status, branch):
        self.closestatus = status

        milestones = [m.name for m in Milestone.select(self.env) if m.name != "unknown"]
        if branch.startswith("fixes/"):
            branch = branch[6:]
            milestones = [m for m in milestones if m.startswith(branch)]
        self.milestone = sorted(milestones)[-1]

        msg = commit["message"]
        self.env.log.debug("Processing Commit: %s", msg)
        msg = "%s \n Branch:    %s \n Changeset: %s" % (msg, branch, commit["id"])
        #        author = commit['author']['name']
        author = "Github"
        timestamp = datetime.now(utc)

        cmd_groups = command_re.findall(msg)
        self.env.log.debug("Function Handlers: %s" % cmd_groups)

        tickets = {}
        for cmd, tkts in cmd_groups:
            funcname = self.__class__._supported_cmds.get(cmd.lower(), "")
            self.env.log.debug("Function Handler: %s" % funcname)
            if funcname:
                for tkt_id in ticket_re.findall(tkts):
                    if (branch == "master") or branch.startswith("fixes/"):
                        tickets.setdefault(tkt_id, []).append(getattr(self, funcname))
        #                    disable this stuff for now, it causes duplicates on merges
        #                    proper implementation of this will require tracking commit hashes
        #                    else:
        #                        tickets.setdefault(tkt_id, []).append(self._cmdRefs)

        for tkt_id, cmds in tickets.iteritems():
            try:
                db = self.env.get_db_cnx()

                ticket = Ticket(self.env, int(tkt_id), db)
                for cmd in cmds:
                    cmd(ticket)

                # determine sequence number...
                cnum = 0
                tm = TicketModule(self.env)
                for change in tm.grouped_changelog_entries(ticket, db):
                    if change["permanent"]:
                        cnum += 1

                ticket.save_changes(author, msg, timestamp, db, cnum + 1)
                db.commit()

                tn = TicketNotifyEmail(self.env)
                tn.notify(ticket, newticket=0, modtime=timestamp)
            except Exception, e:
                import traceback

                traceback.print_exc(file=sys.stderr)
コード例 #47
0
    def _do_create(self, req, ticket):
        ticket.insert()

        # Notify
        try:
            tn = TicketNotifyEmail(self.env)
            tn.notify(ticket, newticket=True)
        except Exception, e:
            self.log.error("""Failure sending notification on creation of
                ticket #%s: %s""", ticket.id, e)
コード例 #48
0
ファイル: core.py プロジェクト: spscream/old_code
 def notify(self, env, tkt, new=True, modtime=0):
     """ A Wrapper for TRAC notify function """
     try:
         # create false {abs_}href properties, to trick Notify()
         #
         tn = TicketNotifyEmail(env)
         tn.notify(tkt, new, modtime)
     except Exception, e:
         print 'TD: Failure sending notification on creation of ticket #%s: %s' % (
             tkt['id'], e)
コード例 #49
0
ファイル: commit_updater.py プロジェクト: krivit/tractogithub
 def _notify(self, ticket, date):
     """Send a ticket update notification."""
     if not self.notify:
         return
     try:
         tn = TicketNotifyEmail(self.env)
         tn.notify(ticket, newticket=False, modtime=date)
     except Exception, e:
         self.log.error(
             "Failure sending notification on change to "
             "ticket #%s: %s", ticket.id, exception_to_unicode(e))
コード例 #50
0
    def process_message(self, req, msgstr):

        project_list = get_project_list(self.env,
                                        req,
                                        return_self=True,
                                        include_errors=False)

        msg = email.message_from_string(msgstr)
        msg_from = parseaddr(msg.get("from"))[1]
        msg_subject = msg.get("subject")
        in_reply_to = msg.get("in-reply-to", "")

        msg_content = ""
        if not msg.is_multipart():
            msg_content = msg.get_payload(decode=True)
        else:
            for part in msg.walk():
                if part.get_content_type() == 'text/plain':
                    msg_content = part.get_payload(decode=True)

        msg_content = to_unicode(msg_content)

        match = INREPLYTO_TICKET_EXPR.match(in_reply_to)
        if match:
            for project, project_path, project_url, project_env in project_list:
                if not project_env:
                    continue

                if os.path.basename(project_path).lower() != match.group(
                        'base').lower():
                    continue

                ticket = Ticket(project_env, int(match.group('id')))
                now = datetime.now(utc)
                ticket.save_changes(msg_from, msg_content, when=now)

                #----- Copiado de web_ui.py -----

                try:
                    tn = TicketNotifyEmail(project_env)
                    tn.notify(ticket, newticket=False, modtime=now)
                except Exception, e:
                    self.log.error(
                        "Failure sending notification on change to "
                        "ticket #%s: %s", ticket.id, exception_to_unicode(e))

                ## After saving the changes, apply the side-effects.
                #for controller in controllers:
                #    self.env.log.debug('Side effect for %s' %
                #                       controller.__class__.__name__)
                #----- Fin Copiado de web_ui.py -----

                return (True, "Ticket reply match - %s#%s" %
                        (match.group('base'), match.group('id')))
コード例 #51
0
    def process(self, commit, status, enable_revmap, reponame):
        self.closestatus = status

        msg = commit['message']
        self.env.log.debug("Processing Commit: %s", msg)
        note = "Changeset: [/changeset/%s %s]" % (commit['id'], commit['id'])
        url = "URL: %s" % commit['url']
        msg = "%s \n * %s \n * %s" % (msg, note, url)
        author = commit['author']['name']
        timestamp = datetime.now(utc)
        if int(enable_revmap):
            self.env.log.debug("adding commit %s to revmap", commit['id'])
            db = self.env.get_db_cnx()
            cursor = db.cursor()
            cursor.execute(
                "INSERT INTO svn_revmap (svn_rev, git_hash, commit_msg) VALUES (0, %s, %s);",
                (commit['id'], commit['message']))
            db.commit()

        cmd_groups = command_re.findall(msg)
        self.env.log.debug("Function Handlers: %s" % cmd_groups)

        tickets = {}
        for cmd, tkts in cmd_groups:
            funcname = self.__class__._supported_cmds.get(cmd.lower(), '')
            self.env.log.debug("Function Handler: %s" % funcname)
            if funcname:
                for tkt_id in ticket_re.findall(tkts):
                    func = getattr(self, funcname)
                    tickets.setdefault(tkt_id, []).append(func)

        for tkt_id, cmds in tickets.iteritems():
            try:
                db = self.env.get_db_cnx()

                ticket = Ticket(self.env, int(tkt_id), db)
                for cmd in cmds:
                    cmd(ticket)

                # determine sequence number...
                cnum = 0
                tm = TicketModule(self.env)
                for change in tm.grouped_changelog_entries(ticket, db):
                    if change['permanent']:
                        cnum += 1

                ticket.save_changes(author, msg, timestamp, db, cnum + 1)
                db.commit()

                tn = TicketNotifyEmail(self.env)
                tn.notify(ticket, newticket=0, modtime=timestamp)
            except Exception, e:
                import traceback
                traceback.print_exc(file=sys.stderr)
コード例 #52
0
    def _do_create(self, req, ticket):
        ticket.insert()

        # Notify
        try:
            tn = TicketNotifyEmail(self.env)
            tn.notify(ticket, newticket=True)
        except Exception, e:
            self.log.error(
                """Failure sending notification on creation of
                ticket #%s: %s""", ticket.id, e)
コード例 #53
0
 def test_cc_only(self):
     """Notification w/o explicit recipients but Cc: (#3101)"""
     ticket = Ticket(self.env)
     ticket['summary'] = 'Foo'
     ticket.insert()
     tn = TicketNotifyEmail(self.env)
     tn.notify(ticket, newticket=True)
     recipients = notifysuite.smtpd.get_recipients()
     # checks that all cc recipients have been notified
     cc_list = self.env.config.get('notification', 'smtp_always_cc')
     for r in cc_list.replace(',', ' ').split():
         self.failIf(r not in recipients)
コード例 #54
0
 def test_notification_does_not_alter_ticket_instance(self):
     ticket = Ticket(self.env)
     ticket['summary'] = 'My Summary'
     ticket['description'] = 'Some description'
     ticket.insert()
     tn = TicketNotifyEmail(self.env)
     tn.notify(ticket, newticket=True)
     self.assertNotEqual(None, notifysuite.smtpd.get_message())
     self.assertEqual('My Summary', ticket['summary'])
     self.assertEqual('Some description', ticket['description'])
     valid_fieldnames = set([f['name'] for f in ticket.fields])
     current_fieldnames = set(ticket.values.keys())
     self.assertEqual(set(), current_fieldnames - valid_fieldnames)
コード例 #55
0
 def test_md5_digest(self):
     """MD5 digest w/ non-ASCII recipient address (#3491)"""
     self.env.config.set('notification', 'always_notify_owner', 'false')
     self.env.config.set('notification', 'always_notify_reporter', 'true')
     self.env.config.set('notification', 'smtp_always_cc', '')
     ticket = Ticket(self.env)
     ticket['reporter'] = u'"Jöe Usèr" <*****@*****.**>'
     ticket['summary'] = u'This is a summary'
     ticket.insert()
     tn = TicketNotifyEmail(self.env)
     tn.notify(ticket, newticket=True)
     message = notifysuite.smtpd.get_message()
     (headers, body) = parse_smtp_message(message)
コード例 #56
0
 def send_notification(self, ticket, author):
     if TicketNotifyEmail:
         tn = TicketNotifyEmail(self.env)
         tn.notify(ticket, newticket=False, modtime=ticket['changetime'])
     else:
         event = TicketChangeEvent('changed', ticket, ticket['changetime'],
                                   author)
         try:
             NotificationSystem(self.env).notify(event)
         except Exception as e:
             self.log.error(
                 "Failure sending notification on change to "
                 "ticket #%s: %s", ticket.id, exception_to_unicode(e))