def cmd_bar(self, _chan, _args, sender_nick): "envoie un email aux grelakins" # vérification que l'invocateur soit un grelakins if hashlib.sha224(sender_nick).hexdigest() in self.liste_grelakins: # vérification que c'est la première invocation du messager if self.date_bar != str(time.strftime('%d/%m/%y', time.localtime())): heure = _args[0].decode('utf-8') lieu = ' '.join(_args[1:]).decode('utf-8') lieu = lieu.lower().strip().replace(" ", "") if re.match( r"(1[6-9]|2[0-4])+([hH]$|([hH]+" + "[0-5][0-9])|[:]+[0-5][0-9]+)", heure): # test de la compatibilité du format de l'heure # REGLE: on va au bar entre 16h et 24h59, # après c'est fermé, avant c'est être alcoolique for cle, valeur in self.liste_bar.items(): if lieu in valeur: # teste si le bar proposé est cool from_address = [ u"Honorable tofbot", os.getenv("TOFBOT_MAIL", "") ] pwd = "" recipient = [ u"Michels", os.getenv("TOFBOT_MAILINGLIST", "") ] subject = u"Bar ce soir" content = u"""Bonsoir les jeunes, Aujourd'hui, certains Michels vont au bar %s à %s. Rejoignez les! Tofbot, au service de %s """ % (cle, heure, sender_nick) content = content.encode('utf-8') Charset.add_charset('utf-8', Charset.QP, Charset.QP, 'utf-8') msg = MIMEMultipart('alternative') msg['Subject'] = "%s" % Header(subject, 'utf-8') msg['From'] = "\"%s\" <%s>" % (Header( from_address[0], 'utf-8'), from_address[1]) msg['To'] = "\"%s\" <%s>" % (Header( recipient[0], 'utf-8'), recipient[1]) txtpart = MIMEText(content, 'plain', 'UTF-8') msg.attach(txtpart) str_out = StringIO() g = Generator(str_out, False) g.flatten(msg) mail_server = "localhost" server = smtplib.SMTP(mail_server, 25) server.ehlo() server.sendmail(from_address[1], recipient[1], str_out.getvalue()) server.quit() # message de confirmation de l'envoi de l'email self.say(u"Michels avertis!") self.date_bar = str( time.strftime('%d/%m/%y', time.localtime())) return # avertissement bar non autorisé self.say(u"J'envoie pas ce mail, ce bar n'est pas cool!") else: # avertissement mauvaise heure if re.match(r"^(0[0-9]|1[0-5])", heure): # cas de l'heure trop matinale pour un Michel self.say(u"Beaucoup trop tôt, mec!") else: # cas d'un format horaire faux self.say(u"Euh... L'heure n'est pas claire.") else: self.say(u"Rameutage au bar déjà invoqué aujourd'hui") else: self.say(u"Seul un Grelakins autorisé peut envoyer un mail !bar")
def msg_as_string(msg): fp = StringIO() g = Generator(fp, mangle_from_=False, maxheaderlen=60) g.flatten(msg) return fp.getvalue()
email_from = email_obj['from'] email_subject = email_obj['subject'] email_obj.add_header('reply-to', email_to) # check email subject to see if we should continue if((not email_subject.startswith("Advising Signup") and not email_subject.startswith("Accepted: Advising Signup with") and not email_subject.startswith("Declined: Advising Signup with")) or "Pending" in email_subject ): sys.exit(1) # check if email is from the user's email address if so check if it is not accepted or declined # if this is the case then this is the email with the attachment added if "*****@*****.**" not in email_from and "*****@*****.**" not in email_from and "*****@*****.**" not in email_from: if email_subject.startswith("Accepted") or email_subject.startswith("Declined"): # print the final email adapted from http://stackoverflow.com/questions/389398/trouble-with-encoding-in-emails out_obj = StringIO() gen = Generator(out_obj) gen.flatten(email_obj) email_string = out_obj.getvalue() reg_exp = re.compile('base64\s*([^\-]*)') match = reg_exp.search(email_string) if match: base64_encoded_vevent = match.group(1) decoded_vevent = base64.b64decode(base64_encoded_vevent) reg_exp = re.compile('UID:([^\s]+)') match = reg_exp.search(decoded_vevent) if match: uid = match.group(1) else: sys.exit(12) else: sys.exit(11)
raw_msg = sys.stdin.read() msg = email.message_from_string(raw_msg) date = msg.get('Date', None) if date: from email.utils import mktime_tz, parsedate_tz, formatdate try: # Convert to local TZ tz_tuple = parsedate_tz(date) epoch_time = mktime_tz(tz_tuple) msg.add_header('Local-Date', formatdate(epoch_time, localtime=True)) #from cStringIO import StringIO try: from StringIO import StringIO except ImportError: from io import StringIO from email.generator import Generator fp = StringIO() g = Generator(fp, mangle_from_=False, maxheaderlen=200) g.flatten(msg) sys.stdout.write(fp.getvalue()) except: import traceback print(traceback.format_exc()) sys.stdout.write(raw_msg) else: # just write it out sys.stdout.write(raw_msg)
def _send_mail(headers, body, db, category=None, filters=None, unique_args=None, smtp=None): def to_json(data): j = json.dumps(data) return re.compile('(["\]}])([,:])(["\[{])').sub('\1\2 \3', j) # smtp connection setup and timings t0 = time.time() if not smtp: smtp = smtp_connect() # Message header assembly msg = MIMEMultipart('alternative') msg['Subject'] = Header(headers['Subject'].encode('utf-8'), 'UTF-8').encode() msg['To'] = headers['To'] msg['From'] = headers.get('From', 'NewHive <*****@*****.**>') # Sendgrid smtp api setup if category or unique_args or filters: smtpapi = {} if category: smtpapi.update({'category': category}) if unique_args: smtpapi.update({'unique_args': unique_args}) if filters: smtpapi.update({'filters': filters}) msg['X-SMTPAPI'] = to_json(smtpapi) # Message body assembly if type(body) == dict: if body.has_key('plain'): plain = MIMEText(body['plain'].encode('utf-8'), 'plain', 'UTF-8') msg.attach(plain) if body.has_key('html'): html = MIMEText(body['html'].encode('utf-8'), 'html', 'UTF-8') msg.attach(html) else: part1 = MIMEText(body.encode('utf-8'), 'plain') msg.attach(part1) # Unicode support is super wonky. see # http://radix.twistedmatrix.com/2010/07/how-to-send-good-unicode-email-with.html io = StringIO() g = Generator(io, False) # second argument means "should I mangle From?" g.flatten(msg) encoded_msg = io.getvalue() if config.debug_mode: with open(config.src_home + '/log/last_email.txt', 'w') as f: f.write(encoded_msg) if not config.live_server: test_emails = [ r['email'] for r in db.User.search({'name': { '$in': config.admins }}) ] # Send mail, but if we're in debug mode only send to admins send_email = send_real_email # Why can't we break into separate emails? smtp.sendmail accepts "to" field but # sends it to the To in encoded_msg anyway! # Ensure ALL TO: emails are in test_emails if send_email and not config.live_server: for to in (msg['To'] or '').split(','): if not to in test_emails: send_email = False break if send_email: t0 = time.time() sent = smtp.sendmail(msg['From'], (msg['To'] or '').split(','), encoded_msg) logger.debug('SMTP sendmail time %d ms', (time.time() - t0) * 1000) return sent else: logger.warn("Not sending mail to '%s' in debug mode" % (msg['To'])) with open('/tmp/sent_mail', 'w') as f: f.write(body['html'].encode('utf-8')) f.close()
def send_raw_email(self): obj = self.queue[self.current] # create MIME message msg = MIMEMultipart() msg['Subject'] = self.queue[self.current]['subject'] msg['Message-Id'] = make_msgid('calibre-web') msg['Date'] = formatdate(localtime=True) text = _(u'This email has been sent via calibre web.') msg.attach(MIMEText(text.encode('UTF-8'), 'plain', 'UTF-8')) if obj['attachment']: result = get_attachment(obj['filepath'], obj['attachment']) if result: msg.attach(result) else: self.queue[self.current]['status'] = STAT_FAIL self.UIqueue[self.current]['status'] = _('Failed') self.UIqueue[self.current]['progress'] = "100 %" self.queue[self.current]['starttime'] = datetime.now() self.UIqueue[self.current]['formStarttime'] = self.queue[ self.current]['starttime'] self.UIqueue[self.current]['runtime'] = self._formatRuntime( datetime.now() - self.queue[self.current]['starttime']) return msg['From'] = obj['settings']["mail_from"] msg['To'] = obj['recipent'] use_ssl = int(obj['settings'].get('mail_use_ssl', 0)) # convert MIME message to string fp = StringIO() gen = Generator(fp, mangle_from_=False) gen.flatten(msg) msg = fp.getvalue() # send email try: timeout = 600 # set timeout to 5mins org_stderr = sys.stderr sys.stderr = StderrLogger() self.queue[self.current]['status'] = STAT_STARTED self.UIqueue[self.current]['status'] = _('Started') self.queue[self.current]['starttime'] = datetime.now() self.UIqueue[self.current]['formStarttime'] = self.queue[ self.current]['starttime'] if use_ssl == 2: self.asyncSMTP = email_SSL(obj['settings']["mail_server"], obj['settings']["mail_port"], timeout) else: self.asyncSMTP = email(obj['settings']["mail_server"], obj['settings']["mail_port"], timeout) # link to logginglevel if web.ub.config.config_log_level != logging.DEBUG: self.asyncSMTP.set_debuglevel(0) else: self.asyncSMTP.set_debuglevel(1) if use_ssl == 1: self.asyncSMTP.starttls() if obj['settings']["mail_password"]: self.asyncSMTP.login(str(obj['settings']["mail_login"]), str(obj['settings']["mail_password"])) self.asyncSMTP.sendmail(obj['settings']["mail_from"], obj['recipent'], msg) self.asyncSMTP.quit() self.queue[self.current]['status'] = STAT_FINISH_SUCCESS self.UIqueue[self.current]['status'] = _('Finished') self.UIqueue[self.current]['progress'] = "100 %" self.UIqueue[self.current]['runtime'] = self._formatRuntime( datetime.now() - self.queue[self.current]['starttime']) sys.stderr = org_stderr except (socket.error, smtplib.SMTPRecipientsRefused, smtplib.SMTPException) as e: self.queue[self.current]['status'] = STAT_FAIL self.UIqueue[self.current]['status'] = _('Failed') self.UIqueue[self.current]['progress'] = "100 %" self.UIqueue[self.current]['runtime'] = self._formatRuntime( datetime.now() - self.queue[self.current]['starttime']) web.app.logger.error(e)
def mail(to, subject, prioflag1, prioflag2, text): msg = MIMEMultipart() msg['From'] = str( Header(from_displayname, 'UTF-8').encode() + ' <' + from_address + '> ') msg['To'] = to msg['X-Priority'] = prioflag1 msg['X-MSMail-Priority'] = prioflag2 msg['Subject'] = Header(subject, 'UTF-8').encode() body_type = MIMEText(text, "%s" % (message_flag), 'UTF-8') msg.attach(body_type) # now attach the file if file_format != "": fileMsg = email.mime.base.MIMEBase('application', '') fileMsg.set_payload(file(file_format).read()) email.encoders.encode_base64(fileMsg) fileMsg.add_header( 'Content-Disposition', 'attachment; filename="%s"' % os.path.basename(file_format)) msg.attach(fileMsg) for inline_file in inline_files: if inline_file != "": fileMsg = email.mime.base.MIMEBase('application', '') fileMsg.set_payload(file(inline_file).read()) email.encoders.encode_base64(fileMsg) fileMsg.add_header( 'Content-Disposition', 'inline; filename="%s"' % os.path.basename(inline_file)) fileMsg.add_header("Content-ID", "<%s>" % os.path.basename(inline_file)) msg.attach(fileMsg) mailServer = smtplib.SMTP(smtp, port) io = StringIO() msggen = Generator(io, False) msggen.flatten(msg) if sendmail == 0: if email_provider == "gmail" or email_provider == "yahoo" or email_provider == "hotmail": try: mailServer.starttls() except: pass mailServer.ehlo() else: mailServer.ehlo() try: if provideruser != "" or pwd != "": mailServer.login(provideruser, pwd) mailServer.sendmail(from_address, to, io.getvalue()) else: mailServer.sendmail(from_address, to, io.getvalue()) except: # try logging in with base64 encoding here import base64 try: mailServer.docmd("AUTH LOGIN", base64.b64encode(provideruser)) mailServer.docmd(base64.b64encode(pwd), "") # except exceptions and print incorrect password except Exception as e: print_warning( "It appears your password was incorrect.\nPrinting response: " + (str(e))) return_continue() if sendmail == 1: mailServer.sendmail(from_address, to, io.getvalue())
def process_822(self, dmarcemail): """Extract report from rfc822 email, non standard""" report = FBReport() dmarc_reporter = None try: dmarc_reporter = dmarcemail.get('from') report.reporter = FBReporter.objects.get(email=dmarc_reporter) except ObjectDoesNotExist: try: report.reporter = FBReporter.objects.create( org_name=dmarc_reporter, email=dmarc_reporter, ) except: msg = 'Failed to find or create reporter {}'.format( dmarc_reporter) logger.error(msg) raise CommandError(msg) except: msg = 'Unable to get feedback report' logger.warning(msg) tf = tempfile.mkstemp(prefix='dmarc-', suffix='.eml') tmpf = os.fdopen(tf[0], 'w') tmpf.write(dmarcemail.get_payload()) tmpf.close() msg = 'Saved as: {}'.format(tf[1]) logger.error(msg) raise CommandError(msg) report.feedback_source = dmarcemail.get_payload() fp = StringIO() g = Generator(fp, maxheaderlen=0) g.flatten(dmarcemail) report.email_source = fp.getvalue() g = None fp = None print report.feedback_source for line in report.feedback_source.splitlines(): line = line.lstrip() (ls0, ls1, ls2) = line.partition(':') ls0 = ls0.strip() ls2 = ls2.strip() if ls1: if not report.domain: if ls0 == 'Sender Domain': report.domain = ls2 if not report.source_ip: if ls0 == 'Sender IP Address': report.source_ip = ls2 if not report.date: if ls0 == 'Received Date': try: # get tuples t = parsedate_tz(ls2) # get timestamp t = mktime_tz(t) report.date = datetime.fromtimestamp(t) tz_utc = pytz.timezone('UTC') report.date = report.date.replace(tzinfo=tz_utc) except: msg = 'Unable to get date from: {}'.format(ls2) logger.error(msg) report.date = datetime.now() if not report.spf_alignment: if ls0 == 'SPF Alignment': report.spf_alignment = ls2 if not report.dkim_alignment: if ls0 == 'DKIM Alignment': report.dkim_alignment = ls2 if not report.dmarc_result: if ls0 == 'DMARC Results': report.dmarc_result = ls2 if not report.email_from: if ls0 == 'From': report.email_from = ls2 if not report.email_subject: if ls0 == 'Subject': report.email_subject = ls2 try: report.save() except: msg = 'Failed save from {}'.format(dmarc_reporter) logger.error(msg) tf = tempfile.mkstemp(prefix='dmarc-', suffix='.eml') tmpf = os.fdopen(tf[0], 'w') tmpf.write(dmarcemail.get_payload()) tmpf.close() msg = 'Saved as: {}'.format(tf[1]) logger.error(msg)
def process_multipart(self, dmarcemail): """Extract multipart report""" report = FBReport() dmarc_reporter = None try: dmarc_source = dmarcemail.get_payload() dmarc_reporter = dmarcemail.get('from') report.reporter = FBReporter.objects.get(email=dmarc_reporter) mimepart = dmarcemail.get_payload() except ObjectDoesNotExist: try: report.reporter = FBReporter.objects.create( org_name=dmarc_reporter, email=dmarc_reporter, ) except: msg = 'Failed to find or create reporter {}'.format( dmarc_reporter) logger.error(msg) raise CommandError(msg) except: msg = 'Unable to get rfc822 report' logger.error(msg) tf = tempfile.mkstemp(prefix='dmarc-', suffix='.eml') tmpf = os.fdopen(tf[0], 'w') tmpf.write(dmarcemail.get_payload()) tmpf.close() msg = 'Saved as: {}'.format(tf[1]) logger.error(msg) raise CommandError(msg) fp = StringIO() g = Generator(fp, maxheaderlen=0) g.flatten(dmarcemail) report.feedback_source = fp.getvalue() g = None fp = None # Get the human readable part try: mimepart = dmarcemail.get_payload(0) if mimepart.get_content_type() == 'text/plain': # get the human-readable part of the message report.description = mimepart except: msg = 'Unable to get human readable part' logger.warning(msg) # Get the feedback report try: mimepart = dmarcemail.get_payload(1) if mimepart.get_content_type() == 'message/feedback-report': fp = StringIO() g = Generator(fp, maxheaderlen=0) g.flatten(mimepart) report.feedback_report = fp.getvalue() g = None fp = None else: msg = 'Found {} instead of message/feedback-report'.format( mimepart.get_content_type()) logger.error(msg) except: msg = 'Unable to get feedback-report part' logger.error(msg) if report.feedback_report: for line in report.feedback_report.splitlines(): line = line.lstrip() (ls0, ls1, ls2) = line.partition(':') ls0 = ls0.strip() ls2 = ls2.strip() if ls1: if not report.domain: if ls0 == 'Reported-Domain': report.domain = ls2 if not report.source_ip: if ls0 == 'Source-IP': report.source_ip = ls2 if not report.email_from: if ls0 == 'Original-Mail-From': report.email_from = ls2 if not report.date: if ls0 == 'Arrival-Date': try: # get tuples t = parsedate_tz(ls2) # get timestamp t = mktime_tz(t) report.date = datetime.fromtimestamp(t) tz_utc = pytz.timezone('UTC') report.date = report.date.replace( tzinfo=tz_utc) except: msg = 'Unable to get date from: {}'.format(ls2) logger.error(msg) report.date = datetime.now() if not report.dmarc_result: if ls0 == 'Delivery-Result': report.dmarc_result = ls2 if ls0 == 'Authentication-Results': ar = ls2.split() for r in ar: (r0, r1, r2) = r.partition('=') if r1: if not report.dkim_alignment and r0 == 'dkim': report.dkim_alignment = r2.rstrip(';') if not report.spf_alignment and r0 == 'spf': report.spf_alignment = r2.rstrip(';') # Get the rfc822 headers and any message fp = StringIO() g = Generator(fp, maxheaderlen=0) try: mimepart = dmarcemail.get_payload(2, False) mimepart_type = mimepart.get_content_type() g.flatten(mimepart) if mimepart_type == 'message/rfc822': report.email_source = fp.getvalue() elif mimepart_type == 'message/rfc822-headers': report.email_source = fp.getvalue() elif mimepart_type == 'text/rfc822': report.email_source = fp.getvalue() elif mimepart_type == 'text/rfc822-headers': report.email_source = fp.getvalue() else: msg = 'Found {} instead of rfc822'.format(mimepart_type) logger.debug(msg) except: msg = 'Unable to get rfc822 part' logger.warning(msg) g = None fp = None if report.email_source: for line in report.email_source.splitlines(): line = line.lstrip() (ls0, ls1, ls2) = line.partition(':') ls0 = ls0.strip() ls2 = ls2.strip() if ls1: if not report.email_subject: if ls0 == 'Subject': report.email_subject = ls2 try: report.save() except: msg = 'Failed save from {}'.format(report.reporter) logger.error(msg) tf = tempfile.mkstemp(prefix='dmarc-', suffix='.eml') tmpf = os.fdopen(tf[0], 'w') tmpf.write(dmarcemail.get_payload()) tmpf.close() msg = 'Saved as: {}'.format(tf[1]) logger.error(msg)
def write_pkg_info(path, message): with open(path, 'w') as metadata: Generator(metadata, mangle_from_=False, maxheaderlen=0).flatten(message)
import fileinput import subprocess import sys import os filename = sys.argv[1] subprocess.call("%s %s" % (os.environ.get("EDITOR", "vim"), filename), shell=True) parser = FeedParser() for line in fileinput.FileInput(filename, inplace=1): parser.feed(line) msg = parser.close() # Harvest all email addresses from the header # Bcc ignored for privacy reasons / can't do multiple mails from editor script addrs = lambda h: [m[1].lower() for m in getaddresses(msg.get_all(h, []))] email_addrs = set(addrs("To")).union(set(addrs("Cc"))) # Check if an appropriate token is already generated for the mail for hash in msg.get_all("X-Hashcash", []): email_addrs.discard(hash.split(":")[3]) # Call the hashcash function from the operating system to mint tokens for email in email_addrs: t = subprocess.Popen("hashcash -mq -Z 2 %s" % email, shell=True, stdout=subprocess.PIPE) msg["X-Hashcash"] = t.stdout.read().strip() # Write out the message! with open(filename, 'w') as msg_out: Generator(msg_out, mangle_from_=False).flatten(msg)
def create_raw_email(recipients, from_address, subject, body, attachments=None, extra_headers=None): ''' Creates a i18n-compatible raw email. recipients may be an array of address or a single address string. body may be an array of MIME parts in the form: [['plain', plainbody], ['html', htmlbody], ...] May raise exceptions, such as if character encodings fail. attachment should be an array of tuples of (file-type-object, display-filename). extra_headers should be a dictionary of header-name:header-string values. ''' # For email with attachments, the MIME structure will be as follows: # multipart/mixed # multipart/alternative # text/plain - the plain text message # text/html - the html message # application/octet-stream - the first attachment # application/octet-stream - the second attachment, etc. # # For email without an attachment, it will be the same, but we'll omit the # last piece. # We expect body to be an array of mime parts. So make one if that's not # what we got. if isinstance(body, str) or isinstance(body, unicode): body = [ ['plain', body], ] if body is None: body = [] # Override python's weird assumption that utf-8 text should be encoded with # base64, and instead use quoted-printable (for both subject and body). I # can't figure out a way to specify QP (quoted-printable) instead of base64 in # a way that doesn't modify global state. :-( Charset.add_charset('utf-8', Charset.QP, Charset.QP, 'utf-8') # The root MIME section. msgRoot = MIMEMultipart('mixed') # We need to use Header objects here instead of just assigning the strings in # order to get our headers properly encoded (with QP). # You may want to avoid this if your headers are already ASCII, just so people # can read the raw message without getting a headache. # NOTE: encoding the email addresses in UTF-8 did not work with AmazonSES, # and it's not clear if it's necessary to do so. Some day we should determine # a) if there's a reason to UTF-8 encode, and b) if it's okay to UTF-8 encode # now that we're sending directly with SMTP. #multipart['To'] = Header(recipient.encode('utf-8'), 'UTF-8').encode() #multipart['From'] = Header(from_address.encode('utf-8'), 'UTF-8').encode() if type(recipients) == list: recipients = ', '.join(recipients) msgRoot['To'] = Header(recipients.encode('utf-8'), 'ascii').encode() msgRoot['From'] = Header(from_address.encode('utf-8'), 'ascii').encode() msgRoot['Subject'] = Header(subject.encode('utf-8'), 'UTF-8').encode() if extra_headers: for header_name, header_value in extra_headers.iteritems(): # We need a special case for the Reply-To header. Like To and From, # it needs to be ASCII encoded. encoding = 'UTF-8' if header_name.lower() == 'reply-to': encoding = 'ascii' msgRoot[header_name] = Header(header_value.encode('utf-8'), encoding).encode() # The MIME section that contains the plaintext and HTML alternatives. msgAlternative = MIMEMultipart('alternative') msgRoot.attach(msgAlternative) # Attach the body alternatives with the given encodings. for mimetype, content in body: msgpart = MIMEText(content.encode('utf-8'), mimetype, 'UTF-8') msgAlternative.attach(msgpart) # Attach the attachments if attachments: for attachment in attachments: fp, filename = attachment msgAttachment = MIMEBase('application', 'octet-stream') msgAttachment.add_header('Content-Disposition', 'attachment', filename=filename) msgAttachment.set_payload(fp.read()) fp.close() encoders.encode_base64(msgAttachment) msgRoot.attach(msgAttachment) # And here we have to instantiate a Generator object to convert the multipart # object to a string (can't use multipart.as_string, because that escapes # "From" lines). io = StringIO() g = Generator(io, False) # second argument means "should I mangle From?" g.flatten(msgRoot) return io.getvalue()
def send_message( self, sender: str, recipients: str, subject: str = "", body: str = "", attachments: str = None, html: bool = False, images: str = None, ) -> bool: """Send SMTP email Valid sender values: - First Lastname <address@domain> - address@domain :param sender: who is sending, ie. 'from' :param recipients: who is receiving, ie. 'to' :param subject: mail subject field :param body: mail body content :param attachments: list of filepaths to attach, defaults to [] :param html: if message content is in HTML, default `False` :param images: list of filepaths for inline use, defaults to [] Example: .. code-block:: robotframework Send Message [email protected] [email protected] ... subject=Greetings Software Robot Developer ... body=${email_body} ... attachments:${CURDIR}${/}report.pdf """ add_charset("utf-8", QP, QP, "utf-8") recipients, attachments, images = self._handle_message_parameters( recipients, attachments, images) msg = MIMEMultipart() self._add_attachments_to_msg(attachments, msg) msg["From"] = sender msg["To"] = ",".join(recipients) msg["Subject"] = Header(subject, "utf-8") if html: for im in images: im = im.strip() imname = Path(im).name body = body.replace(str(imname), f"cid:{imname}") with open(im, "rb") as f: img = MIMEImage(f.read()) img.add_header("Content-ID", f"<{imname}>") msg.attach(img) htmlpart = MIMEText(body, "html", "UTF-8") msg.attach(htmlpart) else: textpart = MIMEText(body, "plain", "UTF-8") msg.attach(textpart) for im in images: im = im.strip() imname = Path(im).name with open(im, "rb") as f: img = MIMEImage(f.read()) msg.add_header( "Content-Disposition", f"inline; filename= {imname}", ) msg.attach(img) # Create a generator and flatten message object to 'file’ str_io = StringIO() g = Generator(str_io, False) g.flatten(msg) try: self.smtp_conn.sendmail(sender, recipients, str_io.getvalue()) except Exception as err: raise ValueError(f"Send Message failed: {err}") from err return True
def test_repoze_sendmail_send_to_queue_functional(self): # functest that emulates the interaction between pyramid_mailer and # repoze.maildir.add and queuedelivery.send. import tempfile from email.generator import Generator from email.parser import Parser from pyramid_mailer.message import Message from pyramid_mailer.message import Attachment from repoze.sendmail.encoding import cleanup_message from repoze.sendmail.delivery import copy_message def checkit(msg): self.assertEqual(msg['Content-Type'], 'text/plain; charset="iso-8859-1"') self.assertEqual(msg['Content-Transfer-Encoding'], transfer_encoding) payload = msg.get_payload() self.assertEqual(payload, expected) charset = 'iso-8859-1' text_encoded = b'LaPe\xf1a' text = text_encoded.decode(charset) expected = _qencode(text_encoded).decode('ascii') transfer_encoding = 'quoted-printable' body = Attachment(data=text, transfer_encoding=transfer_encoding) msg = Message(subject="testing", sender="*****@*****.**", recipients=["*****@*****.**"], body=body) # done in pyramid_mailer via mailer/send_to_queue msg = msg.to_message() msg.as_string() checkit(msg) # done in repoze.sendmail via delivery/AbstractMailDelivery/send cleanup_message(msg) checkit(msg) # done in repoze.sendmail via # delivery/AbstractMailDelivery/createDataManager msg_copy = copy_message(msg) checkit(msg_copy) try: # emulate what repoze.sendmail maildir.py/add does fn = tempfile.mktemp() fd = os.open(fn, os.O_CREAT | os.O_EXCL | os.O_WRONLY, 0o600) with os.fdopen(fd, 'w') as f: writer = Generator(f) writer.flatten(msg_copy) # emulate what repoze.sendmail.queue _parseMessage does with open(fn) as foo: parser = Parser() reconstituted = parser.parse(foo) checkit(reconstituted) finally: # pragma: no cover try: os.remove(fn) except: pass
def body(self, msg, section): """ Fetch the appropriate part of the message and return it to the user. """ msg_text = None g = None if len(section) == 0: # They want the entire message. # # This really only ever is the case as our first invocation of the # body() method. All further recursive calls will always have at # least one element in the section list when they are called. # fp = StringIO() g = Generator(fp, mangle_from_=False) g.flatten(msg) msg_text = fix_eols(fp.getvalue()) else: if len(section) == 1: fp = StringIO() if isinstance(section[0], int): # The want a sub-part. Get that sub-part. Watch # out for messages that are not multipart. You can # get a sub-part of these as long as it is only # sub-part #1. # g = TextGenerator(fp, headers=False) if section[0] == 1 and not msg.is_multipart(): # The logic is simpler to read this way.. if # they want section 1 and this message is NOT # a multipart message, then do the same as # 'TEXT' ie: We will fall through to the end of this # function where we will take the generator # already created above and use it. # pass else: # Otherwise, get the sub-part they are after # as the message to pass to the generator. # if section[0] != 1 and not msg.is_multipart(): raise BadSection("Trying to retrieve section %d " "and this message is not " "multipart" % section[0]) try: msg = msg.get_payload(section[0] - 1) except IndexError: raise BadSection("Section %d does not exist in " "this message sub-part" % section[0]) elif isinstance(section[0], str) and section[0].upper() == "TEXT": g = TextGenerator(fp, headers=False) elif isinstance(section[0], (list, tuple)): if section[0][0].upper() == "HEADER.FIELDS": g = HeaderGenerator(fp, headers=section[0][1], skip=False) elif section[0][0].upper() == "HEADER.FIELDS.NOT": g = HeaderGenerator(fp, headers=section[0][1], skip=True) else: raise BadSection("Section value must be either " "HEADER.FIELDS or HEADER.FIELDS.NOT, " "not: %s" % section[0][0]) else: g = HeaderGenerator(fp) if isinstance(section[0], str) and section[0].upper() == "MIME": # XXX just use the generator as it is for MIME.. I know # this is not quite right in that it will accept more # then it should, but it will otherwise work. # pass elif isinstance(section[0], str) and section[0].upper() == "HEADER": # if the content type is message/rfc822 then to # get the headers we need to use the first # sub-part of this message. # if msg.is_multipart() and msg.get_content_type( ) == "message/rfc822": msg = msg.get_payload(0) else: self.log.warn("body: Unexpected section[0] value: %s" % repr(section)) raise BadSection("%s: Unexpected section value: %s" % (str(self), repr(section[0]))) elif isinstance(section[0], int): # We have an integer sub-section. This means that we # need to pull apart the message (it MUST be a # multi-part message) and pass to a recursive # invocation of this function the sub-part and the # section list (with the top element of the section # list removed.) # if not msg.is_multipart(): raise BadSection( "Message does not contain subsection %d " "(section list: %s" % section[0], section) try: msg = msg.get_payload(section[0] - 1) except TypeError: raise BadSection( "Message does not contain subsection %d " "(section list: %s)" % section[0], section) return self.body(msg, section[1:]) # We should have a generator that will give us the text # that we want. If we do not then we were not able to find # an appropriate section to parse. # if g is None: raise BadSection("Section selector '%s' can not be parsed" % section) g.flatten(msg) msg_text = fp.getvalue() # We have our message text we need to return to our caller. # truncate if it we also have a 'partial' defined. # # Convert \n in to \r\n # msg_text = fix_eols(msg_text) if self.partial: msg_text = msg_text[self.partial[0]:self.partial[1]] # We return all of these body sections as a length prefixed # IMAP string. Also run the message text through the wringer # converter it through unicode via utf8 back in to bytes # (since we are sending messages over the network we want # stuff a bytes as much as possible.) # msg_text = to_bytes(msg_text) return b"{%d}\r\n%s" % (len(msg_text), msg_text)
def write_pkg_info(path: Union[bytes, str, PathLike], message: Message) -> None: """Write to a PKG-INFO or METADATA file.""" with open(path, "w", encoding="utf-8") as out: Generator(out, mangle_from_=False, maxheaderlen=0).flatten(message)
logging.basicConfig(filename='subjects.log', level=logging.DEBUG) import mailbox from email.generator import Generator import os import re regex = re.compile(r'CDS-ISIS LOG(\d\d\d\d)') for msg in mailbox.mbox(SRC_PATH): subject = msg.get('subject', '[NO_SUBJECT]').strip() match = regex.search(subject) if match: lognum = match.group(1) copy_num = 0 while True: copy = '-' + str(copy_num) if copy_num else '' try_name = '{0}{1}{2}.email'.format(DEST_DIR, lognum, copy) print '.' * copy_num, try_name if not os.path.exists(try_name): dest_name = try_name break copy_num += 1 print dest_name dest = open(dest_name, 'w') Generator(dest).flatten(msg) dest.close() else: logging.debug(subject)
#debug: print part.get_payload() return msg # main logic - interate over files in folder, open & check if contains attachment, if yes, sanitize and copy to output folder; if no, copy to output folder for filename in os.listdir(inputFolder): path = os.path.join(inputFolder, filename) if not os.path.isfile(path): continue else: with open(path, 'rU') as eml: # hash contents and use for filename MD5_filename = hashlib.md5(eml.read()).hexdigest() eml.seek(0) #debug: print MD5_filename folders = inputFolder.split('\\') src_folder = folders[-1] outPath = os.path.join(resultsFolder, 's_'+src_folder+'_'+MD5_filename+'.eml') #debug: print outPath # if contains attachment, sanitizes and builds new .eml w/ result if containsAttach(eml): print "Found an attachment in %s. Deleting payload..." % filename clean_msg = sanitize(eml) with open(outPath, 'w') as clean_eml: g = Generator(clean_eml) g.flatten(clean_msg) clean_eml.flush() clean_eml.close() else: copy(path, resultsFolder+'\\'+src_folder+'_'+MD5_filename+'.eml') eml.close()
def _send_raw_email(self): self.doLock.acquire() index = self.current self.doLock.release() self.queue[index]['starttime'] = datetime.now() self.UIqueue[index]['formStarttime'] = self.queue[index]['starttime'] self.UIqueue[index]['stat'] = STAT_STARTED obj = self.queue[index] # create MIME message msg = MIMEMultipart() msg['Subject'] = self.queue[index]['subject'] msg['Message-Id'] = make_msgid('calibre-web') msg['Date'] = formatdate(localtime=True) text = self.queue[index]['text'] msg.attach(MIMEText(text.encode('UTF-8'), 'plain', 'UTF-8')) if obj['attachment']: result = get_attachment(obj['filepath'], obj['attachment']) if result: msg.attach(result) else: self._handleError(u"Attachment not found") return msg['From'] = obj['settings']["mail_from"] msg['To'] = obj['recipent'] use_ssl = int(obj['settings'].get('mail_use_ssl', 0)) try: # convert MIME message to string fp = StringIO() gen = Generator(fp, mangle_from_=False) gen.flatten(msg) msg = fp.getvalue() # send email timeout = 600 # set timeout to 5mins # redirect output to logfile on python2 pn python3 debugoutput is caught with overwritten # _print_debug function if sys.version_info < (3, 0): org_smtpstderr = smtplib.stderr smtplib.stderr = logger.StderrLogger('worker.smtp') if use_ssl == 2: self.asyncSMTP = email_SSL(obj['settings']["mail_server"], obj['settings']["mail_port"], timeout=timeout) else: self.asyncSMTP = email(obj['settings']["mail_server"], obj['settings']["mail_port"], timeout=timeout) # link to logginglevel if logger.is_debug_enabled(): self.asyncSMTP.set_debuglevel(1) if use_ssl == 1: self.asyncSMTP.starttls() if obj['settings']["mail_password"]: self.asyncSMTP.login(str(obj['settings']["mail_login"]), str(obj['settings']["mail_password"])) self.asyncSMTP.sendmail(obj['settings']["mail_from"], obj['recipent'], msg) self.asyncSMTP.quit() self._handleSuccess() if sys.version_info < (3, 0): smtplib.stderr = org_smtpstderr except (MemoryError) as e: log.exception(e) self._handleError(u'MemoryError sending email: ' + str(e)) return None except (smtplib.SMTPException, smtplib.SMTPAuthenticationError) as e: if hasattr(e, "smtp_error"): text = e.smtp_error.decode('utf-8').replace("\n", '. ') elif hasattr(e, "message"): text = e.message else: log.exception(e) text = '' self._handleError(u'Smtplib Error sending email: ' + text) return None except (socket.error) as e: self._handleError(u'Socket Error sending email: ' + e.strerror) return None
from io import StringIO from email.generator import Generator fp = StringIO() g = Generator(fp, mangle_from_=True, maxheaderlen=60) g.flatten(msg) text = fp.getvalue()
def mail(to, subject, text, attach, prioflag1, prioflag2): msg = MIMEMultipart() msg['From'] = str( Header(from_displayname, 'UTF-8').encode() + ' <' + from_address + '> ') msg['To'] = to msg['X-Priority'] = prioflag1 msg['X-MSMail-Priority'] = prioflag2 msg['Subject'] = Header(subject, 'UTF-8').encode() # specify if its html or plain # body message here body_type = MIMEText(text, "%s" % (message_flag), 'UTF-8') msg.attach(body_type) # define connection mimebase part = MIMEBase('application', 'octet-stream') part.set_payload(open(attach, 'rb').read()) # base 64 encode message mimebase Encoders.encode_base64(part) # add headers part.add_header('Content-Disposition', 'attachment; filename="%s"' % os.path.basename(attach)) msg.attach(part) io = StringIO() msggen = Generator(io, False) msggen.flatten(msg) # define connection to smtp server mailServer = smtplib.SMTP(smtp, int(port)) mailServer.ehlo() # send ehlo to smtp server if sendmail == 0: if email_provider == "gmail" or email_provider == "yahoo": mailServer.ehlo() # start TLS needed for gmail and yahoo and hotmail (live) try: mailServer.starttls() except: pass mailServer.ehlo() if not "gmail|yahoo|hotmail|" in email_provider: tls = yesno_prompt(["1"], "Does your server support TLS? [yes|no]") if tls == "YES": mailServer.starttls() if counter == 0: try: if email_provider == "gmail" or email_provider == "yahoo" or email_provider == "hotmail": try: mailServer.starttls() except: pass mailServer.ehlo() if len(provideruser) > 0: mailServer.login(provideruser, pwd) mailServer.sendmail(from_address, to, io.getvalue()) except Exception as e: print_error( "Unable to deliver email. Printing exceptions message below, this is most likely due to an illegal attachment. If using GMAIL they inspect PDFs and is most likely getting caught." ) input("Press {return} to view error message.") print(str(e)) try: mailServer.docmd("AUTH LOGIN", base64.b64encode(provideruser)) mailServer.docmd(base64.b64encode(pwd), "") except Exception as e: print(str(e)) try: mailServer.login(provideremail, pwd) thread.start_new_thread( mailServer.sendmail(from_address, to, io.getvalue())) except Exception as e: return_continue() if email_provider == "hotmail": mailServer.login(provideruser, pwd) thread.start_new_thread(mailServer.sendmail, (from_address, to, io.getvalue())) if sendmail == 1: thread.start_new_thread(mailServer.sendmail, (from_address, to, io.getvalue()))
def send_message( self, sender: str, recipients: str, subject: str, body: str, attachments: str = None, html: bool = False, ) -> None: """Send SMTP email Valid sender values: - First Lastname <address@domain> - address@domain :param sender: who is sending, ie. 'from' :param recipients: who is receiving, ie. 'to' :param subject: mail subject field :param body: mail body content :param attachments: list of filepaths to attach, defaults to [] :param html: if message content is in HTML, default `False` """ if self.smtp_conn is None: raise ValueError("Requires authorized SMTP connection") add_charset("utf-8", QP, QP, "utf-8") attachments = attachments or [] if not isinstance(attachments, list): attachments = attachments.split(",") msg = MIMEMultipart() if len(attachments) > 0: for filename in attachments: self.logger.debug("Adding attachment: %s", filename) with open(filename, "rb") as attachment: _, ext = filename.lower().rsplit(".", 1) ctype, _ = mimetypes.guess_type(filename) _, subtype = ctype.split("/", 1) if ext in IMAGE_FORMATS: # image attachment part = MIMEImage( attachment.read(), name=os.path.basename(filename), _subtype=subtype, ) else: # attach other filetypes part = MIMEBase("application", "octet-stream") part.set_payload(attachment.read()) encoders.encode_base64(part) part.add_header( "Content-Disposition", f"attachment; filename= {Path(filename).name}", ) msg.attach(part) msg["From"] = sender msg["Subject"] = Header(subject, "utf-8") if html: htmlpart = MIMEText(body, "html", "UTF-8") msg.attach(htmlpart) else: textpart = MIMEText(body, "plain", "UTF-8") msg.attach(textpart) # Create a generator and flatten message object to 'file’ str_io = StringIO() g = Generator(str_io, False) g.flatten(msg) if not isinstance(recipients, list): recipients = recipients.split(",") try: self.smtp_conn.sendmail(sender, recipients, str_io.getvalue()) except Exception as err: raise ValueError(f"Send Message failed: {err}")
mail.add_header('Mime-Version', '1.0') #mail.add_header('Content-Type', 'text-plain') mail.set_param('charset', 'utf-8') mail.add_header('Content-Transfer-Encoding', 'quoted-printable') # Rewrite some fields fields = ('to', 'cc', 'bcc', 'subject') for field in fields: if field in mail: value = mail[field] #mail.replace_header(field.capitalize(), value) del mail[field] mail.add_header(field.capitalize(), value) # Add the potential attachment if len(sys.argv) == 3: pathname = sys.argv[2] filename = path.basename(sys.argv[2]) try: mimetype, subtype = guess_type(pathname)[0].split('/') except AttributeError: mimetype, subtype = "application", "octet-stream" with open(pathname, 'rb') as attachment: data = attachment.read() mail.add_attachment(data, mimetype, subtype, filename=filename) # Rewrite the file with open(draft, 'w') as fo: gen = Generator(fo) gen.flatten(mail, unixfrom=True)
def yahoo_sent(msgfile, out_file): mto = [] # emails address for to mfrom = [] # emails address for from mcc = [] # emails address for cc # read file fp = open(msgfile) eformat = fp.read() fp.close() # find extract main data data = data_tag(eformat, 'message') # extract subject subject = data_tag(data, 'subject') # extract to tmp = data i = 0 while True: to = data_tag(tmp, 'to') if to != "": mto.append(address(to)) tmp = next_tag(data, 'to', i) i += 1 else: break # extract from tmp = data i = 0 while True: frm = data_tag(tmp, 'from') if frm != "": mfrom.append(address(frm)) tmp = next_tag(data, 'from', i) i += 1 else: break # extract cc tmp = data i = 0 while True: cc = data_tag(tmp, 'cc') if cc != "": mcc.append(address(cc)) tmp = next_tag(data, 'cc', i) i += 1 else: break # extract simplebody simplebody = data_tag(data, 'simplebody') # extract text text = data_tag(simplebody, 'text') # extract html html = data_tag(simplebody, 'html') # to string tos = "" for elem in mto: if tos != "": tos += "," tos = tos + elem[0] + " <" + elem[1] + ">" # from string froms = "" for elem in mfrom: if froms != "": froms += ";" froms = froms + elem[0] + " <" + elem[1] + ">" # cc string ccs = "" for elem in mcc: if ccs != "": ccs += "," ccs = ccs + elem[0] + " <" + elem[1] + ">" # write info extracted out_file += "_0" info_file = open(out_file, "w") info_file.write("SUBJECT:" + subject + "\n") info_file.write("FROM:" + froms + "\n") info_file.write("TO:" + tos + "\n") if ccs != "": info_file.write("CC:" + ccs + "\n") # write text file if text != "": text_file = open(out_file + ".txt", "w") text_file.write(text) text_file.close() info_file.write("PART_0:" + out_file + ".txt" + "\n") # write html file if html != "": html_file = open(out_file + ".html", "w") html_file.write(html) html_file.close() info_file.write("HTML_0:" + out_file + ".html" + "\n") # convert os.system("recode html.. " + out_file + ".html") html_file = open(out_file + ".html", 'r') html_page = html_file.read() html_file.close() # eml file # Create message container - the correct MIME type is multipart/alternative. compose = False if text != "" and html != "": msg = MIMEMultipart('alternative') part1 = MIMEText(text, 'plain') part2 = MIMEText(html_page, 'html') msg.attach(part1) msg.attach(part2) compose = True elif text != "": msg = MIMEText(text, 'plain') compose = True elif html != "": msg = MIMEText(html_page, 'html') compose = True if compose: msg['Subject'] = subject msg['From'] = froms msg['To'] = tos if ccs != "": msg['Cc'] = ccs fp = io.StringIO() g = Generator(fp, mangle_from_=False, maxheaderlen=60) g.flatten(msg) eml_file = open(out_file + ".eml", "w") eml_file.write(fp.getvalue()) eml_file.close() info_file.write("EML:" + out_file + ".eml" + "\n") info_file.close()
def method(self, **kwargs): # Don't bother with doc string, it will be over-written by createMethod. for name in six.iterkeys(kwargs): if name not in parameters.argmap: raise TypeError('Got an unexpected keyword argument "%s"' % name) # Remove args that have a value of None. keys = list(kwargs.keys()) for name in keys: if kwargs[name] is None: del kwargs[name] for name in parameters.required_params: if name not in kwargs: raise TypeError('Missing required parameter "%s"' % name) for name, regex in six.iteritems(parameters.pattern_params): if name in kwargs: if isinstance(kwargs[name], six.string_types): pvalues = [kwargs[name]] else: pvalues = kwargs[name] for pvalue in pvalues: if re.match(regex, pvalue) is None: raise TypeError( 'Parameter "%s" value "%s" does not match the pattern "%s"' % (name, pvalue, regex)) for name, enums in six.iteritems(parameters.enum_params): if name in kwargs: # We need to handle the case of a repeated enum # name differently, since we want to handle both # arg='value' and arg=['value1', 'value2'] if (name in parameters.repeated_params and not isinstance(kwargs[name], six.string_types)): values = kwargs[name] else: values = [kwargs[name]] for value in values: if value not in enums: raise TypeError( 'Parameter "%s" value "%s" is not an allowed value in "%s"' % (name, value, str(enums))) actual_query_params = {} actual_path_params = {} for key, value in six.iteritems(kwargs): to_type = parameters.param_types.get(key, 'string') # For repeated parameters we cast each member of the list. if key in parameters.repeated_params and type(value) == type([]): cast_value = [_cast(x, to_type) for x in value] else: cast_value = _cast(value, to_type) if key in parameters.query_params: actual_query_params[parameters.argmap[key]] = cast_value if key in parameters.path_params: actual_path_params[parameters.argmap[key]] = cast_value body_value = kwargs.get('body', None) media_filename = kwargs.get('media_body', None) if self._developerKey: actual_query_params['key'] = self._developerKey model = self._model if methodName.endswith('_media'): model = MediaModel() elif 'response' not in methodDesc: model = RawModel() headers = {} headers, params, query, body = model.request(headers, actual_path_params, actual_query_params, body_value) expanded_url = uritemplate.expand(pathUrl, params) url = _urljoin(self._baseUrl, expanded_url + query) resumable = None multipart_boundary = '' if media_filename: # Ensure we end up with a valid MediaUpload object. if isinstance(media_filename, six.string_types): (media_mime_type, encoding) = mimetypes.guess_type(media_filename) if media_mime_type is None: raise UnknownFileType(media_filename) if not mimeparse.best_match([media_mime_type], ','.join(accept)): raise UnacceptableMimeTypeError(media_mime_type) media_upload = MediaFileUpload(media_filename, mimetype=media_mime_type) elif isinstance(media_filename, MediaUpload): media_upload = media_filename else: raise TypeError('media_filename must be str or MediaUpload.') # Check the maxSize if maxSize > 0 and media_upload.size() > maxSize: raise MediaUploadSizeError("Media larger than: %s" % maxSize) # Use the media path uri for media uploads expanded_url = uritemplate.expand(mediaPathUrl, params) url = _urljoin(self._baseUrl, expanded_url + query) if media_upload.resumable(): url = _add_query_parameter(url, 'uploadType', 'resumable') if media_upload.resumable(): # This is all we need to do for resumable, if the body exists it gets # sent in the first request, otherwise an empty body is sent. resumable = media_upload else: # A non-resumable upload if body is None: # This is a simple media upload headers['content-type'] = media_upload.mimetype() body = media_upload.getbytes(0, media_upload.size()) url = _add_query_parameter(url, 'uploadType', 'media') else: # This is a multipart/related upload. msgRoot = MIMEMultipart('related') # msgRoot should not write out it's own headers setattr(msgRoot, '_write_headers', lambda self: None) # attach the body as one part msg = MIMENonMultipart(*headers['content-type'].split('/')) msg.set_payload(body) msgRoot.attach(msg) # attach the media as the second part msg = MIMENonMultipart(*media_upload.mimetype().split('/')) msg['Content-Transfer-Encoding'] = 'binary' payload = media_upload.getbytes(0, media_upload.size()) msg.set_payload(payload) msgRoot.attach(msg) # encode the body: note that we can't use `as_string`, because # it plays games with `From ` lines. fp = io.StringIO() g = Generator(fp, mangle_from_=False) g.flatten(msgRoot, unixfrom=False) body = fp.getvalue() multipart_boundary = msgRoot.get_boundary() headers['content-type'] = ( 'multipart/related; ' 'boundary="%s"') % multipart_boundary url = _add_query_parameter(url, 'uploadType', 'multipart') logger.info('URL being requested: %s %s' % (httpMethod, url)) return self._requestBuilder(self._http, model.response, url, method=httpMethod, body=body, headers=headers, methodId=methodId, resumable=resumable)
subject = "サービスメンテナンスのご連絡{}".format(company) # サービス毎にフォルダを作る mail_path = "サービス_" + service if not os.path.exists(mail_path): os.mkdir(mail_path) mail_data = create_mail(subject, to_mail, cc_mail, from_mail, honbun.format(company, name, service)) # 設定した内容をファイルに書き込む with open( os.path.join(mail_path, 'サービスメンテナンスのご連絡_{}_{}.eml'.format(company, name)), 'w') as eml: eml_file = Generator(eml) eml_file.flatten(mail_data) #添付ファイル有だった場合はメールを作成する if mail_attach_int == 1: honbun = read_txt("mail_attach.txt") subject = "【PW】サービスメンテナンスのご連絡{}".format(company) mail_data = create_mail(subject, to_mail, cc_mail, from_mail, honbun.format(company, name, service)) with open( os.path.join( mail_path, '【PW】サービスメンテナンスのご連絡_{}_{}.eml'.format(company, name)), 'w') as eml:
def save_msg(msg, out_file): eml = MIMEMultipart() info_file = open(out_file, "w") # convert strings for key, val in msg.items(): if key != 'parts': msg[key] = val.encode('raw_unicode_escape', 'ignore').decode('ascii', 'ignore') # write info extracted if msg['subject']: info_file.write("SUBJECT:" + msg['subject'] + "\n") if msg['from']: info_file.write("FROM:" + msg['from'] + "\n") if msg['to']: info_file.write("TO:" + msg['to'] + "\n") if msg['cc'] != "": info_file.write("CC:" + msg['cc'] + "\n") if msg['messageid'] != "": info_file.write("MESSAGEID:" + msg['messageid'] + "\n") if msg['received'] != "": info_file.write("RECEIVED:" + msg['received'] + "\n") if msg['sent'] != "": info_file.write("SENT:" + msg['sent'] + "\n") # mime eml['Subject'] = msg['subject'] eml['From'] = msg['from'] eml['To'] = msg['to'] if msg['sent'] != "": eml['Date'] = msg['sent'] eml['Message-Id'] = msg['messageid'] if msg['cc'] != "": eml['Cc'] = msg['cc'] j = 0 for part in msg['parts']: prt = '%d' % j out_file_part = out_file + "_" + prt if part['txt'] != "" and part['html'] != "": msg = MIMEMultipart('alternative') text_file = open(out_file_part + ".txt", "w") text_file.write(part['txt']) text_file.close() info_file.write("PART_" + prt + ":" + out_file_part + ".txt" + "\n") part1 = MIMEText(part['txt'], 'plain') html_file = open(out_file_part + ".html", "w") html_file.write(part['html']) html_file.close() info_file.write("HTML_" + prt + ":" + out_file_part + ".html" + "\n") # convert os.system("recode html.. " + out_file_part + ".html") html_file = open(out_file_part + ".html", 'r') html_page = html_file.read() html_file.close() part2 = MIMEText(html_page, 'html') msg.attach(part1) msg.attach(part2) eml.attach(msg) elif part['txt'] != "": text_file = open(out_file_part + ".txt", "w") text_file.write(part['txt']) text_file.close() info_file.write("PART_" + prt + ":" + out_file_part + ".txt" + "\n") #eml eml_part = MIMEText(part['txt'], 'plain') eml.attach(eml_part) elif part['html'] != "": html_file = open(out_file_part + ".html", "w") html_file.write(part['html']) html_file.close() info_file.write("HTML_" + prt + ":" + out_file_part + ".html" + "\n") # convert os.system("recode html.. " + out_file_part + ".html") html_file = open(out_file_part + ".html", 'r') html_page = html_file.read() html_file.close() #eml eml_part = MIMEText(html_page, 'html') eml.attach(eml_part) if part['filename'] != "": info_file.write("FILENAME_" + prt + ":" + part['filename'] + "\n") j += 1 # eml file fp = io.StringIO() g = Generator(fp, mangle_from_=False, maxheaderlen=60) g.flatten(eml) eml_file = open(out_file + ".eml", "w") eml_file.write(fp.getvalue()) eml_file.close() info_file.write("EML:" + out_file + ".eml" + "\n") info_file.close()
print (pop.pass_(password)) except: print ("Authentication error") sys.exit(-2) # gets the mail list mail_list = pop.list()[1] for m in mail_list: mno, size = m.split() message = "\r\n".join(pop.retr(mno)[1]) message = email.message_from_string(message) # uses the email flatten out_file = StringIO.StringIO() message_gen = Generator(out_file, mangle_from_=False, maxheaderlen=60) message_gen.flatten(message) message_text = out_file.getvalue() # fixes mime encoding issues (for display within html) clean_text = quopri.decodestring(message_text) msg = email.message_from_string(clean_text) # finds the last body (when in mime multipart, html is the last one) for part in msg.walk(): if part.get_content_type(): body = part.get_payload(decode=True) filename = "%s.email" % random.randint(1,100)
def run(self, worker_thread): # create MIME message msg = MIMEMultipart() msg['Subject'] = self.subject msg['Message-Id'] = make_msgid('calibre-web') msg['Date'] = formatdate(localtime=True) text = self.text msg.attach(MIMEText(text.encode('UTF-8'), 'plain', 'UTF-8')) if self.attachment: result = self._get_attachment(self.filepath, self.attachment, self.bookname) if result: msg.attach(result) else: self._handleError(u"Attachment not found") return msg['From'] = self.settings["mail_from"] msg['To'] = self.recipent use_ssl = int(self.settings.get('mail_use_ssl', 0)) try: # convert MIME message to string fp = StringIO() gen = Generator(fp, mangle_from_=False) gen.flatten(msg) msg = fp.getvalue() # send email timeout = 600 # set timeout to 5mins # redirect output to logfile on python2 pn python3 debugoutput is caught with overwritten # _print_debug function if sys.version_info < (3, 0): org_smtpstderr = smtplib.stderr smtplib.stderr = logger.StderrLogger('worker.smtp') if use_ssl == 2: self.asyncSMTP = EmailSSL(self.settings["mail_server"], self.settings["mail_port"], timeout=timeout) else: self.asyncSMTP = Email(self.settings["mail_server"], self.settings["mail_port"], timeout=timeout) # link to logginglevel if logger.is_debug_enabled(): self.asyncSMTP.set_debuglevel(1) if use_ssl == 1: self.asyncSMTP.starttls() if self.settings["mail_password"]: self.asyncSMTP.login(str(self.settings["mail_login"]), str(self.settings["mail_password"])) self.asyncSMTP.sendmail(self.settings["mail_from"], self.recipent, msg) self.asyncSMTP.quit() self._handleSuccess() if sys.version_info < (3, 0): smtplib.stderr = org_smtpstderr except (MemoryError) as e: log.exception(e) self._handleError(u'MemoryError sending email: ' + str(e)) # return None except (smtplib.SMTPException, smtplib.SMTPAuthenticationError) as e: if hasattr(e, "smtp_error"): text = e.smtp_error.decode('utf-8').replace("\n", '. ') elif hasattr(e, "message"): text = e.message elif hasattr(e, "args"): text = '\n'.join(e.args) else: log.exception(e) text = '' self._handleError(u'Smtplib Error sending email: ' + text) # return None except (socket.error) as e: self._handleError(u'Socket Error sending email: ' + e.strerror)
def save_to_file(filepath, message): with open(filepath, 'w') as file: generator = Generator(file) generator.flatten(message)