Esempio n. 1
0
def encodedMIMEText(body, encoding=None):
    """Wrap ``MIMEText`` with ``guess_encoding`` detection.

    >>> message = encodedMIMEText('Hello')
    >>> print(message.as_string())  # doctest: +REPORT_UDIFF
    Content-Type: text/plain; charset="us-ascii"
    MIME-Version: 1.0
    Content-Transfer-Encoding: 7bit
    Content-Disposition: inline
    <BLANKLINE>
    Hello
    >>> message = encodedMIMEText('Джон Доу')
    >>> print(message.as_string())  # doctest: +REPORT_UDIFF
    Content-Type: text/plain; charset="utf-8"
    MIME-Version: 1.0
    Content-Transfer-Encoding: base64
    Content-Disposition: inline
    <BLANKLINE>
    0JTQttC+0L0g0JTQvtGD
    <BLANKLINE>
    """
    if encoding == None:
        encoding = guess_encoding(body)
    if encoding == 'us-ascii':
        message = _MIMEText(body)
    else:
        # Create the message ('plain' stands for Content-Type: text/plain)
        message = _MIMEText(body, 'plain', encoding)
    message.add_header('Content-Disposition', 'inline')
    return message
Esempio n. 2
0
def encodedMIMEText(body, encoding=None):
    """Wrap ``MIMEText`` with ``guess_encoding`` detection.

    >>> message = encodedMIMEText('Hello')
    >>> print(message.as_string())  # doctest: +REPORT_UDIFF
    Content-Type: text/plain; charset="us-ascii"
    MIME-Version: 1.0
    Content-Transfer-Encoding: 7bit
    Content-Disposition: inline
    <BLANKLINE>
    Hello
    >>> message = encodedMIMEText('Джон Доу')
    >>> print(message.as_string())  # doctest: +REPORT_UDIFF
    Content-Type: text/plain; charset="utf-8"
    MIME-Version: 1.0
    Content-Transfer-Encoding: base64
    Content-Disposition: inline
    <BLANKLINE>
    0JTQttC+0L0g0JTQvtGD
    <BLANKLINE>
    """
    if encoding == None:
        encoding = guess_encoding(body)
    if encoding == 'us-ascii':
        message = _MIMEText(body)
    else:
        # Create the message ('plain' stands for Content-Type: text/plain)
        message = _MIMEText(body, 'plain', encoding)
    message.add_header('Content-Disposition', 'inline')
    return message
Esempio n. 3
0
 def _get_mine_message(self):
     ''' generate MIMEText or MIMEMultipart objects '''
     if self._attachments:
         return _MIMEMultipart('related')
     elif self.html:
         #return _MIMEMultipart('alternative')
         return _MIMEText(self.html, 'html', self.encoding)
     return _MIMEText(self.text, 'plain', self.encoding)
Esempio n. 4
0
def _add_plain_multipart(guid: str, message, html: str):
    headers = message.items()
    msg = MIMEMultipart('alternative')
    for name, value in headers:
        if name.lower().startswith('content-'):
            continue
        msg[str(name)] = value

    html_part = _MIMEText(html, _subtype='html')
    msg.attach(html_part)

    text_content = html2text.html2text(html=html, baseurl=guid)
    text_part = _MIMEText(text_content)
    msg.attach(text_part)
    return msg
Esempio n. 5
0
    def _attach_files(self, outer):
        ''' attach file list '''
        for attachment in self._attachments:
            filename = attachment
            cid = None
            if (isinstance(attachment, list) or isinstance(attachment, tuple)
                    and len(attachment) == 2):
                filename, cid = attachment

            ctype, encoding = mimetypes.guess_type(filename)
            if ctype is None or encoding is not None:
                ctype = 'application/octet-stream'
            maintype, subtype = ctype.split('/', 1)
            fp = open(filename, 'rb')
            if maintype == 'text':
                msg = _MIMEText(fp.read(), _subtype=subtype)
            elif maintype == 'image':
                msg = _MIMEImage(fp.read(), _subtype=subtype)
            elif maintype == 'audio':
                msg = _MIMEAudio(fp.read(), _subtype=subtype)
            else:
                msg = _MIMEBase(maintype, subtype)
                msg.set_payload(fp.read())
                _encoder.encode_base64(msg)
            fp.close()

            if cid:
                msg.add_header('Content-ID', '<%s>' % cid)
                msg.add_header('Content-Disposition', 'inline')
            else:
                msg.add_header('Content-Disposition', 'attachment', filename=os.path.basename(filename))
            outer.attach(msg)
        return
