def filter_stream(self, req, method, filename, stream, data): # Add delete buttons to the ticket form ticket = data.get('ticket') if filename == 'ticket.html' and 'TICKET_ADMIN' in req.perm(ticket.resource): # Add Delete button to ticket description if data['ticket'].values['description']: # Reply button and associated elements are present filter = Transformer("//div[@class='description']//div[@class='inlinebuttons']") stream |= filter.append(tag.input(type='submit', name='delete', title="Delete this ticket", value='Delete')) else: # Reply button and associated elements not present filter = Transformer("//div[@class='description']/h3") stream |= filter.after( \ tag.form(tag.div(tag.input(type='submit', name='delete', title="Delete this ticket", value='Delete'), class_='inlinebuttons' ), name='addreply', method='get', action='#comment') ) # Add Delete buttons to ticket comments stream |= Transformer("//div[@id='changelog']//div[@class='inlinebuttons']") \ .append(tag.input(type='submit', name='delete', title="Delete this comment", value='Delete')) return stream
def filter_stream(self, req, method, filename, stream, data): """Return a filtered Genshi event stream, or the original unfiltered stream if no match. """ if filename == "ticket.html" and \ ('TICKET_REMINDER_VIEW' in req.perm or 'TICKET_REMINDER_MODIFY' in req.perm or 'TICKET_ADMIN' in req.perm): tags = self._reminder_tags(req, data) if tags: ticket_resource = data['ticket'].resource context = Context.from_request(req, ticket_resource) attachments_data = AttachmentModule( self.env).attachment_data(context) add_stylesheet(req, 'ticketreminder/css/ticketreminder.css') # Will attachments section be displayed? attachments_or_ticket = Transformer( '//div[@id="attachments"]' ) if attachments_data['can_create'] or attachments_data[ 'attachments'] else Transformer('//div[@id="ticket"]') trac_nav = Transformer( '//form[@id="propertyform"]/div[@class="trac-nav"]') return stream | attachments_or_ticket.after( tags) | trac_nav.append(self._reminder_trac_nav(req, data)) return stream
def filter_stream(self, req, method, filename, stream, data): # Add delete buttons to the ticket form ticket = data.get("ticket") if filename == "ticket.html" and "TICKET_ADMIN" in req.perm(ticket.resource): # Add Delete button to ticket description if data["ticket"].values["description"]: # Reply button and associated elements are present filter = Transformer("//div[@class='description']//div[@class='inlinebuttons']") stream |= filter.append( tag.input(type="submit", name="delete", title="Delete this ticket", value="Delete") ) else: # Reply button and associated elements not present filter = Transformer("//div[@class='description']/h3") stream |= filter.after( tag.form( tag.div( tag.input(type="submit", name="delete", title="Delete this ticket", value="Delete"), class_="inlinebuttons", ), name="addreply", method="get", action="#comment", ) ) # Add Delete buttons to ticket comments stream |= Transformer("//div[@id='changelog']//div[@class='inlinebuttons']").append( tag.input(type="submit", name="delete", title="Delete this comment", value="Delete") ) return stream
def _show_branches_tags(self, req, info, changes): filters = [] for idx, item in enumerate(info): change = changes[item['rev']] branch_filter = Transformer('//table/tbody/tr[%d]/td[@class="summary"]' % (idx+1)) for name, head in change.get_branches(): #if branch not in ('default', 'master'): span = tag.span(name, class_="branch" + (" head" if head else ''), title="Branch head" if head else 'Branch') filters.append(branch_filter.append(span)) for tagname in change.get_tag_contains(): span = tag.span(tagname, class_="tag", title="Tag") filters.append(branch_filter.append(span)) return filters
def filter_stream(self, req, method, filename, stream, data): """ Filter the ticket template and add the Cc Me! button next to the Cc list. """ if filename == 'ticket.html': ticket = data.get('ticket') if ticket and ticket.exists and \ 'TICKET_APPEND' in req.perm(ticket.resource): transformer = Transformer('//th[@id="h_cc"]') stream |= transformer.append(self._ccme_form( req, ticket, data)) add_stylesheet(req, 'ccme/css/ccme.css') return stream
def _customize_View(self, stream): filter = Transformer('.//div [@id="banner"]') stream = stream | filter.wrap(self.css_banner_top2) buffer = StreamBuffer() stream = stream | Transformer('.//div [@id="banner"]').copy(buffer) \ .end().select('.//div [@id="top2"]').after(tag.div(id_='top1')(buffer)) filter = Transformer('.//div [@id="mainnav"]') stream = stream | filter.wrap(self.css_banner_top4) buffer = StreamBuffer() stream = stream | Transformer('.//div [@id="mainnav"]').copy(buffer) \ .end().select('.//div [@id="top4"]').after(tag.div(id_='top3')(buffer)) filter = Transformer('.//div [@id="top3"]') stream = stream | filter.after(tag.div(id_='right')(tag.p())) filter = Transformer('.//div [@id="right"]') stream = stream | filter.append( tag.div(class_='wiki-toc')(tag.h4(_('Table of Contents')))) # just for the menu / TOC filter = Transformer('.//div [@class="wiki-toc"]') if self.anchors and self.keylist: for key in self.keylist: stream = stream | filter.append( tag.a(key, href='#' + self.anchors.get(key), onclick="scrollup();") + tag.br()) filter = Transformer('.//div [@id="main"]') stream = stream | filter.wrap(self.css_left) return stream
def _customize_View(self, stream): filter = Transformer('.//div [@id="banner"]') stream = stream | filter.wrap(self.css_banner_top2) buffer = StreamBuffer() stream = stream | Transformer('.//div [@id="banner"]').copy(buffer).end().select('.//div [@id="top2"]').after( tag.div(id_="top1")(buffer) ) filter = Transformer('.//div [@id="mainnav"]') stream = stream | filter.wrap(self.css_banner_top4) buffer = StreamBuffer() stream = stream | Transformer('.//div [@id="mainnav"]').copy(buffer).end().select('.//div [@id="top4"]').after( tag.div(id_="top3")(buffer) ) filter = Transformer('.//div [@id="top3"]') stream = stream | filter.after(tag.div(id_="right")(tag.p())) filter = Transformer('.//div [@id="right"]') stream = stream | filter.append(tag.div(class_="wiki-toc")(tag.h4(_("Table of Contents")))) # just for the menu / TOC filter = Transformer('.//div [@class="wiki-toc"]') if self.anchors and self.keylist: for key in self.keylist: stream = stream | filter.append( tag.a(key, href="#" + self.anchors.get(key), onclick="scrollup();") + tag.br() ) filter = Transformer('.//div [@id="main"]') stream = stream | filter.wrap(self.css_left) return stream
def filter_stream(self, req, method, filename, stream, data): if 'TICKET_ADMIN' in req.perm and req.path_info.startswith('/admin/ticket/components'): if data.get('components'): filter = Transformer('//form[@id="addcomponent"]/fieldset/div[@class="buttons"]') stream = stream | filter.before(tag.div("Default CC:", tag.br(), tag.input(type='text', name='defaultcc'), class_='field')) default_ccs = DefaultCC.select(self.env) stream = stream | Transformer('//table[@id="complist"]/thead/tr') \ .append(tag.th('Default CC')) filter = Transformer('//table[@id="complist"]/tbody') default_comp = self.config.get('ticket', 'default_component') for comp in data.get('components'): if comp.name == default_comp: default_tag = tag.input(type='radio', name='default', value=comp.name, checked='checked') else: default_tag = tag.input(type='radio', name='default', value=comp.name) if comp.name in default_ccs: default_cc = default_ccs[comp.name] else: default_cc = '' filter = filter.append(tag.tr(tag.td(tag.input(type='checkbox', name='sel', value=comp.name), class_='sel'), tag.td(tag.a(comp.name, href=req.href.admin('ticket', 'components') + '/' + comp.name), class_='name'), tag.td(comp.owner, class_='owner'), tag.td(default_tag, class_='default'), tag.td(default_cc, class_='defaultcc'))) return stream | filter elif data.get('component'): cc = DefaultCC(self.env, data.get('component').name) filter = Transformer('//form[@id="modcomp"]/fieldset/div[@class="buttons"]') filter = filter.before(tag.div("Default CC:", tag.br(), tag.input(type='text', name='defaultcc', value=cc.cc), class_='field')) \ .before(tag.input(type='hidden', name='old_name', value=cc.name)) return stream | filter return stream
def filter_stream(self, req, method, filename, stream, data): if 'TICKET_ADMIN' in req.perm: if req.path_info == '/admin/ticket/components' or req.path_info == '/admin/ticket/components/': components = data.get('components') # 'components' will be None if component with specified name already exists. if not components: return stream default_ccs = DefaultCC.select(self.env) stream = stream | Transformer('//table[@id="complist"]/thead/tr') \ .append(tag.th('Default CC')) filter = Transformer('//table[@id="complist"]/tbody') default_comp = self.config.get('ticket', 'default_component') for comp in components: if default_comp == comp.name: default_tag = tag.input(type='radio', name='default', value=comp.name, checked='checked') else: default_tag = tag.input(type='radio', name='default', value=comp.name) if comp.name in default_ccs: default_cc = default_ccs[comp.name] else: default_cc = '' filter = filter.append(tag.tr(tag.td(tag.input(type='checkbox', name='sel', value=comp.name), class_='sel'), tag.td(tag.a(comp.name, href=req.href.admin('ticket', 'components') + '/' + comp.name), class_='name'), tag.td(comp.owner, class_='owner'), tag.td(default_tag, class_='default'), tag.td(default_cc, class_='defaultcc'))) return stream | filter elif req.path_info.startswith('/admin/ticket/components/') and data.get('component'): cc = DefaultCC(self.env, data.get('component').name) filter = Transformer('//form[@id="modcomp"]/fieldset/div[@class="buttons"]') filter = filter.before(tag.div("Default CC:", tag.br(), tag.input(type="text", name="defaultcc", value=cc.cc), class_="field")) \ .before(tag.input(type='hidden', name='old_name', value=cc.name)) return stream | filter return stream
def filter_stream(self, req, method, filename, stream, data): if 'TICKET_ADMIN' in req.perm and \ req.path_info.startswith('/admin/ticket/components'): if data.get('component'): cc = DefaultCC(self.env, data.get('component').name) filter = Transformer('//form[@id="modcomp"]/fieldset' '/div[@class="field"][2]') filter = filter.after(tag.div("Default CC:", tag.br(), tag.input(type='text', name='defaultcc', value=cc.cc), class_='field')) \ .before(tag.input(type='hidden', name='old_name', value=cc.name)) return stream | filter else: filter = Transformer('//form[@id="addcomponent"]' '/fieldset/div[@class="buttons"]') stream |= filter.before(tag.div("Default CC:", tag.br(), tag.input(type='text', name='defaultcc'), class_='field')) default_ccs = DefaultCC.select(self.env) stream |= Transformer('//table[@id="complist"]/thead/tr') \ .append(tag.th('Default CC')) for i, comp in enumerate(data.get('components')): if comp.name in default_ccs: default_cc = default_ccs[comp.name] else: default_cc = '' filter = Transformer('//table[@id="complist"]' '/tbody/tr[%d]' % (i + 1)) stream |= filter.append(tag.td(default_cc, class_='defaultcc')) return stream return stream
def filter_stream(self, req, method, filename, stream, data): if filename != 'ticket.html': return stream fields = data.get("fields") if not fields: return stream if not data.get('ticket'): return stream readd_fields = [] for field in data['fields']: if field['name'] in \ self.get_ticket_action_fields(req, data['ticket']): if field['name'] in ("reporter", "owner"): # these are hardcoded in trac's ticket_box.html template continue readd_fields.append(field) filter = Transformer('//table[@class="properties"]') trs = [] contents = [] for i, field in enumerate(readd_fields): field = [tag.th('%s:' % field.get("label", field['name']), id='h_%s' % field['name'], class_="missing" if not data['ticket'][field['name']] else ""), tag.td(field['rendered'] \ if 'rendered' in field \ else data['ticket'][field['name']], headers='h_%s' % field['name'], class_='searchable')] contents.append(field) if i % 2 == 1: trs.append(tag.tr(*contents)) contents = [] if len(contents): trs.append(tag.tr(*contents)) stream |= filter.append(tag(*trs)) return stream
def filter_stream(self, req, method, filename, stream, data): """Return a filtered Genshi event stream, or the original unfiltered stream if no match. """ if filename == "ticket.html" and \ ('TICKET_REMINDER_VIEW' in req.perm or 'TICKET_REMINDER_MODIFY' in req.perm or 'TICKET_ADMIN' in req.perm): tags = self._reminder_tags(req, data) if tags: ticket_resource = data['ticket'].resource context = Context.from_request(req, ticket_resource) attachments_data = AttachmentModule(self.env).attachment_data(context) add_stylesheet(req, 'ticketreminder/css/ticketreminder.css') # Will attachments section be displayed? attachments_or_ticket = Transformer('//div[@id="attachments"]') if attachments_data['can_create'] or attachments_data['attachments'] else Transformer('//div[@id="ticket"]') trac_nav = Transformer('//form[@id="propertyform"]/div[@class="trac-nav"]') return stream | attachments_or_ticket.after(tags) | trac_nav.append(self._reminder_trac_nav(req, data)) return stream
def filter_stream(self, req, method, filename, stream, data): # Tickets will be modified to show the child tickets as a list under the 'Description' section. if filename == 'ticket.html': # Get the ticket info. ticket = data.get('ticket') # Modify ticket.html with sub-ticket table, create button, etc... # As follows: # - If ticket has no child tickets and child tickets are NOT allowed then skip. # - If ticket has child tickets and child tickets are NOT allowed (ie. rules changed or ticket type changed after children were assigned), # print list of tickets but do not allow any tickets to be created. # - If child tickets are allowed then print list of child tickets or 'No Child Tickets' if non are currently assigned. # if ticket and ticket.exists: filter = Transformer('//div[@class="description"]') snippet = tag() # Are there any child tickets to display? childtickets = [ Ticket(self.env, n) for n in self.env.childtickets.get(ticket.id, []) ] # (tempish) fix for #8612 : force sorting by ticket id childtickets = sorted(childtickets, key=lambda t: t.id) # trac.ini : Which columns to display in child ticket listing? columns = self.config.getlist('childtickets', 'parent.%s.table_headers' % ticket['type'], default=['summary', 'owner']) # trac.ini : child tickets are allowed. if self.config.getbool( 'childtickets', 'parent.%s.allow_child_tickets' % ticket['type']): # trac.ini : Default 'type' of child tickets? default_child_type = self.config.get( 'childtickets', 'parent.%s.default_child_type' % ticket['type'], default=self.config.get('ticket', 'default_type')) self.env.log.debug( "TracchildticketsModule : default_child_type: %s" % default_child_type) # Can user create a new ticket? If not, just display title (ie. no 'create' button). if 'TICKET_CREATE' in req.perm(ticket.resource): # Always pass these fields default_child_fields = (tag.input(type="hidden", name="parent", value='#' + str(ticket.id)), ) #Pass extra fields defined in inherit parameter of parent inherited_child_fields = [ tag.input(type="hidden", name="%s" % field, value=ticket[field]) for field in self.config.getlist( 'childtickets', 'parent.%s.inherit' % ticket['type']) ] # If child types are restricted then create a set of buttons for the allowed types (This will override 'default_child_type). restrict_child_types = self.config.getlist( 'childtickets', 'parent.%s.restrict_child_type' % ticket['type'], default=[]) if not restrict_child_types: # ... create a default submit button submit_button_fields = ( tag.input(type="submit", name="childticket", value="New Child Ticket", title="Create a child ticket"), tag.input(type="hidden", name="type", value=default_child_type), ) else: submit_button_fields = [ tag.input(type="submit", name="type", value="%s" % ticket_type, title="Create a %s child ticket" % ticket_type) for ticket_type in restrict_child_types ] snippet.append( tag.div( tag.form( tag.div(default_child_fields, inherited_child_fields, submit_button_fields, class_="inlinebuttons"), method="get", action=req.href.newticket(), ), tag.h3("Child Tickets", id="comment:child_tickets"), )) else: snippet.append( tag.div( tag.h3("Child Tickets", id="comment:child_tickets"))) # trac.ini : child tickets are NOT allowed but (somehow?!) this parent ticket has children assigned. elif childtickets: snippet.append( tag.div( tag.h3("Child Tickets", id="comment:child_tickets"))) # Test if the ticket has children: If so, then list in pretty table. if childtickets: snippet.append( tag.div( tag.table( tag.thead( tag.tr(tag.th("Ticket", class_="id"), [ tag.th(s.title(), class_=s) for s in columns ])), tag.tbody([ self._table_row(req, tkt, columns) for tkt in childtickets ]), class_="listing tickets", ), )) elif self.config.getbool( 'childtickets', 'parent.%s.allow_child_tickets' % ticket['type']): snippet.append(tag.div(tag.p("NO SUB-TICKETS."))) return stream | filter.append(snippet) return stream
def filter_stream(self, req, method, filename, stream, data): """ Quick and dirty solution - modify page on the fly to inject special field. It would be nicer if we can do it by creating custom field as this depends on page structure. """ #embed(header='Ticket Stream Filter') if filename == 'ticket.html': # Disable any direct bounty input filter = Transformer('.//input[@id="field-bounty"]') stream |= filter.attr("disabled", "disabled") ticket = data.get('ticket') if ticket and ticket.exists: identifier = ticket.id user = req.authname if req.authname != 'anonymous' else None request = self.call_api('GET', '/issue/%s' % identifier) fragment = tag() sponsorships = {} status = self.convert_status(ticket.values['status']) owner = ticket.values['owner'] tooltip = None if request != None and (request.status_code == 200 or request.status_code == 404): sponsorships = self.get_sponsorships(identifier) pledged_amount = sum_amounts(sponsorships.values()) user_sponsorship = sponsorships.get(user, Sponsorship()) # Bounty tooltip = u"Pledged: %d\u20ac" % pledged_amount if status == 'STARTED' or status == 'COMPLETED': confirmed_amount = sum_amounts( sponsorships.values(), ('CONFIRMED', 'VALIDATED', 'REJECTED', 'TRANSFERRED', 'REFUNDED')) tooltip += u" \nConfirmed: %d\u20ac" % confirmed_amount if status == 'COMPLETED': validated_amount = sum_amounts(sponsorships.values(), 'VALIDATED') tooltip += u" \nValidated: %d\u20ac" % validated_amount # Action action = None if (((status == 'STARTED' or status == 'COMPLETED') and user_sponsorship.status == 'PLEDGED') or (status == 'STARTED' and user != None and user != owner and user_sponsorship.status == None)): response = self.call_api('GET', '/config/payment_gateways') gateways = response.json().get('gateways') gateway_tags = [] if 'DUMMY' in gateways: gateway_tags.append( tag.input(type="submit", value="Payment Card", name='DUMMY')) if 'PAYPAL_STANDARD' in gateways: gateway_tags.append( tag.input(type="submit", value="PayPal", name='PAYPAL_STANDARD')) if 'PAYPAL_ADAPTIVE' in gateways: gateway_tags.append( tag.input(type="submit", value="PayPal", name='PAYPAL_ADAPTIVE')) if user_sponsorship.status == 'PLEDGED': action = tag.form( tag.input(type="button", name="confirm", value=u"Confirm %d\u20ac" % user_sponsorship.amount, id="confirm-button"), tag.span(gateway_tags, id="confirm-options"), tag.input(type="submit", name="delete", value="Delete"), method="post", action=req.href.ticket(identifier, "confirm")) else: #TODO: should be separate action action = tag.form( tag.input(name="amount", type="text", size="3", value="0", pattern="[0-9]*", title="money amount"), tag.input(type="button", value="Pledge & Confirm", id="confirm-button"), tag.span(gateway_tags, id="confirm-options"), method="post", action=req.href.ticket(identifier, "confirm")) elif status == 'COMPLETED' and user_sponsorship.status in ( 'CONFIRMED', 'REJECTED', 'VALIDATED'): action = tag.form(method="post", action=req.href.ticket( identifier, "validate")) if user_sponsorship.status == 'CONFIRMED' or user_sponsorship.status == 'REJECTED': action.append( tag.input(type="submit", name='validate', value=u"Validate %d\u20ac" % user_sponsorship.amount)) if user_sponsorship.status == 'CONFIRMED' or user_sponsorship.status == 'VALIDATED': action.append( tag.input(type="submit", name='reject', value="Reject")) elif (status == 'READY' and user != None): if user_sponsorship.status == None: action = tag.form( tag.input(name="amount", type="text", size="3", value=user_sponsorship.amount, pattern="[0-9]*", title="money amount"), tag.input(type="submit", value="Pledge"), method="post", action=req.href.ticket(identifier, "sponsor")) elif user_sponsorship.status == 'PLEDGED': action = tag.form( tag.input(name="amount", type="text", size=3, value=user_sponsorship.amount, pattern="[0-9]*", title="money amount"), tag.input(type="submit", name="update", value="Update"), tag.input(type="submit", name="delete", value="Delete"), method="post", action=req.href.ticket(identifier, "update_sponsorship")) elif (user == None): action = tag.span( u"\u00A0", tag.a("Login", href=req.href.login()), " or ", tag.a("Register", href=req.href.register()), " to sponsor") if action != None: fragment.append(" ") fragment.append(action) else: error = "Connection error" if request: error = request.json().get("error", "Unknown error") fragment.append( tag.span("[BountyFunding Error]", title=error)) #chrome = Chrome(self.env) #chrome.add_jquery_ui(req) add_stylesheet(req, 'htdocs/styles/bountyfunding.css') add_script(req, 'htdocs/scripts/bountyfunding.js') if tooltip != None: filter = Transformer('.//td[@headers="h_bounty"]/text()') stream |= filter.wrap(tag.span(title=tooltip)) filter = Transformer('.//td[@headers="h_bounty"]') stream |= filter.attr("class", "bountyfunding") stream |= filter.append(fragment) return stream
def filter_stream(self, req, method, filename, stream, data): # Tickets will be modified to show the child tickets as a list under the 'Description' section. if filename == 'ticket.html': # Get the ticket info. ticket = data.get('ticket') # Modify ticket.html with sub-ticket table, create button, etc... # As follows: # - If ticket has no child tickets and child tickets are NOT allowed then skip. # - If ticket has child tickets and child tickets are NOT allowed (ie. rules changed or ticket type changed after children were assigned), # print list of tickets but do not allow any tickets to be created. # - If child tickets are allowed then print list of child tickets or 'No Child Tickets' if non are currently assigned. # if ticket and ticket.exists: filter = Transformer('//div[@class="description"]') snippet = tag() # Are there any child tickets to display? childtickets = [ Ticket(self.env, n) for n in self.env.childtickets.get(ticket.id, []) ] # trac.ini : Which columns to display in child ticket listing? columns = self.config.getlist('childtickets', 'parent.%s.table_headers' % ticket['type'], default = ['summary', 'owner']) # Forcing default setting to inherit from the parent ticket default_child_milestone = ticket['milestone'] default_child_type = ticket['type'] # Test if the ticket has children: If so, then list in pretty table. if childtickets: snippet.append( tag.div(tag.h3("Child Tickets:", id = "comment:child_tickets"), tag.table( tag.thead( tag.tr( tag.th("Ticket", class_ = "id"), [ tag.th(s.title(), class_ = s) for s in columns ]) ), tag.tbody([ self._table_row(req, tkt, columns) for tkt in childtickets ]), class_ = "listing", ), ) ) else: snippet.append(tag.div(tag.h3("Child Tickets:", id = "comment:child_tickets"), tag.p("NO SUB-TICKETS."))) # Can user create a new ticket? If not, just display title (ie. no 'create' button). if 'TICKET_CREATE' in req.perm(ticket.resource): snippet.append( tag.div( tag.form( tag.div( tag.span( tag.input(type = "hidden", name = "parent", value = '#' + str(ticket.id)), tag.input(type = "hidden", name = "milestone", value = default_child_milestone), tag.input(type = "hidden", name = "type", value = default_child_type), tag.input(type = "submit", name = "childticket", value = "Create", title = "Create a child ticket"), class_ = "primaryButton"), class_ = "buttons"), method = "get", action = req.href.newticket() ) ) ) return stream | filter.append(snippet) return stream
def filter_stream(self, req, method, filename, stream, data): field_name = self._get_field_name(req.args) if 'TICKET_ADMIN' in req.perm and field_name and \ req.path_info.startswith('/admin/ticket'): if field_name in self._non_abstract_enums: field_objects = data.get(field_name + 's') else: field_objects = data.get('enums') default_ccs = DefaultCC.select(self.env, field_name) if field_objects: # list of field objects stream = stream | Transformer( '//table[@class="listing"]/thead/tr').append( tag.th('CC')) if field_name == 'component': transformer = Transformer('//table[@id="complist"]/tbody') default_comp = self.config.get( 'ticket', 'default_component') for idx, field_object in enumerate(field_objects): # Milestone object can be a tuple :/ try: field_object_name = field_object.name except AttributeError: field_object_name = field_object[0].name if field_object_name in default_ccs: default_cc = default_ccs[field_object_name] else: default_cc = '' # Annoyingly, we can't just append to the row if the # collection is components, it appears to blat it for # rendering later so you end up with no rows # This may be due to the collection being a generator, # but then again, who knows? if field_name == 'component': if default_comp == field_object_name: default_tag = tag.input( type='radio', name='default', value=field_object_name, checked='checked') else: default_tag = tag.input( type='radio', name='default', value=field_object_name) transformer = transformer.append( tag.tr( tag.td( tag.input(type='checkbox', name='sel', value=field_object_name), class_='sel'), tag.td( tag.a(field_object_name, href=req.href.admin( 'ticket', 'components') + '/' + \ field_object_name), class_='name'), tag.td(field_object.owner, class_='owner'), tag.td(default_tag, class_='default'), tag.td(default_cc, class_='defaultcc') ) ) else: stream = stream | Transformer( '//table[@class="listing"]/tbody/tr[%s]' % (idx+1,) ).append(tag.td(default_cc, class_='defaultcc')) if field_name == 'component': return stream | transformer else: # edit field object if field_name in self._non_abstract_enums: field_object = data.get(field_name) else: field_object = data.get('enum') if field_object: # Milestone object can be a tuple :/ try: field_object_name = field_object.name except AttributeError: field_object_name = field_object[0] if field_object_name in default_ccs: default_cc = default_ccs[field_object_name] else: default_cc = '' transformer = Transformer( '//form[@class="mod"]/fieldset/div[@class="buttons"]') transformer = transformer.before( tag.div(tag.label("Default CC:"), tag.br(), tag.input(type="text", name="defaultcc", value=default_cc), class_="field") ).before(tag.input(type='hidden', name='old_name', value=field_object_name)) return stream | transformer return stream
def filter_stream(self, req, method, filename, stream, data): """ Quick and dirty solution - modify page on the fly to inject special field. It would be nicer if we can do it by creating custom field as this depends on page structure. """ #embed(header='Ticket Stream Filter') if filename == 'ticket.html': # Disable any direct bounty input filter = Transformer('.//input[@id="field-bounty"]') stream |= filter.attr("disabled", "disabled") ticket = data.get('ticket') if ticket and ticket.exists: identifier = ticket.id user = req.authname if req.authname != 'anonymous' else None request = self.call_api('GET', '/issue/%s' % identifier) fragment = tag() sponsorships = {} status = self.convert_status(ticket.values['status']) owner = ticket.values['owner'] tooltip = None if request != None and (request.status_code == 200 or request.status_code == 404): sponsorships = self.get_sponsorships(identifier) pledged_amount = sum_amounts(sponsorships.values()) user_sponsorship = sponsorships.get(user, Sponsorship()) # Bounty tooltip = u"Pledged: %d\u20ac" % pledged_amount if status == 'STARTED' or status == 'COMPLETED': confirmed_amount = sum_amounts(sponsorships.values(), ('CONFIRMED', 'VALIDATED', 'REJECTED', 'TRANSFERRED', 'REFUNDED')) tooltip += u" \nConfirmed: %d\u20ac" % confirmed_amount if status == 'COMPLETED': validated_amount = sum_amounts(sponsorships.values(), 'VALIDATED') tooltip += u" \nValidated: %d\u20ac" % validated_amount # Action action = None if (((status == 'STARTED' or status == 'COMPLETED') and user_sponsorship.status == 'PLEDGED') or (status == 'STARTED' and user != None and user != owner and user_sponsorship.status == None)): response = self.call_api('GET', '/config/payment_gateways') gateways = response.json().get('gateways') gateway_tags = [] if 'DUMMY' in gateways: gateway_tags.append(tag.input(type="submit", value="Payment Card", name='DUMMY')) if 'PAYPAL_STANDARD' in gateways: gateway_tags.append(tag.input(type="submit", value="PayPal", name='PAYPAL_STANDARD')) if 'PAYPAL_ADAPTIVE' in gateways: gateway_tags.append(tag.input(type="submit", value="PayPal", name='PAYPAL_ADAPTIVE')) if user_sponsorship.status == 'PLEDGED': action = tag.form( tag.input(type="button", name="confirm", value=u"Confirm %d\u20ac" % user_sponsorship.amount, id="confirm-button"), tag.span(gateway_tags, id="confirm-options"), tag.input(type="submit", name="delete", value="Delete"), method="post", action=req.href.ticket(identifier, "confirm")) else: #TODO: should be separate action action = tag.form( tag.input(name="amount", type="text", size="3", value="0", pattern="[0-9]*", title="money amount"), tag.input(type="button", value="Pledge & Confirm", id="confirm-button"), tag.span(gateway_tags, id="confirm-options"), method="post", action=req.href.ticket(identifier, "confirm")) elif status == 'COMPLETED' and user_sponsorship.status in ('CONFIRMED', 'REJECTED', 'VALIDATED'): action = tag.form(method="post", action=req.href.ticket(identifier, "validate")) if user_sponsorship.status == 'CONFIRMED' or user_sponsorship.status == 'REJECTED': action.append(tag.input(type="submit", name='validate', value=u"Validate %d\u20ac" % user_sponsorship.amount)) if user_sponsorship.status == 'CONFIRMED' or user_sponsorship.status == 'VALIDATED': action.append(tag.input(type="submit", name='reject', value="Reject")) elif (status == 'READY' and user != None): if user_sponsorship.status == None: action = tag.form(tag.input(name="amount", type="text", size="3", value=user_sponsorship.amount, pattern="[0-9]*", title="money amount"), tag.input(type="submit", value="Pledge"), method="post", action=req.href.ticket(identifier, "sponsor")) elif user_sponsorship.status == 'PLEDGED': action = tag.form(tag.input(name="amount", type="text", size=3, value=user_sponsorship.amount, pattern="[0-9]*", title="money amount"), tag.input(type="submit", name="update", value="Update"), tag.input(type="submit", name="delete", value="Delete"), method="post", action=req.href.ticket(identifier, "update_sponsorship")) elif (user == None): action = tag.span(u"\u00A0", tag.a("Login", href=req.href.login()), " or ", tag.a("Register", href=req.href.register()), " to sponsor") if action != None: fragment.append(" ") fragment.append(action) else: error = "Connection error" if request: error = request.json().get("error", "Unknown error") fragment.append(tag.span("[BountyFunding Error]", title=error)) #chrome = Chrome(self.env) #chrome.add_jquery_ui(req) add_stylesheet(req, 'htdocs/styles/bountyfunding.css') add_script(req, 'htdocs/scripts/bountyfunding.js') if tooltip != None: filter = Transformer('.//td[@headers="h_bounty"]/text()') stream |= filter.wrap(tag.span(title=tooltip)) filter = Transformer('.//td[@headers="h_bounty"]') stream |= filter.attr("class", "bountyfunding") stream |= filter.append(fragment) return stream
def filter_stream(self, req, method, filename, stream, data): # Tickets will be modified to show the child tickets as a list under the 'Description' section. if filename == 'ticket.html': # Get the ticket info. ticket = data.get('ticket') # Modify ticket.html with sub-ticket table, create button, etc... # As follows: # - If ticket has no child tickets and child tickets are NOT allowed then skip. # - If ticket has child tickets and child tickets are NOT allowed (ie. rules changed or ticket type changed after children were assigned), # print list of tickets but do not allow any tickets to be created. # - If child tickets are allowed then print list of child tickets or 'No Child Tickets' if non are currently assigned. # if ticket and ticket.exists: filter = Transformer('//div[@class="description"]') snippet = tag() # Are there any child tickets to display? childtickets = [ Ticket(self.env,n) for n in self.env.childtickets.get(ticket.id,[]) ] # (tempish) fix for #8612 : force sorting by ticket id childtickets = sorted(childtickets, key=lambda t: t.id) # trac.ini : Which columns to display in child ticket listing? columns = self.config.getlist('childtickets', 'parent.%s.table_headers' % ticket['type'], default=['summary','owner']) # trac.ini : child tickets are allowed. if self.config.getbool('childtickets', 'parent.%s.allow_child_tickets' % ticket['type']): # trac.ini : Default 'type' of child tickets? default_child_type = self.config.get('childtickets', 'parent.%s.default_child_type' % ticket['type'], default=self.config.get('ticket','default_type')) self.env.log.debug("TracchildticketsModule : default_child_type: %s" % default_child_type) # Can user create a new ticket? If not, just display title (ie. no 'create' button). if 'TICKET_CREATE' in req.perm(ticket.resource): # Always pass these fields default_child_fields = ( tag.input(type="hidden", name="parent", value='#'+str(ticket.id)), ) #Pass extra fields defined in inherit parameter of parent inherited_child_fields = [ tag.input(type="hidden",name="%s"%field,value=ticket[field]) for field in self.config.getlist('childtickets','parent.%s.inherit' % ticket['type']) ] # If child types are restricted then create a set of buttons for the allowed types (This will override 'default_child_type). restrict_child_types = self.config.getlist('childtickets','parent.%s.restrict_child_type' % ticket['type'],default=[]) if not restrict_child_types: # ... create a default submit button submit_button_fields = ( tag.input(type="submit",name="childticket",value="New Child Ticket",title="Create a child ticket"), tag.input(type="hidden", name="type", value=default_child_type), ) else: submit_button_fields = [ tag.input(type="submit",name="type",value="%s" % ticket_type,title="Create a %s child ticket" % ticket_type) for ticket_type in restrict_child_types ] snippet.append(tag.div( tag.form( tag.div( default_child_fields, inherited_child_fields, submit_button_fields, class_="inlinebuttons"), method="get", action=req.href.newticket(), ), tag.h3("Child Tickets",id="comment:child_tickets"), )) else: snippet.append(tag.div(tag.h3("Child Tickets",id="comment:child_tickets"))) # trac.ini : child tickets are NOT allowed but (somehow?!) this parent ticket has children assigned. elif childtickets: snippet.append(tag.div(tag.h3("Child Tickets",id="comment:child_tickets"))) # Test if the ticket has children: If so, then list in pretty table. if childtickets: snippet.append( tag.div( tag.table( tag.thead( tag.tr( tag.th("Ticket",class_="id"), [ tag.th(s.title(),class_=s) for s in columns ]) ), tag.tbody([ self._table_row(req,tkt,columns) for tkt in childtickets ]), class_="listing tickets", ), ) ) elif self.config.getbool('childtickets', 'parent.%s.allow_child_tickets' % ticket['type']): snippet.append(tag.div(tag.p("NO SUB-TICKETS."))) return stream | filter.append(snippet) return stream