def __init__(self, _text, _subtype='plain', _charset='us-ascii', _encoder=None): """Create a text/* type MIME document. _text is the string for this message object. _subtype is the MIME sub content type, defaulting to "plain". _charset is the character set parameter added to the Content-Type header. This defaults to "us-ascii". Note that as a side-effect, the Content-Transfer-Encoding header will also be set. The use of the _encoder is deprecated. The encoding of the payload, and the setting of the character set parameter now happens implicitly based on the _charset argument. If _encoder is supplied, then a DeprecationWarning is used, and the _encoder functionality may override any header settings indicated by _charset. This is probably not what you want. """ MIMENonMultipart.__init__(self, 'text', _subtype, **{'charset': _charset}) self.set_payload(_text, _charset) if _encoder is not None: warnings.warn('_encoder argument is obsolete.', DeprecationWarning, 2) # Because set_payload() with a _charset will set its own # Content-Transfer-Encoding header, we need to delete the # existing one or will end up with two of them. :( del self['content-transfer-encoding'] _encoder(self)
def __init__(self, _audiodata, _subtype=None, _encoder=Encoders.encode_base64, **_params): """Create an audio/* type MIME document. _audiodata is a string containing the raw audio data. If this data can be decoded by the standard Python `sndhdr' module, then the subtype will be automatically included in the Content-Type header. Otherwise, you can specify the specific audio subtype via the _subtype parameter. If _subtype is not given, and no subtype can be guessed, a TypeError is raised. _encoder is a function which will perform the actual encoding for transport of the image data. It takes one argument, which is this Image instance. It should use get_payload() and set_payload() to change the payload to the encoded form. It should also add any Content-Transfer-Encoding or other headers to the message as necessary. The default encoding is Base64. Any additional keyword arguments are passed to the base class constructor, which turns them into parameters on the Content-Type header. """ if _subtype is None: _subtype = _whatsnd(_audiodata) if _subtype is None: raise TypeError('Could not find audio MIME subtype') MIMENonMultipart.__init__(self, 'audio', _subtype, **_params) self.set_payload(_audiodata) _encoder(self)
def __init__(self, _imagedata, _subtype=None, _encoder=Encoders.encode_base64, **_params): """Create an image/* type MIME document. _imagedata is a string containing the raw image data. If this data can be decoded by the standard Python `imghdr' module, then the subtype will be automatically included in the Content-Type header. Otherwise, you can specify the specific image subtype via the _subtype parameter. _encoder is a function which will perform the actual encoding for transport of the image data. It takes one argument, which is this Image instance. It should use get_payload() and set_payload() to change the payload to the encoded form. It should also add any Content-Transfer-Encoding or other headers to the message as necessary. The default encoding is Base64. Any additional keyword arguments are passed to the base class constructor, which turns them into parameters on the Content-Type header. """ if _subtype is None: _subtype = imghdr.what(None, _imagedata) if _subtype is None: raise TypeError, 'Could not guess image MIME subtype' MIMENonMultipart.__init__(self, 'image', _subtype, **_params) self.set_payload(_imagedata) _encoder(self)
def __init__(self, _text, _subtype="plain", _charset="us-ascii", _encoder=None): """Create a text/* type MIME document. _text is the string for this message object. _subtype is the MIME sub content type, defaulting to "plain". _charset is the character set parameter added to the Content-Type header. This defaults to "us-ascii". Note that as a side-effect, the Content-Transfer-Encoding header will also be set. The use of the _encoder is deprecated. The encoding of the payload, and the setting of the character set parameter now happens implicitly based on the _charset argument. If _encoder is supplied, then a DeprecationWarning is used, and the _encoder functionality may override any header settings indicated by _charset. This is probably not what you want. """ MIMENonMultipart.__init__(self, "text", _subtype, **{"charset": _charset}) self.set_payload(_text, _charset) if _encoder is not None: warnings.warn("_encoder argument is obsolete.", DeprecationWarning, 2) # Because set_payload() with a _charset will set its own # Content-Transfer-Encoding header, we need to delete the # existing one or will end up with two of them. :( del self["content-transfer-encoding"] _encoder(self)
def __init__(self, _text, _subtype='plain', _charset='us-ascii'): """Create a text/* type MIME document. _text is the string for this message object. _subtype is the MIME sub content type, defaulting to "plain". _charset is the character set parameter added to the Content-Type header. This defaults to "us-ascii". Note that as a side-effect, the Content-Transfer-Encoding header will also be set. """ MIMENonMultipart.__init__(self, 'text', _subtype, **{'charset': _charset}) self.set_payload(_text, _charset)
def sendNonMultipartMail(context, sender, receiver, cc=[], bcc=[], subject="", text="", charset="utf-8"): """ """ mail = MIMENonMultipart("text", "plain") mail['From'] = sender mail['To'] = receiver mail['Cc'] = ", ".join(cc) mail['Bcc'] = ", ".join(bcc) mail['Subject'] = subject text = text.encode("utf-8") mail.set_payload(text) context.MailHost.send(mail.as_string())
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 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 __init__(self, _data, _maintype='text', _subtype='plain', _charset='utf-8', **_params): if _maintype is None: raise TypeError('Invalid application MIME maintype') if _subtype is None: raise TypeError('Invalid application MIME subtype') MIMENonMultipart.__init__(self, _maintype, _subtype, **_params) # Base64 encoded data must first comply with RFC 822 # CRLF requirement. So make sure CRLF newlines are present # before encoding the data _data = addCarriageReturn(_data) self.set_payload(_data, _charset)
def __init__(self, _msg, _subtype='rfc822'): """Create a message/* type MIME document. _msg is a message object and must be an instance of Message, or a derived class of Message, otherwise a TypeError is raised. Optional _subtype defines the subtype of the contained message. The default is "rfc822" (this is defined by the MIME standard, even though the term "rfc822" is technically outdated by RFC 2822). """ MIMENonMultipart.__init__(self, 'message', _subtype) if not isinstance(_msg, Message.Message): raise TypeError, 'Argument is not an instance of Message' # It's convenient to use this base class method. We need to do it # this way or we'll get an exception Message.Message.attach(self, _msg) # And be sure our default type is set correctly self.set_default_type('message/rfc822')
def __init__(self, _data, _subtype=None, _encoder=Encoders.encode_base64, **_params): """Create an audio/* type MIME document. _data is a string containing the raw applicatoin data. _encoder is a function which will perform the actual encoding for transport of the application data. Any additional keyword arguments are passed to the base class constructor, which turns them into parameters on the Content-Type header. """ if _subtype is None: raise TypeError, 'Could not find application MIME subtype' MIMENonMultipart.__init__(self, 'application', _subtype, **_params) self.set_payload(_data) _encoder(self)
def generate(self, fp): msg = MIMEMultipart(_subtype='related') msg['Subject'] = 'archived' msg.epilogue = '' # Guarantees the message ends in a newline for res in self.resource_list: if '/' in res.ctype_actual: maintype, subtype = res.ctype_actual.split('/',1) else: maintype, subtype = res.ctype_actual, '' part = MIMENonMultipart(maintype, subtype) part.set_payload(res.data) part['content-location'] = res.uri Encoders.encode_base64(part) msg.attach(part) # generate the MIME message Generator(fp, False).flatten(msg)
def addAttachment(self, path): filename = os.path.split(path)[-1] ext = os.path.splitext(filename)[-1] subtype = mime_types.get(ext, "octet-stream") msgAttachment = MIMENonMultipart("application", subtype, name=filename) fp = open(path, 'rb') msgAttachment.set_payload(fp.read()) fp.close() Encoders.encode_base64(msgAttachment) id = "attach_%s" % self.next self.next += 1 msgAttachment.add_header('Content-ID', id) self.root.attach(msgAttachment)
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 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 getAttachments(self): attachments = [] # attach files for data, content_type, filename, disposition in \ self.context.getAttachments(): maintype, subtype = content_type.split('/') msg = MIMENonMultipart(maintype, subtype) msg.set_payload(data) if filename: msg['Content-Id'] = '<%s@z3ext>' % filename msg['Content-Disposition'] = '%s; filename="%s"' % ( disposition, filename) Encoders.encode_base64(msg) attachments.append(msg) return attachments
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 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 __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 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 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 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 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 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 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
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
def __init__(self, _text, _subtype='plain'): MIMENonMultipart.__init__(self, 'text', _subtype, charset='utf-8') self.set_payload(_text, UTF8)
title=detail[0] category=detail[1] author_name=detail[2] author_email=detail[3] coauthor_name=detail[4] coauthor_email=detail[5] ref_no=detail[6] msg=MIMEMultipart() msg['From']=formataddr((str(Header('Paper Presentation Team, BITS Pilani', 'utf-8')), '*****@*****.**')) msg['To']=author_email msg['Subject']='Paper Presentation, APOGEE 2016' msg.attach(MIMEText(body %(author_name.encode('ascii'),title.encode('ascii'),category.encode('ascii')), 'html')) #attach PDF fp=open((ref_no+'.pdf').decode('ascii'),'rb') attach = MIMENonMultipart('application', 'pdf') payload = base64.b64encode(fp.read()).decode('ascii') attach.set_payload(payload) attach['Content-Transfer-Encoding'] = 'base64' fp.close() attach.add_header('Content-Disposition', 'attachment', filename = ref_no+'_report.pdf') msg.attach(attach) toadr=author_email try: server.sendmail(fromadr,toadr,msg.as_string()) time.sleep(30) print "Mail sent to "+toadr except smtplib.SMTPRecipientsRefused: print "Mail not sent to "+toadr
def __init__(self, _data, _subtype, _encoder, **params): MIMENonMultipart.__init__(self, 'application', _subtype, **params) self.set_payload(_data) _encoder(self)
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)