def process_action(self, msg, author, githash=None):
        self.env.log.debug('process_action')

        # Find all the #123 strings in the commit message.
        ticket_re = re.compile('#[0-9]+')
        ticket_numbers = ticket_re.findall(msg)

        # Turn the ticket numbers into ints.
        ticket_numbers = set(
            [int(ticket_number[1:]) for ticket_number in ticket_numbers])

        # For each ticket
        date = datetime_now(utc)
        for ticket_number in ticket_numbers:
            self.env.log.debug(
                'Found ticket number: {n}'.format(n=str(ticket_number)))
            if (githash is not None
                    and self._githash_storecheck(ticket_number, githash)):
                continue
            try:
                db = self.env.get_db_cnx()
                ticket = Ticket(self.env, int(ticket_number), db)
                ticket.save_changes(author, msg, date)
                db.commit()
                self._notify(ticket, date)
                self.env.log.debug('Comment added')
            except ResourceNotFound, e:
                self.log.error(
                    'Ticket not found: {n}'.format(n=str(ticket_number)))
                continue
Example #2
0
    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))
Example #3
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
Example #4
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))
Example #5
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)
Example #6
0
    def _update_ticket(self, changeset, biff_names, biff_cc):
        ticket_updator = self.env.compmgr.components.get(CommitTicketUpdater)
        if not ticket_updator:
            self.env.log.error('CommitTicketUpdater is not available, '
                               'enable it to parse changeset message')
            return

        date = datetime.now(utc)
        tickets = ticket_updator._parse_message(changeset.message)
        perm = PermissionCache(self.env, changeset.author)
        for tkt_id, cmds in tickets.iteritems():
            try:
                has_permission = False
                with self.env.db_transaction:
                    ticket = Ticket(self.env, tkt_id)
                    ticket_perm = perm(ticket.resource)
                    for cmd in cmds:
                        if cmd(ticket, changeset, ticket_perm) is not False:
                            has_permission = True
                    if has_permission:
                        cc_list = ', ' + ', '.join(biff_cc)
                        ticket['cc'] += cc_list
                        fb_field = FileBiffTicketCustomField(ticket)
                        fb_field.add(biff_names)
                        if fb_field.is_updated:
                            ticket.save_changes(changeset.author, '', date)
            except Exception as e:
                self.env.log.error('Unexpected error while processing ticket '
                                   '#%s: %s', tkt_id, exception_to_unicode(e))
Example #7
0
    def _handle_ripe_save(self, req):
        """ hander for save  """
        # TODO: workflow

        # get ticket id
        ticket_id = req.args.get("ticket_id")
        value = req.args.get("value", "").strip()
        field = req.args.get("field")
        old_value = req.args.get("old_value")

        # ticket
        ticket = Ticket(self.env, ticket_id)
        current_value = ticket.values.get(field)

        # validation
        if current_value != old_value and (old_value or current_value):
            self.log.info("Field value should be %s, got %s" % (repr(current_value), repr(old_value)))
            raise TracError("field value inconsistant.")

        # set params
        params = {}
        params[field] = value
        ticket.populate(params)

        # save ticket
        comment = "Updated from report"
        author = get_reporter_id(req, 'author')
        ticket.save_changes(author, comment)

        return value
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)
Example #9
0
    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)
Example #10
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)
 def ticket_created(self, ticket):
     """Called when a ticket is created."""
     hours = convertfloat(ticket['hours'])
     # makes the hours a ticket change like all the other hours records
     if hours > 0:
         self.watch_hours(ticket)  # clears the hours
         t = Ticket(self.env, ticket.id)
         t['hours'] = str(hours)
         t.save_changes(ticket['reporter'])
Example #12
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)
Example #13
0
    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)
