command: Sluggify feed names on opmlimport
authorW. Trevor King <wking@tremily.us>
Sun, 13 Oct 2013 21:54:29 +0000 (14:54 -0700)
committerW. Trevor King <wking@tremily.us>
Mon, 14 Oct 2013 22:22:45 +0000 (15:22 -0700)
Gaëtan Harter writes [1]:
> Importing the following opml file fails with `invalid feed name
> 'Arch Linux: Recent news updates`
>
>   <?xml version="1.0" encoding="UTF-8"?>
>   <opml version="1.0">
>     <head>
>       <title>Google reader export</title>
>     </head>
>     <body>
>       <outline text="Arch Linux: Recent news updates"
>                title="Arch Linux: Recent news updates" type="rss"
>                xmlUrl="http://www.archlinux.org/feeds/news/"
>                htmlUrl="https://www.archlinux.org/news/" />
>     </body>
>   </opml>
>
> It fails because the `text` field is used directly as `name` for
> creating a Feed object.

ConfigParser can handle colons and accented characters in their
section names [2], but Feed._set_name checks names against
Feed._name_regexp which only allows ASCII letters, digits, periods,
underscores, and the hyphen-minus (U+002D).  Add an inverse
name_slug_regexp to opmlimport that replaces any runs of illegal
characters with a single hyphen-minus, to avoid crashing if the text
attribute contains anything illegal.

[1]: https://github.com/wking/rss2email/issues/24#issuecomment-26224593
[2]: http://docs.python.org/3/library/configparser.html#supported-ini-file-structure

Reported-by: Gaëtan Harter <hartergaetan@gmail.com>
Signed-off-by: W. Trevor King <wking@tremily.us>
rss2email/command.py

index 54c080836a5df07365e1829699748af741bae63a..aca5de8c98ec0becddc8041da04f683424346d0b 100644 (file)
@@ -17,6 +17,7 @@
 """rss2email commands
 """
 
+import re as _re
 import sys as _sys
 import xml.dom.minidom as _minidom
 import xml.sax.saxutils as _saxutils
@@ -131,6 +132,7 @@ def opmlimport(feeds, args):
         raise _error.OPMLReadError() from e
     if args.file:
         f.close()
+    name_slug_regexp = _re.compile('[^a-zA-Z0-9._-]+')
     for feed in new_feeds:
         if feed.hasAttribute('xmlUrl'):
             url = _saxutils.unescape(feed.getAttribute('xmlUrl'))
@@ -138,7 +140,7 @@ def opmlimport(feeds, args):
             if feed.hasAttribute('text'):
                 text = _saxutils.unescape(feed.getAttribute('text'))
                 if text != url:
-                    name = text
+                    name = name_slug_regexp.sub('-', text)
             feed = feeds.new_feed(name=name, url=url)
             _LOG.info('add new feed {}'.format(feed))
     feeds.save()