id	summary	reporter	owner	description	type	status	priority	component	severity	resolution	keywords	cc	release
2861	SubversionFind macro	anonymous	anybody	To describe project architecture I had to do macros that seek the string in source subversion file and set reference to first finding string on wiki page.\r\n\r\nfor example, wiki page code:\r\n\r\n{{{\r\n[[SvnQuery(HelloWorld,.../_trunk/example.c, HelloWorld::HelloWorld)]]\r\n}}}\r\n\r\n\r\nresult:\r\n<a href="/trac/browser/.../_trunk/example.c#L480">HelloWorld::HelloWorld</a>\r\n\r\nIt's comfortable if the HelloWorld method moves or changes in the example.c code.\r\n\r\nI wrote the macros:\r\n\r\n{{{\r\n# -*- coding: utf-8 -*-\r\n\r\nimport sys \r\nfrom trac.core import * \r\nfrom trac.wiki.macros import WikiMacroBase\r\nfrom trac.wiki.macros import IWikiMacroProvider\r\n#from trac.versioncontrol.api import NoSuchChangeset\r\nfrom trac.versioncontrol.web_ui.util import *\r\n\r\nimport re\r\nimport urllib\r\nimport os.path\r\nfrom fnmatch import fnmatchcase\r\n\r\nfrom trac import util\r\nfrom trac.config import ListOption, Option\r\n#from trac.core import *\r\nfrom trac.mimeview import Mimeview, is_binary, get_mimetype\r\nfrom trac.perm import IPermissionRequestor\r\nfrom trac.util import sorted, embedded_numbers\r\nfrom trac.util.datefmt import http_date, format_datetime, pretty_timedelta\r\nfrom trac.util.html import escape, html, Markup\r\nfrom trac.util.text import pretty_size\r\nfrom trac.web import IRequestHandler, RequestDone\r\nfrom trac.web.chrome import add_link, add_stylesheet, INavigationContributor\r\nfrom trac.wiki import wiki_to_html, IWikiSyntaxProvider\r\nfrom trac.versioncontrol.api import NoSuchChangeset\r\nfrom trac.versioncontrol.web_ui.util import *\r\nfrom trac.web.href import Href\r\n\r\nfrom urllib import quote, urlencode\r\nfrom trac.util.text import unicode_quote, unicode_urlencode\r\n\r\n\r\nfrom svn import core, fs, ra\r\nimport codecs\r\nfrom StringIO import StringIO\r\n\r\n\r\nCHUNK_SIZE = 4096\r\n\r\nclass SvnQuery(WikiMacroBase):\r\n\r\n    implements(IPermissionRequestor)\r\n\r\n    def get_permission_actions(self):\r\n        return ['BROWSER_VIEW', 'FILE_VIEW']\r\n\r\n\r\n    """ Usage: `[[SvnQuery]]` """\r\n    def render_macro(self, formatter, name, content):\r\n        if not content:\r\n            return 'Not Argument for SvnQuery' \r\n\r\n        args = content.split(',')\r\n        if len(args) == 0: \r\n            raise Exception("No argument.") \r\n\r\n#        print 'args:' + args[0].encode('utf-8')\r\n        repos = self.env.get_repository(formatter.authname)\r\n\r\n        node = get_existing_node(formatter, repos, args[1].encode('utf-8').strip(), repos.youngest_rev)\r\n\r\n\r\n        formatter.perm.assert_permission('FILE_VIEW')\r\n\r\n        content = node.get_content()\r\n        import StringIO as StringIO\r\n        self.strin = StringIO.StringIO('')   \r\n        chunk = content.read(CHUNK_SIZE)\r\n\r\n        res=-1\r\n        i = 0\r\n        self.str = ''\r\n        while 1:\r\n            if not chunk:\r\n                n = self.find_line(args[2].encode('utf-8'), formatter)\r\n                if n != -1:\r\n                    return Markup(html.A(args[0].encode('utf-8'), href=formatter.href.browser(args[1].encode('utf-8').strip()) + '#L%d' % n\r\n, style='padding:0; border:none') ).sanitize()\r\n                return\r\n            self.strin.write(chunk)\r\n            chunk = content.read(CHUNK_SIZE)\r\n        return ''\r\n# return 'SvnQuery: ' + formatter.href.browser(content, format = 'raw')\r\n    def find_line(self, str, fmt):\r\n        res = -1\r\n        i = 1\r\n        self.strin.seek(0)\r\n#        line = self.strin.readline()\r\n        for line in self.strin.readlines():#while 1:\r\n          if line.find(str) != -1:\r\n              res = i\r\n              return res\r\n#line = self.strin.readline()\r\n          i = i + 1\r\n\r\n        return -1\r\n\r\n}}}\r\n\r\n\r\nAlexander Alyabushev alexhalf NOTDOG gmail.com	enhancement	new	normal	Request-a-Hack	blocker				0.10
