示例#1
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
示例#2
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)
示例#3
0
 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
示例#4
0
    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
文件: 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)
示例#6
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)
示例#7
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)
示例#8
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)
示例#9
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)
示例#10
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)
示例#11
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)
    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)
示例#13
0
 def _update_ticket(ticket):
     # Determine sequence number.
     cnum = 0
     tm = TicketModule(self.env)
     db = self.env.get_db_cnx()
     for change in tm.grouped_changelog_entries(ticket, db):
         # FIXME - should this say "and change['cnum'] > cnum?
         if change['permanent']:
             cnum = change['cnum']
     # FIXME - Put something in the message?
     # FIXME - the ticket_changed method gets an author, should
     # this say "value propagation on behalf of <author>"?
     ticket.save_changes('value propagation', '', when, db, cnum+1)
示例#14
0
    def __init__(self, project=options.project, author=AUTHOR,
                     maxage=options.maxage):

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

            msg = MESSAGE % (maxage)

            now = datetime.now(utc)
            maxtime = to_utimestamp(now - timedelta(days=maxage))

            cursor.execute("SELECT id FROM ticket " \
                           "WHERE status = %s " \
                           "AND changetime < %s ", ('pending', maxtime))
    
            rows = cursor.fetchall()

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

                    ticket['status'] = 'closed'

                    # 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)

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

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

                    tn = TicketNotifyEmail(self.env)
                    tn.notify(ticket, newticket=0, modtime=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)
        except Exception, e:
               import traceback
               traceback.print_exc(file=sys.stderr)
               print>>sys.stderr, 'Unexpected error while retrieving tickets '
示例#15
0
    def process(self, commit, status, payload):
        self.closestatus = status
        
        self.env.log.debug("Processing Commit: %s", commit['id'])
        comment = (commit['message']
            + "\n\n"
            + self.comment_template.format(commit=commit,**payload))
        self.env.log.debug("Prepared Comment: %s", comment)
        author = commit['author']['name']
        timestamp = datetime.now(utc)
        
        cmd_groups = command_re.findall(comment)
        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, comment, 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)
示例#16
0
    def process(self, commit, status):
        self.closestatus = status

        msg = commit['message']
        self.env.log.debug("Processing Commit: %s", msg)
        note = "Changeset: %s" % commit['id']
        msg = "%s[[BR]]\n%s" % (msg, note)
        author = commit['author']['name']
        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):
                    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)
def handle_commit(commit, env, repo):
    from trac.ticket.notification import TicketNotifyEmail
    from trac.ticket import Ticket
    from trac.ticket.web_ui import TicketModule
    from trac.util.text import to_unicode
    from trac.util.datefmt import utc

    commit_log = call_git("rev-list", ["-n", "1", commit, "--pretty=medium"])
    commit_log = process_commit_log(commit_log, repo)
    commit_log = commit_log.rstrip()
    msg = to_unicode(commit_log)
    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"

            # 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(eml, msg, now, db, cnum + 1)
            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)
示例#18
0
    def on_change(self, env, chgset):
        self.env = env
        self.author = chgset.author
        self.rev = chgset.rev
        self.msg = "(In [%s]) %s" % (self.rev, chgset.message)
        self.now = chgset.date

        cmd_groups = command_re.findall(self.msg)

        tickets = {}
        for cmd, tkts in cmd_groups:
            funcname = self._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)
示例#19
0
    def on_change(self, env, chgset):
        self.env = env
        self.author = chgset.author
        self.rev = chgset.rev        
        self.msg = "(In [%s]) %s" % (self.rev, chgset.message)        
        self.now = chgset.date

        cmd_groups = command_re.findall(self.msg)

        tickets = {}
        for cmd, tkts in cmd_groups:
            funcname = self._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)
def handle_commit(commit, env):
    from trac.ticket.notification import TicketNotifyEmail
    from trac.ticket import Ticket
    from trac.ticket.web_ui import TicketModule
    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'

            # 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(eml, msg, now, db, cnum + 1)
            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)
示例#21
0
    def process(self, commit):
        msg = commit['message']
        author = commit['author']['name']
        timestamp = datetime.now(utc)
        
        cmd_groups = command_re.findall(msg)

        tickets = {}
        for cmd, tkts in cmd_groups:
            funcname = self.__class__._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(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)
