from James Henstridge http://sourceforge.net/tracker/index.php?func=detail&aid=986023&group_id=18760&atid=318760 lib/config.py | 1 + lib/viewvc.py | 22 +++++++++++++--------- viewvc.conf.dist | 15 +++++++++++++++ 3 files changed, 29 insertions(+), 9 deletions(-) Index: viewvc.conf.dist =================================================================== --- viewvc.conf.dist.orig +++ viewvc.conf.dist @@ -257,6 +257,21 @@ languages = en-us #--------------------------------------------------------------------------- [options] +# The 'buglink_base' value is a string that can be used to form a URL +# by appending a bug number. If viewvc sees something that looks +# like a bug number in a log message (eg. "bug 12345" or "#12345"), it +# will be displayed as a link to the bug in your bug tracking system. +# +# For a Bugzilla installation, you probably want to set this to +# something like "http://hostname/show_bug.cgi?id=". For the Debian +# bug tracker, you might use +# "http://hostname/cgi-bin/bugreport.cgi?bug=". +# +# If 'buglink_base' is not set, then bug tracker links won't be +# generated. +# +# buglink_base = http://example.com/show_bug.cgi?id= + # root_as_url_component: Interpret the first path component in the URL # after the script location as the root to use. This is an # alternative to using the "root=" query key. If ViewVC is configured Index: lib/config.py =================================================================== --- lib/config.py.orig +++ lib/config.py @@ -221,6 +221,7 @@ class Config: self.options.use_localtime = 0 self.options.http_expiration_time = 600 self.options.generate_etags = 1 + self.options.buglink_base = None def is_forbidden(self, module): if not module: Index: lib/viewvc.py =================================================================== --- lib/viewvc.py.orig +++ lib/viewvc.py @@ -970,14 +970,18 @@ def get_file_view_info(request, where, r # addresses. Note that the regexps assume the text is already HTML-encoded. _re_rewrite_url = re.compile('((http|https|ftp|file|svn|svn\+ssh)(://[-a-zA-Z0-9%.~:_/]+)((\?|\&)([-a-zA-Z0-9%.~:_]+)=([-a-zA-Z0-9%.~:_])+)*(#([-a-zA-Z0-9%.~:_]+)?)?)') _re_rewrite_email = re.compile('([-a-zA-Z0-9_.\+]+)@(([-a-zA-Z0-9]+\.)+[A-Za-z]{2,4})') -def htmlify(html): +_re_rewrite_bug = re.compile(r'((?:\bbug[\s#+]|[^&]#|^#)\s*(\d\d+))', re.I) +def htmlify(html, buglink = None): html = cgi.escape(html) html = re.sub(_re_rewrite_url, r'\1', html) html = re.sub(_re_rewrite_email, r'\1@\2', html) + if buglink is not None: + html = re.sub(_re_rewrite_bug, r'\1' % buglink, html) return html + def format_log(log, cfg): - s = htmlify(log[:cfg.options.short_log_len]) + s = htmlify(log[:cfg.options.short_log_len], cfg.options.buglink_base) if len(log) > cfg.options.short_log_len: s = s + '...' return s @@ -1394,7 +1398,7 @@ def view_markup(request): 'date' : make_time_string(entry.date, cfg), 'author' : entry.author, 'changed' : entry.changed, - 'log' : htmlify(entry.log), + 'log' : htmlify(entry.log, cfg.options.buglink_base), 'size' : entry.size, }) @@ -1651,7 +1655,7 @@ def view_directory(request): 'sortby' : sortby, 'sortdir' : sortdir, 'tarball_href' : None, - 'search_re' : search_re and htmlify(search_re) or None, + 'search_re' : search_re and htmlify(search_re, cfg.options.buglink_base) or None, 'dir_pagestart' : None, 'sortby_file_href' : request.get_url(params={'sortby': 'file', 'sortdir': None}, @@ -1897,7 +1901,7 @@ def view_log(request): entry.ago = None if rev.date is not None: entry.ago = html_time(request, rev.date, 1) - entry.log = htmlify(rev.log or "") + entry.log = htmlify(rev.log or "", cfg.options.buglink_base) entry.size = rev.size entry.branch_point = None entry.next_main = None @@ -2359,7 +2363,7 @@ def spaced_html_text(text, cfg): text = string.replace(text, ' ', ' \x01nbsp;') else: text = string.replace(text, ' ', '\x01nbsp;') - text = htmlify(text) + text = htmlify(text, cfg.options.buglink_base) text = string.replace(text, '\x01', '&') text = string.replace(text, '\x02', '\
') return text @@ -2767,7 +2771,7 @@ def view_diff(request): else: changes = DiffSource(fp, cfg) else: - raw_diff_fp = MarkupPipeWrapper(fp, htmlify(headers), None, 1) + raw_diff_fp = MarkupPipeWrapper(fp, htmlify(headers, cfg.options.buglink_base), None, 1) data.update({ 'date_left' : rcsdiff_date_reformat(date1, cfg), @@ -3051,7 +3055,7 @@ def view_revision(request): 'rev' : str(rev), 'author' : author, 'date' : date_str, - 'log' : msg and htmlify(msg) or None, + 'log' : msg and htmlify(msg, request.cfg.options.buglink_base) or None, 'ago' : None, 'changes' : changes, 'prev_href' : prev_rev_href, @@ -3202,7 +3206,7 @@ def build_commit(request, files, limited commit = _item(num_files=len(files), files=[]) commit.limited_files = ezt.boolean(limited_files) desc = files[0].GetDescription() - commit.log = htmlify(desc) + commit.log = htmlify(desc, request.cfg.options.buglink_base) commit.short_log = format_log(desc, request.cfg) commit.author = htmlify(files[0].GetAuthor()) commit.rss_date = make_rss_time_string(files[0].GetTime(), request.cfg)