Esempio n. 6
0
    def text(self, text):
        '''
        .. seealso:: :attr:`text`
        '''

        if text:
            if not isinstance(text, str):
                text = _pformat(text)
            text += '\n\n'
            self.m('add text to mail', more=dict(len=len(text)))
            self.__message.attach(_MIMEText(text, 'plain', 'UTF-8'))
Esempio n. 7
0
def email(to, subject, body):
 """Sends email, doing all the (not so) heavy lifting."""
 try:
  s = _SMTP('localhost')
  msg = _MIMEText(body)
  msg['from'] = 'Driver Mail Subsystem <noreply@%s>' % _getfqdn()
  msg['to'] = to
  msg['subject'] = subject
  s.sendmail(msg['from'], msg['to'], msg.as_string())
  s.quit()
  logger.info('Sent mail to %s with subject %s.', msg['to'], msg['subject'])
 except Exception as e:
  logger.exception(e)
Esempio n. 8
0
    def text(self, text):
        '''
        .. seealso:: :attr:`text`
        '''

        if text:
            if not isinstance(text, str):
                text = _pformat(text)
            text += '\n\n'
            self.m(
                'add text to mail',
                more=dict(len=len(text))
            )
            self.__message.attach(_MIMEText(text, 'plain', 'UTF-8'))
Esempio n. 9
0
def myMIMEText(body, subtype=None, encoding='utf-8', filename=None):
    r"""Wrap ``MIMEText`` with proper ``encoding``
    only utf-8 or us-ascii are supported

    by default: all text files are encoded with utf-8 to avoid signature error
    if, however, you don't like this, risk yourself for us-ascii/utf-8
    """
    if ( encoding != 'utf-8' ):
        if nonAsciiString(body):
            encoding = 'utf-8'
        else:
            encoding = 'us-ascii'
    message = _MIMEText(body, subtype, encoding)
    message.add_header('Content-Disposition', 'inline', filename = filename)
    return message
Esempio n. 10
0
def get_message(sender, recipient, subject, body, content_type="plain",
                extra_headers=None):
    """Generate a `Message` instance.

    All arguments should be Unicode strings (plain ASCII works as well).

    Only the real name part of sender and recipient addresses may
    contain non-ASCII characters.

    The email will be properly MIME encoded.

    The charset of the email will be the first one out of the list
    that can represent all the characters occurring in the email.
    """

    # Split real name (which is optional) and email address parts
    sender_name, sender_addr = _parseaddr(sender)
    recipient_name, recipient_addr = _parseaddr(recipient)

    sender_encoding = guess_encoding(sender_name)
    recipient_encoding = guess_encoding(recipient_name)
    subject_encoding = guess_encoding(subject)
    body_encoding = guess_encoding(body)

    # We must always pass Unicode strings to Header, otherwise it will
    # use RFC 2047 encoding even on plain ASCII strings.
    sender_name = str(_Header(sender_name, sender_encoding).encode())
    recipient_name = str(_Header(recipient_name, recipient_encoding).encode())

    # Make sure email addresses do not contain non-ASCII characters
    sender_addr.encode('ascii')
    recipient_addr.encode('ascii')

    # Create the message ('plain' stands for Content-Type: text/plain)
    message = _MIMEText(body, content_type, body_encoding)
    message['From'] = _formataddr((sender_name, sender_addr))
    message['To'] = _formataddr((recipient_name, recipient_addr))
    message['Subject'] = _Header(subject, subject_encoding)

    if extra_headers:
        for key, value in extra_headers.items():
            encoding = guess_encoding(value)
            message[key] = _Header(value, encoding)
    return message