Example #14
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)
Example #15
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)
Example #16
0
    def move(self, ticket_id, author, env, delete=False):
        """
        move a ticket to another environment
        
        env: environment to move to
        """
        tables = {"attachment": "id", "ticket_change": "ticket"}

        # open the environment if it is a string
        if isinstance(env, basestring):
            base_path, _project = os.path.split(self.env.path)
            env = open_environment(os.path.join(base_path, env), use_cache=True)

        # get the old ticket
        old_ticket = Ticket(self.env, ticket_id)

        # make a new ticket from the old ticket values
        new_ticket = Ticket(env)
        new_ticket.values = old_ticket.values.copy()
        new_ticket.insert(when=old_ticket.time_created)

        # copy the changelog and attachment DBs
        for table, _id in tables.items():
            for row in get_all_dict(self.env, "SELECT * FROM %s WHERE %s=%%s" % (table, _id), str(ticket_id)):
                row[_id] = new_ticket.id
                insert_row_from_dict(env, table, row)

        # copy the attachments
        src_attachment_dir = os.path.join(self.env.path, "attachments", "ticket", str(ticket_id))
        if os.path.exists(src_attachment_dir):
            dest_attachment_dir = os.path.join(env.path, "attachments", "ticket")
            if not os.path.exists(dest_attachment_dir):
                os.makedirs(dest_attachment_dir)
            dest_attachment_dir = os.path.join(dest_attachment_dir, str(new_ticket.id))
            shutil.copytree(src_attachment_dir, dest_attachment_dir)

        # note the previous location on the new ticket
        new_ticket.save_changes(author, "moved from %s" % self.env.abs_href("ticket", ticket_id))

        # location of new ticket
        new_location = env.abs_href.ticket(new_ticket.id)

        if delete:
            old_ticket.delete()
        else:
            # close old ticket and point to new one
            old_ticket["status"] = u"closed"
            old_ticket["resolution"] = u"moved"
            old_ticket.save_changes(author, u"moved to %s" % new_location)

        if env.config["trac"].get("base_url"):
            return new_location
        else:
            return None
Example #17
0
 def _implementation(db):
     """Apply each change to the ticket and save it."""
     for change in changes.strip(',').split(','):
         change_items = change.split(':')
         self.log.debug('WhiteboardModule: change_items=%s', change_items)
         t = Ticket(self.env, int(change_items[0]))
         values = {}
         values[field] = change_items[1]
         
         t.populate(values)
         t.save_changes(req.authname)
Example #18
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)
Example #19
0
        def _implementation(db):
            """Apply each change to the ticket and save it."""
            for change in changes.strip(',').split(','):
                change_items = change.split(':')
                self.log.debug('WhiteboardModule: change_items=%s',
                               change_items)
                t = Ticket(self.env, int(change_items[0]))
                values = {}
                values[field] = change_items[1]

                t.populate(values)
                t.save_changes(req.authname)
    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)
	def _update_tickets(self, tickets, authname, comment, date):
		"""Update the tickets with the given comment."""
		for tkt_id, cmds in tickets.iteritems():
			try:
				self.log.debug("Updating ticket #%d", tkt_id)
				save = False
				with self.env.db_transaction:
					ticket = Ticket(self.env, tkt_id)
					ticket.save_changes(authname, comment, date)
					self._notify(ticket, date)
			except Exception, e:
				self.log.error("Unexpected error while processing ticket "
							   "#%s: %s", tkt_id, exception_to_unicode(e))
Example #22
0
 def _update_tickets(self, tickets, changeset, comment, date):
     """Update the tickets with the given comment."""
     perm = PermissionCache(self.env, changeset.author)
     for tkt_id, cmds in tickets.iteritems():
         try:
             self.log.debug("Updating ticket #%d", tkt_id)
             with self.env.db_transaction as db:
                 ticket = Ticket(self.env, tkt_id, db)
                 for cmd in cmds:
                     cmd(ticket, changeset, perm(ticket.resource))
                 ticket.save_changes(changeset.author, comment, date, db)
             self._notify(ticket, date)
         except Exception, e:
             self.log.error("Unexpected error while processing ticket " "#%s: %s", tkt_id, exception_to_unicode(e))
Example #23
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 '
Example #24
0
    def process_request(self, req):
        """
        Handle the POST and add or remove the current user from Cc of the given
        ticket.
        """
        cclist = []

        # extract the ticket number from the request
        try:
            ticket_id = int(req.args.get('ticket'))
        except ValueError:
            raise TracError(_("Could not parse ticket ID for Cc Me!"))

        if not req.perm.has_permission('TICKET_APPEND'):
            add_warning(
                req,
                _("You do not have permission to Cc yourself to ticket #%d"),
                ticket_id)
            return self._redirect(req, ticket_id)

        # pylint: disable=no-member
        ticket = Ticket(self.env, ticket_id)

        if len(ticket['cc']) > 0:
            cclist = re.split(r'[;,\s]+', ticket['cc'])

        user = req.authname
        if user is None:
            add_warning(
                req,
                _("Unauthenticated users cannot Cc themselves to tickets"))
            return self._redirect(req, ticket_id)

        if user in cclist:
            add_notice(req,
                       _("You will no longer receive notifications for #%d"),
                       ticket_id)
            cclist.remove(user)
        else:
            add_notice(req,
                       _("You will now receive notifications for ticket #%d"),
                       ticket_id)
            cclist.append(user)

        ticket['cc'] = ', '.join(cclist)

        ticket.save_changes(author=user)

        return self._redirect(req, ticket_id)
