def test_html_email_with_images(self): msg = MIMEMultipart( _subparts=[ MIMEMultipart( 'alternative', _subparts=[ MIMEText('This is a test message'), MIMEText('This is a <em>test</em> message', 'html') ]) ]) with open(pkg_resources.resource_filename( 'forgediscussion', 'tests/data/python-logo.png'), 'rb') as fp: img = MIMEImage(fp.read()) img.add_header('Content-Disposition', 'attachment', filename='python-logo.png') msg.attach(img) self._post_email( self.email_address, [self.forum.email_address], 'Test Simple Thread', msg) r = self.app.get('/p/test/discussion/testforum/') assert 'Test Simple Thread' in str(r) assert len(r.html.findAll('tr')) == 2 href = r.html.findAll('tr')[1].find('a')['href'] r = self.app.get(href) assert 'alternate' in str(r) assert 'python-logo.png' in str(r)
def test_unicode_complex_message(self): charset = 'utf-8' p1 = MIMEText( '''По оживлённым берегам Громады стройные теснятся Дворцов и башен; корабли Толпой со всех концов земли К богатым пристаням стремятся;'''.encode(charset), 'plain', charset) p2 = MIMEText( '''<p>По оживлённым берегам Громады стройные теснятся Дворцов и башен; корабли Толпой со всех концов земли К богатым пристаням стремятся;</p>'''.encode(charset), 'plain', charset) msg1 = MIMEMultipart() msg1['Message-ID'] = '<*****@*****.**>' msg1.attach(p1) msg1.attach(p2) s_msg = msg1.as_string() msg2 = parse_message(s_msg) for part in msg2['parts']: if part['payload'] is None: continue assert isinstance(part['payload'], six.text_type), type(part['payload'])
def test_send_raw_email_without_source(): conn = boto3.client("ses", region_name="us-east-1") message = MIMEMultipart() message["Subject"] = "Test" message["From"] = "*****@*****.**" message["To"] = "[email protected], [email protected]" # Message body part = MIMEText("test file attached") message.attach(part) # Attachment part = MIMEText("contents of test file here") part.add_header("Content-Disposition", "attachment; filename=test.txt") message.attach(part) kwargs = dict(RawMessage={"Data": message.as_string()}) conn.send_raw_email.when.called_with(**kwargs).should.throw(ClientError) conn.verify_email_identity(EmailAddress="*****@*****.**") conn.send_raw_email(**kwargs) send_quota = conn.get_send_quota() sent_count = int(send_quota["SentLast24Hours"]) sent_count.should.equal(2)
def test_send_raw_email_without_source(): conn = boto3.client('ses', region_name='us-east-1') message = MIMEMultipart() message['Subject'] = 'Test' message['From'] = '*****@*****.**' message['To'] = '[email protected], [email protected]' # Message body part = MIMEText('test file attached') message.attach(part) # Attachment part = MIMEText('contents of test file here') part.add_header('Content-Disposition', 'attachment; filename=test.txt') message.attach(part) kwargs = dict(RawMessage={'Data': message.as_string()}, ) conn.send_raw_email.when.called_with(**kwargs).should.throw(ClientError) conn.verify_email_identity(EmailAddress="*****@*****.**") conn.send_raw_email(**kwargs) send_quota = conn.get_send_quota() sent_count = int(send_quota['SentLast24Hours']) sent_count.should.equal(2)
def encode_email_part(content, content_type): try: # simplest email - plain ascii encoded_content = content.encode('ascii') encoding = 'ascii' except Exception: # utf8 will get base64 encoded so we only do it if ascii fails encoded_content = content.encode('utf-8') encoding = 'utf-8' for line in encoded_content.splitlines(): if len(line) > MAX_MAIL_LINE_OCTETS: # switch to Quoted-Printable encoding to avoid too-long lines # we could always Quoted-Printabl, but it makes the output a little messier and less human-readable # the particular order of all these operations seems to be very important for everything to end up right msg = MIMEText(None, content_type) msg.replace_header('content-transfer-encoding', 'quoted-printable') cs = email.charset.Charset('utf-8') cs.header_encoding = email.charset.QP cs.body_encoding = email.charset.QP payload = cs.body_encode(content.encode('utf-8')) msg.set_payload(payload, 'utf-8') return msg else: return MIMEText(encoded_content, content_type, encoding)
def send(self, recipients, subject, text_body, html_body=None, sender=None, **kwargs): # type: (List[str], str, str, Optional[str], Optional[str], Any) -> None """ Send email Args: recipients (List[str]): Email recipient subject (str): Email subject text_body (str): Plain text email body html_body (Optional[str]): HTML email body sender (Optional[str]): Email sender. Defaults to global sender. **kwargs: See below mail_options (list): Mail options (see smtplib documentation) rcpt_options (list): Recipient options (see smtplib documentation) Returns: None """ if sender is None: sender = self.sender v = validate_email(sender, check_deliverability=False) # validate and get info sender = v['email'] # replace with normalized form normalised_recipients = list() for recipient in recipients: v = validate_email( recipient, check_deliverability=True) # validate and get info normalised_recipients.append( v['email']) # replace with normalized form if html_body is not None: msg = MIMEMultipart('alternative') part1 = MIMEText(text_body, 'plain') part2 = MIMEText(html_body, 'html') msg.attach(part1) msg.attach(part2) else: msg = MIMEText(text_body) msg['Subject'] = subject msg['From'] = sender msg['To'] = ', '.join(normalised_recipients) # Perform operations via server self.connect() self.server.sendmail(sender, normalised_recipients, msg.as_string(), **kwargs) self.close()
def get_raw_email(): message = MIMEMultipart() message["Subject"] = "Test" message["From"] = "*****@*****.**" message["To"] = "[email protected], [email protected]" # Message body part = MIMEText("test file attached") message.attach(part) # Attachment part = MIMEText("contents of test file here") part.add_header("Content-Disposition", "attachment; filename=test.txt") message.attach(part) return message
def test_html_email(self): msg = MIMEMultipart('alternative', _subparts=[ MIMEText('This is a test message'), MIMEText('This is a <em>test</em> message', 'html') ]) self._post_email(self.email_address, [self.forum.email_address], 'Test Simple Thread', msg) r = self.app.get('/p/test/discussion/testforum/') assert 'Test Simple Thread' in str(r), r assert len(r.html.findAll('tr')) == 2 href = r.html.findAll('tr')[1].find('a')['href'] r = self.app.get(href) assert 'alternate' in str(r)
def AttacheFichiersJoints(self, email=None): for fichier in self.fichiers: """Guess the content type based on the file's extension. Encoding will be ignored, altough we should check for simple things like gzip'd or compressed files.""" ctype, encoding = mimetypes.guess_type(fichier) if ctype is None or encoding is not None: # No guess could be made, or the file is encoded (compresses), so # use a generic bag-of-bits type. ctype = 'application/octet-stream' maintype, subtype = ctype.split('/', 1) if maintype == 'text': fp = open(fichier) # Note : we should handle calculating the charset part = MIMEText(fp.read(), _subtype=subtype) fp.close() elif maintype == 'image': fp = open(fichier, 'rb') part = MIMEImage(fp.read(), _subtype=subtype) fp.close() else: fp = open(fichier, 'rb') part = MIMEBase(maintype, subtype) part.set_payload(fp.read()) fp.close() # Encode the payload using Base64 encoders.encode_base64(part) # Set the filename parameter nomFichier = os.path.basename(fichier) if type(nomFichier) == six.text_type: nomFichier = FonctionsPerso.Supprime_accent(nomFichier) # changement cosmetique pour ajouter les guillements autour du filename part.add_header('Content-Disposition', "attachment; filename=\"%s\"" % nomFichier) email.attach(part)
def test_send_raw_email_without_source_or_from(): conn = boto3.client('ses', region_name='us-east-1') message = MIMEMultipart() message['Subject'] = 'Test' message['To'] = '[email protected], [email protected]' # Message body part = MIMEText('test file attached') message.attach(part) # Attachment part = MIMEText('contents of test file here') part.add_header('Content-Disposition', 'attachment; filename=test.txt') message.attach(part) kwargs = dict(RawMessage={'Data': message.as_string()}, ) conn.send_raw_email.when.called_with(**kwargs).should.throw(ClientError)
def test_simple_email(self): msg = MIMEText('This is a test message') self._post_email( self.email_address, [self.forum.email_address], 'Test Simple Thread', msg) r = self.app.get('/p/test/discussion/testforum/') assert 'Test Simple Thread' in str(r)
def test_send_raw_email_without_source_or_from(): conn = boto3.client("ses", region_name="us-east-1") message = MIMEMultipart() message["Subject"] = "Test" message["To"] = "[email protected], [email protected]" # Message body part = MIMEText("test file attached") message.attach(part) # Attachment part = MIMEText("contents of test file here") part.add_header("Content-Disposition", "attachment; filename=test.txt") message.attach(part) kwargs = dict(RawMessage={"Data": message.as_string()}) conn.send_raw_email.when.called_with(**kwargs).should.throw(ClientError)
def _build_msg(self, stash_name, reason): msg = MIMEMultipart() msg['From'] = self._from msg['To'] = self._to msg['Subject'] = '%s %s' % (self._subject_prefix, stash_name) msg_text = self._mail_tpl.render(stash_name=stash_name, reason=reason, uchiwa_url=self._uchiwa_url) msg.attach(MIMEText(msg_text, _charset='utf-8')) return msg
def send_error_mail(from_, subject, text, html=None): """Sends an email to JuliaBase's administrators. Normally, it is about an error condition but it may be anything. :param from_: name (and only the name, not an email address) of the sender; this typically is the name of the currently running program :param subject: the subject of the message :param text: text body of the message :param html: optional HTML attachment :type from_: unicode :type subject: unicode :type text: unicode :type html: unicode """ cycles = 5 while cycles: try: server = smtplib.SMTP(settings.SMTP_SERVER) if settings.SMTP_LOGIN: server.starttls() server.login(settings.SMTP_LOGIN, settings.SMTP_PASSWORD) message = MIMEMultipart() message["Subject"] = subject message["From"] = '"{0}" <{1}>'. \ format(from_.replace('"', ""), settings.EMAIL_FROM).encode("ascii", "replace") message["To"] = settings.EMAIL_TO message["Date"] = email.utils.formatdate() message.attach(MIMEText(text.encode("utf-8"), _charset="utf-8")) if html: message.attach( MIMEText(html.encode("utf-8"), "html", _charset="utf-8")) server.sendmail(settings.EMAIL_FROM, message["To"], message.as_string()) server.quit() except smtplib.SMTPException: pass else: break cycles -= 1 time.sleep(10)
def send(self, sendto='', subject='', attach='', body=' '): print('Sending email') msg = MIMEMultipart() msg["From"] = self.mailfrom msg["To"] = sendto msg["Subject"] = subject msg['Date'] = formatdate(localtime=True) #add messagw self._print('Attaching msg: %s' % body) message = MIMEText('text', "plain") message.set_payload(body + '\n') msg.attach(message) # attach a file if attach: self._print('Attachment found: %s' % attach) part = MIMEBase('application', "octet-stream") part.set_payload(open(attach, "rb").read()) Encoders.encode_base64(part) part.add_header('Content-Disposition', 'attachment; filename="%s"' % attach) msg.attach(part) self._print('Creating SMTP') server = smtplib.SMTP(self.host, int(self.port)) if self.tls == 'True' or self.tls == 'true': server.starttls() self._print('tls started.') if self.auth == 'True' or self.auth == 'true': try: self._print('Logging into to SMTP: %s %s' % (self.user, self.passwd)) server.login(self.user, self.passwd) # optional except Exception as e: print('Failed Login %s' % e) sys.exit(0) else: try: self._print('Connecting to SMTP') server.connect() except Exception as e: print('Failed to connect %s' % e) sys.exit(0) try: self._print('Sending mail to: %s' % sendto) server.sendmail(self.mailfrom, sendto, msg.as_string()) print('mail sent.') server.close() except Exception as e: errorMsg = "Unable to send email. Error: %s" % str(e)
def Envoyer(self, message=None): # Création du message email = MIMEMultipart('alternative') # msg['Message-ID'] = make_msgid() # if accuseReception == True: # msg['Disposition-Notification-To'] = adresseExpediteur email.attach( MIMEText(message.texte_plain.encode('utf-8'), 'plain', 'utf-8')) email.attach( MIMEText(message.texte_html.encode('utf-8'), 'html', 'utf-8')) tmpmsg = email email = MIMEMultipart('mixed') email.attach(tmpmsg) # Ajout des headers à ce Multipart if self.nom_exp in ("", None): email['From'] = self.email_exp else: sender = Header(self.nom_exp, "utf-8") sender.append(self.email_exp, "ascii") email[ 'From'] = sender # formataddr((nomadresseExpediteur, adresseExpediteur)) email['To'] = ";".join(message.destinataires) email['Date'] = formatdate(localtime=True) email['Subject'] = message.sujet message.AttacheImagesIncluses(email) message.AttacheFichiersJoints(email) try: self.connection.sendmail(self.email_exp, message.destinataires, email.as_string()) except smtplib.SMTPException: if not self.fail_silently: raise return False return True
def test_unicode_simple_message(self): charset = 'utf-8' msg1 = MIMEText( '''По оживлённым берегам Громады стройные теснятся Дворцов и башен; корабли Толпой со всех концов земли К богатым пристаням стремятся;'''.encode(charset), 'plain', charset) msg1['Message-ID'] = '<*****@*****.**>' s_msg = msg1.as_string() msg2 = parse_message(s_msg) assert isinstance(msg2['payload'], six.text_type) assert_in('всех', msg2['payload'])
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 create_message(recipient, image, size, sender, reply_to): msg = MIMEMultipart('related') msg['from'] = Header(sender, 'utf-8') msg['to'] = Header(recipient, 'utf-8') msg['subject'] = Header(EMAIL_SUBJECT, 'utf-8') if reply_to: msg['reply-to'] = Header(reply_to, 'utf-8') template = EMAIL_TEMPLATE template = template.replace('${width}', str(size[0])) template = template.replace('${height}', str(size[1])) text = MIMEText(template, 'html', 'utf-8') msg.attach(text) with open(image, 'rb') as fp: img = MIMEImage(fp.read()) img.add_header('Content-ID', 'image') img.add_header('Content-Disposition', 'inline', filename=basename(image)) msg.attach(img) return msg
def sendMail(to, subject, text, files=[], server="mail1.psfc.mit.edu", ssl=False, ssl_port=465, ssl_username='', ssl_passwd=''): assert type(to) == list assert type(files) == list # me = '*****@*****.**' me = ssl_username # '*****@*****.**' msg = MIMEMultipart() msg['From'] = me # msg['To'] = COMMASPACE.join(['*****@*****.**']) msg['To'] = COMMASPACE.join(to) msg['Date'] = formatdate(localtime=True) msg['Subject'] = subject msg.attach(MIMEText(text)) for file in files: part = MIMEBase('application', "octet-stream") part.set_payload(open(file, "rb").read()) Encoders.encode_base64(part) part.add_header('Content-Disposition', 'attachment; filename="%s"' % os.path.basename(file)) msg.attach(part) if ssl: print((server, ssl_port)) smtp = smtplib.SMTP_SSL(server, ssl_port) smtp.login(ssl_username, ssl_passwd) else: smtp = smtplib.SMTP(server) smtp.sendmail(me, to, msg.as_string()) smtp.close()
def encrypt_message(self, message, recipients, signer=None, **kwargs): """Get an encrypted MIME message from the passed message or str. This function returns a fully encrypted MIME message including a control message and the encrypted payload message. Parameters ---------- message : MIMEBase or str Message to encrypt. recipients : list of key ids List of key ids to encrypt to. signer : str Key id to sign the message with. **kwargs Any additional parameters to the GPG backend. """ if isinstance(message, six.string_types): message = MIMEText(message) msg = self.get_octet_stream(message, recipients, signer, **kwargs) return self.get_encrypted_message(msg)
def sign_message(self, message, signer, add_cr=True): """ message : MIMEBase or str Message to encrypt. recipients : list of key ids List of key ids to encrypt to. signer : str Key id to sign the message with. add_cr : bool, optional Wether or not to replace newlines (``\\n``) with carriage-return/newlines (``\\r\\n``). E-Mail messages generally use ``\\r\\n``, so the default is True. """ if isinstance(message, six.string_types): message = MIMEText(message) del message['MIME-Version'] data = message.as_bytes() if add_cr is True: data = data.replace(b'\n', b'\r\n') # get the gpg signature signature = self.sign(data, signer) signature_msg = self.get_mime_signature(signature) return self.get_signed_message(message, signature_msg)
def send_mail(to_addr, subj_msg, body_msg, attach_path, serv_addr, serv_port, from_addr, passwd): """Send an e-mail message using smtplib and email standard python libraries. IMPORTANT! Password is stored as plain text! Do NOT use with your personal account! Args: to_addr (str): Recipient address. subj_msg (str): Message subject. body_msg (str): Message body. serv_addr (str): Server's address. Default: <smtp.gmail.com>. serv_port (int): Server's port. Default: <587>. from_addr (str): Account address. Default: <*****@*****.**>. passwd (str): Account password. """ msg = MIMEMultipart() if attach_path is not None: with open(attach_path, "rb") as fin: part = MIMEBase("application", "octet-stream") part.set_payload(fin.read()) encoders.encode_base64(part) part.add_header("Content-Disposition", "attachment; filename={0}".format(attach_path)) msg.attach(part) else: pass msg["From"] = from_addr msg["To"] = to_addr msg["Subject"] = subj_msg msg.attach(MIMEText(body_msg, "plain")) server = smtplib.SMTP(serv_addr, serv_port) server.starttls() server.login(from_addr, passwd) text_msg = msg.as_string() server.sendmail(from_addr, to_addr, text_msg) server.quit
def send(self, recipients, subject, body, sender=None, **kwargs): # type: (str, str, str, Optional[str], ...) -> None """ Send email Args: recipient (str): Email recipient subject (str): Email subject body (str): Email body sender (Optional[str]): Email sender. Defaults to SMTP username. **kwargs: See below mail_options (list): Mail options (see smtplib documentation) rcpt_options (list): Recipient options (see smtplib documentation) Returns: None """ if sender is None: sender = self.username v = validate_email(sender, check_deliverability=False) # validate and get info sender = v['email'] # replace with normalized form normalised_recipients = list() for recipient in recipients: v = validate_email(recipient, check_deliverability=True) # validate and get info normalised_recipients.append(v['email']) # replace with normalized form msg = MIMEText(body) msg['Subject'] = subject msg['From'] = sender msg['To'] = ', '.join(normalised_recipients) # Perform operations via server self.connect() self.server.sendmail(sender, normalised_recipients, msg.as_string(), **kwargs) self.close()
def send_email(xfrom, to, subject, body, cc=None, bcc=None, attachments=None, host=None): if not has_len(host): host = 'localhost' outer = MIMEMultipart() if has_len(xfrom): outer['From'] = xfrom elif isinstance(xfrom, (list, tuple)) and len(xfrom) == 2: outer['From'] = "%s <%s>" % (Header(unidecoder(xfrom[0]), 'utf-8'), xfrom[1]) xfrom = xfrom[1] else: raise ValueError("Invalid e-mail sender. (from: %r)" % xfrom) outer['Date'] = formatdate(localtime=True) smtp = smtplib.SMTP(host) if has_len(to): to = [to] if isinstance(to, (list, tuple)): to = list(to) outer['To'] = COMMASPACE.join(list(to)) else: raise ValueError("Invalid e-mail recipients. (to: %r)" % to) if has_len(cc): cc = [cc] if isinstance(cc, (list, tuple)): to += list(cc) outer['Cc'] = COMMASPACE.join(list(cc)) if has_len(bcc): bcc = [bcc] if isinstance(bcc, (list, tuple)): to += list(bcc) if has_len(subject): outer['Subject'] = Header(unidecoder(subject), 'utf-8') if has_len(body): outer.attach(MIMEText(unidecoder(body), _charset='utf-8')) if has_len(attachments): attachments = [attachments] if attachments: if isinstance(attachments, (list, tuple)): attachments = dict( zip(attachments, len(attachments) * ('application/octet-stream', ))) for attachment in sorted(iterkeys(attachments)): fp = open(attachment, 'rb') part = MIMEBase('application', 'octet-stream') part.set_type(attachments[attachment]) filename = os.path.basename(attachment) part.set_payload(fp.read()) fp.close() encoders.encode_base64(part) part.add_header('Content-Disposition', 'attachment', filename=filename) outer.attach(part) smtp.sendmail(xfrom, to, outer.as_string()) smtp.quit()
def _process(self,kw): # sort out what encoding we're going to use encoding = kw.get('encoding', self.getProperty('encoding', default_encoding)) text = self.__class__.__bases__[1].__call__(self,**kw) # ZPT adds newline at the end, but it breaks backward compatibility. # So I remove it. if text.endswith('\n'): text = text[:-1] if not self.html() and isinstance(text, six.text_type): text = text.encode(encoding,'replace') # now turn the result into a MIMEText object msg = MIMEText( text.replace('\r',''), self.content_type.split('/')[1], encoding ) # sort out what headers and addresses we're going to use headers = {} values = {} # headers from the headers property for header in getattr(self,'headers',()): name,value = header.split(':',1) headers[name]=value # headers from the headers parameter headers_param = kw.get('headers',{}) headers.update(headers_param) # values and some specific headers for key,header in (('mfrom','From'), ('mto','To'), ('mcc','Cc'), ('mbcc','Bcc'), ('subject','Subject')): value = kw.get(key, headers_param.get(header, getattr(self, key, headers.get(header)))) if value is not None: values[key]=value if key == 'subject': try: # Try to keep header non encoded value = Header(value) except UnicodeDecodeError: value = Header(value, "UTF-8") else: dest_list = [] for name, email in getaddresses((value,) if isinstance(value, basestring) else value): try: name = Header(name) except UnicodeDecodeError: name = Header(name, "UTF-8") dest_list.append(formataddr((name.encode(), email))) value = ", ".join(dest_list) headers[header]=value # check required values have been supplied errors = [] for param in ('mfrom','mto'): if not values.get(param): errors.append(param) if errors: raise TypeError( 'The following parameters were required by not specified: '+( ', '.join(errors) )) # add date header headers['Date']=DateTime().rfc822() # do not let the MTA to generate the Message-ID: # we want to have it stored in ERP5, for mail threading headers['Message-ID'] = make_msgid() # turn headers into an ordered list for predictable header order keys = ensure_list(headers.keys()) keys.sort() return msg,values,[(key,headers[key]) for key in keys]