It's a common use case to have your tracker system somehow integrated within your Source Control Manager. A simple way I found to do this is to have keywords in the item messages that expand to hyperlinks.
Hence, if you type in the item's note textbox something like This problem is solved in Version:35 the recipe I present here lets roundup expands such message with an hyperlink in Version:35 that points to a custom Versioning system.
This solution is very customizable and you may find many others useful cases.
Procedures
1) In issue.item.html replace the line where it says:
'"structure msg.content.hyperlinked"'
by:
'"structure python:utils.localReplace(msg.content.hyperlinked())"'
2) In your extensions directory, create a file local_replace.py with:
from custom_tags import CustomTags
def localReplace(aMessage):
return CustomTags().replace(aMessage)
def init(instance):
instance.registerUtil('localReplace', localReplace)
3) Add the custom_tags.py to a directory where Roundup can find it (I'd use python's
site-packages --see footnote)
customizing the substitute attribute for your own needs.
All the specific work you need to do is in this variable. Read the CustomTags?
class doc for details.
Ask any question at the roundup users mailing list or by email to hfoffani@gmail.com.
Regards,
-Hernan.
custom_tags.py:
import re
class CustomTags:
"""Replace custom tags
Use this class if you want to do parametrized string substitution
in a given text. It's useful to expand some keywords with a full
html tag. Customize this class by changing the 'substitute'
attribute. This attribute is a list of tuples. Each tuple
represents a substitution task. The first item of the tuple is
the lookup regular expression, the second item is the replace
string template. Just be careful to match the names in the
regular expression, eg. '(?P<a_name>...)', with the corresponding
ones in the template, eg. '... %(a_name)s ...'
A simple case:
>>> ct = CustomTags()
>>> ct.substitute = [('mom','papa')]
>>> ct.replace("hey! look mom! no hands!")
'hey! look papa! no hands!'
A more complex one:
>>> ct.substitute = [ (
... r'(?P<kw>rev):(?P<int>\d*)',
... r'<a href="http://%(kw)s?%(int)s">%(kw)s:%(int)s</a>'
... ) ]
>>> ct.replace("this is rev:33. but not rev:44")
'this is <a href="http://rev?33">rev:33</a>. but not <a href="http://rev?44">rev:44</a>'
>>> ct.replace("this remains untouched")
'this remains untouched'
More than one substitution task:
>>> ct = CustomTags()
>>> ct.substitute = [
... ( r'mom', r'papa' ),
... ( # a more complex one
... r'(?P<kw>rev):(?P<int>\d*)',
... r'<a href="http://%(kw)s?%(int)s">%(kw)s:%(int)s</a>')
... ]
>>> ct.replace("mom, look for rev:1")
'papa, look for <a href="http://rev?1">rev:1</a>'
Do nothing:
>>> ct = CustomTags()
>>> ct.substitute = [ ]
>>> ct.replace("this should be untouched.")
'this should be untouched.'
For better performance you may precompile the regexp adding a
call to 're.compile(..)' to the first member of each tuple in
the 'substitute' list.
"""
substitute = [
# ( r'mom', r'papa' ),
# ( r'(?P<kw>rev):(?P<int>\d*)',
# r'<a href="http://%(kw)s?%(int)s">%(kw)s:%(int)s</a>' )
]
def replace(self, text):
"""Returns a copy of text with its contents replaced."""
ntext = text
for regex, template in self.substitute:
for match in re.finditer(regex, text):
ntag = template % match.groupdict()
ntext = ntext.replace(match.group(0), ntag, 1)
return ntext
if __name__ == "__main__":
import doctest
doctest.testmod()
How to use site-packages for custom scripts.
- Make a subdirectory under
PYTHONPATH/Lib/site-packageswhere you can place your convenience files, saymycompany. Python won't touch those on future upgrades. - Create an empty file called
__init__.py(that's two underscores before and after.) - Place
custom_tags.pythere. In this caselocal_replace.pymust import this file as:from mycompany.custom_tags import CustomTags
Back to top LinkFormattingExample
Back to roundup's FrontPage