def test_invalid_ticket_id(self): self.assertEqual(Ticket.id_is_valid(-1), False) self.assertEqual(Ticket.id_is_valid(0), False) self.assertEqual(Ticket.id_is_valid(1), True) self.assertEqual(Ticket.id_is_valid(1L << 31), True) self.assertEqual(Ticket.id_is_valid(1L << 32), False) self.assertRaises(ResourceNotFound, Ticket, self.env, -1) self.assertRaises(ResourceNotFound, Ticket, self.env, 1L << 32)
def update_connections(self): ''' Rewrite Ticket Dependencies ''' # search choosen connection of tickets dep_from = self.get_args('ppdep_from') dep_to = self.get_args('ppdep_to') # 1. check for numbers if dep_from == None or dep_to == None or ( not dep_from.strip().isdigit() ) or ( not dep_to.strip().isdigit() ): return False dep_from = dep_from.strip() dep_to = dep_to.strip() # 2. check for valid tkid if ( not Ticket.id_is_valid( dep_from ) ) or ( not Ticket.id_is_valid( dep_to ) ): return False toticket = Ticket( self.env, int(dep_to) ) # 3. check valid ticket from database if toticket.id == None: return False # get dependencies depstring = toticket.get_value_or_default( self.conf.get( 'custom_dependency_field' ) ) if depstring != None: deps = pputil.ticketIDsFromString( depstring ) else: deps = set() # modify dependencies if int(dep_from) in deps: comstring = "removed dependency #%s" % str(dep_from) deps.remove( int(dep_from) ) else: comstring = "added dependency #%s" % str(dep_from) deps.add( int(dep_from) ) # build new depstring depstring = ",".join( [ str(d) for d in deps ] ) toticket[ self.conf.get( 'custom_dependency_field' ) ] = depstring # commit try: if not toticket.save_changes( self.req.authname, comstring ): raise TracError( "Could not update Ticket #%s " % str(dep_to) ) except: return False return True
def update_connections(self): ''' Rewrite Ticket Dependencies ''' # search choosen connection of tickets dep_from = self.get_args('ppdep_from') dep_to = self.get_args('ppdep_to') # 1. check for numbers if dep_from == None or dep_to == None or ( not dep_from.strip().isdigit()) or ( not dep_to.strip().isdigit()): return False dep_from = dep_from.strip() dep_to = dep_to.strip() # 2. check for valid tkid if (not Ticket.id_is_valid(dep_from)) or ( not Ticket.id_is_valid(dep_to)): return False toticket = Ticket(self.env, int(dep_to)) # 3. check valid ticket from database if toticket.id == None: return False # get dependencies depstring = toticket.get_value_or_default( self.conf.get('custom_dependency_field')) if depstring != None: deps = pputil.ticketIDsFromString(depstring) else: deps = set() # modify dependencies if int(dep_from) in deps: comstring = "removed dependency #%s" % str(dep_from) deps.remove(int(dep_from)) else: comstring = "added dependency #%s" % str(dep_from) deps.add(int(dep_from)) # build new depstring depstring = ",".join([str(d) for d in deps]) toticket[self.conf.get('custom_dependency_field')] = depstring # commit try: if not toticket.save_changes(self.req.authname, comstring): raise TracError("Could not update Ticket #%s " % str(dep_to)) except: return False return True
def _format_link(self, formatter, ns, target, label, fullmatch=None): intertrac = formatter.shorthand_intertrac_helper(ns, target, label, fullmatch) if intertrac: return intertrac try: link, params, fragment = formatter.split_link(target) r = Ranges(link) if len(r) == 1: num = r.a ticket = formatter.resource('ticket', num) from trac.ticket.model import Ticket if Ticket.id_is_valid(num) and \ 'TICKET_VIEW' in formatter.perm(ticket): # TODO: watch #6436 and when done, attempt to retrieve # ticket directly (try: Ticket(self.env, num) ...) cursor = formatter.db.cursor() cursor.execute("SELECT type,summary,status,resolution " "FROM ticket WHERE id=%s", (str(num),)) for type, summary, status, resolution in cursor: title = self.format_summary(summary, status, resolution, type) href = formatter.href.ticket(num) + params + fragment return tag.a(label, class_='%s ticket' % status, title=title, href=href) else: ranges = str(r) if params: params = '&' + params[1:] return tag.a(label, title='Tickets '+ranges, href=formatter.href.query(id=ranges) + params) except ValueError: pass return tag.a(label, class_='missing ticket')
def get_deco(self, formatter, ns, target, label, fullmatch=None): link, params, fragment = formatter.split_link(target) # @UnusedVariable r = Ranges(link) if len(r) == 1: num = r.a ticket = formatter.resource('ticket', num) from trac.ticket.model import Ticket if Ticket.id_is_valid(num) and \ 'TICKET_VIEW' in formatter.perm(ticket): ticket = Ticket(self.env, num) fields = self.config.getlist('ticket', 'decorate_fields') return ['%s_is_%s' % (field, ticket.values[field]) for field in fields if field in ticket.values]
def get_tag(ticketId, commentId): from trac.ticket.model import Ticket if Ticket.id_is_valid(ticketId) and Ticket.commentid_is_valid(commentId): href = "%s#comment:%s" % (formatter.href.ticket(ticketId), commentId) title = _("Comment %(cnum)s for Ticket #%(id)s", cnum=commentId, id=ticketId) ticket = formatter.resource("ticket", ticketId) if "TICKET_VIEW" in formatter.perm(ticket): for (status,) in self.env.db_query("SELECT status FROM ticket WHERE id=%s", (ticketId,)): return tag.a(label, href=href, title=title, class_=status) return tag.a(label, href=href, title=title) return tag.a(label, class_="missing ticket")
def post_process_request(self, req, template, data, content_type): """ overridden from IRequestFilter""" if req.path_info.startswith('/newticket') or \ req.path_info.startswith('/ticket'): add_script(req, 'hw/js/budgeting.js') if not data: return template, data, content_type tkt = data['ticket'] if tkt and tkt.id and Ticket.id_is_valid(tkt.id): # ticket is ready for saving if self._changed_by_author: self._save_budget(tkt) self._budgets = None return template, data, content_type
def post_process_request(self, req, template, data, content_type): """ overridden from IRequestFilter""" if req.path_info.startswith('/newticket') or \ req.path_info.startswith('/ticket'): add_script(req, 'hw/js/budgeting.js') if not data: return template, data, content_type tkt = data['ticket'] if tkt and tkt.id and Ticket.id_is_valid( tkt.id): # ticket is ready for saving if self._changed_by_author: self._save_budget(tkt) self._budgets = None return template, data, content_type
def _format_link(self, formatter, ns, target, label, fullmatch=None): intertrac = formatter.shorthand_intertrac_helper( ns, target, label, fullmatch) if intertrac: return intertrac try: link, params, fragment = formatter.split_link(target) r = Ranges(link) if len(r) == 1: num = r.a ticket = formatter.resource('ticket', num) from trac.ticket.model import Ticket if Ticket.id_is_valid(num) and \ 'TICKET_VIEW' in formatter.perm(ticket): # TODO: attempt to retrieve ticket view directly, # something like: t = Ticket.view(num) for type, summary, status, resolution in \ self.env.db_query(""" SELECT type, summary, status, resolution FROM ticket WHERE id=%s """, (str(num),)): title = self.format_summary(summary, status, resolution, type) href = formatter.href.ticket(num) + params + fragment return tag.a(label, title=title, href=href, class_='%s ticket' % status) else: ranges = str(r) if params: params = '&' + params[1:] if isinstance(label, Markup): _label = unescape(label) else: _label = label label_wrap = _label.replace(',', u',\u200b') ranges_wrap = ranges.replace(',', u', ') return tag.a(label_wrap, title=_("Tickets %(ranges)s", ranges=ranges_wrap), href=formatter.href.query(id=ranges) + params) except ValueError: pass return tag.a(label, class_='missing ticket')
def _format_link(self, formatter, ns, target, label, fullmatch=None): intertrac = formatter.shorthand_intertrac_helper(ns, target, label, fullmatch) if intertrac: return intertrac try: link, params, fragment = formatter.split_link(target) r = Ranges(link) if len(r) == 1: num = r.a ticket = formatter.resource('ticket', num) from trac.ticket.model import Ticket if Ticket.id_is_valid(num) and \ 'TICKET_VIEW' in formatter.perm(ticket): # TODO: attempt to retrieve ticket view directly, # something like: t = Ticket.view(num) for type, summary, status, resolution in \ self.env.db_query(""" SELECT type, summary, status, resolution FROM ticket WHERE id=%s """, (str(num),)): title = self.format_summary(summary, status, resolution, type) href = formatter.href.ticket(num) + params + fragment return tag.a(label, title=title, href=href, class_='%s ticket' % status) else: ranges = str(r) if params: params = '&' + params[1:] if isinstance(label, Markup): _label = unescape(label) else: _label = label label_wrap = _label.replace(',', u',\u200b') ranges_wrap = ranges.replace(',', u', ') return tag.a(label_wrap, title=_("Tickets %(ranges)s", ranges=ranges_wrap), href=formatter.href.query(id=ranges) + params) except ValueError: pass return tag.a(label, class_='missing ticket')
def _format_link(self, formatter, ns, target, label, fullmatch=None): intertrac = formatter.shorthand_intertrac_helper( ns, target, label, fullmatch) if intertrac: return intertrac try: link, params, fragment = formatter.split_link(target) r = Ranges(link) if len(r) == 1: num = r.a ticket = formatter.resource('ticket', num) from trac.ticket.model import Ticket if Ticket.id_is_valid(num) and \ 'TICKET_VIEW' in formatter.perm(ticket): # TODO: watch #6436 and when done, attempt to retrieve # ticket directly (try: Ticket(self.env, num) ...) cursor = formatter.db.cursor() cursor.execute( "SELECT type,summary,status,resolution " "FROM ticket WHERE id=%s", (str(num), )) for type, summary, status, resolution in cursor: title = self.format_summary(summary, status, resolution, type) href = formatter.href.ticket(num) + params + fragment return tag.a(label, class_='%s ticket' % status, title=title, href=href) else: ranges = str(r) if params: params = '&' + params[1:] return tag.a(label, title='Tickets ' + ranges, href=formatter.href.query(id=ranges) + params) except ValueError: pass return tag.a(label, class_='missing ticket')
def resource_exists(self, resource): """ >>> from trac.test import EnvironmentStub >>> from trac.resource import Resource, resource_exists >>> env = EnvironmentStub() >>> resource_exists(env, Resource('ticket', 123456)) False >>> from trac.ticket.model import Ticket >>> t = Ticket(env) >>> int(t.insert()) 1 >>> resource_exists(env, t.resource) True """ try: id_ = int(resource.id) except (TypeError, ValueError): return False from trac.ticket.model import Ticket if not Ticket.id_is_valid(id_): return False if self.env.db_query("SELECT id FROM ticket WHERE id=%s", (id_,)): if resource.version is None: return True revcount = self.env.db_query( """ SELECT count(DISTINCT time) FROM ticket_change WHERE ticket=%s """, (id_,), ) return revcount[0][0] >= resource.version else: return False
return "" if not page.exists: if page_version: return system_message('No version "%s" for wiki page "%s"' % (page_version, page_name)) else: return system_message('Wiki page "%s" does not exist' % page_name) out = page.text ctxt = Context.from_request(formatter.req, "wiki", source_obj) elif source_format == "source": if not formatter.perm.has_permission("FILE_VIEW"): return "" out, ctxt, dest_format = self._get_source(formatter, source_obj, dest_format) elif source_format == "ticket": if ":" in source_obj: ticket_num, source_obj = source_obj.split(":", 1) if not Ticket.id_is_valid(ticket_num): return system_message("%s is not a valid ticket id" % ticket_num) try: ticket = Ticket(self.env, ticket_num) if not "TICKET_VIEW" in formatter.perm(ticket.resource): return "" except ResourceNotFound, e: return system_message("Ticket %s does not exist" % ticket_num) if ":" in source_obj: source_format, comment_num = source_obj.split(":", 1) if source_format == "comment": changelog = ticket.get_changelog() out = [] if changelog: for (ts, author, field, oldval, newval, permanent) in changelog: if field == "comment" and oldval == comment_num:
if source_section: out = self._extract_section(out, source_section) if out is None: return system_message( 'Section "%s" not found in wiki page "%s"' % (source_section, page_name)) ctxt = Context.from_request(formatter.req, 'wiki', source_obj) elif source_format in ('source', 'browser', 'repos'): if 'FILE_VIEW' not in formatter.perm: return '' out, ctxt, dest_format = self._get_source(formatter, source_obj, dest_format) elif source_format == 'ticket': if ':' in source_obj: ticket_num, source_obj = source_obj.split(':', 1) if not Ticket.id_is_valid(ticket_num): return system_message("%s is not a valid ticket id" % ticket_num) try: ticket = Ticket(self.env, ticket_num) if 'TICKET_VIEW' not in formatter.perm(ticket.resource): return '' except ResourceNotFound: return system_message("Ticket %s does not exist" % ticket_num) if ':' in source_obj: source_format, comment_num = source_obj.split(':', 1) if source_format == 'comment': changelog = ticket.get_changelog() out = [] if changelog:
def _format_link(self, formatter, ns, target, label, fullmatch=None): intertrac = formatter.shorthand_intertrac_helper(ns, target, label, fullmatch) if intertrac: return intertrac try: link, params, fragment = formatter.split_link(target) # NEW vvvvv # Short "#<ticketId>:<commentId>" # or "#<ticketId>#comment:<commentId>" (last part of trac url) if ":" in link: def get_tag(ticketId, commentId): from trac.ticket.model import Ticket if Ticket.id_is_valid(ticketId) and Ticket.commentid_is_valid(commentId): href = "%s#comment:%s" % (formatter.href.ticket(ticketId), commentId) title = _("Comment %(cnum)s for Ticket #%(id)s", cnum=commentId, id=ticketId) ticket = formatter.resource("ticket", ticketId) if "TICKET_VIEW" in formatter.perm(ticket): for (status,) in self.env.db_query("SELECT status FROM ticket WHERE id=%s", (ticketId,)): return tag.a(label, href=href, title=title, class_=status) return tag.a(label, href=href, title=title) return tag.a(label, class_="missing ticket") if "#" in link: arr = link.split("#") if len(arr) == 2: tnum, cnum = arr if cnum.startswith("comment:"): return get_tag(tnum, cnum[8:]) arr = link.split(":") if len(arr) == 2: tnum, cnum = arr return get_tag(tnum, cnum) # NEW ^^^^^ r = Ranges(link) if len(r) == 1: num = r.a ticket = formatter.resource("ticket", num) from trac.ticket.model import Ticket if Ticket.id_is_valid(num) and "TICKET_VIEW" in formatter.perm(ticket): # TODO: attempt to retrieve ticket view directly, # something like: t = Ticket.view(num) for type, summary, status, resolution in self.env.db_query( """ SELECT type, summary, status, resolution FROM ticket WHERE id=%s """, (str(num),), ): title = self.format_summary(summary, status, resolution, type) href = formatter.href.ticket(num) + params + fragment return tag.a(label, title=title, href=href, class_="%s ticket" % status) else: ranges = str(r) if params: params = "&" + params[1:] label_wrap = label.replace(",", u",\u200b") ranges_wrap = ranges.replace(",", u", ") return tag.a( label_wrap, title=_("Tickets %(ranges)s", ranges=ranges_wrap), href=formatter.href.query(id=ranges) + params, ) except ValueError: pass return tag.a(label, class_="missing ticket")