예제 #1
0
    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")
예제 #2
0
def msg_as_string(msg):
    fp = StringIO()
    g = Generator(fp, mangle_from_=False, maxheaderlen=60)
    g.flatten(msg)

    return fp.getvalue()
예제 #3
0
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)
예제 #4
0
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)
예제 #5
0
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()
예제 #6
0
    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)
예제 #7
0
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())
예제 #8
0
    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)
예제 #9
0
    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)
예제 #10
0
 def write_pkg_info(path, message):
     with open(path, 'w') as metadata:
         Generator(metadata, mangle_from_=False,
                   maxheaderlen=0).flatten(message)
예제 #11
0
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)
예제 #12
0
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()
예제 #13
0
    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
예제 #14
0
    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
예제 #15
0
    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)
예제 #16
0
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)
예제 #17
0
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)
예제 #18
0
			#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()
예제 #19
0
    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()
예제 #21
0
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()))
예제 #22
0
    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}")
예제 #23
0
    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)
예제 #24
0
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()
예제 #25
0
    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)
예제 #26
0
파일: main.py 프로젝트: pymee/studygroup
        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:
예제 #27
0
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()
예제 #28
0
    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)
예제 #29
0
    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)
예제 #30
0
def save_to_file(filepath, message):
    with open(filepath, 'w') as file:
        generator = Generator(file)
        generator.flatten(message)