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']) actions = ts.get_available_actions(req, ticket) for action in actions: tickets_by_action.setdefault(action, []).append(ticket) sorted_actions = sorted(set(tickets_by_action.keys())) 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 _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 _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']) actions = ts.get_available_actions(req, ticket) for action in actions: tickets_by_action.setdefault(action, []).append(ticket) sorted_actions = sorted(set(tickets_by_action.keys())) 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 filter_stream(self, req, method, filename, stream, formdata): '''Add workflows to query/report output''' if filename != 'query.html' and filename != 'report_view.html': return stream if not (req.perm.has_permission('TICKET_ADMIN') or req.perm.has_permission('TICKET_GRID_WORKFLOW')): return stream ts = TicketSystem(self.env) add_script(req, 'gridflow/gridflow.js') html = stream.render() js = '' tickets = [] copy = genshi.XML(html) nodes = genshi.path.Path('//td[contains(@class, "ticket")]//a/text()') tickets += [int(a[1][1:]) for a in nodes.select(copy)] copy = genshi.XML(html) nodes = genshi.path.Path('//td[contains(@class, "id")]//a/text()') tickets += [int(a[1][1:]) for a in nodes.select(copy)] copy = genshi.XML(html) tktDict = {} for tno in tickets: tktDict[tno] = {'labels': [], 'widgets': [], 'actions': []} tkt = trac.ticket.Ticket(self.env, tno) actions = ts.get_available_actions(req, tkt) for action in actions: for controller in self._get_action_controllers( req, tkt, action): (label, widget, hint) = controller.render_ticket_action_control( req, tkt, action) tktDict[tno]['actions'].append(action) tktDict[tno]['labels'].append(label) tktDict[tno]['widgets'].append(widget.generate().render()) js += 'tktDict = ' + repr(tktDict).replace(", u'", ", '").replace( "[u'", "['") + ';\n' js += 'baseURL = "%s";\n' % req.base_url script = genshi.builder.tag.script(js, type="text/javascript") xpath = '//head' copy |= Transformer(xpath).append(script) return copy
def _process_request(self, req): '''Intercept and execute GridFlow AJAX callbacks.''' if not req.perm.has_permission('TICKET_ADMIN') and \ not req.perm.has_permission('TICKET_GRID_WORKFLOW'): raise Exception('Permission denied') id = req.args.get('id') action = req.args.get('action') ticket = Ticket(self.env, id) ts = TicketSystem(self.env) validActions = ts.get_available_actions(req, ticket) if action not in validActions: req.send_response(500) req.send_header('Content-Type', 'text/plain') req.end_headers() req.write('"%s" is not a valid action for #%d\n' % (action, id)) return changes, problems = self.get_ticket_changes(req, ticket, action) if problems: req.send_response(500) req.send_header('Content-Type', 'text/plain') req.end_headers() req.write('Problems: %s\n' % problems) return self._apply_ticket_changes(ticket, changes) valid, reasons = self._validate_ticket(req, ticket) if not valid: req.send_response(500) req.send_header('Content-Type', 'text/plain') req.end_headers() req.write('Changes not valid:\n') for reason in reasons: req.write('* ' + reason + '\n') return self._save(req, ticket, action) req.send_response(200) req.send_header('Content-Type', 'text/plain') req.end_headers() req.write('OK') return
def filter_stream(self, req, method, filename, stream, formdata): '''Add workflows to query/report output''' if filename != 'query.html' and filename != 'report_view.html': return stream if not (req.perm.has_permission('TICKET_ADMIN') or req.perm.has_permission('TICKET_GRID_WORKFLOW')): return stream ts = TicketSystem(self.env) add_script(req, 'gridflow/gridflow.js') html = stream.render() js = '' tickets = [] copy = genshi.XML(html) nodes = genshi.path.Path('//td[contains(@class, "ticket")]//a/text()') tickets += [int(a[1][1:]) for a in nodes.select(copy)] copy = genshi.XML(html) nodes = genshi.path.Path('//td[contains(@class, "id")]//a/text()') tickets += [int(a[1][1:]) for a in nodes.select(copy)] copy = genshi.XML(html); tktDict = {} for tno in tickets: tktDict[tno] = {'labels': [], 'widgets': [], 'actions': []} tkt = trac.ticket.Ticket(self.env, tno) actions = ts.get_available_actions(req, tkt) for action in actions: for controller in self._get_action_controllers(req, tkt, action): (label, widget, hint) = controller.render_ticket_action_control(req, tkt, action) tktDict[tno]['actions'].append(action) tktDict[tno]['labels'].append(label) tktDict[tno]['widgets'].append(widget.generate().render()) js += 'tktDict = ' + repr(tktDict).replace(", u'", ", '").replace("[u'", "['") + ';\n' js += 'baseURL = "%s";\n' % req.base_url script = genshi.builder.tag.script(js, type="text/javascript") xpath = '//head' copy |= Transformer(xpath).append(script) return copy
def _process_request(self, req): '''Intercept and execute GridFlow AJAX callbacks.''' if not req.perm.has_permission('TICKET_ADMIN') and \ not req.perm.has_permission('TICKET_GRID_WORKFLOW'): raise Exception('Permission denied') id = req.args.get('id') action = req.args.get('action') ticket = Ticket(self.env, id) ts = TicketSystem(self.env) validActions = ts.get_available_actions(req, ticket) if action not in validActions: req.send_response(500) req.send_header('Content-Type', 'text/plain') req.end_headers() req.write('"%s" is not a valid action for #%d\n' % (action, id)) return changes, problems = self.get_ticket_changes(req, ticket, action) if problems: req.send_response(500) req.send_header('Content-Type', 'text/plain') req.end_headers() req.write('Problems: %s\n' % problems) return self._apply_ticket_changes(ticket, changes) valid, reasons = self._validate_ticket(req, ticket) if not valid: req.send_response(500) req.send_header('Content-Type', 'text/plain') req.end_headers() req.write('Changes not valid:\n') for reason in reasons: req.write('* ' + reason + '\n') return self._save(req, ticket, action) req.send_response(200) req.send_header('Content-Type', 'text/plain') req.end_headers() req.write('OK') return