Example #25
0
 def _update_tickets(self, tickets, changeset, comment, date):
     """Update the tickets with the given comment."""
     perm = PermissionCache(self.env, changeset.author)
     for tkt_id, cmds in tickets.iteritems():
         try:
             self.log.debug("Updating ticket #%d", tkt_id)
             with self.env.db_transaction as db:
                 ticket = Ticket(self.env, tkt_id, db)
                 for cmd in cmds:
                     cmd(ticket, changeset, perm(ticket.resource))
                 ticket.save_changes(changeset.author, comment, date, db)
             self._notify(ticket, date)
         except Exception, e:
             self.log.error("Unexpected error while processing ticket "
                            "#%s: %s", tkt_id, exception_to_unicode(e))
Example #26
0
 def notify_new_tickets(self, req, id, tickets, addMessage):
     try:
         tag = "[[Estimate(%s)]]" % id
         tickets = intlist(tickets)
         for t in tickets:
             ticket = Ticket (self.env, t)
             if ticket['description'].find (tag) == -1:
                 self.log.debug('Updating Ticket Description : %s'%t)
                 ticket['description'] = ticket['description']+'\n----\n'+tag
                 ticket.save_changes(req.authname, 'added estimate')
         return True
     except Exception, e:
         self.log.error("Error saving new ticket changes: %s" % e)  
         addMessage("Error: %s"  % e)
         return None
Example #27
0
 def _update_field(self, authname, comment, ticket_ids, fb_methodcaller):
     date = datetime.now(utc)
     for tkt_id in chain.from_iterable(ticket_ids):
         try:
             with self.env.db_transaction:
                 ticket = Ticket(self.env, tkt_id)
                 fb_field = FileBiffTicketCustomField(ticket)
                 fb_methodcaller(fb_field)
                 if fb_field.is_updated:
                     ticket.save_changes(authname, comment, date)
         except Exception as e:
             self.env.log.error(
                 'Failed to update ticket file biff field value: '
                 'tkt id: %s, authname: %s, exception: %s', tkt_id,
                 authname, exception_to_unicode(e))
Example #28
0
    def _batch_modify(self, req):
        tickets = req.session["query_tickets"].split(" ")
        comment = req.args.get("comment", "")
        values = {}

        for field in TicketSystem(self.env).get_ticket_fields():
            name = field["name"]
            if name not in ("summary", "reporter", "description", "type", "status", "resolution", "owner"):
                if req.args.has_key("bm_" + name):
                    values[name] = req.args.get(name)

        for id in tickets:
            t = Ticket(self.env, id)
            t.populate(values)
            t.save_changes(req.authname, comment)
Example #29
0
    def process_request(self, req, db=None):
        req.perm.assert_permission('TRAC_ADMIN')

        if not db:
            self.db = self.env.get_db_cnx()

        ticket_id = req.args.get('ticket_id')
        req.hdf['ticket_id'] = ticket_id
        req.hdf['message'] = ''

        repos = self.env.get_repository(req.authname)
        authzperm = SubversionAuthorizer(self.env, req.authname)

        diff_options = get_diff_options(req)
        if req.args.has_key('update'):
            req.redirect(self.env.href.svnpublish(ticket_id))

        ticket = Ticket(self.env, ticket_id)
        chgset = []

        if (ticket['ticketaction'] == "ClonePublish"):
            from publishrevert.setchangeset import SetChangesetModule
            setchangeset = SetChangesetModule(self.env)
            setchangesets = setchangeset.get_setchangesets(ticket_id)

            # get the list of changesets for the ticket_id
            # then loop through and get the actual changesets like the following line
            for rev in setchangesets:
                authzperm.assert_permission_for_changeset(rev)
                changeset = repos.get_changeset(rev)

                # now loop through the files in changeset to get all the paths
                # and for each path, find the current test/prod revision number and save that info
                chgset.append(changeset)

            format = req.args.get('format')
            self._render_html(req, ticket, repos, chgset, diff_options)
            req.hdf['setchangesets'] = setchangesets
            ticket['ticketaction'] = 'CloneTest'
            ticket.save_changes(req.authname, 'published to clone', 0, db)
            req.hdf['message'] += 'Successfully Published All Files'
            req.hdf['ticket'] = ticket.values
        else:
            req.hdf['error'] = 'Error: not in correct state to publish'

        return 'setchangeset.cs', None
