Danamir / imap-attachment-extractor

IMAP attachment exporter, with optional Thunderbird detach mode
11 stars 4 forks source link

AttributeError: 'list' object has no attribute 'encode' #1

Closed pengu-fr closed 3 years ago

pengu-fr commented 3 years ago

Extracted 3 attachments, replacing email. Append message on IMAP server. Delete original message. Traceback (most recent call last): File "/home/pengu/aurore/imap-attachment-extractor/.env/bin/imap_aex", line 11, in load_entry_point('imap-attachment-extractor', 'console_scripts', 'imap_aex')() File "/home/pengu/aurore/imap-attachment-extractor/imap_aex.py", line 824, in cli main(options, defaults) File "/home/pengu/aurore/imap-attachment-extractor/imap_aex.py", line 816, in main imap.extract(**extract_kwargs) File "/home/pengu/aurore/imap-attachment-extractor/imap_aex.py", line 493, in extract attachment_content = part.get_payload().encode("utf-8") AttributeError: 'list' object has no attribute 'encode'

Danamir commented 3 years ago

get_payload() returns either a list or string, I thought that in this part of the code only str would be returnable, but it may depend on the mail server and/or the sender mail server.

I tested extensively with Gandi, Zimbra, and Gmail servers ; but I don't have access to other ones.

Without access to the mail or the server provoking the error I will have a hard time debugging.

Could you try to replace attachment_content = part.get_payload().encode("utf-8") line 488 by something like :

                    if isinstance(part.get_payload(), list):
                        attachment_content = part.get_payload(1).encode("utf-8")
                    else:
                        attachment_content = part.get_payload().encode("utf-8")  

But I'm not sure about using only the first part of the payload in this instance ; it could prevent the handling of multiple attachments.

Danamir commented 3 years ago

You can checkout the develop branch to try this solution.

pengu-fr commented 3 years ago

Thank you. I've tried this :

                if part.is_multipart():
                    attachment_content = part.get_payload()
                else:
                    attachment_content = part.get_payload(True)

And it worked pretty well for about 14Gb (on a 20Gb Gmail account). But it fails again somewhere else, and I gave up (sorry). But nice work here ! It would need a little more debugging, but it's already pretty usefull !

Danamir commented 3 years ago

No problem, thanks for testing anyway !

It's a pain to develop a tool for mail handling as the protocol is implemented differently by almost every servers. So I got it working for the few servers I use, but it may not be ok for others.