def ticket_changed(self, tkt, comment, author, old_values): db = self.env.get_db_cnx() links = TicketLinks(self.env, tkt, db) old_relations = {'blocking': set([]), 'blockedby': set([])} if "blocking" in old_values: old_relations['blocking'] = extract_ticket_ids(old_values['blocking']) if "blockedby" in old_values: old_relations['blockedby'] = extract_ticket_ids(old_values['blockedby']) links.save(old_relations, author, comment, tkt.time_changed, db) db.commit()
def post_process_request(self, req, template, data, content_type): if req.path_info.startswith('/ticket/'): # In case of an invalid ticket, the data is invalid if not data: return template, data, content_type tkt = data['ticket'] links = TicketLinks(self.env, tkt) for i in links.blocked_by: if Ticket(self.env, i)['status'] != 'closed': add_script(req, 'ticketrelations/disable_resolve.js') break for change in data.get('changes', {}): if not change.has_key('fields'): continue for field, field_data in change['fields'].iteritems(): if field in self.fields: if field_data['new'].strip(): new = extract_ticket_ids(field_data['new']) else: new = set() if field_data['old'].strip(): old = extract_ticket_ids(field_data['old']) else: old = set() add = new - old sub = old - new elms = tag() if add: elms.append( tag.em(u', '.join([unicode(n) for n in sorted(add)])) ) elms.append(u' added') if add and sub: elms.append(u'; ') if sub: elms.append( tag.em(u', '.join([unicode(n) for n in sorted(sub)])) ) elms.append(u' removed') field_data['rendered'] = elms return template, data, content_type
def validate_ticket(self, req, ticket): db = self.env.get_db_cnx() cursor = db.cursor() id = unicode(ticket.id) links = TicketLinks(self.env, ticket, db) links.blocking = extract_ticket_ids(ticket['blocking'] or '') links.blocked_by = extract_ticket_ids(ticket['blockedby'] or '') # Check that ticket does not have itself as a blocker if id in links.blocking | links.blocked_by: yield 'blocked_by', 'This ticket is blocking itself' return # Check that there aren't any blocked_by in blocking or their parents blocking = links.blocking.copy() while len(blocking) > 0: if len(links.blocked_by & blocking) > 0: yield 'blocked_by', 'This ticket has circular dependencies' return new_blocking = set() for link in blocking: tmp_tkt = Ticket(self.env, link) new_blocking |= TicketLinks(self.env, tmp_tkt, db).blocking blocking = new_blocking for field in ('blocking', 'blockedby'): try: ids = self.NUMBERS_RE.findall(ticket[field] or '') for id in ids[:]: cursor.execute('SELECT id FROM ticket WHERE id=%s', (id,)) row = cursor.fetchone() if row is None: ids.remove(id) ticket[field] = ', '.join(sorted(ids, key=lambda x: int(x))) except Exception, e: self.log.debug('TicketRelations: Error parsing %s "%s": %s', field, ticket[field], e) yield field, 'Not a valid list of ticket IDs'