Example #30
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)
Example #31
0
    def process_request(self, req, db=None):
        req.perm.assert_permission('TRAC_ADMIN')

        if not db:
            self.db = self.env.get_db_cnx()

        ticket_id = req.args.get('ticket_id')
	req.hdf['ticket_id'] = ticket_id
	req.hdf['message'] = ''

        repos = self.env.get_repository(req.authname)
        authzperm = SubversionAuthorizer(self.env, req.authname)

        diff_options = get_diff_options(req)
        if req.args.has_key('update'):
            req.redirect(self.env.href.svnpublish(ticket_id))

	ticket = Ticket(self.env, ticket_id)
        chgset = []

	if(ticket['ticketaction'] == "ClonePublish"):
            from publishrevert.setchangeset import SetChangesetModule
  	    setchangeset = SetChangesetModule(self.env)
            setchangesets = setchangeset.get_setchangesets(ticket_id)

	    # get the list of changesets for the ticket_id
	    # then loop through and get the actual changesets like the following line
	    for rev in setchangesets:
	        authzperm.assert_permission_for_changeset(rev)
	        changeset = repos.get_changeset(rev)

	    # now loop through the files in changeset to get all the paths
	    # and for each path, find the current test/prod revision number and save that info
                chgset.append(changeset)

            format = req.args.get('format')
            self._render_html(req, ticket, repos, chgset, diff_options)
	    req.hdf['setchangesets'] = setchangesets
	    ticket['ticketaction'] = 'CloneTest'
	    ticket.save_changes(req.authname, 'published to clone', 0, db)
	    req.hdf['message'] += 'Successfully Published All Files'
            req.hdf['ticket'] = ticket.values
	else:
	    req.hdf['error'] = 'Error: not in correct state to publish'

        return 'setchangeset.cs', None
Example #32
0
    def process_request(self, req, env, log):
        tickets = req.session['query_tickets'].split(' ')
        comment = req.args.get('batchmod_value_comment', '')
        modify_changetime = bool(
            req.args.get('batchmod_modify_changetime', False))

        values = self._get_new_ticket_values(req, env)
        self._check_for_resolution(values)
        self._remove_resolution_if_not_closed(values)

        selectedTickets = req.args.get('selectedTickets')
        log.debug('BatchModifyPlugin: selected tickets: %s', selectedTickets)
        selectedTickets = isinstance(
            selectedTickets,
            list) and selectedTickets or selectedTickets.split(',')
        if not selectedTickets:
            raise TracError, 'No tickets selected'

        for id in selectedTickets:
            if id in tickets:
                t = Ticket(env, int(id))

                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)

                if not modify_changetime:
                    log_msg = "(changetime not modified)"
                    db = env.get_db_cnx()
                    db.cursor().execute(
                        "UPDATE ticket set changetime=%s where id=%s" %
                        (original_changetime, t.id))
                    db.commit()

                log.debug('BatchModifyPlugin: saved changes to #%s %s' %
                          (id, log_msg))
Example #33
0
    def _batch_modify(self, req):
        tickets = req.session['query_tickets'].split(' ')
        comment = req.args.get('comment', '')
        values = {}

        for field in TicketSystem(self.env).get_ticket_fields():
            name = field['name']
            if name not in ('summary', 'reporter', \
                        'description', 'type', 'status',
                        'resolution', 'owner'):
                if req.args.has_key('bm_' + name):
                    values[name] = req.args.get(name)

        for id in tickets:
            t = Ticket(self.env, id)
            t.populate(values)
            t.save_changes(req.authname, comment)