示例#22
0
for command, ticketList in commandPattern.findall(message):
	if commands.has_key(command.lower()):
		for ticketId in ticketPattern.findall(ticketList):
			tickets.setdefault(ticketId, []).append(commands[command.lower()])

for ticketId, commands in tickets.iteritems():
	db = env.get_db_cnx()

	ticket = Ticket(env, int(ticketId), db)
	for command in commands:
		command(ticket)

	# determine sequence number...
	cnum = 0
	tm = TicketModule(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)

	username = authorPattern.findall(author)[0]
	now = datetime.now(utc)
	message = "(On %s [changeset:%s %s]) %s" % (refname, rev, describe_tags, message)
	ticket['branch'] = refname
	ticket.save_changes(username, message, now, db, cnum+1)
	db.commit()

	tn = TicketNotifyEmail(env)
	tn.notify(ticket, newticket=0, modtime=now)

示例#23
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)

        log("cmd_groups:%s", cmd_groups)
        tickets = {}
        # \todo Explain what xxx1 and xxx2 do; I can't see more params
        # in command_re.
        for cmd, tkts, xxx1, xxx2 in cmd_groups:
            log("cmd:%s, tkts%s ", cmd, tkts)
            funcname = _supported_cmds.get(cmd.lower(), '')
            if funcname:
                for tkt_id, spent in ticket_re.findall(tkts):
                    func = getattr(self, funcname)
                    tickets.setdefault(tkt_id, []).append([func, spent])

        for tkt_id, vals in tickets.iteritems():
            log("tkt_id:%s, vals%s ", tkt_id, vals)
            spent_total = 0.0
            try:
                db = self.env.get_db_cnx()

                ticket = Ticket(self.env, int(tkt_id), db)
                for (cmd, spent) in vals:
                    cmd(ticket)
                    if spent:
                        spent_total += float(spent)

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

                if spent_total:
                    self._setTimeTrackerFields(ticket, spent_total)
                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)
                log('Unexpected error while processing ticket ' \
                                   'ID %s: %s' % (tkt_id, e))
                print>>sys.stderr, 'Unexpected error while processing ticket ' \
                                   'ID %s: %s' % (tkt_id, e)
示例#24
0
for command, ticketList in commandPattern.findall(message):
    if commands.has_key(command.lower()):
        for ticketId in ticketPattern.findall(ticketList):
            tickets.setdefault(ticketId, []).append(commands[command.lower()])

for ticketId, commands in tickets.iteritems():
    db = env.get_db_cnx()

    ticket = Ticket(env, int(ticketId), db)
    for command in commands:
        command(ticket)

    # determine sequence number...
    cnum = 0
    tm = TicketModule(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)

    username = authorPattern.findall(author)[0]
    now = datetime.now(utc)
    message = "(On %s [changeset:%s %s]) %s" % (refname, rev, describe_tags,
                                                message)
    ticket['branch'] = refname
    ticket.save_changes(username, message, now, db, cnum + 1)
    db.commit()

    tn = TicketNotifyEmail(env)
    tn.notify(ticket, newticket=0, modtime=now)