Esempio n. 11
0
    def send(self):
        """Send message
        """

        def do_send(msg: Message):
            try:
                engine = _SMTP('localhost')
                engine.sendmail(msg._from_addr, msg._to_addrs, str(msg))
                log_msg = "Message '{}' has been sent to {}.".format(msg.subject, msg.to_addrs)
                _logger.info(log_msg)
            except Exception as e:
                _logger.error('Unable to send message to {}: {}'.format(msg.to_addrs, e), exc_info=e)

        super().attach(_MIMEText(self.body, 'html', 'utf-8'))
        for attachment in self._attachments:
            super().attach(attachment)

        _threading.run_in_thread(do_send, msg=self)

        _logger.info('Started new message send thread to {}'.format(self.to_addrs))
Esempio n. 12
0
    def notify(self):
        config = load_config()
        assert (
            config.get('notify', 'email_address') != 'None'
        ), 'No email has been specified, _please do so in ~/.ceilopy/config.ini'

        out = self._last_processing
        messages = ['run started {}'.format(out['start_time'])]
        messages.append('run finshed {}'.format(out['finish_time']))

        #### summary
        no_of_errors = len(out['errors'])
        no_of_files_processed = out['no_of_files_processed']

        messages.append('\n'.join([
            f'length of workplan:\t\t{self.workplan.shape[0]}',
            f'successfully created files:\t{no_of_files_processed}',
            f'errors encountered:\t\t{no_of_errors}'
        ]))

        #### errors
        if no_of_errors != 0:
            errs = out['errors']
            err_types = _np.array([err.__class__.__name__ for err in errs])

            typoferrors = []
            for toe in _np.unique(err_types):
                typoferrors.append({
                    'name':
                    toe,
                    'times': (err_types == toe).sum(),
                    'first_err':
                    errs[_np.where(err_types == toe)[0][0]]
                })

            messages.append('\n'.join([
                'Errors by type:',
            ] + [
                '\t{tn}:\t{tt}'.format(tn=toe['name'], tt=toe['times'])
                for toe in typoferrors
            ]))
            messages.append(
                '\n=============================================\n'.join([
                    'First traceback for each error type',
                ] + [
                    ''.join(
                        _tb.format_tb(toe['first_err'].__traceback__) + [
                            toe['first_err'].__str__(),
                        ]) for toe in typoferrors
                ]))

        #### email body
        message_txt = '\n=========================================================================\n'.join(
            messages)
        msg = _MIMEText(message_txt)

        #### subject
        if no_of_errors == 0:
            status = 'clean'
        else:
            status = 'errors'
        subject = f'cl51cloudprod - status: {status} (clean: {no_of_files_processed}; errors: {no_of_errors})'
        address = config.get('notify', 'email_address')
        smtp = config.get('notify', 'smtp')

        msg['Subject'] = subject
        msg['From'] = address
        msg['To'] = address

        # Send the message via our own SMTP server.
        s = _smtplib.SMTP(smtp)
        s.send_message(msg)
        s.quit()
Esempio n. 13
0
 def _attach_text(self, msg, inline=False):
     ''' attach plain text body '''
     part = _MIMEText(self.text, 'plain', self.encoding)
     if inline:
         part.add_header('Content-Disposition', 'inline')
     msg.attach(part)
Esempio n. 14
0
 def _attach_html(self, msg, inline=False):
     ''' attach html body '''
     part = _MIMEText(self.html, 'html', self.encoding)
     if inline:
         part.add_header('Content-Disposition', 'inline')
     msg.attach(part)
Esempio n. 15
0
                                            f"{index}.pdf")

                    # Set the content of the attachment:
                    ctype, encoding = _mimetypes.guess_type(source_pdf)
                    maintype, subtype = ctype.split('/', 1)
                    with open(source_pdf, 'rb') as fp:
                        msg = _MIMEImage(fp.read(), _subtype=subtype)

                    # Set the filename parameter
                    msg.add_header('Content-Disposition',
                                   'attachment',
                                   filename=_settings.EMAIL_PDF)
                    outer.attach(msg)

                    # Add our message:
                    part1 = _MIMEText(body, 'plain', 'UTF-8')
                    outer.attach(part1)

                    # Now send the message
                    try:
                        smtp.sendmail(_settings.SMTP_USER, email,
                                      outer.as_bytes())
                    except _smtplib.SMTPRecipientsRefused:
                        print(f'Cannot send to {email}. Recipient refused.')
                    except Exception as e:
                        print(
                            f'Cannot send to {email} due to server error: {e}')
                        _traceback.print_exc()
                        break
                    else:
                        print(f'Mail sent to {email}')