Example #34
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)
Example #35
0
    def _process_request(self, req):
        field = req.args.get("whiteboard_group_by")
        changes = req.args.get("whiteboard_changes")

        self.log.debug("WhiteboardModule: field=%s", field)
        self.log.debug("WhiteboardModule: changes=%s", changes)

        db = self.env.get_db_cnx()
        for change in changes.strip(",").split(","):
            change_items = change.split(":")
            self.log.debug("WhiteboardModule: change_items=%s", change_items)
            t = Ticket(self.env, int(change_items[0]))
            values = {}
            values[field] = change_items[1]

            t.populate(values)
            t.save_changes(req.authname, "")
        db.commit()
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)
Example #37
0
 def _save_ticket_changes(self, req, selected_tickets, new_values, comment,
                          action):
     """Save all of the changes to tickets."""
     when = datetime_now(utc)
     list_fields = self._get_list_fields()
     with self.env.db_transaction as db:
         for id in selected_tickets:
             t = Ticket(self.env, int(id))
             _values = new_values.copy()
             for field in list_fields:
                 if field in new_values:
                     old = t.values[field] if field in t.values else ''
                     new = new_values[field]
                     mode = req.args.get('batchmod_value_' + field +
                                         '_mode')
                     new2 = req.args.get(
                         'batchmod_value_' + field + '_secondary', '')
                     _values[field] = self._change_list(
                         old, new, new2, mode)
             controllers = list(self._get_action_controllers(
                 req, t, action))
             for controller in controllers:
                 _values.update(
                     controller.get_ticket_changes(req, t, action))
             t.populate(_values)
             t.save_changes(req.authname, comment, when=when)
             for controller in controllers:
                 controller.apply_action_side_effects(req, t, action)
     tn = BatchTicketNotifyEmail(self.env)
     try:
         tn.notify(selected_tickets, new_values, comment, action,
                   req.authname, when)
     except Exception, e:
         self.log.error(
             "Failure sending notification on ticket batch"
             "change: %s", exception_to_unicode(e))
         add_warning(
             req,
             tag_(
                 "The changes have been saved, but an "
                 "error occurred while sending "
                 "notifications: %(message)s",
                 message=to_unicode(e)))
Example #38
0
 def _process_request(self, req):
     field = req.args.get('whiteboard_group_by')
     changes = req.args.get('whiteboard_changes')
     
     self.log.debug('WhiteboardModule: field=%s', field)
     self.log.debug('WhiteboardModule: changes=%s', changes)
     
     db = self.env.get_db_cnx()
     for change in changes.strip(',').split(','):
         change_items = change.split(':')
         self.log.debug('WhiteboardModule: change_items=%s', change_items)
         t = Ticket(self.env, int(change_items[0]))
         values = {}
         values[field] = change_items[1]
         
         t.populate(values)
         t.save_changes(req.authname, '')        
     db.commit()
     
Example #39
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)
Example #40
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)
Example #42
0
 def _update_tickets(self, tickets, changeset, comment, date):
     """Update the tickets with the given comment."""
     authname = self._authname(changeset)
     perm = PermissionCache(self.env, authname)
     for tkt_id, cmds in tickets.iteritems():
         try:
             self.log.debug("Updating ticket #%d", tkt_id)
             save = False
             with self.env.db_transaction:
                 ticket = Ticket(self.env, tkt_id)
                 ticket_perm = perm(ticket.resource)
                 for cmd in cmds:
                     if cmd(ticket, changeset, ticket_perm) is not False:
                         save = True
                 if save:
                     ticket.save_changes(authname, comment, date)
             if save:
                 self._notify(ticket, date, changeset.author, comment)
         except Exception as e:
             self.log.error("Unexpected error while processing ticket "
                            "#%s: %s", tkt_id, exception_to_unicode(e))
Example #43
0
    def process_request(self, req):
        
        if not req.args.has_key('ticket_id') or not req.args.has_key('author') or not req.args.has_key('spent') or not req.args.has_key('message'):
            raise Exception("Request variables 'ticket_id', 'author', 'spent' and 'message' must be set.")

        ticket = Ticket(self.env, int(req.args.get('ticket_id')))
        
        # Check that timingandestimation plugin is installed...
        if not ticket.values.has_key('hours'):
            raise Exception("Ticket doesn't have 'hours' - check timingandestimation plugin is installed.", 500)
    
        ticket['hours'] = str(req.args.get('spent'))
        ticket.save_changes(req.args.get('author'), req.args.get('message'), datetime.now(utc))

        content = 'OK'
        req.send_response(200)
        req.send_header('Content-Type', 'text/plain')
        req.send_header('Content-Length', len(content))
        req.end_headers()
        req.write(content)
            
