Merge branch 'robust-file-saving'
authorW. Trevor King <wking@tremily.us>
Fri, 11 Oct 2013 14:56:15 +0000 (07:56 -0700)
committerW. Trevor King <wking@tremily.us>
Fri, 11 Oct 2013 14:56:15 +0000 (07:56 -0700)
* robust-file-saving:
  CHANGELOG: Document this branch's atomic saves
  feeds: Make Feeds.save fully atomic, assuming a working fsync

Signed-off-by: W. Trevor King <wking@tremily.us>
AUTHORS
CHANGELOG
r2e.1
rss2email/config.py
rss2email/email.py
rss2email/feed.py
rss2email/post_process/prettify.py

diff --git a/AUTHORS b/AUTHORS
index 480b0fc9de4ba30ac53c69dd71df15e16e42fbb5..aeec5a2b25c9120953fd9e9f00b54334dbb5153a 100644 (file)
--- a/AUTHORS
+++ b/AUTHORS
@@ -3,11 +3,13 @@ Aaron Swartz
 Arun Persaud <apersaud@lbl.gov>
 Brian Lalor
 Dean Jackson
+Dennis Keitzel <github@pinshot.net>
 Dmitry Bogatov <KAction@gnu.org>
 Eelis van der Weegen <eelis@eelis.net>
 Erik Hetzner
 Etienne Millon <me@emillon.org>
 George Saunders <georgesaunders@gmail.com>
+J. Lewis Muir <jlmuir@imca-cat.org>
 Joey Hess
 Lindsey Smith <lindsey.smith@gmail.com>
 Marcel Ackermann
index 68d8ece36ef8a89b01bdadbdb2885369e2b55496..a14f2a340b2cea927cc1e772ffe93fc308e7ac8b 100644 (file)
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,5 +1,7 @@
 v3.7 (unreleased)
     * Fix atomic saves to avoid garbling config and data files if the disk is full.
+    * Convert the `friendly-name` boolean to the new `name-format` setting.  This allow users to customize how the friendly name is constructed.
+    * Demote guessed encodings logs from 'error' to 'warning'.
 
 v3.6 (2013-09-09)
     * Fix missing port argument for IMAPAuthenticationError.
diff --git a/r2e.1 b/r2e.1
index 19da7008e1bd328543f399e7474db5ead2f72934..4079399be0214f023210c235735ef5a6078590b5 100644 (file)
--- a/r2e.1
+++ b/r2e.1
@@ -115,7 +115,7 @@ configuration file for you, which you can edit as you see fit.  The
 setting for all feeds, change the value in the \fB[DEFAULT]\fR
 section.  To override a setting for a particular feed, add that
 setting to the feed-specific section.  Here is an example overriding
-\fBuse-publisher-email\fR and \fBfriendly-name\fR for the
+\fBuse-publisher-email\fR and \fBname-format\fR for the
 \fBfeedname\fR feed.
 .P
 .RS 4
@@ -124,14 +124,14 @@ setting to the feed-specific section.  Here is an example overriding
 from = user@rss2email.invalid
 force-from = False
 use-publisher-email = False
-friendly-name = True
+name-format = {feed-title}: {author}
   .\|.\|.
 verbose = warning
 
 [feed.feedname]
 url = http://feed.url/somewhere.rss
 use-publisher-email = True
-friendly-name = False
+name-format = {author} ({feed.title})
 .RE
 .P
 .SH FILES