Esempio n. 16
0
def get_message(sender, recipient, subject, body, content_type,
                extra_headers=None, config=None, section='DEFAULT'):
    """Generate a `Message` instance.

    All arguments should be Unicode strings (plain ASCII works as well).

    Only the real name part of sender and recipient addresses may contain
    non-ASCII characters.

    The email will be properly MIME encoded.

    The charset of the email will be the first one out of the list
    that can represent all the characters occurring in the email.

    >>> message = get_message(
    ...     sender='John <*****@*****.**>', recipient='Ζεύς <*****@*****.**>',
    ...     subject='Testing',
    ...     body='Hello, world!\\n',
    ...     content_type='plain',
    ...     extra_headers={'Approved': '*****@*****.**'})
    >>> print(message.as_string())  # doctest: +REPORT_UDIFF
    MIME-Version: 1.0
    Content-Type: text/plain; charset="us-ascii"
    Content-Transfer-Encoding: 7bit
    From: John <*****@*****.**>
    To: =?utf-8?b?zpbOtc+Nz4I=?= <*****@*****.**>
    Subject: Testing
    Approved: [email protected]
    <BLANKLINE>
    Hello, world!
    <BLANKLINE>
    """
    if config is None:
        config = _config.CONFIG
    if section not in config.sections():
        section = 'DEFAULT'
    encodings = [
        x.strip() for x in config.get(section, 'encodings').split(',')]

    # Split real name (which is optional) and email address parts
    sender_name,sender_addr = _parseaddr(sender)
    recipient_name,recipient_addr = _parseaddr(recipient)

    sender_encoding = guess_encoding(sender_name, encodings)
    recipient_encoding = guess_encoding(recipient_name, encodings)
    subject_encoding = guess_encoding(subject, encodings)
    body_encoding = guess_encoding(body, encodings)

    # We must always pass Unicode strings to Header, otherwise it will
    # use RFC 2047 encoding even on plain ASCII strings.
    sender_name = str(_Header(sender_name, sender_encoding).encode())
    recipient_name = str(_Header(recipient_name, recipient_encoding).encode())

    # Make sure email addresses do not contain non-ASCII characters
    sender_addr.encode('ascii')
    recipient_addr.encode('ascii')

    # Create the message ('plain' stands for Content-Type: text/plain)
    message = _MIMEText(body, content_type, body_encoding)
    message['From'] = _formataddr((sender_name, sender_addr))
    message['To'] = _formataddr((recipient_name, recipient_addr))
    message['Subject'] = _Header(subject, subject_encoding)
    if config.getboolean(section, 'use-8bit'):
        del message['Content-Transfer-Encoding']
        charset = _Charset(body_encoding)
        charset.body_encoding = _email_encoders.encode_7or8bit
        message.set_payload(body, charset=charset)
    if extra_headers:
        for key,value in extra_headers.items():
            encoding = guess_encoding(value, encodings)
            message[key] = _Header(value, encoding)
    return message