Example #44
0
 def _update_tickets(self, tickets, changeset, comment, date):
     """Update the tickets with the given comment."""
     authname = self._authname(changeset)
     perm = PermissionCache(self.env, authname)
     for tkt_id, cmds in tickets.iteritems():
         try:
             self.log.debug("Updating ticket #%d", tkt_id)
             save = False
             with self.env.db_transaction:
                 ticket = Ticket(self.env, tkt_id)
                 ticket_perm = perm(ticket.resource)
                 for cmd in cmds:
                     if cmd(ticket, changeset, ticket_perm) is not False:
                         save = True
                 if save:
                     ticket.save_changes(authname, comment, date)
             if save:
                 self._notify(ticket, date, changeset.author, comment)
         except Exception as e:
             self.log.error("Unexpected error while processing ticket "
                            "#%s: %s", tkt_id, exception_to_unicode(e))
Example #45
0
 def _save_ticket_changes(self, req, selected_tickets,
                          new_values, comment, action):
     """Save all of the changes to tickets."""
     when = datetime.now(utc)
     list_fields = self._get_list_fields()
     with self.env.db_transaction as db:
         for id in selected_tickets:
             t = Ticket(self.env, int(id))
             _values = new_values.copy()
             for field in list_fields:
                 if field in new_values:
                     old = t[field] if field in t else ''
                     new = new_values[field]
                     mode = req.args.get('batchmod_value_' + field +
                                         '_mode')
                     new2 = req.args.get('batchmod_value_' + field +
                                         '_secondary', '')
                     _values[field] = self._change_list(old, new, new2,
                                                        mode)
             controllers = list(self._get_action_controllers(req, t,
                                                             action))
             for controller in controllers:
                 _values.update(controller.get_ticket_changes(req, t,
                                                              action))
             t.populate(_values)
             t.save_changes(req.authname, comment, when=when)
             for controller in controllers:
                 controller.apply_action_side_effects(req, t, action)
     event = BatchTicketChangeEvent(selected_tickets, when,
                                    req.authname, comment, new_values,
                                    action)
     try:
         NotificationSystem(self.env).notify(event)
     except Exception as e:
         self.log.error("Failure sending notification on ticket batch"
                        "change: %s", exception_to_unicode(e))
         add_warning(req, tag_("The changes have been saved, but an "
                               "error occurred while sending "
                               "notifications: %(message)s",
                               message=to_unicode(e)))
Example #46
0
    def ticket_changed(self, ticket, comment, author, old_values):

        pattern = re.compile(self.TICKET_REGEX, re.DOTALL | re.VERBOSE)

        if not isinstance(comment, basestring):
            return

        tickets_referenced = pattern.findall(comment)
        # convert from strings to ints and discard duplicates
        tickets_referenced = set(int(t) for t in tickets_referenced)
        # remove possible self-reference
        tickets_referenced.discard(ticket.id)

        # put trackbacks on the tickets that we found
        if not self.is_tracback(comment):  # prevent infinite recursion
            for ticket_to_tracback in tickets_referenced:
                try:
                    t = Ticket(self.env, ticket_to_tracback)
                except ResourceNotFound:  # referenced ticket does not exist
                    continue

                tracback = self.create_tracbacks(ticket, t, comment)

                # cnum is stored in the ticket_change table as an string
                # identifying the comment number, and if applicable,
                # the replyto comment number. If comment 8 is a reply to
                # comment 4, the string will be '4.8'. The index is used
                # by the TicketChangePlugin to identify the comment being
                # edited, so we make sure to add it here.
                change_log = [
                    i for i in t.get_changelog() if i[2] == "comment"
                ]
                if change_log != []:
                    lastchange = change_log[-1]
                    cnum_lastchange = lastchange[3].rsplit('.', 1)
                    cnum_lastcomment = int(cnum_lastchange[-1])
                    cnum_thischange = str(cnum_lastcomment + 1)
                else:
                    cnum_thischange = "1"
                t.save_changes(author, tracback, cnum=cnum_thischange)
