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)
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)
def test_upgrade_moves_tickets_and_related_objects_to_default_prod(self): self._add_custom_field('custom_field') with self.env.db_direct_transaction as db: db("""INSERT INTO ticket (id) VALUES (1)""") db("""INSERT INTO attachment (type, id, filename) VALUES ('ticket', '1', '')""") db("""INSERT INTO ticket_custom (ticket, name, value) VALUES (1, 'custom_field', '42')""") db("""INSERT INTO ticket_change (ticket, time, field) VALUES (1, 42, 'summary')""") self._enable_multiproduct() self.env.upgrade() with self.product('@'): ticket = Ticket(self.env, 1) attachments = list( Attachment.select(self.env, ticket.resource.realm, ticket.resource.id)) self.assertEqual(len(attachments), 1) self.assertEqual(ticket['custom_field'], '42') changes = ticket.get_changelog() self.assertEqual(len(changes), 3)
def test_upgrade_moves_tickets_and_related_objects_to_default_prod(self): self._add_custom_field('custom_field') with self.env.db_direct_transaction as db: db("""INSERT INTO ticket (id) VALUES (1)""") db("""INSERT INTO attachment (type, id, filename) VALUES ('ticket', '1', '')""") db("""INSERT INTO ticket_custom (ticket, name, value) VALUES (1, 'custom_field', '42')""") db("""INSERT INTO ticket_change (ticket, time, field) VALUES (1, 42, 'summary')""") self._enable_multiproduct() self.env.upgrade() with self.product('@'): ticket = Ticket(self.env, 1) attachments = list(Attachment.select(self.env, ticket.resource.realm, ticket.resource.id)) self.assertEqual(len(attachments), 1) self.assertEqual(ticket['custom_field'], '42') changes = ticket.get_changelog() self.assertEqual(len(changes), 3)
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)