Skip to content

Commit

Permalink
Quoted printable decoding support
Browse files Browse the repository at this point in the history
  • Loading branch information
jamesridgway committed Apr 30, 2022
1 parent bba233a commit 4ee36e5
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 4 deletions.
18 changes: 18 additions & 0 deletions attachment_downloader/encoding.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import base64
import quopri
import re


class QuoPriEncoding:
@staticmethod
def decode(encoded_text):
encoded_word_regex = r'=\?{1}(.+)\?{1}([B|Q|b|q])\?{1}(.+)\?{1}='
matches = re.match(encoded_word_regex, encoded_text)
if matches is None:
return encoded_text
charset, encoding, encoded_text = matches.groups()
if encoding.upper() == 'B':
byte_string = base64.b64decode(encoded_text)
elif encoding.upper() == 'Q':
byte_string = quopri.decodestring(encoded_text)
return byte_string.decode(charset)
3 changes: 2 additions & 1 deletion attachment_downloader/version_info.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import os
import platform
import subprocess
import sys

VERSION_FILENAME = os.path.abspath(os.path.join(os.path.dirname(__file__), 'version.py'))

Expand Down Expand Up @@ -37,4 +38,4 @@ def get(retry=True):
@staticmethod
def get_env_info():
os_info = f"Release: {platform.release()}, Platform: {platform.platform()}"
return f"(Python: {platform.python_version()}), OS: ({os_info})"
return f"(Python: {platform.python_version()}), OS: ({os_info}). Default Encoding: {sys.getdefaultencoding()}"
8 changes: 5 additions & 3 deletions bin/attachment-downloader
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ from imbox import Imbox
from jinja2 import Template, UndefinedError

from attachment_downloader.cli import valid_date, get_password
from attachment_downloader.encoding import QuoPriEncoding
from attachment_downloader.logging import Logger
from attachment_downloader.version_info import Version

Expand Down Expand Up @@ -108,7 +109,7 @@ if __name__ == '__main__':
for (uid, message) in messages:
subject = ''
if hasattr(message, 'subject'):
subject = message.subject
subject = QuoPriEncoding.decode(message.subject)

try:
parsed_message_date = dateparser.parse(message.date)
Expand Down Expand Up @@ -141,7 +142,8 @@ if __name__ == '__main__':

for idx, attachment in enumerate(message.attachments):
try:
download_filename = filename_template.render(attachment_name=attachment.get('filename'),
attachment_filename = QuoPriEncoding.decode(attachment.get('filename'))
download_filename = filename_template.render(attachment_name=attachment_filename,
attachment_idx=idx,
subject=subject,
message_id=message.message_id,
Expand All @@ -150,7 +152,7 @@ if __name__ == '__main__':

download_path = os.path.join(options.download_folder, download_filename)
os.makedirs(os.path.dirname(os.path.abspath(download_path)), exist_ok=True)
logging.info("Downloading attachment '%s' to path %s", attachment.get('filename'), download_path)
logging.info("Downloading attachment '%s' to path %s", attachment_filename, download_path)

if os.path.isfile(download_path):
logging.warning("Overwriting file: '%s'", download_path)
Expand Down
10 changes: 10 additions & 0 deletions tests/attachment_downloader/test_encoding.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
from assertpy import assert_that

from attachment_downloader.encoding import QuoPriEncoding


class TestQuoPriEncoding:
def test_decode(self):
assert_that(QuoPriEncoding.decode('=?utf-8?b?2LPZhNin2YU=?=')).is_equal_to('سلام')
assert_that(QuoPriEncoding.decode('=?UTF-8?B?2LPZhNin2YU=?=')).is_equal_to('سلام')
assert_that(QuoPriEncoding.decode('Hello')).is_equal_to('Hello')

0 comments on commit 4ee36e5

Please sign in to comment.