示例#25
0
    def invoke(self, chgset):

        # regular expressions
        ticket_prefix = "(?:#|(?:ticket|issue|bug)[: ]?)"
        if self.intertrac:  # TODO: split to separate function?
            # find intertrac links
            intertrac = {}
            aliases = {}
            for key, value in self.env.config.options("intertrac"):
                if "." in key:
                    name, type_ = key.rsplit(".", 1)
                    if type_ == "url":
                        intertrac[name] = value
                else:
                    aliases.setdefault(value, []).append(key)
            intertrac = dict([(value, [key] + aliases.get(key, [])) for key, value in intertrac.items()])
            project = os.path.basename(self.env.path)

            if "/%s" % project in intertrac:  # TODO:  checking using base_url for full paths:
                ticket_prefix = "(?:%s):%s" % ("|".join(intertrac["/%s" % project]), ticket_prefix)
            else:  # hopefully sesible default:
                ticket_prefix = "%s:%s" % (project, ticket_prefix)

        ticket_reference = ticket_prefix + "[0-9]+"
        ticket_command = r"(?P<action>[A-Za-z]*).?" "(?P<ticket>%s(?:(?:[, &]*|[ ]?and[ ]?)%s)*)" % (
            ticket_reference,
            ticket_reference,
        )
        ticket_command = r"%s%s%s" % (re.escape(self.envelope_open), ticket_command, re.escape(self.envelope_close))
        command_re = re.compile(ticket_command, re.IGNORECASE)
        ticket_re = re.compile(ticket_prefix + "([0-9]+)", re.IGNORECASE)

        # other variables
        msg = "(In [%s]) %s" % (chgset.rev, chgset.message)
        now = chgset.date
        supported_cmds = {}  # TODO: this could become an extension point
        supported_cmds.update(dict([(key, self._cmdClose) for key in self.cmd_close]))
        supported_cmds.update(dict([(key, self._cmdRefs) for key in self.cmd_refs]))

        cmd_groups = command_re.findall(msg)

        tickets = {}
        for cmd, tkts in cmd_groups:
            func = supported_cmds.get(cmd.lower(), None)
            if func:
                for tkt_id in ticket_re.findall(tkts):
                    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 comment sequence number
                cnum = 0
                tm = TicketModule(self.env)
                for change in tm.grouped_changelog_entries(ticket, db):
                    if change["permanent"]:
                        cnum += 1

                # validate the ticket

                # fake a request
                # XXX cargo-culted environ from
                # http://trac.edgewall.org/browser/trunk/trac/web/tests/api.py
                environ = {
                    "wsgi.url_scheme": "http",
                    "wsgi.input": StringIO(""),
                    "SERVER_NAME": "0.0.0.0",
                    "REQUEST_METHOD": "POST",
                    "SERVER_PORT": 80,
                    "SCRIPT_NAME": "/" + self.env.project_name,
                    "REMOTE_USER": chgset.author,
                    "QUERY_STRING": "",
                }
                req = Request(environ, None)
                req.args["comment"] = msg
                req.authname = chgset.author
                req.perm = PermissionCache(self.env, req.authname)
                for manipulator in tm.ticket_manipulators:
                    manipulator.validate_ticket(req, ticket)
                msg = req.args["comment"]
                ticket.save_changes(chgset.author, msg, now, db, cnum + 1)
                db.commit()

                tn = TicketNotifyEmail(self.env)
                tn.notify(ticket, newticket=0, modtime=now)

            except Exception, e:
                message = "Unexpected error while processing ticket ID %s: %s" % (tkt_id, repr(e))
                print >>sys.stderr, message
                self.env.log.error("TicketChanger: " + message)
    def _create_sheet_history(self, req, context, data, book):
        def write_headers(writer, headers):
            writer.write_row((header['label'], 'thead', None, None)
                             for idx, header in enumerate(headers))

        groups = data['groups']
        headers = [
            header for header in data['headers']
            if header['name'] not in ('id', 'time', 'changetime')
        ]
        headers[0:0] = [
            {
                'name': 'id',
                'label': dgettext("messages", "Ticket")
            },
            {
                'name': 'time',
                'label': dgettext("messages", "Time")
            },
            {
                'name': 'author',
                'label': dgettext("messages", "Author")
            },
            {
                'name': 'comment',
                'label': dgettext("messages", "Comment")
            },
        ]

        sheet_name = dgettext("messages", "Change History")
        sheet_count = 1
        writer = book.create_sheet(sheet_name)
        write_headers(writer, headers)

        tkt_ids = [
            result['id']
            for result in chain(*[results for groupname, results in groups])
        ]
        tickets = BulkFetchTicket.select(self.env, tkt_ids)

        mod = TicketModule(self.env)
        for result in chain(*[results for groupname, results in groups]):
            id = result['id']
            ticket = tickets[id]
            ticket_context = context('ticket', id)
            if 'TICKET_VIEW' not in req.perm(ticket_context.resource):
                continue
            values = ticket.values.copy()
            changes = []

            for change in mod.grouped_changelog_entries(ticket, None):
                if change['permanent']:
                    changes.append(change)
            for change in reversed(changes):
                change['values'] = values
                values = values.copy()
                for name, field in change['fields'].iteritems():
                    if name in values:
                        values[name] = field['old']
            changes[0:0] = [{
                'date': ticket.time_created,
                'fields': {},
                'values': values,
                'cnum': None,
                'comment': '',
                'author': ticket['reporter']
            }]

            if writer.row_idx + len(changes) >= writer.MAX_ROWS:
                sheet_count += 1
                writer = book.create_sheet('%s (%d)' %
                                           (sheet_name, sheet_count))
                write_headers(writer, headers)

            for change in changes:
                cells = []
                for idx, header in enumerate(headers):
                    name = header['name']
                    if name == 'id':
                        value = id
                    elif name == 'time':
                        value = change.get('date', '')
                    elif name == 'comment':
                        value = change.get('comment', '')
                    elif name == 'author':
                        value = change.get('author', '')
                        value = Chrome(self.env).format_author(req, value)
                    else:
                        value = change['values'].get(name, '')
                    value, style, width, line = \
                            self._get_cell_data(name, value, req,
                                                ticket_context, writer)
                    if name in change['fields']:
                        style = '%s:change' % style
                    cells.append((value, style, width, line))
                writer.write_row(cells)

        writer.set_col_widths()
