[1/3] rendercomment: safer Flyspray task linkification

Message ID 20200202192508.GA274475@tsubame.mg0.fr
State New
Headers show
Series [1/3] rendercomment: safer Flyspray task linkification | expand

Commit Message

Frédéric Mangano-Tarumi Feb. 2, 2020, 7:25 p.m. UTC
When an FS#123 is part of a code block, it must not be converted into a
link. FS#123 may also appear inside an URL, in which case regular
linkifaction of URLs must take precedence.
---
 aurweb/scripts/rendercomment.py | 21 ++++++++++++++-------
 test/t2600-rendercomment.sh     | 26 ++++++++++++++++++++++++++
 2 files changed, 40 insertions(+), 7 deletions(-)

Comments

Lukas Fleischer Feb. 2, 2020, 7:50 p.m. UTC | #1
On Sun, 02 Feb 2020 at 20:25:08, Frédéric Mangano-Tarumi wrote:
> When an FS#123 is part of a code block, it must not be converted into a
> link. FS#123 may also appear inside an URL, in which case regular
> linkifaction of URLs must take precedence.
> ---
>  aurweb/scripts/rendercomment.py | 21 ++++++++++++++-------
>  test/t2600-rendercomment.sh     | 26 ++++++++++++++++++++++++++
>  2 files changed, 40 insertions(+), 7 deletions(-)

Thanks! I merged all patches in this patch series.

Patch

diff --git a/aurweb/scripts/rendercomment.py b/aurweb/scripts/rendercomment.py
index ba28486..7cba6ef 100755
--- a/aurweb/scripts/rendercomment.py
+++ b/aurweb/scripts/rendercomment.py
@@ -29,18 +29,25 @@  class LinkifyExtension(markdown.extensions.Extension):
         md.inlinePatterns.add('linkify', processor, '_end')
 
 
-class FlysprayLinksPreprocessor(markdown.preprocessors.Preprocessor):
-    _fsre = re.compile(r'\b(FS#(\d+))\b')
-    _sub = r'[\1](https://bugs.archlinux.org/task/\2)'
+class FlysprayLinksInlineProcessor(markdown.inlinepatterns.InlineProcessor):
+    """
+    Turn Flyspray task references like FS#1234 into links to bugs.archlinux.org.
+
+    The pattern's capture group 0 is the text of the link and group 1 is the
+    Flyspray task ID.
+    """
 
-    def run(self, lines):
-        return [self._fsre.sub(self._sub, line) for line in lines]
+    def handleMatch(self, m, data):
+        el = markdown.util.etree.Element('a')
+        el.set('href', f'https://bugs.archlinux.org/task/{m.group(1)}')
+        el.text = markdown.util.AtomicString(m.group(0))
+        return el, m.start(0), m.end(0)
 
 
 class FlysprayLinksExtension(markdown.extensions.Extension):
     def extendMarkdown(self, md, md_globals):
-        preprocessor = FlysprayLinksPreprocessor(md)
-        md.preprocessors.add('flyspray-links', preprocessor, '_end')
+        processor = FlysprayLinksInlineProcessor(r'\bFS#(\d+)\b',md)
+        md.inlinePatterns.add('flyspray-links', processor, '_end')
 
 
 class GitCommitsInlineProcessor(markdown.inlinepatterns.InlineProcessor):
diff --git a/test/t2600-rendercomment.sh b/test/t2600-rendercomment.sh
index b0209eb..1da422d 100755
--- a/test/t2600-rendercomment.sh
+++ b/test/t2600-rendercomment.sh
@@ -103,4 +103,30 @@  test_expect_success 'Test Git commit linkification.' '
 	test_cmp actual expected
 '
 
+test_expect_success 'Test Flyspray issue linkification.' '
+	sqlite3 aur.db <<-EOD &&
+	INSERT INTO PackageComments (ID, PackageBaseID, Comments, RenderedComment) VALUES (6, 1, "
+		FS#1234567.
+		*FS#1234*
+		FS#
+		XFS#1
+		\`FS#1234\`
+		https://archlinux.org/?test=FS#1234
+	", "");
+	EOD
+	"$RENDERCOMMENT" 6 &&
+	cat <<-EOD >expected &&
+		<p><a href="https://bugs.archlinux.org/task/1234567">FS#1234567</a>.
+		<em><a href="https://bugs.archlinux.org/task/1234">FS#1234</a></em>
+		FS#
+		XFS#1
+		<code>FS#1234</code>
+		<a href="https://archlinux.org/?test=FS#1234">https://archlinux.org/?test=FS#1234</a></p>
+	EOD
+	sqlite3 aur.db <<-EOD >actual &&
+	SELECT RenderedComment FROM PackageComments WHERE ID = 6;
+	EOD
+	test_cmp actual expected
+'
+
 test_done