Example #47
0
    def test_ticket(self):
        self.env.config.set('ticket-custom', 'foo', 'text')
        ticket = Ticket(self.env)
        ticket.populate({
            'reporter': 'santa',
            'summary': 'Summary line',
            'description': 'Lorem ipsum dolor sit amet',
            'foo': 'This is a custom field',
            'keywords': 'alpha bravo charlie',
            'cc': '[email protected], [email protected]',
        })
        ticket.insert()
        so = self._get_so()
        self.assertEquals('%s:ticket:1' % self.basename, so.doc_id)
        self.assertEquals('ticket', so.realm)
        self.assertEquals('1', so.id)
        self.assertTrue('#1' in so.title)
        self.assertTrue('Summary line' in so.title)
        self.assertEquals('santa', so.author)
        self.assertEquals(ticket['time'], so.created)
        self.assertEquals(ticket['changetime'], so.changed)
        self.assertTrue('*****@*****.**' in so.involved)
        self.assertTrue('*****@*****.**' in so.involved)
        self.assertTrue('bravo' in so.tags)
        self.assertTrue('Lorem ipsum' in so.oneline)
        self.assertTrue('Lorem ipsum' in so.body)

        original_time = ticket['time']
        ticket['description'] = 'No latin filler here'
        ticket.save_changes('Jack Sprat', 'Could eat no fat')
        so = self._get_so()
        self.assertEquals('%s:ticket:1' % self.basename, so.doc_id)
        self.assertEquals('ticket', so.realm)
        self.assertEquals('1', so.id)
        self.assertEquals(original_time, so.created)
        self.assertEquals(ticket['changetime'], so.changed)
        self.assertFalse('Lorem ipsum' in so.body)
        self.assertTrue('No latin filler here' in so.body)
        self.assertTrue('Could eat no fat' in so.comments)
Example #48
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')

                    ticket.save_changes(attachment.author, comment)

                    #trigger notification since we've changed the ticket
                    tn = TicketNotifyEmail(self.env)
                    tn.notify(ticket, newticket=False, modtime=attachment.date)
Example #49
0
    def ticket_changed(self, ticket, comment, author, old_values):
        
        pattern = re.compile(self.TICKET_REGEX, re.DOTALL|re.VERBOSE)

        if not isinstance(comment, basestring):
            return
        
        tickets_referenced = pattern.findall(comment)
        # convert from strings to ints and discard duplicates
        tickets_referenced = set(int(t) for t in tickets_referenced)
        # remove possible self-reference
        tickets_referenced.discard(ticket.id)

        # put trackbacks on the tickets that we found
        if not self.is_tracback(comment): # prevent infinite recursion
            for ticket_to_tracback in tickets_referenced:
                try:
                    t = Ticket(self.env, ticket_to_tracback)
                except ResourceNotFound: # referenced ticket does not exist
                    continue
                    
                tracback = self.create_tracbacks(ticket, t, comment)
                
                # cnum is stored in the ticket_change table as an string
                # identifying the comment number, and if applicable,
                # the replyto comment number. If comment 8 is a reply to
                # comment 4, the string will be '4.8'. The index is used
                # by the TicketChangePlugin to identify the comment being
                # edited, so we make sure to add it here.
                change_log = [i for i in t.get_changelog()
                              if i[2] == "comment"]
                if change_log != []:
                    lastchange = change_log[-1]
                    cnum_lastchange = lastchange[3].rsplit('.', 1)
                    cnum_lastcomment = int(cnum_lastchange[-1])
                    cnum_thischange = str(cnum_lastcomment + 1)
                else:
                    cnum_thischange = "1"
                t.save_changes(author, tracback, cnum=cnum_thischange)
Example #50
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)
    def _update_tickets(self, tickets, changeset, comment, date):
        """Update the tickets with the given comment."""

        authname = self._get_username_for_changeset_author(changeset.author)
        if not authname:
            authname = self._authname(changeset)
        perm = PermissionCache(self.env, authname)
        ret = {}
        for tkt_id, cmds in tickets.iteritems():
            self.log.debug("Updating ticket #%d", tkt_id)
            save = False
            with self.env.db_transaction:
                try:
                    ticket = Ticket(self.env, tkt_id)
                except ResourceNotFound:
                    self.log.warning("Ticket %i does not exist", tkt_id)
                    ticket = None
                if ticket is not None:
                    ticket_perm = perm(ticket.resource)
                    if self.check_perms and not 'TICKET_MODIFY' in ticket_perm:
                        #sys.stderr.write("%s doesn't have TICKET_MODIFY permission for #%d\n" % (authname, ticket.id))
                        self.log.info("%s doesn't have TICKET_MODIFY permission for #%d",
                                    authname, ticket.id)
                    else:
                        if self._is_author_allowed(changeset.author):
                            for cmd in cmds:
                                if cmd(ticket, changeset, ticket_perm):
                                    save = True
                        else:
                            #sys.stderr.write("%s is not allowed to modify to #%d\n" % (changeset.author, ticket.id))
                            self.log.info("%s is not allowed to modify to #%d",
                                        changeset.author, ticket.id)
                    if save:
                        ticket.save_changes(authname, comment, date)
            if save:
                self._notify(ticket, date)
            ret[tkt_id] = (cmds, ticket)
        return ret
