envelopes icon indicating copy to clipboard operation
envelopes copied to clipboard

Allow adding attachment from memory

Open cool-RR opened this issue 12 years ago • 5 comments

Sometimes I have a file in-memory, not saved to disk, and I'd like to add it as an attachment.

Currently add_attachment only works on files that are saved to the filesystem.

Please allow attaching files that are in-memory.

cool-RR avatar Aug 19 '13 19:08 cool-RR

Hello, this is a nice idea. Tell me, by "in-memory files" do you mean StringIO objects or just plain strings?

I'll be working on the feature in the following days.

Thanks for your input.

tomekwojcik avatar Aug 20 '13 07:08 tomekwojcik

I meant plain strings, but I think it's trivial to have a function that looks at the argument and checks whether it's a string or a StringIO and does the right thing.

On Tue, Aug 20, 2013 at 10:34 AM, Tomek Wójcik [email protected]:

Hello, this is a nice idea. Tell me, by "in-memory files" do you mean StringIOobjects or just plain strings?

I'll be working on the feature in the following days.

Thanks for your input.

— Reply to this email directly or view it on GitHubhttps://github.com/tomekwojcik/envelopes/issues/7#issuecomment-22927373 .

cool-RR avatar Aug 20 '13 09:08 cool-RR

I think this enhancement is pretty important. So :+1: for it. Below is how I think it should work. I considered having it use a file like object but there is no advantage as set_payload uses a string. Instead a convience method add_file can be used which has the old api.

def add_attachment(self, data, name, mimetype=None):
    """Attaches a file from a string, *data*, and gives it the name
    specified in name. If *mimetype* is not specified an attempt to guess it is
    made. If nothing is guessed then `application/octet-stream` is used."""

    if mimetype is None:
        mimetype, _ = mimetypes.guess_type(name)

    if mimetype is None:
        mimetype = 'application/octet-stream'

    type_maj, type_min = mimetype.split('/')
    part = MIMEBase(type_maj, type_min)
    part.set_payload(data)
    email_encoders.encode_base64(part)

    encoded_name = self._encoded(name)
    part.add_header(
        'Content-Disposition', 'attachment; filename="%s"' % encoded_name)

    self._parts.append((mimetype, part))

def add_file(self, file_path, mimetype=None):
    """Attaches a file located at *file_path* to the envelope. If *mimetype* is
    not specified an attempt to guess it is made. If nothing is guessed then
    `application/octet-stream` is used."""

    with open(file_path, 'rb') as f:
        data = f.read()
    filename = os.path.basename(file_path)
    self.add_attachment(data, filename, mimetype=mimetype)

timtadh avatar Sep 02 '13 15:09 timtadh

@timtadh I have pretty much the same solution in the pipeline. I've been caught between other things lately so I haven't had a chance finish it and merge into master yet. I should be able to do so over the following days.

Thanks for your response :).

tomekwojcik avatar Sep 02 '13 17:09 tomekwojcik

Has this been implemented yet?

cool-RR avatar Jul 07 '14 21:07 cool-RR