Esempio n. 17
0
def get_message(sender,
                recipient,
                subject,
                body,
                content_type,
                extra_headers=None,
                config=None,
                section='DEFAULT'):
    """Generate a `Message` instance.

    All arguments should be Unicode strings (plain ASCII works as well).

    Only the real name part of sender and recipient addresses may contain
    non-ASCII characters.

    The email will be properly MIME encoded.

    The charset of the email will be the first one out of the list
    that can represent all the characters occurring in the email.

    >>> message = get_message(
    ...     sender='John <*****@*****.**>', recipient='Ζεύς <*****@*****.**>',
    ...     subject='Testing',
    ...     body='Hello, world!\\n',
    ...     content_type='plain',
    ...     extra_headers={'Approved': '*****@*****.**'})
    >>> print(message.as_string())  # doctest: +REPORT_UDIFF
    MIME-Version: 1.0
    Content-Type: text/plain; charset="us-ascii"
    Content-Transfer-Encoding: 7bit
    From: John <*****@*****.**>
    To: =?utf-8?b?zpbOtc+Nz4I=?= <*****@*****.**>
    Subject: Testing
    Approved: [email protected]
    <BLANKLINE>
    Hello, world!
    <BLANKLINE>
    """
    if config is None:
        config = _config.CONFIG
    if section not in config.sections():
        section = 'DEFAULT'
    encodings = [
        x.strip() for x in config.get(section, 'encodings').split(',')
    ]

    # Split real name (which is optional) and email address parts
    sender_name, sender_addr = _parseaddr(sender)
    recipient_list = []
    for recipient_name, recipient_addr in _getaddresses([recipient]):
        recipient_encoding = guess_encoding(recipient_name, encodings)
        recipient_name = str(
            _Header(recipient_name, recipient_encoding).encode())
        recipient_addr.encode('ascii')
        recipient_list.append(_formataddr((recipient_name, recipient_addr)))

    sender_encoding = guess_encoding(sender_name, encodings)
    recipient_encoding = guess_encoding(recipient_name, encodings)
    subject_encoding = guess_encoding(subject, encodings)
    body_encoding = guess_encoding(body, encodings)

    # We must always pass Unicode strings to Header, otherwise it will
    # use RFC 2047 encoding even on plain ASCII strings.
    sender_name = str(_Header(sender_name, sender_encoding).encode())

    # Make sure email addresses do not contain non-ASCII characters
    sender_addr.encode('ascii')

    # Create the message ('plain' stands for Content-Type: text/plain)
    message = _MIMEText(body, content_type, body_encoding)
    message['From'] = _formataddr((sender_name, sender_addr))
    message['To'] = ', '.join(recipient_list)
    message['Subject'] = _Header(subject, subject_encoding)
    if config.getboolean(section, 'use-8bit'):
        del message['Content-Transfer-Encoding']
        charset = _Charset(body_encoding)
        charset.body_encoding = _email_encoders.encode_7or8bit
        message.set_payload(body, charset=charset)
    if extra_headers:
        for key, value in extra_headers.items():
            encoding = guess_encoding(value, encodings)
            message[key] = _Header(value, encoding)
    return message
Esempio n. 18
0
def embed_report(report, file_name='reporty', del_files='no',
                 subject='', sender_name='', rec_name='', text=''):
    """ embeds report in custom email, and attaches html files and pngs

    Args:
        report (str): html code
        filename (str): name of html file (if you entered a custom file name in
        'generate report', you must pass that filename through in this function)
        - default is 'reporty'
        del_files (str): 'yes' will delete files - default is 'no' (keep files)
        subject (str): subject of email - default is '' (no subject)
        sender_name (str): name of sender (will be email name no matter what on
        outlook) - default is '' (will result to email address on all platforms)
        rec_name (str): name of receiver (must be left blank for outlook users)
        - default is '' (will result in no send tag for gmail)
        text (str): any extra text you want to send will appear at start of
        email - default is '' (will result to no extra text)

    Returns:
        encoded multipart message
    """

    # declaring message object
    message = _MIMEMultipart()

    # takes custom file name and adds html file extension
    file_name = file_name + ".html"

    # declaring empty file names list
    file_names = []

    # takes filenames from
    if _os.path.exists("filenames.txt"):
        file = open("filenames.txt", "r")
        filenames = file.read()
        file.close()
        _os.remove("filenames.txt")
        file_names = filenames.strip('][').split(', ')
    else:
        pass

    # adds a sender_name, receiver name, and a subject
    if sender_name == '':
        pass
    else:
        message["From"] = str(sender_name)
    if rec_name == '':
        pass
    else:
        rec_name = (str(rec_name)).replace(" ", "_")
        message["To"] = rec_name
    if subject == '':
        pass
    else:
        message["Subject"] = str(subject)

    # attatches 'text' to message
    message.attach(_MIMEText(text, 'plain'))

    # attatches the html attachment to message
    attachment = _MIMEText(report, "html")
    message.attach(attachment)

    # adds a content id to all matplot pngs and attaches images
    if len(file_names) > 0:
        for i in range(len(file_names)):
            f_p = open(file_names[i], 'rb')
            image = _MIMEImage(f_p.read(), filename=file_names[i])
            _encoders.encode_base64(image)
            f_p.close()
            image.add_header('Content-ID', '<' + file_names[i].replace('.png', '') + '>')
            image.add_header('Content-Disposition', 'inline', filename=file_names[i])
            message.attach(image)
    else:
        pass

    # opens the html file and adds 'payload'
    attach_file = open(file_name, 'rb')
    payload = _MIMEBase('application', 'octate-stream')
    payload.set_payload(attach_file.read())

    # encodes payload
    _encoders.encode_base64(payload)

    # add payload header with filename
    payload.add_header('Content-Disposition', 'attachment', filename=file_name)

    # attatches html file to the email
    message.attach(payload)
    attach_file.close()

    # creates final message (str)
    final_message = message.as_string()

    # deletes extra files if user specifies
    if del_files == 'yes':
        if _os.path.exists(file_name):
            _os.remove(file_name)
        else:
            pass
        for i in range(len(file_names)):
            if _os.path.exists(file_names[i]):
                _os.remove(file_names[i])
    else:
        pass

    # returns the mime multipart message (str)
    return final_message
