rss2email: Sort __contributors__ by first name and add missing folks

This brings __contributors__ in line with the auto-generated AUTHORS.
I'm not convinced that listing __contributors__ in a Python-parsable
manner is worth the trouble, but I'll leave it in for now.

Signed-off-by: W. Trevor King <wking@tremily.us>
main: Catch command-less case for Python 3.3

In Python 3.2, the argument parser raises an error if no subcommand is
listed on the command line.  This does not seem to be the case with
Python 3.3.0, and the changed behavior seems to have been a side
effect of this:

  http://hg.python.org/cpython/rev/cab204a79e09
  changeset:   70741:cab204a79e09
  user:        R David Murray <rdmurray@bitdance.com>
  date:        Thu Jun 09 12:34:07 2011 -0400
  summary:     #10424: argument names are now included in the missing argument mes

Anyhow, it's easy enough to catch the new behaviour in rss2email and
print the appropriate error.

Reported-by: Dmitry Bogatov <KAction@gnu.org>
Signed-off-by: W. Trevor King <wking@tremily.us>
feed: Remove the for loop variable `e` for a clean namespace

Otherwise:

  >>> import rss2email.feed
  >>> print([x for x in dir(rss2email) if not x.startswith('_')])
  ['Feed', 'e']

which might confuse people ;).

Signed-off-by: W. Trevor King <wking@tremily.us>
email: Don't assume `extra_headers` has content in get_message()

The default is None, so we should at least handle that case
gracefully.

Signed-off-by: W. Trevor King <wking@tremily.us>
feeds: Raise an RSS2EmailError on invalid Feeds.index() arguments

Don't confuse non-Python folks by giving a traceback for this usage
error.

Reported-by: Dmitry Bogatov <KAction@gnu.org>
Signed-off-by: W. Trevor King <wking@tremily.us>
Add 8bit Content-Transfer-Encoding support.

Signed-off-by: Dmitry Bogatov <KAction@gnu.org>
Add use of `sender' parameter in `sendmail_send'.

Signed-off-by: Dmitry Bogatov <KAction@gnu.org>
feed: Pass config and section arguments to get_message()

Otherwise it will always use the default config.

Also add section fallback code to get_message in case the
feed-specific section is not in the config file.  This is useful for
testing, although in production every feed should have a section to
hold it's URL.

Signed-off-by: W. Trevor King <wking@tremily.us>
config: Rename use_8bit to use-8bit for uniformity

We use hyphens in all the other config settings.

Signed-off-by: W. Trevor King <wking@tremily.us>
test/bbc-chinese: Add tests for use-8bit

The BBC's Chinese feed should have a few non-ASCII characters in it
;).

Signed-off-by: W. Trevor King <wking@tremily.us>
email: When setting an 8bit CTE, remove the old header

From the docs [1]:

  Note that this does not overwrite or delete any existing header with
  the same name. If you want to ensure that the new header is the only
  one present in the message with field name name, delete the field
  first, e.g.:

    del msg['subject']
    msg['subject'] = 'Python roolz!'

[1]: http://docs.python.org/3/library/email.message.html#email.message.Message.__setitem__

Signed-off-by: W. Trevor King <wking@tremily.us>
feed: Convert missing/extra key errors to InvalidFeedConfig

This way we get the message and not a full traceback, to avoid scaring
users who aren't familiar with Python tracebacks.  Theres not much
information to go on in the new message, but if you crank up the
verbosity, you get:

  $ PYTHONPATH=. ./r2e -c conf -d data -VVV list
  load feed configuration from ['conf']
  loaded configuration from ['conf']
  load feed data from data
  extra configuration key: use_8bit

which seems good enough for me.

Reported-by: Dmitry Bogatov <KAction@gnu.org>
Signed-off-by: W. Trevor King <wking@tremily.us>
main: Show traceback when we're extra verbose

Adding --verbose (or -V) flags moves the logger from ERROR to WARNING
(-V), INFO (-VV), and DEBUG (-VVV).  Additional increments were
ignored, but I don't like always masking tracebacks.  This patch sets
an additional verbosity level (-VVVV) which logs at DEBUG and
additionally prints exception tracebacks instead of hiding them.

Signed-off-by: W. Trevor King <wking@tremily.us>
email: Alphabetize imports (swap email.mime and email.header)

Signed-off-by: W. Trevor King <wking@tremily.us>
email: Use Charsets to set the Content-Transfer-Encoding

This ensures that payload encoding/decoding happens appropriately, and
allows 7-bit-clean data to be sent with a 7bit CTE, even when the
use-8bit setting is on.

Signed-off-by: W. Trevor King <wking@tremily.us>
email: Factor message-to-bytes formatting out into _flatten()

Signed-off-by: W. Trevor King <wking@tremily.us>
email: Add a failing UTF-16 _flatten example

Signed-off-by: W. Trevor King <wking@tremily.us>
email: Fix _flatten() implementation for non-ASCII bodies

The email header should be flattened to ASCII with funky encoded
headers [1], but the body may be encoded in a non-ASCII-compatible
charset (e.g. UTF-16-LE).  The old _flatten() implementation used the
body charset to encode the entire message, which could garble the
header.  This patch uses BytesGenerator, which takes advantage of
email.charset.Charset's separate fields for the header encoding and
body encoding.

[1]: http://docs.python.org/3/library/email.header.html

Signed-off-by: W. Trevor King <wking@tremily.us>
email: Encode the body when we might use 8bit encoding

R. David Murray writes [1]:
> In 2.x that will work, and will give you the 8bit CTE at need, as
> long as you pass encoded text to MIMEText (as opposed to
> unicode...which it doesn't really handle correctly if I recall
> right).

See also, [2].

[1]: http://bugs.python.org/issue12552
     email.MIMEText overide BASE64 for utf8 charset
[2]: http://bugs.python.org/issue12553
     Add support for using a default CTE of '8bit' to MIMEText

Signed-off-by: W. Trevor King <wking@tremily.us>
config: Fix 'significan' -> 'significant' typo in a comment

Signed-off-by: W. Trevor King <wking@tremily.us>