summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPatrick Totzke <patricktotzke@gmail.com>2012-03-11 19:05:54 +0000
committerPatrick Totzke <patricktotzke@gmail.com>2012-03-11 19:05:54 +0000
commit4a9f2f1e24643b549902488ef96edce88de96c27 (patch)
tree480896604ab8de8eb3d39b11824df253404af7d2
parent9e1fc49ad48e23d6c327e184f4a85ce16778d7e0 (diff)
forgot to add attachments.py
-rw-r--r--alot/db/attachment.py75
1 files changed, 75 insertions, 0 deletions
diff --git a/alot/db/attachment.py b/alot/db/attachment.py
new file mode 100644
index 00000000..905e66b8
--- /dev/null
+++ b/alot/db/attachment.py
@@ -0,0 +1,75 @@
+import os
+import tempfile
+import email.charset as charset
+charset.add_charset('utf-8', charset.QP, charset.QP, 'utf-8')
+import alot.helper as helper
+from alot.helper import string_decode
+
+from alot.db.utils import decode_header
+
+
+class Attachment(object):
+ """represents a mail attachment"""
+
+ def __init__(self, emailpart):
+ """
+ :param emailpart: a non-multipart email that is the attachment
+ :type emailpart: :class:`email.message.Message`
+ """
+ self.part = emailpart
+
+ def __str__(self):
+ desc = '%s:%s (%s)' % (self.get_content_type(),
+ self.get_filename(),
+ helper.humanize_size(self.get_size()))
+ return string_decode(desc)
+
+ def get_filename(self):
+ """
+ return name of attached file.
+ If the content-disposition header contains no file name,
+ this returns `None`
+ """
+ extracted_name = decode_header(self.part.get_filename())
+ if extracted_name:
+ return os.path.basename(extracted_name)
+ return None
+
+ def get_content_type(self):
+ """mime type of the attachment part"""
+ ctype = self.part.get_content_type()
+ # replace underspecified mime description by a better guess
+ if ctype in ['octet/stream', 'application/octet-stream']:
+ ctype = helper.guess_mimetype(self.get_data())
+ return ctype
+
+ def get_size(self):
+ """returns attachments size in bytes"""
+ return len(self.part.get_payload())
+
+ def save(self, path):
+ """
+ save the attachment to disk. Uses :meth:`get_filename` in case path
+ is a directory
+ """
+ filename = self.get_filename()
+ path = os.path.expanduser(path)
+ if os.path.isdir(path):
+ if filename:
+ basename = os.path.basename(filename)
+ FILE = open(os.path.join(path, basename), "w")
+ else:
+ FILE = tempfile.NamedTemporaryFile(delete=False, dir=path)
+ else:
+ FILE = open(path, "w") # this throws IOErrors for invalid path
+ FILE.write(self.get_data())
+ FILE.close()
+ return FILE.name
+
+ def get_data(self):
+ """return data blob from wrapped file"""
+ return self.part.get_payload(decode=True)
+
+ def get_mime_representation(self):
+ """returns mime part that constitutes this attachment"""
+ return self.part