def send(self, to, subject, body, cc=None, attachs=(), mimetype='text/plain', _callback=None): if attachs: msg = MIMEMultipart() else: msg = MIMENonMultipart(*mimetype.split('/', 1)) msg['From'] = self.mailfrom msg['To'] = COMMASPACE.join(to) msg['Date'] = formatdate(localtime=True) msg['Subject'] = subject rcpts = to[:] if cc: rcpts.extend(cc) msg['Cc'] = COMMASPACE.join(cc) if attachs: msg.attach(MIMEText(body)) for attach_name, mimetype, f in attachs: part = MIMEBase(*mimetype.split('/')) part.set_payload(f.read()) Encoders.encode_base64(part) part.add_header('Content-Disposition', 'attachment; filename="%s"' \ % attach_name) msg.attach(part) else: msg.set_payload(body) if _callback: _callback(to=to, subject=subject, body=body, cc=cc, attach=attachs, msg=msg) dfd = self._sendmail(rcpts, msg.as_string()) dfd.addCallbacks(self._sent_ok, self._sent_failed, callbackArgs=[to, cc, subject, len(attachs)], errbackArgs=[to, cc, subject, len(attachs)]) reactor.addSystemEventTrigger('before', 'shutdown', lambda: dfd) return dfd
def __mimeData(filename, msg): fp = open(filename, 'rb') data = MIMENonMultipart('application', 'pdf', name=os.path.basename(filename), charset='us-ascii') data.set_payload(base64.encodestring(fp.read())) data.add_header('Content-Transfer-Encoding', 'base64') fp.close() msg.attach(data) return data
def send(self, to, subject, body, cc=None, attachs=()): if attachs: msg = MIMEMultipart() else: msg = MIMENonMultipart('text', 'plain') msg['From'] = self.mailfrom msg['To'] = COMMASPACE.join(to) msg['Date'] = formatdate(localtime=True) msg['Subject'] = subject rcpts = to[:] if cc: rcpts.extend(cc) msg['Cc'] = COMMASPACE.join(cc) if attachs: msg.attach(MIMEText(body)) for attach_name, mimetype, f in attachs: part = MIMEBase(*mimetype.split('/')) part.set_payload(f.read()) Encoders.encode_base64(part) part.add_header('Content-Disposition', 'attachment; filename="%s"' \ % attach_name) msg.attach(part) else: msg.set_payload(body) if self.signals: self.signals.send_catch_log(signal=mail_sent, to=to, subject=subject, body=body, cc=cc, attach=attachs, msg=msg) if self.debug: log.msg( format= 'Debug mail sent OK: To=%(mailto)s Cc=%(mailcc)s Subject="%(mailsubject)s" Attachs=%(mailattachs)d', level=log.DEBUG, mailto=to, mailcc=cc, mailsubject=subject, mailattachs=len(attachs)) return dfd = self._sendmail(rcpts, msg.as_string()) dfd.addCallbacks(self._sent_ok, self._sent_failed, callbackArgs=[to, cc, subject, len(attachs)], errbackArgs=[to, cc, subject, len(attachs)]) reactor.addSystemEventTrigger('before', 'shutdown', lambda: dfd) return dfd
def send(self, to, subject, body, cc=None, attachs=(), mimetype='text/plain', charset=None, _callback=None): if attachs: msg = MIMEMultipart() else: msg = MIMENonMultipart(*mimetype.split('/', 1)) to = list(arg_to_iter(to)) cc = list(arg_to_iter(cc)) msg['From'] = self.mailfrom msg['To'] = COMMASPACE.join(to) msg['Date'] = formatdate(localtime=True) msg['Subject'] = subject rcpts = to[:] if cc: rcpts.extend(cc) msg['Cc'] = COMMASPACE.join(cc) if charset: msg.set_charset(charset) if attachs: msg.attach(MIMEText(body, 'plain', charset or 'us-ascii')) for attach_name, mimetype, f in attachs: part = MIMEBase(*mimetype.split('/')) part.set_payload(f.read()) Encoders.encode_base64(part) part.add_header('Content-Disposition', 'attachment; filename="%s"' \ % attach_name) msg.attach(part) else: msg.set_payload(body) if _callback: _callback(to=to, subject=subject, body=body, cc=cc, attach=attachs, msg=msg) if self.debug: logger.debug('Debug mail sent OK: To=%(mailto)s Cc=%(mailcc)s ' 'Subject="%(mailsubject)s" Attachs=%(mailattachs)d', {'mailto': to, 'mailcc': cc, 'mailsubject': subject, 'mailattachs': len(attachs)}) return dfd = self._sendmail(rcpts, msg.as_string().encode(charset or 'utf-8')) dfd.addCallbacks(self._sent_ok, self._sent_failed, callbackArgs=[to, cc, subject, len(attachs)], errbackArgs=[to, cc, subject, len(attachs)]) reactor.addSystemEventTrigger('before', 'shutdown', lambda: dfd) return dfd
def send_email(email_to, email_from, email_subject, email_body): msg = MIMENonMultipart('text', 'plain') msg['Content-Transfer-Encoding'] = '8bit' msg.set_payload(email_body, 'utf-8') msg['From'] = email_from msg['Subject'] = Header(email_subject, 'utf-8') server = smtplib.SMTP(config.smtp_host, config.smtp_port) server.ehlo() server.starttls() server.ehlo() server.login(email_from, config.email_password) for addr in email_to: msg['To'] = addr body = msg.as_string() server.sendmail(email_from, addr, body, '8bitmime') server.quit()
def addAttachment(self, attachment, filename, mimetype=None): "Do³¹cza do wiadomoœci wskazany plik." #Odgadnij g³ówny i dodatkowy typ MIME na podstawie nazwy pliku. if not mimetype: mimetype = mimetypes.guess_type(filename)[0] if not mimetype: raise Exception, "Nie uda³o siê okreœliæ typu MIME dla", filename if '/' in mimetype: major, minor = mimetype.split('/') else: major = mimetype minor = None #Wiadomoœæ by³a konstruowana z za³o¿eniem, i¿ bêdzie zawieraæ #tylko i wy³¹cznie tekst. Poniewa¿ wiem, ¿e bêdzie zawieraæ #co najmniej jeden za³¹cznik, musimy zmieniæ j¹ na wiadomoœæ #wieloczêœciow¹ i wkleiæ tekst jako pierwsz¹ czêœæ. if not self.hasAttachments: body = self.msg.get_payload() newMsg = MIMEMultipart() newMsg.attach(MIMEText(body, 'plain', self.enc)) #Skopiuj stare nag³ówki do nowego obiektu. for header, value in self.msg.items(): newMsg[header] = value self.msg = newMsg self.hasAttachments = True subMessage = MIMENonMultipart(major, minor, name=filename) subMessage.set_payload(attachment) #Zakoduj teksty jako quoted printable natomiast wszystkie #inne typy jako base64. if major == 'text': encoder = Encoders.encode_quopri else: encoder = Encoders.encode_base64 encoder(subMessage) #Powi¹¿ fragment MIME z g³ówn¹ wiadomoœci¹. self.msg.attach(subMessage)
def patch_to_attachment(self, patch, index): # patches don't come with an encoding. If the patch is valid utf-8, # we'll attach it as MIMEText; otherwise, it gets attached as a binary # file. This will suit the vast majority of cases, since utf8 is by # far the most common encoding. if type(patch[1]) != types.UnicodeType: try: unicode = patch[1].decode('utf8') except UnicodeDecodeError: unicode = None else: unicode = patch[1] if unicode: a = MIMEText(unicode.encode(ENCODING), _charset=ENCODING) else: # MIMEApplication is not present in Python-2.4 :( a = MIMENonMultipart('application', 'octet-stream') a.set_payload(patch[1]) a.add_header('Content-Disposition', "attachment", filename="source patch " + str(index) ) return a
def to_mail(self): message = MIMEMultipart('alternative') try: author = self.author except AttributeError: try: author = self.feed.author except AttributeError: try: author = self.feed.title except AttributeError: author = self.feed.name message['From'] = '%s <rsspull@localhost>' % author message['To'] = Feed.recipient message['Date'] = self.timestamp.strftime( '%a, %d %b %Y %H:%M:%S +0000') # XXX: msgid? message['Subject'] = ws.rsspull.util.header(self.title) message['X-RSS-Id'] = self.feed.name message['Content-Location'] = self.resolved_link body = self.body body = ws.rsspull.util.expandNumEntities(body) body = ws.rsspull.util.fixQuotes(body) body = ws.rsspull.util.html2text(body).strip() body += '\n\n' + 'Link: [ ' + self.resolved_link + ' ]\n' text_part = MIMEText(body.encode('utf-8'), 'plain', 'utf-8') html_part = MIMENonMultipart('text', 'html', charset='utf-8') html_body = self.body if sys.version_info < (3, ): html_body = html_body.encode('utf-8') html_part.set_payload(html_body) message.attach(text_part) message.attach(html_part) return message
def send(self, to, subject, body, cc=None, attachs=(), mimetype='text/plain', body_encode='utf8'): if attachs: msg = MIMEMultipart() else: msg = MIMENonMultipart(*mimetype.split('/', 1)) msg['From'] = self.mailfrom msg['To'] = COMMASPACE.join(to) msg['Date'] = formatdate(localtime=True) msg['Subject'] = subject rcpts = to[:] if cc: rcpts.extend(cc) msg['Cc'] = COMMASPACE.join(cc) if attachs: msg.attach(MIMEText(body, 'plain', body_encode)) for attach_name, mimetype, f in attachs: part = MIMEBase(*mimetype.split('/')) part.set_payload(f.read()) Encoders.encode_base64(part) part.add_header('Content-Disposition', 'attachment; filename="%s"' \ % attach_name) msg.attach(part) else: msg.set_payload(body) try: self._sendmail(rcpts, msg.as_string()) except smtplib.SMTPException, e: self._sent_failed(e, to, cc, subject, len(attachs)) return False
def odf2mht(self, odtfile): tmpfile = saveodtfile(odtfile) self.REQUEST.RESPONSE.setHeader('Content-Type', 'message/rfc822') msg = MIMEMultipart('related', type="text/html") msg.preamble = 'This is a multi-part message in MIME format.' msg.epilogue = '' result = odf2xhtml(tmpfile).encode('us-ascii', 'xmlcharrefreplace') htmlpart = MIMEText(result, 'html', 'us-ascii') htmlpart['Content-Location'] = 'index.html' msg.attach(htmlpart) z = zipfile.ZipFile(tmpfile) for file in z.namelist(): if file[0:9] == 'Pictures/': suffix = file[file.rfind(".") + 1:] main, sub = suffices.get(suffix, ('application', 'octet-stream')) img = MIMENonMultipart(main, sub) img.set_payload(z.read(file)) img['Content-Location'] = "" + file Encoders.encode_base64(img) msg.attach(img) z.close() unlink(tmpfile) return msg.as_string()
def sendEmail(mail, subj): fromaddr = "*****@*****.**" toaddr = [ "*****@*****.**", "*****@*****.**" ] #toaddr = ["*****@*****.**"] msg = MIMENonMultipart('text', 'plain') msg['Content-Transfer-Encoding'] = '8bit' msg.set_payload(mail.encode('utf8'), 'utf-8') msg['From'] = fromaddr msg['To'] = toaddr[0] msg['Subject'] = subj server = smtplib.SMTP('smtp.gmail.com', 587) server.ehlo() server.starttls() server.ehlo() server.login(settings.email, settings.emailpass) body = msg.as_string() server.sendmail(fromaddr, toaddr[0], body, '8bitmime') msg['To'] = toaddr[1] body = msg.as_string() server.sendmail(fromaddr, toaddr[1], body, '8bitmime') server.quit()
def apply_mtom(headers, envelope, params, paramvals): ''' Apply MTOM to a SOAP envelope, separating attachments into a MIME multipart message. References: XOP http://www.w3.org/TR/xop10/ MTOM http://www.w3.org/TR/soap12-mtom/ http://www.w3.org/Submission/soap11mtom10/ @param headers Headers dictionary of the SOAP message that would originally be sent. @param envelope SOAP envelope string that would have originally been sent. @param params params attribute from the Message object used for the SOAP @param paramvals values of the params, passed to Message.to_xml @return tuple of length 2 with dictionary of headers and string of body that can be sent with HTTPConnection ''' # grab the XML element of the message in the SOAP body soapmsg = StringIO(envelope) soaptree = ElementTree.parse(soapmsg) soapns = soaptree.getroot().tag.split('}')[0].strip('{') soapbody = soaptree.getroot().find("{%s}Body" % soapns) message = None for child in list(soapbody): if child.tag != "%sFault" % (soapns, ): message = child break # Get additional parameters from original Content-Type ctarray = [] for n, v in headers.items(): if n.lower() == 'content-type': ctarray = v.split(';') break roottype = ctarray[0].strip() rootparams = {} for ctparam in ctarray[1:]: n, v = ctparam.strip().split('=') rootparams[n] = v.strip("\"'") # Set up initial MIME parts mtompkg = MIMEMultipart('related', boundary='?//<><>soaplib_MIME_boundary<>') rootpkg = None try: rootpkg = MIMEApplication(envelope, 'xop+xml', encode_7or8bit) except NameError: rootpkg = MIMENonMultipart("application", "xop+xml") rootpkg.set_payload(envelope) encode_7or8bit(rootpkg) # Set up multipart headers. del (mtompkg['mime-version']) mtompkg.set_param('start-info', roottype) mtompkg.set_param('start', '<soaplibEnvelope>') if 'SOAPAction' in headers: mtompkg.add_header('SOAPAction', headers.get('SOAPAction')) # Set up root SOAP part headers. del (rootpkg['mime-version']) rootpkg.add_header('Content-ID', '<soaplibEnvelope>') for n, v in rootparams.items(): rootpkg.set_param(n, v) rootpkg.set_param('type', roottype) mtompkg.attach(rootpkg) # Extract attachments from SOAP envelope. for i in range(len(params)): name, typ = params[i] if typ == Attachment: id = "soaplibAttachment_%s" % (len(mtompkg.get_payload()), ) param = message[i] param.text = "" incl = create_xml_subelement( param, "{http://www.w3.org/2004/08/xop/include}Include") incl.attrib["href"] = "cid:%s" % id if paramvals[i].fileName and not paramvals[i].data: paramvals[i].load_from_file() data = paramvals[i].data attachment = None try: attachment = MIMEApplication(data, _encoder=encode_7or8bit) except NameError: attachment = MIMENonMultipart("application", "octet-stream") attachment.set_payload(data) encode_7or8bit(attachment) del (attachment['mime-version']) attachment.add_header('Content-ID', '<%s>' % (id, )) mtompkg.attach(attachment) # Update SOAP envelope. soapmsg.close() soapmsg = StringIO() soaptree.write(soapmsg) rootpkg.set_payload(soapmsg.getvalue()) soapmsg.close() # extract body string from MIMEMultipart message bound = '--%s' % (mtompkg.get_boundary(), ) marray = mtompkg.as_string().split(bound) mtombody = bound mtombody += bound.join(marray[1:]) # set Content-Length mtompkg.add_header("Content-Length", str(len(mtombody))) # extract dictionary of headers from MIMEMultipart message mtomheaders = {} for name, value in mtompkg.items(): mtomheaders[name] = value if len(mtompkg.get_payload()) <= 1: return (headers, envelope) return (mtomheaders, mtombody)
def add_a_post(groupId, siteId, replyToId, topic, message, tags, email, uploadedFiles, context, request): result = {'error': False, 'message': "Message posted.", 'id': ''} site_root = context.site_root() assert site_root userInfo = createObject('groupserver.LoggedInUser', context) siteObj = getattr(site_root.Content, siteId) groupObj = getattr(siteObj.groups, groupId) messages = getattr(groupObj, 'messages') assert messages listManager = messages.get_xwfMailingListManager() assert listManager groupList = getattr(listManager, groupObj.getId()) assert groupList #audit = WebPostAuditor(groupObj) #audit.info(POST, topic) # Step 1, check if the user can post userPostingInfo = getMultiAdapter((groupObj, userInfo), IGSPostingUser) if not userPostingInfo.canPost: raise 'Forbidden', userPostingInfo.status # --=mpj17-- Bless WebKit. It adds a file, even when no file has # been specified; if the files are empty, do not add the files. uploadedFiles = [f for f in uploadedFiles if f] # Step 2, Create the message # Step 2.1 Body message = message.encode('utf-8') if uploadedFiles: msg = MIMEMultipart() msgBody = MIMEText(message, 'plain', 'utf-8') # As God intended. msg.attach(msgBody) else: msg = MIMEText(message, 'plain', 'utf-8') # Step 2.2 Headers # msg['To'] set below # TODO: Add the user's name. The Header class will be needed # to ensure it is escaped properly. msg['From'] = unicode(Addressee(userInfo, email)).encode('ascii', 'ignore') msg['Subject'] = topic # --=mpj17=-- This does not need encoding. tagsList = tagProcess(tags) tagsString = ', '.join(tagsList) if tagsString: msg['Keywords'] = tagsString if replyToId: msg['In-Reply-To'] = replyToId # msg['Reply-To'] set by the list # Step 2.3 Attachments for f in uploadedFiles: # --=mpj17=-- zope.formlib has already read the data, so we # seek to the beginning to read it all again :) f.seek(0) data = f.read() if data: t = f.headers.getheader('Content-Type', 'application/octet-stream') mimePart = MIMENonMultipart(*t.split('/')) mimePart.set_payload(data) mimePart['Content-Disposition'] = 'attachment' filename = removePathsFromFilenames(f.filename) mimePart.set_param('filename', filename, 'Content-Disposition') encode_base64(mimePart) # Solves a lot of problems. msg.attach(mimePart) # Step 3, check the moderation. # --=mpj17=-- This changes *how* we send the message to the # mailing list. No, really. via_mailserver = False moderatedlist = groupList.get_moderatedUserObjects(ids_only=True) moderated = groupList.getValueFor('moderated') # --=rrw=--if we are moderated _and_ we have a moderatedlist, only # users in the moderated list are moderated if moderated and moderatedlist and (userInfo.id in moderatedlist): log.warn('User "%s" posted from web while moderated' % userInfo.id) via_mailserver = True # --=rrw=-- otherwise if we are moderated, everyone is moderated elif moderated and not (moderatedlist): log.warn('User "%s" posted from web while moderated' % userInfo.id) via_mailserver = True errorM = 'The post was not added to the topic '\ '<code class="topic">%s</code> because a post with the same '\ 'body already exists in the topic.' % topic # Step 4, send the message. for list_id in messages.getProperty('xwf_mailing_list_ids', []): curr_list = listManager.get_list(list_id) msg['To'] = curr_list.getValueFor('mailto') if via_mailserver: # If the message is being moderated, we have to emulate # a post via email so it can go through the moderation # subsystem. mailto = curr_list.getValueFor('mailto') try: send_email(email, mailto, msg.as_string()) except BadRequest as e: result['error'] = True result['message'] = errorM log.error(e.encode('ascii', 'ignore')) break result['error'] = True result['message'] = 'Your message has been sent to the '\ 'moderators for approval.' break else: # Send the message directly to the mailing list because # it is not moderated try: request = {'Mail': msg.as_string()} r = groupList.manage_listboxer(request) result['message'] = \ '<a href="/r/topic/%s#post-%s">Message '\ 'posted.</a>' % (r, r) except BadRequest as e: result['error'] = True result['message'] = errorM log.error(e) break except DuplicateMessageError as e: result['error'] = True result['message'] = errorM break if (not r): # --=mpj17=-- This could be lies. result['error'] = True result['message'] = errorM break return result