示例#27
0
    def invoke(self, chgset):

        # regular expressions
        ticket_prefix = '(?:#|(?:ticket|issue|bug)[: ]?)'
        if self.intertrac:  # TODO: split to separate function?
            # find intertrac links
            intertrac = {}
            aliases = {}
            for key, value in self.env.config.options('intertrac'):
                if '.' in key:
                    name, type_ = key.rsplit('.', 1)
                    if type_ == 'url':
                        intertrac[name] = value
                else:
                    aliases.setdefault(value, []).append(key)
            intertrac = dict([(value, [key] + aliases.get(key, []))
                              for key, value in intertrac.items()])
            project = os.path.basename(self.env.path)

            if '/%s' % project in intertrac:  # TODO:  checking using base_url for full paths:
                ticket_prefix = '(?:%s):%s' % ('|'.join(
                    intertrac['/%s' % project]), ticket_prefix)
            else:  # hopefully sesible default:
                ticket_prefix = '%s:%s' % (project, ticket_prefix)

        ticket_reference = ticket_prefix + '[0-9]+'
        ticket_command = (r'(?P<action>[A-Za-z]*).?'
                          '(?P<ticket>%s(?:(?:[, &]*|[ ]?and[ ]?)%s)*)' %
                          (ticket_reference, ticket_reference))
        ticket_command = r'%s%s%s' % (re.escape(
            self.envelope_open), ticket_command, re.escape(
                self.envelope_close))
        command_re = re.compile(ticket_command, re.IGNORECASE)
        ticket_re = re.compile(ticket_prefix + '([0-9]+)', re.IGNORECASE)

        # other variables
        msg = "(In [%s]) %s" % (chgset.rev, chgset.message)
        now = chgset.date
        supported_cmds = {}  # TODO: this could become an extension point
        supported_cmds.update(
            dict([(key, self._cmdClose) for key in self.cmd_close]))
        supported_cmds.update(
            dict([(key, self._cmdRefs) for key in self.cmd_refs]))

        cmd_groups = command_re.findall(msg)

        tickets = {}
        for cmd, tkts in cmd_groups:
            func = supported_cmds.get(cmd.lower(), None)
            if func:
                for tkt_id in ticket_re.findall(tkts):
                    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 comment sequence number
                cnum = 0
                tm = TicketModule(self.env)
                for change in tm.grouped_changelog_entries(ticket, db):
                    if change['permanent']:
                        cnum += 1

                # validate the ticket

                # fake a request
                # XXX cargo-culted environ from
                # http://trac.edgewall.org/browser/trunk/trac/web/tests/api.py
                environ = {
                    'wsgi.url_scheme': 'http',
                    'wsgi.input': StringIO(''),
                    'SERVER_NAME': '0.0.0.0',
                    'REQUEST_METHOD': 'POST',
                    'SERVER_PORT': 80,
                    'SCRIPT_NAME': '/' + self.env.project_name,
                    'REMOTE_USER': chgset.author,
                    'QUERY_STRING': ''
                }
                req = Request(environ, None)
                req.args['comment'] = msg
                req.authname = chgset.author
                req.perm = PermissionCache(self.env, req.authname)
                for manipulator in tm.ticket_manipulators:
                    manipulator.validate_ticket(req, ticket)
                msg = req.args['comment']
                ticket.save_changes(chgset.author, msg, now, db, cnum + 1)
                db.commit()

                tn = TicketNotifyEmail(self.env)
                tn.notify(ticket, newticket=0, modtime=now)

            except Exception, e:
                message = 'Unexpected error while processing ticket ID %s: %s' % (
                    tkt_id, repr(e))
                print >> sys.stderr, message
                self.env.log.error('TicketChanger: ' + message)