Esempio n. 19
0
    def send(self,
             receiver,
             cc=None,
             bcc=None,
             subject: str = None,
             message: str = None,
             image: str = None,
             audio: str = None,
             file: str = None):
        """
        :param cc: Email Address as String or List. (Carbon Copy)
        :param bcc: Email Address as String or List. (Blind Carbon Copy)
        :param receiver: Email Address as String or List
        :param subject: Message Title
        :param message: Your Message
        :param image: Image File Name
        :param audio: Audio File Name
        :param file: File Name
        :return: Boolean
        """

        msg = _MIMEMultipart()
        msg['Subject'] = subject
        msg['From'] = self.email

        try:
            if message is not None:
                text = _MIMEText(message)
                msg.attach(text)

            if image is not None:
                image_data = self._file_reader(image)
                image = _MIMEImage(_imagedata=image_data, name=image)
                msg.attach(image)

            if audio is not None:
                audio_data = self._file_reader(audio)
                audio = _MIMEAudio(_audiodata=audio_data,
                                   name=audio,
                                   _subtype='')
                msg.attach(audio)

            if file is not None:
                file_data = self._file_reader(file)
                file = _MIMEApp(_data=file_data, name=file)
                msg.attach(file)
        except Exception:
            print('Error: File Not Found!')
            self.status = False
            return False

        send_info = []
        multi_info = {}

        if 'list' in str(type(receiver)):
            self.count_rec = len(receiver)
            receiver = ','.join(i for i in receiver)

        if 'list' in str(type(cc)):
            self.count_cc = len(cc)
            cc = ','.join(i for i in cc)

        if 'list' in str(type(bcc)):
            self.count_bcc = len(bcc)
            bcc = ','.join(i for i in bcc)

        if self.__login():
            msg['To'] = receiver
            msg['CC'] = cc
            msg['BCC'] = bcc

            if self.multi:
                for _ in range(self.__repeat):
                    try:
                        self.__server.sendmail(from_addr=self.email,
                                               to_addrs=receiver,
                                               msg=msg.as_string())
                    except Exception:
                        if self.__repeat == 1 & self.count_rec == 1:
                            self.status = False
                        else:
                            send_info.append(False)

                    else:
                        if self.__repeat == 1 & self.count_rec == 1:
                            self.status = True
                        else:
                            send_info.append(True)
                            self.status = send_info

                    finally:
                        _sleep(self.__sleep)
            else:
                for rec in receiver.split(','):
                    send_info = []
                    for _ in range(self.__repeat):
                        try:
                            self.__server.sendmail(from_addr=self.email,
                                                   to_addrs=rec,
                                                   msg=msg.as_string())
                        except Exception as e:
                            if self.__repeat == 1 & self.count_rec == 1:
                                self.status = False
                            else:
                                send_info.append(False)

                            if 'OutboundSpamException' in str(e):
                                print(
                                    'Error: Please Login To Your Account And Verify it.'
                                )
                                break

                        else:
                            if self.__repeat == 1 & self.count_rec == 1:
                                self.status = True
                            else:
                                send_info.append(True)
                                self.status = send_info
                                multi_info[rec] = send_info

                        finally:
                            _sleep(self.__sleep)

                    if self.count_rec != 1:
                        self.status = multi_info

        self.__server.close()