martinrusev / imbox

Python IMAP for Human beings
MIT License
1.18k stars 188 forks source link

binascii.Error: Invalid base64-encoded string: number of data characters (109) cannot be 1 more than a multiple of 4 #207

Open churchilldu opened 2 years ago

churchilldu commented 2 years ago

I got this error python3.9 on win10 the language of email is chinese, is that a problem?

Traceback (most recent call last):
  File "D:\Code\download_attatchment.py", line 30, in <module>
    for (uid, message) in messages:
  File "D:\Software\Python\lib\site-packages\imbox\messages.py", line 55, in _fetch_email_list
    yield uid, self._fetch_email(uid)
  File "D:\Software\Python\lib\site-packages\imbox\messages.py", line 42, in _fetch_email
    return fetch_email_by_uid(uid=uid,
  File "D:\Software\Python\lib\site-packages\imbox\parser.py", line 155, in fetch_email_by_uid
    email_object = parse_email(raw_email, policy=parser_policy)
  File "D:\Software\Python\lib\site-packages\imbox\parser.py", line 212, in parse_email
    attachment = parse_attachment(part)
  File "D:\Software\Python\lib\site-packages\imbox\parser.py", line 115, in parse_attachment
    name, value = decode_param(param)
  File "D:\Software\Python\lib\site-packages\imbox\parser.py", line 80, in decode_param
    value = base64.decodebytes(code.encode())
  File "D:\Software\Python\lib\base64.py", line 538, in decodebytes
    return binascii.a2b_base64(s)
binascii.Error: Invalid base64-encoded string: number of data characters (109) cannot be 1 more than a multiple of 4
sebix commented 2 years ago

Do you have a minimal example that you could share?

churchilldu commented 2 years ago

Do you have a minimal example that you could share?

sorry, I got almost three hundred mails with attachment in my inbox. Maybe it's because the language of mail is Chinese and the way decode doesn't match. I use try pass to override the error

sebix commented 2 years ago

But that doesn't fix the error, it just hides it.

churchilldu commented 2 years ago

But that doesn't fix the error, it just hides it.

I don't know if it's helpful, the info of debug console I tried to figure out which mail, there are too many.....

s={bytes: 126}b'5Y2X5Lqs6Iiq56m66Iiq5aSp?= =?UTF-8?B?5aSn5a2m5a2m55Sf5a625bqt5oOF5Ya1?= =?UTF-8?B?6LCD5p+l5Y+K5Zuw6Zq+6K6k5a6a6KGoKDEpLmRvY3g='

churchilldu commented 2 years ago
with open('config.txt', 'r') as f1:
    config = f1.readlines()
for i in range(0, len(config)):
    config[i] = config[i].rstrip('\n')

host = config[0]
username = config[1]
password = config[2]

mail = Imbox(host, username=username, password=password, ssl=True, ssl_context=None, starttls=False)
print("login  successfully")

messages = mail.messages()# defaults to inbox
print("check unread email")

for (uid, message) in messages:
    try:

        if re.search(r'瑞华|春雨|助学金|申请表', message.subject):
             message.subject=re.sub('[\s*]|瑞华|春雨|助学金|申请表|[++:.,_*]|[-*]|[a-zA-Z]',"",message.subject)
             print(message.subject)
           for idx, attachment in enumerate(message.attachments):

                    try:

                        att_fn =attachment.get('filename')
                        download_folder = os.path.join("D:\Downloads\email", message.subject)

                        # if not os.path.isdir(download_folder):
                        os.makedirs(download_folder, exist_ok=True)

                        download_path = f"{download_folder}\{att_fn}"
                        with open(download_path, 'wb') as fp:
                            fp.write(attachment.get('content').read())

                        mail.mark_seen(uid)  # optional, mark message as read

                    except:
                        pass
                        print(message.subject)
                        print(traceback.print_exc())

    except:
        pass

print('--------downlaod all attachment successfully!--------')
mail.logout()