index fb7cd30ea3f49a55d533507341d2d323a4ec5201..6b5155fa8056d7ed9b888e9b79fe7fa2f1d2add5 100644 (file)
@@ -72,9 +72,11 @@ CONFIG['DEFAULT'] = _collections.OrderedDict((
         # True: Use the publisher's email if you can't find the author's.
         # False: Just use the 'from' email instead.
         ('use-publisher-email', str(False)),
-        # Only use the feed email address rather than friendly name
-        # plus email address
-        ('friendly-name', str(True)),
+        # If empty, only use the feed email address rather than
+        # friendly name plus email address.  Available attributes may
+        # include 'feed', 'feed-title', 'author', and 'publisher', but
+        # only 'feed' is guaranteed.
+        ('name-format', '{feed-title}: {author}'),
         # Set this to default To email addresses.
         ('to', ''),
 
index 59fa21ab584f24662838f6fff1a33d0d3978ef7b..ef798f76250eae3dc997c8a59a28f050d0e3b7c7 100644 (file)
@@ -1,6 +1,7 @@
 # -*- encoding: utf-8 -*-
 #
-# Copyright (C) 2012-2013 Dmitry Bogatov <KAction@gnu.org>
+# Copyright (C) 2012-2013 Arun Persaud <apersaud@lbl.gov>
+#                         Dmitry Bogatov <KAction@gnu.org>
 #                         George Saunders <georgesaunders@gmail.com>
 #                         W. Trevor King <wking@tremily.us>
 #
index 3999b0c7dcf3e4d5968da25a841da8b6a16112ac..37845c1a6927cbe667855530a7bfe05791b96dcb 100644 (file)
@@ -1,8 +1,10 @@
 # Copyright (C) 2004-2013 Aaron Swartz
 #                         Brian Lalor
 #                         Dean Jackson
+#                         Dennis Keitzel <github@pinshot.net>
 #                         Erik Hetzner
 #                         Etienne Millon <me@emillon.org>
+#                         J. Lewis Muir <jlmuir@imca-cat.org>
 #                         Joey Hess
 #                         Lindsey Smith <lindsey.smith@gmail.com>
 #                         Marcel Ackermann
@@ -64,6 +66,10 @@ for e in ['error', 'herror', 'gaierror']:
 del e  # cleanup namespace
 _SOCKET_ERRORS = tuple(_SOCKET_ERRORS)
 
+# drv_libxml2 raises:
+#   TypeError: 'str' does not support the buffer interface
+_feedparser.PREFERRED_XML_PARSERS = []
+
 
 class Feed (object):
     """Utility class for feed manipulation and storage.
@@ -164,7 +170,6 @@ class Feed (object):
         'digest',
         'force_from',
         'use_publisher_email',
-        'friendly_name',
         'active',
         'date_header',
         'trust_guid',
@@ -404,6 +409,11 @@ class Feed (object):
         elif isinstance(exc, _sax.SAXParseException):
             _LOG.error('sax parsing error: {}: {}'.format(exc, self))
             warned = True
+        elif (parsed.bozo and
+              isinstance(exc, _feedparser.CharacterEncodingOverride)):
+            _LOG.warning(
+                'incorrectly declared encoding: {}: {}'.format(exc, self))
+            warned = True
         elif parsed.bozo or exc:
             if exc is None:
                 exc = "can't process"
@@ -538,31 +548,38 @@ class Feed (object):
         ...     '</feed>\\n'
         ...     )
         >>> entry = parsed.entries[0]
-        >>> f.friendly_name = False
+        >>> f.name_format = ''
         >>> f._get_entry_name(parsed, entry)
         ''
-        >>> f.friendly_name = True
+        >>> f.name_format = '{author}'
         >>> f._get_entry_name(parsed, entry)
         'Example author'
+        >>> f.name_format = '{feed-title}: {author}'
+        >>> f._get_entry_name(parsed, entry)
+        ': Example author'
+        >>> f.name_format = '{author} ({feed.name})'
+        >>> f._get_entry_name(parsed, entry)
+        'Example author (test-feed)'
         """
-        if not self.friendly_name:
+        if not self.name_format:
             return ''
-        parts = ['']
+        data = {
+            'feed': self,
+            'feed-title': '<feed title>',
+            'author': '<author>',
+            'publisher': '<publisher>',
+            }
         feed = parsed.feed
-        parts.append(feed.get('title', ''))
+        data['feed-title'] = feed.get('title', '')
         for x in [entry, feed]:
             if 'name' in x.get('author_detail', []):
                 if x.author_detail.name:
-                    if ''.join(parts):
-                        parts.append(': ')
-                    parts.append(x.author_detail.name)
+                    data['author'] = x.author_detail.name
                     break
-        if not ''.join(parts) and self.use_publisher_email:
-            if 'name' in feed.get('publisher_detail', []):
-                if ''.join(parts):
-                    parts.append(': ')
-                parts.append(feed.publisher_detail.name)
-        return _html2text.unescape(''.join(parts))
+        if 'name' in feed.get('publisher_detail', []):
+            data['publisher'] = feed.publisher_detail.name
+        name = self.name_format.format(**data)
+        return _html2text.unescape(name)
 
     def _validate_email(self, email, default=None):
         """Do a basic quality check on email address
index 3f3ea6f0c1430d001b2eb65d9a501a06e8056f6a..681d4c391315b6c2a1685d2aada34ae1f3c1664d 100644 (file)
@@ -1,4 +1,5 @@
 # Copyright (C) 2013 Arun Persaud <apersaud@lbl.gov>
+#                    W. Trevor King <wking@tremily.us>
 #
 # This file is part of rss2email.
 #