You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@allura.apache.org by br...@apache.org on 2020/01/27 21:03:08 UTC

[allura] 01/02: [#7878] unicode fixes for rss feeds

This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/allura.git

commit b1a077ab154bbdb8a50d94b6d152786ab34e54e4
Author: Dave Brondsema <da...@brondsema.net>
AuthorDate: Mon Jan 27 15:43:45 2020 -0500

    [#7878] unicode fixes for rss feeds
---
 Allura/allura/lib/helpers.py                       | 17 +++++++++++++++++
 Allura/allura/model/artifact.py                    |  4 ++--
 ForgeBlog/forgeblog/tests/functional/test_feeds.py | 16 ++++++++++------
 3 files changed, 29 insertions(+), 8 deletions(-)

diff --git a/Allura/allura/lib/helpers.py b/Allura/allura/lib/helpers.py
index 6c35dcb..419a9b8 100644
--- a/Allura/allura/lib/helpers.py
+++ b/Allura/allura/lib/helpers.py
@@ -178,6 +178,23 @@ def urlquoteplus(url, safe=b""):
         return urllib.quote_plus(url.encode('utf-8'), safe=safe)
 
 
+def urlquote_path_only(url):
+    """
+    Given a relative url like /fö/bar/?sdf&sdf
+    urlquote only the path portion of it, leaving any querystring or target hash unquoted
+    :param url:
+    :return:
+    """
+    if '?' in url:
+        url_path, url_joiner, url_remainder = url.partition('?')
+    elif '#' in url:
+        url_path, url_joiner, url_remainder = url.partition('#')
+    else:
+        url_path = url
+        url_joiner = url_remainder = ''
+    return urlquote(url_path) + url_joiner + url_remainder
+
+
 def _attempt_encodings(s, encodings):
     if s is None:
         return ''
diff --git a/Allura/allura/model/artifact.py b/Allura/allura/model/artifact.py
index 71a22ee..2094270 100644
--- a/Allura/allura/model/artifact.py
+++ b/Allura/allura/model/artifact.py
@@ -960,7 +960,7 @@ class Feed(MappedClass):
     def feed(cls, q, feed_type, title, link, description,
              since=None, until=None, page=None, limit=None):
         "Produces webhelper.feedgenerator Feed"
-        d = dict(title=title, link=h.absurl(link),
+        d = dict(title=title, link=h.absurl(h.urlquote(link)),
                  description=description, language='en',
                  feed_url=request.url)
         if feed_type == 'atom':
@@ -982,7 +982,7 @@ class Feed(MappedClass):
         cur = cur.skip(limit * page)
         for r in cur:
             feed.add_item(title=r.title,
-                          link=h.absurl(r.link.encode('utf-8')),
+                          link=h.absurl(h.urlquote_path_only(r.link)),
                           pubdate=r.pubdate,
                           description=r.description,
                           unique_id=h.absurl(r.unique_id),
diff --git a/ForgeBlog/forgeblog/tests/functional/test_feeds.py b/ForgeBlog/forgeblog/tests/functional/test_feeds.py
index a90fa68..5ea699f 100644
--- a/ForgeBlog/forgeblog/tests/functional/test_feeds.py
+++ b/ForgeBlog/forgeblog/tests/functional/test_feeds.py
@@ -1,3 +1,4 @@
+# coding=utf-8
 #       Licensed to the Apache Software Foundation (ASF) under one
 #       or more contributor license agreements.  See the NOTICE file
 #       distributed with this work for additional information
@@ -33,7 +34,7 @@ class TestFeeds(TestController):
 
     def _post(self, slug='', **kw):
         d = {
-            'title': 'My Post',
+            'title': 'My Pôst'.encode('utf-8'),
             'text': 'Nothing to see here',
             'labels': '',
             'state': 'published'}
@@ -60,8 +61,11 @@ class TestFeeds(TestController):
         return datetime.datetime.utcnow().strftime('%Y/%m')
 
     def test_feeds(self):
-        self.app.get('/blog/feed.rss')
-        self.app.get('/blog/feed.atom')
+        self._post()
+        r = self.app.get('/blog/feed.rss')
+        r.mustcontain('/my-p%C3%B4st/</link>')
+        r = self.app.get('/blog/feed.atom')
+        r.mustcontain('/my-p%C3%B4st/"')
 
     def test_rss_feed_contains_self_link(self):
         r = self.app.get('/blog/feed.rss')
@@ -74,9 +78,9 @@ class TestFeeds(TestController):
     def test_post_feeds(self):
         self._post()
         d = self._blog_date()
-        response = self.app.get('/blog/%s/my-post/feed.rss' % d)
+        response = self.app.get(h.urlquote('/blog/%s/my-pôst/feed.rss' % d))
         assert 'Nothing to see' in response
-        response = self.app.get('/blog/%s/my-post/feed.atom' % d)
+        response = self.app.get(h.urlquote('/blog/%s/my-pôst/feed.atom' % d))
         assert 'Nothing to see' in response
         self._post(title='test', text='*sometext*')
         response = self.app.get('/blog/feed')
@@ -139,7 +143,7 @@ class TestFeeds(TestController):
             blog_post.discussion_thread.add_post(text='You are a good blogger, I am a boring commentor.')
         ThreadLocalORMSession.flush_all()
 
-        resp = self.app.get("/blog/" + self._blog_date() + "/my-post/feed.rss")
+        resp = self.app.get(h.urlquote("/blog/" + self._blog_date() + "/my-pôst/feed.rss"))
         assert_in('boring comment', resp)
 
         resp = self.app.get("/blog/feed.rss")