Repository: martinrusev/imbox

Issue:
error when parsing attachment
I am running the example provided by README, My python version is 3.5, on windows platform, here is the  error message, please take a look.

```
Traceback (most recent call last):
  File "C:\Users\**\Miniconda3\lib\base64.py", line 518, in _input_type_check
    m = memoryview(s)
TypeError: memoryview: a bytes-like object is required, not 'str'
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
  File "D:/Project/account-adapter/imbox_downloader.py", line 61, in <module>
    for uid, message in all_messages:
  File "C:\Users\**\Miniconda3\lib\site-packages\imbox\__init__.py", line 50, in fetch_list
    yield (uid, self.fetch_by_uid(uid))
  File "C:\Users\**\Miniconda3\lib\site-packages\imbox\__init__.py", line 41, in fetch_by_uid
    email_object = parse_email(raw_email)
  File "C:\Users\**\Miniconda3\lib\site-packages\imbox\parser.py", line 160, in parse_email
    attachment = parse_attachment(part)
  File "C:\Users\**\Miniconda3\lib\site-packages\imbox\parser.py", line 102, in parse_attachment
    name, value = decode_param(param)
  File "C:\Users\**\Miniconda3\lib\site-packages\imbox\parser.py", line 74, in decode_param
    value = base64.decodestring(code)
  File "C:\Users\**\Miniconda3\lib\base64.py", line 560, in decodestring
    return decodebytes(s)
  File "C:\Users\**\Miniconda3\lib\base64.py", line 552, in decodebytes
    _input_type_check(s)
  File "C:\Users\**\Miniconda3\lib\base64.py", line 521, in _input_type_check
    raise TypeError(msg) from err
TypeError: expected bytes-like object, not str

```

Comments:

Patch:
diff --git a/imbox/parser.py b/imbox/parser.py
index 374ffdf..4b1b6f2 100644
--- a/imbox/parser.py
+++ b/imbox/parser.py
@@ -69,7 +69,7 @@ def decode_param(param):
             if type_ == 'Q':
                 value = quopri.decodestring(code)
             elif type_ == 'B':
-                value = base64.decodestring(code)
+                value = base64.decodebytes(code.encode())
             value = str_encode(value, encoding)
             value_results.append(value)
             if value_results:


Test patch:
diff --git a/tests/parser_tests.py b/tests/parser_tests.py
index fae3543..11961b0 100644
--- a/tests/parser_tests.py
+++ b/tests/parser_tests.py
@@ -80,6 +80,46 @@ Content-Transfer-Encoding: quoted-printable
 """
 
 
+raw_email_encoded_bad_multipart = b"""Delivered-To: receiver@example.com
+Return-Path: <sender@example.com>
+From: sender@example.com
+To: "Receiver" <receiver@example.com>, "Second\r\n Receiver" <recipient@example.com>
+Subject: Re: Looking to connect with you...
+Date: Thu, 20 Apr 2017 15:32:52 +0000
+Message-ID: <BN6PR16MB179579288933D60C4016D078C31B0@BN6PR16MB1795.namprd16.prod.outlook.com>
+Content-Type: multipart/related;
+	boundary="_004_BN6PR16MB179579288933D60C4016D078C31B0BN6PR16MB1795namp_";
+	type="multipart/alternative"
+MIME-Version: 1.0
+--_004_BN6PR16MB179579288933D60C4016D078C31B0BN6PR16MB1795namp_
+Content-Type: multipart/alternative;
+	boundary="_000_BN6PR16MB179579288933D60C4016D078C31B0BN6PR16MB1795namp_"
+--_000_BN6PR16MB179579288933D60C4016D078C31B0BN6PR16MB1795namp_
+Content-Type: text/plain; charset="utf-8"
+Content-Transfer-Encoding: base64
+SGkgRGFuaWVsbGUsDQoNCg0KSSBhY3R1YWxseSBhbSBoYXBweSBpbiBteSBjdXJyZW50IHJvbGUs
+Y3J1aXRlciB8IENoYXJsb3R0ZSwgTkMNClNlbnQgdmlhIEhhcHBpZQ0KDQoNCg==
+--_000_BN6PR16MB179579288933D60C4016D078C31B0BN6PR16MB1795namp_
+Content-Type: text/html; charset="utf-8"
+Content-Transfer-Encoding: base64
+PGh0bWw+DQo8aGVhZD4NCjxtZXRhIGh0dHAtZXF1aXY9IkNvbnRlbnQtVHlwZSIgY29udGVudD0i
+CjwvZGl2Pg0KPC9kaXY+DQo8L2JvZHk+DQo8L2h0bWw+DQo=
+--_000_BN6PR16MB179579288933D60C4016D078C31B0BN6PR16MB1795namp_--
+--_004_BN6PR16MB179579288933D60C4016D078C31B0BN6PR16MB1795namp_
+Content-Type: image/png; name="=?utf-8?B?T3V0bG9va0Vtb2ppLfCfmIoucG5n?="
+Content-Description: =?utf-8?B?T3V0bG9va0Vtb2ppLfCfmIoucG5n?=
+Content-Disposition: inline;
+	filename="=?utf-8?B?T3V0bG9va0Vtb2ppLfCfmIoucG5n?="; size=488;
+	creation-date="Thu, 20 Apr 2017 15:32:52 GMT";
+	modification-date="Thu, 20 Apr 2017 15:32:52 GMT"
+Content-ID: <254962e2-f05c-40d1-aa11-0d34671b056c>
+Content-Transfer-Encoding: base64
+iVBORw0KGgoAAAANSUhEUgAAABMAAAATCAYAAAByUDbMAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJ
+cvED9AIR3TCAAAMAqh+p+YMVeBQAAAAASUVORK5CYII=
+--_004_BN6PR16MB179579288933D60C4016D078C31B0BN6PR16MB1795namp_--
+"""
+
+
 class TestParser(unittest.TestCase):
 
     def test_parse_email(self):
@@ -96,6 +136,10 @@ class TestParser(unittest.TestCase):
         self.assertEqual('Выписка по карте', parsed_email.subject)
         self.assertEqual('Выписка по карте 1234', parsed_email.body['html'][0])
 
+    def test_parse_email_bad_multipart(self):
+        parsed_email = parse_email(raw_email_encoded_bad_multipart)
+        self.assertEqual("Re: Looking to connect with you...", parsed_email.subject)
+
     def test_parse_email_ignores_header_casing(self):
         self.assertEqual('one', parse_email('Message-ID: one').message_id)
         self.assertEqual('one', parse_email('Message-Id: one').message_id)