Example #52
0
    def process_request(self, req, env, log):
        tickets = req.session["query_tickets"].split(" ")
        comment = req.args.get("batchmod_value_comment", "")
        modify_changetime = bool(req.args.get("batchmod_modify_changetime", False))

        values = self._get_new_ticket_values(req, env)
        self._check_for_resolution(values)
        self._remove_resolution_if_not_closed(values)

        selectedTickets = req.args.get("selectedTickets")
        log.debug("BatchModifyPlugin: selected tickets: %s", selectedTickets)
        selectedTickets = isinstance(selectedTickets, list) and selectedTickets or selectedTickets.split(",")
        if not selectedTickets:
            raise TracError, "No tickets selected"

        for id in selectedTickets:
            if id in tickets:
                t = Ticket(env, int(id))

                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)

                if not modify_changetime:
                    log_msg = "(changetime not modified)"
                    db = env.get_db_cnx()
                    db.cursor().execute("UPDATE ticket set changetime=%s where id=%s" % (original_changetime, t.id))
                    db.commit()

                log.debug("BatchModifyPlugin: saved changes to #%s %s" % (id, log_msg))
    def test_ticket(self):
        self.env.config.set('ticket-custom', 'foo', 'text')
        ticket = Ticket(self.env)
        ticket.populate({'reporter': 'santa', 'summary': 'Summary line',
                         'description': 'Lorem ipsum dolor sit amet',
                         'foo': 'This is a custom field',
                         'keywords': 'alpha bravo charlie',
                         'cc': '[email protected], [email protected]',
                         })
        ticket.insert()
        so = self._get_so()
        self.assertEquals('%s:ticket:1' % self.basename, so.doc_id)
        self.assertEquals('ticket', so.realm)
        self.assertEquals('1', so.id)
        self.assertTrue('#1' in so.title)
        self.assertTrue('Summary line' in so.title)
        self.assertEquals('santa', so.author)
        self.assertEquals(ticket['time'], so.created)
        self.assertEquals(ticket['changetime'], so.changed)
        self.assertTrue('*****@*****.**' in so.involved)
        self.assertTrue('*****@*****.**' in so.involved)
        self.assertTrue('bravo' in so.tags)
        self.assertTrue('Lorem ipsum' in so.oneline)
        self.assertTrue('Lorem ipsum' in so.body)

        original_time = ticket['time']
        ticket['description'] = 'No latin filler here'
        ticket.save_changes('Jack Sprat', 'Could eat no fat')
        so = self._get_so()
        self.assertEquals('%s:ticket:1' % self.basename, so.doc_id)
        self.assertEquals('ticket', so.realm)
        self.assertEquals('1', so.id)
        self.assertEquals(original_time, so.created)
        self.assertEquals(ticket['changetime'], so.changed)
        self.assertFalse('Lorem ipsum' in so.body)
        self.assertTrue('No latin filler here' in so.body)
        self.assertTrue('Could eat no fat' in so.comments)
Example #54
0
    def process_commit(self, commit):
        '''Process a new git commit.'''
        self.env.log.debug('process_commit: {commit}'.format(commit=commit))

        # Get the git commit message.
        msg = '''{author} [{url} {id}]

{{{{{{
{message}
}}}}}}
'''.format(author=commit['author']['name'],
           url=commit['url'],
           id=commit['id'],
           message=commit['message'])

        # Find all the #123 strings in the commit message.
        ticket_re = re.compile('#[0-9]*')
        ticket_numbers = ticket_re.findall(msg)

        # Turn the ticket numbers into ints.
        ticket_numbers = set(
            [int(ticket_number[1:]) for ticket_number in ticket_numbers])

        for ticket_number in ticket_numbers:
            self.env.log.debug(
                'Found ticket number: {n}'.format(n=str(ticket_number)))
            try:
                db = self.env.get_db_cnx()
                ticket = Ticket(self.env, int(ticket_number), db)
                ticket.save_changes('GitHubServiceHook', msg)
                db.commit()
                self.env.log.debug('Comment added')
            except ResourceNotFound, e:
                self.env.log.debug(
                    'Ticket not found: {n}'.format(n=str(ticket_number)))
                continue