web2py multiple attachments recipe
Copyright (C) 2013 Alan Etkin
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Model (db.py)
...
imap = DAL("imap://<email address>:<password>@<imap server>:993")
imap.define_tables({"draft": "<service drafts folder>", "inbox": "INBOX"})
Controller code (default.py):
def index():
import os
folder = os.path.join(request.folder, "uploads")
message = "Hello"
# subject is just an example, replace it with
# to, sender (naming for imap connections)
form = SQLFORM.factory(Field("subject"),
Field("draft", "boolean", default=False),
*[Field("attachment_%s" % x,
"upload", uploadfolder=folder) for x in
range(10)], _id="uploadForm")
attachments = []
if form.process().accepted:
message = "ok"
for k, v in form.vars.iteritems():
# was this attachment field specified?
if k.startswith("attachment_") and v:
filepath = os.path.join(folder, v)
filename = request.vars[k].filename
# now let's retrieve the files
if form.vars.draft:
# Note: if your attachment is a file with binary
# data, then you need to encode the file
# output with the base64.b64encode function
# and set the proper file mime type and
# payload encoding ("base64"). Using base64
# requires a pending patch
# (web2py google code issue 1714 by IVINH)
request.vars[k].file.seek(0)
payload = request.vars[k].file.read()
attachments.append(dict(payload=payload, filename=filename, mime="text/plain"))
else:
# Here we use the file path to instantiate the Attachment object
attachments.append(mail.Attachment(filepath, filename=filename))
"""
Now you just need to use mail.send(...) for non-draft or
imap.<draft box>.insert(...) for draft emails passing the
attachments and the message values collected
from form.vars
"""
if form.vars.draft:
message = imap.draft.insert(subject=form.vars.subject, attachments=attachments, draft=True, mime="multipart/mixed")
message = "You just created a draft message with attachments with id %s" % message
else:
message = "This form is for draft messages only"
return dict(form=form, message=message)
View (default/index.html):
<h3>{{=message}}</h3>
{{=form.custom.begin}}
{{=form.custom.label.subject}}{{=form.custom.widget.subject}}
{{=form.custom.label.draft}}{{=form.custom.widget.draft}}
{{=INPUT(_type="button", _value="New attachment", _id="addAttachment")}}
<ul>
{{for x in range(10):}}
{{=LI(form.custom.label["attachment_%s" % x],
form.custom.widget["attachment_%s" % x],
_style="display:none", _id="attachment-%s" % x)}}
{{pass}}
</ul>
{{=form.custom.submit}}
{{=form.custom.end}}
{{=SCRIPT("""
var attachmentsCounter = 0;
// This will make a new attachment field to show each time
// the user clicks in the new attachment button
jQuery("#addAttachment").click(function(){
if (attachmentsCounter<11){
jQuery("li#attachment-" + attachmentsCounter).show();
attachmentsCounter++;}
});
""")}}


Comments (0)