Search code examples
google-app-engineemailblobstoreapp-engine-ndb

How to store e-mail attachment to GAE Blobstore?


Let's say the app received a message, which has attachments (mail_message.attachments). Now, I would like to save the message in the datastore. I don't want to store attachment there, so I would like to keep there blobstore keys only. I know that I can write files to blobstore. The questions I have:

  1. how to extract files from the mail attachment;
  2. how to keep original filenames;
  3. how to store blob keys in the datastore (taking into account that one mail can contain several attachments looks like BlobKeyProperty() doesn't work in this case).

Upd. For (1) the following code can be used:

my_file = []
my_list = []
if hasattr(mail_message, 'attachments'):
    file_name = ""
    file_blob = ""
    for filename, filecontents in mail_message.attachments:
        file_name = filename
        file_blob = filecontents.decode()
        my_file.append(file_name)
        my_list.append(str(store_file(self, file_name, file_blob)))

Solution

  • Here is what I finally do:

    class EmailHandler(webapp2.RequestHandler):
        def post(self):
            '''
            Receive incoming e-mails
            Parse message manually
            '''
            msg = email.message_from_string(self.request.body) # http://docs.python.org/2/library/email.parser.html
            for part in msg.walk():
                ctype = part.get_content_type()
                if ctype in ['image/jpeg', 'image/png']:
                    image_file = part.get_payload(decode=True)
                    image_file_name = part.get_filename()
                    # save file to blobstore
                    bs_file = files.blobstore.create(mime_type=ctype, _blobinfo_uploaded_filename=image_file_name)
                    with files.open(bs_file, 'a') as f:
                        f.write(image_file)
                    files.finalize(bs_file)
                    blob_key = files.blobstore.get_blob_key(bs_file)
    

    blob_keys are stored in the datastore as ndb.BlobKeyProperty(repeated=True).