示例#28
0
    def handle_trac(self):
        if ('is_draft' in self.options_dict and
                self.options.is_draft == 'true'):
            return

	if self.trac_over_rpc:
            import xmlrpclib
        else:
            if not (os.path.exists(self.trac_env) and
                    os.path.isdir(self.trac_env)):
                print "trac_env (%s) is not a directory." % self.trac_env
                sys.exit(1)
            # trac specific imports
            from trac.ticket import Ticket
            from trac.env import open_environment
            from trac.ticket.notification import TicketNotifyEmail
            from trac.ticket.web_ui import TicketModule
            from trac.util.datefmt import utc


        # should never be used. but why not...
        if len(self.options.commit) == 0:
            return

        # get actual commit and extract ticket number(s)
        self.commit_msg = call_git('show',['--format=%s%n%b',
                                                '--summary',
                                                self.options.commit])

        # get author for trac comment
        if 'uploader' in self.options_dict and self.options.uploader:
            author = self.options.uploader
        elif 'author' in self.options_dict and self.options.author:
            author = self.options.author
        else:
            author = call_git('rev-list', ['-n',
                                            '1',
                                            self.options.commit,
                                            '--pretty=format:%an <%ae>']
                                    ).splitlines()[1]

        # find ticket numbers referenced in commit message
        ticket_numbers = TICKET_RE.findall(self.commit_msg)

        # create trac comment for every referenced ticket
        if (ticket_numbers):
            for ticket_id in ticket_numbers:

                if self.hook_name.endswith('patchset-created'):
                    msg = self.trac_new_patchset()
                elif self.hook_name.endswith('change-merged'):
                    msg = self.trac_merge_success()
                elif self.hook_name.endswith('comment-added'):
                    if self.comment_always:
                        msg = self.trac_new_review()
                    else:
                        if self.options.verified or self.options.review:
                            if self.options.verified_oldValue == None:
                                continue
                            elif self.options.review_oldValue == None:
                                continue
                        msg = self.trac_new_review()

                if self.debug:
                    print "you should be able to copy and paste the output " \
                          "to trac-comment-preview:"
                    print "---------------------------------------------------"
                    print "%s\n" % msg
                    print "---------------------------------------------------"
                    print "the author of the comment would be: %s"


                if self.trac_over_rpc:
                    try:
                        server = xmlrpclib.ServerProxy(self.trac_env)
                        ticket = {}
                        if self.hook_name.endswith('patchset-created'):
                            if re.search(
                                    "(close|closed|closes|fix|fixed|fixes) #" + \
                                    ticket_id, self.commit_msg, re.IGNORECASE):
                                ticket['status'] = "testing"
                        elif self.hook_name.endswith('change-merged'):
                                ticket['status'] = "closed"
                                ticket['resolution'] = "fixed"
                        server.ticket.update(int(ticket_id), msg, ticket,
                            True, author)

                    except Exception, e:
                        sys.stderr.write('Unexpected error while handling Trac ' \
                                         'ticket ID %s: %s (RPC)' \
                                         % (ticket_id, e))
                        
                else:
                    try:
                        db = self.env.get_db_cnx()
                        ticket = Ticket(self.env, ticket_id, db)
                        now = datetime.now(utc)

                        if self.hook_name.endswith('patchset-created'):
                            if re.search(
                                    "(close|closed|closes|fix|fixed|fixes) #" + \
                                    ticket_id, self.commit_msg, re.IGNORECASE):
                                ticket['status'] = "testing"
                        elif self.hook_name.endswith('change-merged'):
                                ticket['status'] = "closed"
                                ticket['resolution'] = "fixed"

                        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, now, db, str(cnum+1))
                        db.commit()

                        tn = TicketNotifyEmail(self.env)
                        tn.notify(ticket, newticket=0, modtime=now)

                    except Exception, e:
                        sys.stderr.write('Unexpected error while handling Trac ' \
                                         'ticket ID %s: %s (MODULE)' \
                                         % (ticket_id, e))
