def _insert_ticket(cls, env, summary, **kw): """Helper for inserting a ticket into the database""" ticket = Ticket(env) ticket["summary"] = summary for k, v in kw.items(): ticket[k] = v return ticket.insert()
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))
def process_request(self, req): req.perm.assert_permission('TICKET_VIEW') action = req.args.get('action', 'view') if not req.args.has_key('id'): req.redirect(self.env.href.wiki()) db = self.env.get_db_cnx() id = int(req.args.get('id')) ticket = Ticket(self.env, id, db=db) reporter_id = util.get_reporter_id(req) if req.method == 'POST': if not req.args.has_key('preview'): self._do_save(req, db, ticket) else: # Use user supplied values ticket.populate(req.args) req.hdf['ticket.action'] = action req.hdf['ticket.ts'] = req.args.get('ts') req.hdf['ticket.reassign_owner'] = req.args.get('reassign_owner') \ or req.authname req.hdf['ticket.resolve_resolution'] = req.args.get('resolve_resolution') reporter_id = req.args.get('author') comment = req.args.get('comment') if comment: req.hdf['ticket.comment'] = util.escape(comment) # Wiki format a preview of comment req.hdf['ticket.comment_preview'] = wiki_to_html(comment, self.env, req, db) else: req.hdf['ticket.reassign_owner'] = req.authname # Store a timestamp in order to detect "mid air collisions" req.hdf['ticket.ts'] = ticket.time_changed self._insert_ticket_data(req, db, ticket, reporter_id) # If the ticket is being shown in the context of a query, add # links to help navigate in the query result set if 'query_tickets' in req.session: tickets = req.session['query_tickets'].split() if str(id) in tickets: idx = tickets.index(str(ticket.id)) if idx > 0: add_link(req, 'first', self.env.href.ticket(tickets[0]), 'Ticket #%s' % tickets[0]) add_link(req, 'prev', self.env.href.ticket(tickets[idx - 1]), 'Ticket #%s' % tickets[idx - 1]) if idx < len(tickets) - 1: add_link(req, 'next', self.env.href.ticket(tickets[idx + 1]), 'Ticket #%s' % tickets[idx + 1]) add_link(req, 'last', self.env.href.ticket(tickets[-1]), 'Ticket #%s' % tickets[-1]) add_link(req, 'up', req.session['query_href']) add_stylesheet(req, 'common/css/ticket.css') return 'ticket.cs', None
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)
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)
def create_ticket_for_lineitem (self, req, id, addMesage, lineitem, summary=None): #skip line items that have a ticket if re.search('/ticket/\d+', lineitem.description): return compname = 'Estimate-'+str(id) if summary: compname = summary ensure_component(self.env, compname, req.authname) t = Ticket(self.env) # try to split on a newline or space that is less than 80 chars into the string idx = lineitem.description.find('\n', 0, 80) if idx < 0: idx = lineitem.description.find(' ', 45, 80) if idx < 0: idx = 45 summary = lineitem.description[:idx] desc = lineitem.description desc += "\n\nFrom [/Estimate?id=%s Created From Estimate %s]" % \ (lineitem.estimate_id,lineitem.estimate_id) t.values['summary'] = summary t.values['description'] = desc t.values['status'] = 'new' t.values['reporter'] = req.authname t.values['component'] = compname t.values['estimatedhours'] = avg(lineitem.low, lineitem.high) t.insert() lineitem.description+="\n\nCreated as /ticket/%s" % (t.id, ) return t
def submit(self, req): ticket = Ticket(self.env) # required fields ticket['aid'] = req.args['aid'] description = req.args['description'] ticket['description'] = description ticket['summary'] = req.args.get('summary', description) # other fields excluded = ['aid', 'description', 'summary'] fields = [ field['name'] for field in ticket.fields if field['name'] not in excluded ] for field in fields: arg = req.args.get(field) if arg is not None: ticket[field] = arg # create the ticket _id = ticket.insert() # yield the ticket ID return {"servicerequestid": _id}
def find_ticket(self, ticket_spec): ticket = None m = re.match(r'#?(?P<tid>\d+)', ticket_spec) if m: tid = m.group('tid') try: ticket = Ticket(self.env, tid) except ResourceNotFound: # ticket not found in current product, try all other products for p in Product.select(self.env): if p.prefix != self.env.product.prefix: # TODO: check for PRODUCT_VIEW permissions penv = ProductEnvironment(self.env.parent, p.prefix) try: ticket = Ticket(penv, tid) except ResourceNotFound: pass else: break # ticket still not found, use fallback for <prefix>:ticket:<id> syntax if ticket is None: try: resource = ResourceIdSerializer.get_resource_by_id(ticket_spec) ticket = self._create_ticket_by_full_id(resource) except: raise NoSuchTicketError return ticket
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))
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 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
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
def save_changesets(self, ticket_id, author, rev, when=0): """ Store ticket setchangesets in the database. The ticket must already exist in the database. """ # TODO: fetch ticket and assert it exists ticket = Ticket(self.env, ticket_id) assert ticket.exists, 'Cannot update a new ticket' db = None if not db: db = self.env.get_db_cnx() handle_ta = True else: handle_ta = False cursor = db.cursor() when = int(when or time.time()) cursor.execute("INSERT INTO ticket_revision (rev,ticket_id) VALUES(%s,%s)", (rev, ticket_id)) if handle_ta: db.commit() ticket._old = {} ticket.time_changed = when
def process_request(self, req): req.perm.assert_permission('TICKET_VIEW') action = req.args.get('action', 'view') if not req.args.has_key('id'): req.redirect(self.env.href.wiki()) db = self.env.get_db_cnx() id = int(req.args.get('id')) ticket = Ticket(self.env, id, db=db) reporter_id = util.get_reporter_id(req) if req.method == 'POST': if not req.args.has_key('preview'): self._do_save(req, db, ticket) else: # Use user supplied values ticket.populate(req.args) req.hdf['ticket.action'] = action req.hdf['ticket.ts'] = req.args.get('ts') req.hdf['ticket.reassign_owner'] = req.args.get('reassign_owner') \ or req.authname req.hdf['ticket.resolve_resolution'] = req.args.get('resolve_resolution') reporter_id = req.args.get('author') comment = req.args.get('comment') if comment: req.hdf['ticket.comment'] = comment # Wiki format a preview of comment req.hdf['ticket.comment_preview'] = wiki_to_html(comment, self.env, req, db) else: req.hdf['ticket.reassign_owner'] = req.authname # Store a timestamp in order to detect "mid air collisions" req.hdf['ticket.ts'] = ticket.time_changed self._insert_ticket_data(req, db, ticket, reporter_id) # If the ticket is being shown in the context of a query, add # links to help navigate in the query result set if 'query_tickets' in req.session: tickets = req.session['query_tickets'].split() if str(id) in tickets: idx = tickets.index(str(ticket.id)) if idx > 0: add_link(req, 'first', self.env.href.ticket(tickets[0]), 'Ticket #%s' % tickets[0]) add_link(req, 'prev', self.env.href.ticket(tickets[idx - 1]), 'Ticket #%s' % tickets[idx - 1]) if idx < len(tickets) - 1: add_link(req, 'next', self.env.href.ticket(tickets[idx + 1]), 'Ticket #%s' % tickets[idx + 1]) add_link(req, 'last', self.env.href.ticket(tickets[-1]), 'Ticket #%s' % tickets[-1]) add_link(req, 'up', req.session['query_href']) add_stylesheet(req, 'common/css/ticket.css') return 'ticket.cs', None
def import_tickets(self): trac_cursor = self.env.get_db_cnx().cursor() peer = SymfonyErrorPeer(self.env) owners = {} trac_cursor.execute("select owner, name from component") for name, owner in trac_cursor: owners[name] = owner for error in peer.select_grouped(): # ticket with current hash key not exists ? trac_cursor.execute("select ticket from ticket_custom where name = 'symfony_error_key' and value = '%s'" % error['hash_key']) existing = trac_cursor.fetchone() if not existing: ticket = Ticket(self.env) ticket.values['summary'] = 'Bug #' + error['hash_key'] + ' ' + error['message'] ticket.values['symfony_error_key'] = error['hash_key'] ticket.values['reporter'] = 'cron' ticket.values['resolution'] = 'new' ticket.values['status'] = 'new' ticket.values['milestone'] = '0.3.1' if error['module_name'] in owners: owner = owners[error['module_name']] else: owner = self.default_owner ticket.values['owner'] = owner ticket.insert()
def save_changesets(self, ticket_id, author, rev, when=0): """ Store ticket setchangesets in the database. The ticket must already exist in the database. """ # TODO: fetch ticket and assert it exists ticket = Ticket(self.env, ticket_id) assert ticket.exists, 'Cannot update a new ticket' db = None if not db: db = self.env.get_db_cnx() handle_ta = True else: handle_ta = False cursor = db.cursor() when = int(when or time.time()) cursor.execute( "INSERT INTO ticket_revision (rev,ticket_id) VALUES(%s,%s)", (rev, ticket_id)) if handle_ta: db.commit() ticket._old = {} ticket.time_changed = when
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)
def pre_process_request(self, req, handler): if req.method == 'POST' and req.args.get('testman_cnum', None): t = Ticket(self.env, tkt_id=req.args.get('path')) cdate = t.get_change(cnum=req.args.get('testman_cnum'))['date'] comment = t.get_change(cnum=req.args.get('testman_cnum'))['fields']['comment']['new'] new_comment = u"%s\n attachment added: [attachment:ticket:%s:%s]" % (comment, req.args.get("id"), req.args.get('attachment').filename) t.modify_comment(cdate, req.authname, new_comment, when=cdate) return handler
def filter_stream(self, req, method, filename, stream, data): """ filter the stream for the roadmap (/roadmap) and milestones /milestone/<milestone> """ if filename in ('roadmap.html', 'milestone_view.html'): trachours = TracHoursPlugin(self.env) hours = {} milestones = data.get('milestones') this_milestone = None if milestones is None: # /milestone view : only one milestone milestones = [ data['milestone'] ] this_milestone = milestones[0].name find_xpath = "//div[@class='milestone']//h1" xpath = "//div[@class='milestone']//div[@class='info']" else: # /roadmap view find_xpath = "//li[@class='milestone']//h2/a" xpath = "//li[@class='milestone']//div[@class='info']" for milestone in milestones: hours[milestone.name] = dict(totalhours=0., estimatedhours=0.,) db = self.env.get_db_cnx() cursor = db.cursor() cursor.execute("select id from ticket where milestone=%s", (milestone.name,)) tickets = [i[0] for i in cursor.fetchall()] if tickets: hours[milestone.name]['date'] = Ticket(self.env, tickets[0]).time_created for ticket in tickets: ticket = Ticket(self.env, ticket) # estimated hours for the ticket try: estimatedhours = float(ticket['estimatedhours']) except (ValueError, TypeError): estimatedhours = 0. hours[milestone.name]['estimatedhours'] += estimatedhours # total hours for the ticket (seconds -> hours) totalhours = trachours.get_total_hours(ticket.id) / 3600.0 hours[milestone.name]['totalhours'] += totalhours # update date for oldest ticket if ticket.time_created < hours[milestone.name]['date']: hours[milestone.name]['date'] = ticket.time_created b = StreamBuffer() stream |= Transformer(find_xpath).copy(b).end().select(xpath).append(self.MilestoneMarkup(b, hours, req.href, this_milestone)) return stream
def start_work(self, ticket): if not self.can_work_on(ticket): return False # We could just horse all the fields of the ticket to the right values # bit it seems more correct to follow the in-build state-machine for # ticket modification. # If the ticket is closed, we need to reopen it. tckt = Ticket(self.env, ticket) if 'closed' == tckt['status']: tckt['status'] = 'reopened' tckt['resolution'] = '' self.save_ticket( tckt, 'Automatically reopening in order to start work.') # Reinitialise for next test tckt = Ticket(self.env, ticket) if self.authname != tckt['owner']: tckt['owner'] = self.authname if 'new' == tckt['status']: tckt['status'] = 'accepted' else: tckt['status'] = 'new' self.save_ticket( tckt, 'Automatically reassigning in order to start work.') # Reinitialise for next test tckt = Ticket(self.env, ticket) if 'accepted' != tckt['status']: tckt['status'] = 'accepted' self.save_ticket( tckt, 'Automatically accepting in order to start work.') # There is a chance the user may be working on another ticket at the moment # depending on config options if self.config.getbool('worklog', 'autostopstart'): # Don't care if this fails, as with these arguments the only failure # point is if there is no active task... which is the desired scenario :) self.stop_work( comment='Stopping work on this ticket to start work on #%s.' % ticket) self.explanation = '' db = self.env.get_db_cnx() cursor = db.cursor() cursor.execute( """ INSERT INTO work_log (worker, ticket, lastchange, starttime, endtime) VALUES (%s, %s, %s, %s, %s) """, (self.authname, ticket, self.now, self.now, 0)) db.commit() return True
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'])
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 __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 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)
def process_request(self, req): req.perm.assert_permission('TICKET_CREATE') db = self.env.get_db_cnx() if req.method == 'POST' and not req.args.has_key('preview'): self._do_create(req, db) ticket = Ticket(self.env, db=db) ticket.populate(req.args) ticket.values.setdefault('reporter', util.get_reporter_id(req)) if ticket.values.has_key('description'): description = wiki_to_html(ticket['description'], self.env, req, db) req.hdf['newticket.description_preview'] = description req.hdf['title'] = 'New Ticket' req.hdf['newticket'] = dict( zip(ticket.values.keys(), [util.escape(value) for value in ticket.values.values()])) field_names = [ field['name'] for field in ticket.fields if not field.get('custom') ] if 'owner' in field_names: curr_idx = field_names.index('owner') if 'cc' in field_names: insert_idx = field_names.index('cc') else: insert_idx = len(field_names) if curr_idx < insert_idx: ticket.fields.insert(insert_idx, ticket.fields[curr_idx]) del ticket.fields[curr_idx] for field in ticket.fields: name = field['name'] del field['name'] if name in ('summary', 'reporter', 'description', 'type', 'status', 'resolution'): field['skip'] = True elif name == 'owner': field['label'] = 'Assign to' elif name == 'milestone': # Don't make completed milestones available for selection options = field['options'] for option in field['options']: milestone = Milestone(self.env, option, db=db) if milestone.is_completed: options.remove(option) field['options'] = options req.hdf['newticket.fields.' + name] = field add_stylesheet(req, 'common/css/ticket.css') return 'newticket.cs', None
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 _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 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 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 test_remove_all(self): test_name = sys._getframe().f_code.co_name expected = self.expected_results[test_name] ticket = Ticket(self.env) ticket.populate({'reporter': 'santa', 'summary': 'Summary line', 'description': 'Lorem ipsum dolor sit amet', }) ticket.insert() self.assertEqual(1, len(self._get_docs())) rv, output = self._execute('fulltext remove') self.assertEqual(expected, output) self.assertEqual(0, len(self._get_docs()))
def parse(self, fp): msg = email.message_from_file(fp) tkt = Ticket(self.env) tkt['status'] = 'new' tkt['reporter'] = msg['from'] tkt['summary'] = msg['subject'] for part in msg.walk(): if part.get_content_type() == 'text/plain': tkt['description'] = part.get_payload(decode=1).strip() if tkt.values.get('description'): tkt.insert()
def parse(self, fp): msg = email.message_from_file(fp) tkt = Ticket(self.env) tkt['status'] = 'new' tkt['reporter'] = msg['from'] tkt['summary'] = msg['subject'] for part in msg.walk(): if part.get_content_type() == 'text/plain': tkt['description'] = part.get_payload(decode=1).strip() if tkt['description']: tkt.insert()
def parse(self, fp): msg = email.message_from_file(fp) tkt = Ticket(self.env) tkt["status"] = "new" tkt["reporter"] = msg["from"] tkt["summary"] = msg["subject"] for part in msg.walk(): if part.get_content_type() == "text/plain": tkt["description"] = part.get_payload(decode=1).strip() if tkt.values.get("description"): tkt.insert()
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))
def _clone_testcase(self, db, id, status, milestone, assign=None): self.env.log.info("Cloning ticket %d (status == %s)" % (id, status)) ticket_new = Ticket(self.env, db=db) ticket_old = Ticket(self.env, tkt_id=id, db=db) for k,v in ticket_old.values.items(): self.env.log.debug("id: %d\tkey: %s\t\tvalue: %s" % (id,k,v)) ticket_new.values[k] = ticket_old.values[k] if assign and len(assign) > 0: ticket_new['owner'] = assign.strip() ticket_new.values['milestone'] = milestone ticket_new.insert() for k,v in ticket_new.values.items(): self.env.log.info("%s\t%s" % (k, v))
def process_request(self, req): req.perm.assert_permission('TICKET_CREATE') db = self.env.get_db_cnx() if req.method == 'POST' and not req.args.has_key('preview'): self._do_create(req, db) ticket = Ticket(self.env, db=db) ticket.populate(req.args) ticket.values.setdefault('reporter', util.get_reporter_id(req)) if ticket.values.has_key('description'): description = wiki_to_html(ticket['description'], self.env, req, db) req.hdf['newticket.description_preview'] = description req.hdf['title'] = 'New Ticket' req.hdf['newticket'] = ticket.values field_names = [field['name'] for field in ticket.fields if not field.get('custom')] if 'owner' in field_names: curr_idx = field_names.index('owner') if 'cc' in field_names: insert_idx = field_names.index('cc') else: insert_idx = len(field_names) if curr_idx < insert_idx: ticket.fields.insert(insert_idx, ticket.fields[curr_idx]) del ticket.fields[curr_idx] for field in ticket.fields: name = field['name'] del field['name'] if name in ('summary', 'reporter', 'description', 'type', 'status', 'resolution'): field['skip'] = True elif name == 'owner': field['label'] = 'Assign to' elif name == 'milestone': # Don't make completed milestones available for selection options = field['options'][:] for option in field['options']: milestone = Milestone(self.env, option, db=db) if milestone.is_completed: options.remove(option) field['options'] = options req.hdf['newticket.fields.' + name] = field add_stylesheet(req, 'common/css/ticket.css') return 'newticket.cs', None
def test_can_insert_tickets_after_upgrade(self): t1 = Ticket(self.env) t1.summary = "test" t1.insert() self.assertEqual(t1.id, 1) self._enable_multiproduct() self.env.upgrade() with self.product('@'): ticket = Ticket(self.env) ticket.summary = 'test' ticket.insert() self.assertEqual(ticket.id, 2)
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 '
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))
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)
def test_can_insert_tickets_with_same_id_to_different_products(self): self._enable_multiproduct() self.env.upgrade() self.env.db_transaction("INSERT INTO ticket (id, summary)" " VALUES (1, 'first product')") t1 = Ticket(self.env, 1) with self.product('@'): self.env.db_transaction("INSERT INTO ticket (id, summary)" " VALUES (1, 'second product')") t2 = Ticket(self.env, 1) self.assertEqual(t1.id, t2.id) self.assertNotEqual(t1['summary'], t2['summary'])
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)
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))
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
def run(options): # # defualt value # T_STATUS = 'new' T_MILESTONE = '' # # begin to create new ticket # TRAC_ENV = os.environ.get('TRAC_ENV') or os.path.expanduser('/home/trac/glue') if not os.path.isdir(TRAC_ENV): print >>sys.stderr, "Set TRAC_ENV to the Trac project directory." #sys.exit(2) return { "status": 2 } from trac.env import open_environment from trac.ticket import Ticket t = Ticket(open_environment(TRAC_ENV)) info = dict( status=T_STATUS, owner=options["owner"], reporter=options["reporter"], cc=options["cc"], milestone=T_MILESTONE, type=options["type"], summary=options["summary"].decode(sys.getfilesystemencoding()), description = options["description"].decode(sys.getfilesystemencoding()) ) t.populate(info) num = t.insert() if not num: print >>sys.stderr, "Ticket not created" print >>sys.stderr, vals #sys.exit(1) return { "status": 1 } #print "Ticket #%d" % (num) return { "status": 0, "id": num }
def ticket(self, message): """ return a ticket associated with a message subject, or None if not available """ # get and format the subject template subject_template = self.env.config.get('notification', 'ticket_subject_template') prefix = self.env.config.get('notification', 'smtp_subject_prefix') subject_template = subject_template.replace('$prefix', prefix).replace( '$summary', 'summary').replace('$ticket.id', 'ticketid') subject_template_escaped = re.escape(subject_template) # build the regex subject_re = subject_template_escaped.replace('summary', '.*').replace( 'ticketid', '([0-9]+)') # get the real subject subject = strip_res(message['subject']) # see if it matches the regex match = re.match(subject_re, subject) if not match: return None # get the ticket ticket_id = int(match.groups()[0]) try: ticket = Ticket(self.env, ticket_id) except: return None return ticket
def images(self, ticket, href=None): """returns images for a ticket""" # construct a ticket from an id if isinstance(ticket, int): ticket = Ticket(self.env, ticket) if not ticket.exists: return {} attachments = list(Attachment.select(self.env, 'ticket', ticket.id)) images = {} for attachment in attachments: try: filename, category = self.image_category(attachment) except TypeError: continue images.setdefault(filename, {})[category] = attachment.filename if href is not None: # turn the keys into links for values in images.values(): for key, value in values.items(): values[key] = href('attachment', 'ticket', ticket.id, value, format='raw') return images
def _get_action_controls(self, req, tickets): action_controls = [] ts = TicketSystem(self.env) tickets_by_action = {} for t in tickets: ticket = Ticket(self.env, t['id']) available_actions = ts.get_available_actions(req, ticket) for action in available_actions: tickets_by_action.setdefault(action, []).append(ticket) # Sort the allowed actions by the 'default' key. allowed_actions = set(tickets_by_action.keys()) workflow = ConfigurableTicketWorkflow(self.env) all_actions = sorted( ((action['default'], name) for name, action in workflow.get_all_actions().iteritems()), reverse=True) sorted_actions = [ action[1] for action in all_actions if action[1] in allowed_actions ] for action in sorted_actions: first_label = None hints = [] widgets = [] ticket = tickets_by_action[action][0] for controller in self._get_action_controllers( req, ticket, action): label, widget, hint = controller.render_ticket_action_control( req, ticket, action) if not first_label: first_label = label widgets.append(widget) hints.append(hint) action_controls.append((action, first_label, tag(widgets), hints)) return action_controls
def process_request(self, req, db=None): req.perm.assert_permission('CHANGESET_VIEW') if not db: db = self.env.get_db_cnx() # Fetch the standard ticket fields cursor = db.cursor() ticket_id = req.args.get('ticket_id') req.hdf['ticket_id'] = ticket_id 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.setchangeset(ticket_id)) ticket = Ticket(self.env, ticket_id) ticket.setchangesets = self.get_setchangesets(ticket_id,db) ticket.values['setchangesets'] = ticket.setchangesets ticket.values['changesets'] = "" for changeset in ticket.setchangesets: ticket.values['changesets'] += str(changeset) setchangesets = ticket.setchangesets req.hdf['ticket'] = ticket req.hdf['dbWarning'] = False # get the list of changesets for the ticket_id # then loop through and get the actual changesets like the following line chgset = [] self.log.debug('PublishRevert: %s', ticket['ticketaction']) for rev in setchangesets: authzperm.assert_permission_for_changeset(rev) changeset = repos.get_changeset(rev) chgset.append(changeset) format = req.args.get('format') self._render_html(req, ticket, repos, chgset, diff_options) return 'setchangeset.cs', None
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
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)
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()