示例#29
0
	def get_ticket_changes(self, ticket):
		"""Actually calls :meth:`trac.ticket.web_ui.TicketModule.grouped_changelog_entries` since the alternative is to reimplement that method."""
		module = TicketModule(self.env)
		return list(module.grouped_changelog_entries(ticket, None))
示例#30
0
    def __init__(self, project=options.project, author=options.user,
                 rev=options.rev, url=options.url):
        self.init_env( 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 = int(time.time())

        cmd_groups = command_re.findall(self.msg)
        log ("cmd_groups:%s", cmd_groups)
        tickets = {}
        for cmd, tkts, xxx1, xxx2 in cmd_groups:
            log ("cmd:%s, tkts%s ", cmd, tkts)
            funcname = _supported_cmds.get(cmd.lower(), '')
            if funcname:
                for tkt_id, spent in ticket_re.findall(tkts):
                    func = getattr(self, funcname)
                    lst = tickets.setdefault(tkt_id, [])
                    lst.append([func, spent])
                    

        for tkt_id, vals in tickets.iteritems():
            log ("tkt_id:%s, vals%s ", tkt_id, vals)
            spent_total = 0.0
            try:
                db = self.env.get_db_cnx()
                
                ticket = Ticket(self.env, int(tkt_id), db)
                for (cmd, spent) in vals:
                    cmd(ticket)
                    if spent:
                        spent_total += float(spent)

                # determine sequence number... 
                cnum = 0
                tm = TicketModule(self.env)
                for change in tm.grouped_changelog_entries(ticket, db):
                    if change['permanent']:
                        cnum += 1
                if spent_total:
                    self._setTimeTrackerFields(ticket, spent_total)
                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)
                log('Unexpected error while processing ticket ' \
                                   'ID %s: %s' % (tkt_id, e))
                print>>sys.stderr, 'Unexpected error while processing ticket ' \
                                   'ID %s: %s' % (tkt_id, e)
def handle_commit(commit, env):
    from trac.ticket.notification import TicketNotifyEmail
    from trac.ticket import Ticket
    from trac.ticket.web_ui import TicketModule
    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)
    content = msg.split('\n\n', 1)[1]

    tickets = {}
    for cmd, tkts in command_re.findall(content):
        action = COMMANDS.get(cmd.lower())
	#print "action: %s " % action
        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)
	    #print "ticket: %s" % ticket
    	    if ADD_HOURS:
 		#print "message: %s" % content
		hours = hours_re.findall(content)
		if hours:
			#ADD hours to ticket
			hours =  float(hours[0])/len(tickets)
			#code from http://trac-hacks.org/browser/timingandestimationplugin/branches/trac0.11/timingandestimationplugin/ticket_daemon.py
			#print "hours: %s" % hours
			totalHours = readTicketValue("totalhours", convertfloat,ticket,env)
			#print "totalhours: %s" % totalHours
			newtotal = str(totalHours+hours)
			#print "newtotal: %s" % newtotal
			cl = ticket.get_changelog()
			if cl:
				#print "cl: %s" % cl
				most_recent_change = cl[-1]
				change_time  = most_recent_change[0]
				#print "changetime: %s" % change_time
				author = most_recent_change[1]
			else:
				change_time = ticket.time_created
				author = ticket.values["reporter"]
			db =  env.get_db_cnx()
			#print "saving changes"
			save_ticket_change( db, tkt_id, author, change_time, "hours", '0.0', str(hours) )
			save_ticket_change( db, tkt_id, author, change_time, "totalhours", str(totalHours), str(newtotal))
			save_custom_field_value( db, tkt_id, "hours", '0')	
			save_custom_field_value( db, tkt_id, "totalhours", str(newtotal) )
			#print "hour changes saved"

            if 'close' in actions:
                ticket['status'] = 'closed'
                ticket['resolution'] = 'fixed'
	
            # 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(eml, msg, now, db, cnum + 1)
            db.commit()

            tn = TicketNotifyEmail(env)
            tn.notify(ticket, newticket=0, modtime=now)
            
            #dirty workaround for being able to save only one ticket/second, should be fixed in track 0.12 (1 ticket/microsecond)
            #see also http://trac.edgewall.org/ticket/9993
            time.sleep(1)
            now = datetime.now(utc)

        except Exception, e:
            print 'Unexpected error while processing commit %s, for ticket ID %s: %s %s' % (commit, tkt_id, e.__class__,e)