Пример #1
0
    def test_cte_type_7bit_transforms_8bit_cte(self):
        source = textwrap.dedent("""\
            From: [email protected]
            To: Dinsdale
            Subject: Nudge nudge, wink, wink
            Mime-Version: 1.0
            Content-Type: text/plain; charset="latin-1"
            Content-Transfer-Encoding: 8bit

            oh là là, know what I mean, know what I mean?
            """).encode('latin1')
        msg = message_from_bytes(source)
        expected = textwrap.dedent("""\
            From: [email protected]
            To: Dinsdale
            Subject: Nudge nudge, wink, wink
            Mime-Version: 1.0
            Content-Type: text/plain; charset="iso-8859-1"
            Content-Transfer-Encoding: quoted-printable

            oh l=E0 l=E0, know what I mean, know what I mean?
            """).encode('ascii')
        s = io.BytesIO()
        g = BytesGenerator(s,
                           policy=self.policy.clone(cte_type='7bit',
                                                    linesep='\n'))
        g.flatten(msg)
        self.assertEqual(s.getvalue(), expected)
Пример #2
0
def message2email(msg: Message) -> EmailMessage:
    """
    Convert an instance of the old `Message` class (or one of its subclasses,
    like a `mailbox` message class) to an instance of the new `EmailMessage`
    class with the ``default`` policy.  If ``msg`` is already an
    `EmailMessage`, it is returned unchanged.
    """
    if isinstance(msg, EmailMessage):
        return msg
    # Message.as_bytes() refolds long header lines (which can result in changes
    # in whitespace after reparsing) and doesn't give a way to change this, so
    # we need to use a BytesGenerator manually.
    fp = BytesIO()
    # TODO: Instead of maxheaderlen, use a policy with refold_source=None?
    g = BytesGenerator(fp, mangle_from_=False, maxheaderlen=0)
    g.flatten(msg, unixfrom=msg.get_unixfrom() is not None)
    fp.seek(0)
    emsg = email.message_from_binary_file(fp, policy=policy.default)
    assert isinstance(emsg, EmailMessage)
    # MMDFMessage and mboxMessage make their "From " lines available though a
    # different method than normal Messages, so we have to copy it over
    # manually.
    if isinstance(msg, (MMDFMessage, mboxMessage)):
        emsg.set_unixfrom("From " + msg.get_from())
    return emsg
Пример #3
0
    def test_cte_type_7bit_transforms_8bit_cte(self):
        source = textwrap.dedent("""\
            From: [email protected]
            To: Dinsdale
            Subject: Nudge nudge, wink, wink
            Mime-Version: 1.0
            Content-Type: text/plain; charset="latin-1"
            Content-Transfer-Encoding: 8bit

            oh là là, know what I mean, know what I mean?
            """).encode('latin1')
        msg = message_from_bytes(source)
        expected =  textwrap.dedent("""\
            From: [email protected]
            To: Dinsdale
            Subject: Nudge nudge, wink, wink
            Mime-Version: 1.0
            Content-Type: text/plain; charset="iso-8859-1"
            Content-Transfer-Encoding: quoted-printable

            oh l=E0 l=E0, know what I mean, know what I mean?
            """).encode('ascii')
        s = io.BytesIO()
        g = BytesGenerator(s, policy=self.policy.clone(cte_type='7bit',
                                                       linesep='\n'))
        g.flatten(msg)
        self.assertEqual(s.getvalue(), expected)
Пример #4
0
 def _flatten_message(self, message, flattening_policy):
     bytes_io = BytesIO()
     generator = BytesGenerator(bytes_io,
                                mangle_from_=False,
                                policy=flattening_policy)
     generator.flatten(message, unixfrom=False, linesep='\r\n')
     return bytes_io.getvalue()
Пример #5
0
 def _flatten_message(
         self, message,
         _):  #3: remove whole method definition (keeping the above one)
     bytes_io = BytesIO()
     generator = BytesGenerator(bytes_io, mangle_from_=False)
     generator.flatten(message, unixfrom=False)
     return bytes_io.getvalue()
Пример #6
0
    def createMessage(self, entry=None):
        """ Creates a message representing a given feed entry. """

        logging.info("Creating message about: " + entry.title)
        msg = email.mime.multipart.MIMEMultipart('alternative')
        msg.set_charset(self.feed.encoding)
        author = self.title()
        try:
            author = entry.author + " @ " + author
        except AttributeError:
            pass
        msg['From'] = author
        msg['Subject'] = entry.title
        msg['To'] = config.username
        date = time.time()
        if hasattr(entry, 'updated_parsed') \
            and entry.updated_parsed is not None:
            date = entry.updated_parsed
        elif hasattr(entry, 'published_parsed') \
            and entry.published_parsed is not None:
            date = entry.published_parsed
        else:
            logging.warning('Entry without a date: ' + entry.title)
        if date is not None:
            msg['Date'] = email.utils.format_datetime(
                            datetime.datetime.fromtimestamp(
                                time.mktime(date)))
        headerName = 'X-Entry-Link'
        msg[headerName] = email.header.Header(s=entry.link,
                                              charset=self.feed.encoding)
        try:
            content = entry.content[0]['value']
        except AttributeError:
            try:
                content = entry.summary
            except AttributeError:
                content = entry.description
        html = content
        text = html2text.html2text(html)
        text = 'Retrieved from ' + entry.link + '\n' + text
        html = html + \
               '<p><a href="' + \
               entry.link + \
               '">Retrieved from ' + \
               entry.link + \
               '</a></p>'
        part1 = email.mime.text.MIMEText(text, 'plain')
        part2 = email.mime.text.MIMEText(html, 'html')
        msg.attach(part1)
        msg.attach(part2)

        bytesIO = BytesIO()
        bytesGenerator = BytesGenerator(bytesIO,
                                        mangle_from_=True,
                                        maxheaderlen=60)
        bytesGenerator.flatten(msg)
        text = bytesIO.getvalue()

        return text
Пример #7
0
 def __init__(self, fp, root=True):
     # don't try to use super() here; in py2 Generator is not a
     # new-style class.  Yuck.
     TheGenerator.__init__(self,
                           fp,
                           mangle_from_=False,
                           maxheaderlen=0)
     self.root = root
Пример #8
0
 def _dispatch(self, msg):
     # Get the Content-Type: for the message, then try to dispatch to
     # self._handle_<maintype>_<subtype>().  If there's no handler for the
     # full MIME type, then dispatch to self._handle_<maintype>().  If
     # that's missing too, then dispatch to self._writeBody().
     main = msg.get_content_maintype()
     if msg.is_multipart() and main.lower() != 'multipart':
       self._handle_multipart(msg)
     else:
       BytesGenerator._dispatch(self,msg)
Пример #9
0
 def _dispatch(self, msg):
     # Get the Content-Type: for the message, then try to dispatch to
     # self._handle_<maintype>_<subtype>().  If there's no handler for the
     # full MIME type, then dispatch to self._handle_<maintype>().  If
     # that's missing too, then dispatch to self._writeBody().
     main = msg.get_content_maintype()
     if msg.is_multipart() and main.lower() != 'multipart':
       self._handle_multipart(msg)
     else:
       BytesGenerator._dispatch(self,msg)
Пример #10
0
def mail_to_bytes(mail):
    """Get bytes based on a mail.

    Based on email.Message.as_bytes, but we reimplement it here because python
    3.3 lacks it.
    """
    fp = BytesIO()
    g = BytesGenerator(fp, mangle_from_=False, policy=mail.policy)
    g.flatten(mail, unixfrom=False)
    return fp.getvalue()
Пример #11
0
 def test_cte_type_7bit_handles_unknown_8bit(self):
     source = ("Subject: Maintenant je vous présente mon "
              "collègue\n\n").encode('utf-8')
     expected = ('Subject: Maintenant je vous =?unknown-8bit?q?'
                 'pr=C3=A9sente_mon_coll=C3=A8gue?=\n\n').encode('ascii')
     msg = message_from_bytes(source)
     s = io.BytesIO()
     g = BytesGenerator(s, policy=self.policy.clone(cte_type='7bit'))
     g.flatten(msg)
     self.assertEqual(s.getvalue(), expected)
Пример #12
0
def mail_to_bytes(mail):
    """Get bytes based on a mail.

    Based on email.Message.as_bytes, but we reimplement it here because python
    3.3 lacks it.
    """
    fp = BytesIO()
    g = BytesGenerator(fp, mangle_from_=False, policy=mail.policy)
    g.flatten(mail, unixfrom=False)
    return fp.getvalue()
Пример #13
0
 def test_cte_type_7bit_handles_unknown_8bit(self):
     source = ("Subject: Maintenant je vous présente mon "
               "collègue\n\n").encode('utf-8')
     expected = ('Subject: Maintenant je vous =?unknown-8bit?q?'
                 'pr=C3=A9sente_mon_coll=C3=A8gue?=\n\n').encode('ascii')
     msg = message_from_bytes(source)
     s = io.BytesIO()
     g = BytesGenerator(s, policy=self.policy.clone(cte_type='7bit'))
     g.flatten(msg)
     self.assertEqual(s.getvalue(), expected)
Пример #14
0
def main(do_it=False):
    with open('results.pkl', 'rb') as f:
        results = pickle.load(f)

    if not do_it:
        print('This only send data if you give it --ok')
        print('Would send the following mails:')
        print('')

    n = len(results)
    i = 0
    for result in results:
        gifter = result[0]
        gifted = result[1]

        #mail_body = mail_body_fmt.format(gifter=result[0], gifted=result[1])
        #mail_from = f'{sender_email}'
        #mail_to = f'{gifter.email}'
        mail_from = f'{sender_name} <{sender_email}>'
        mail_to = f'{gifter.name} <{gifter.email}>'
        mail_subject = mail_subject_fmt.format()
        mail_body = mail_body_fmt.format(gifter=gifter, gifted=gifted)

        msg = EmailMessage()
        msg['From'] = mail_from
        msg['To'] = mail_to
        msg['Subject'] = mail_subject
        msg.set_payload(mail_body, charset='utf-8')

        if do_it:
            #p = Popen(["/usr/sbin/sendmail", "-t", "-oi"], stdin=PIPE)
            #p.communicate(msg.as_bytes())

            p = Popen(['sendmail', '-F', '-oi', gifter.email], stdin=PIPE)
            g = BytesGenerator(p.stdin,
                               policy=msg.policy.clone(linesep='\r\n'))
            g.flatten(msg)
            p.stdin.close()
            rc = p.wait()

            i += 1
            print(f'{i}/{n} mails sent.')
        else:
            # because utf8 is 8b and transport is 7b, mail is normally encoded in base64
            # this is just a way to add the un-encoded text to the message before printing
            # trying to send it will give errors
            msg.set_payload(mail_body)
            print('-' * 78)
            print(msg)
            print('-' * 78)

    if do_it and i != n:
        print('There were some errors sending the mails')

    os.remove('results.pkl')
Пример #15
0
def write_message_to_file(message, filename):
    """
    Write a message to the file with the
    given filename.
    """
    fp = open(os.path.join(args.dir, filename), "wb")
    try:
        generator = BytesGenerator(fp)
        generator.flatten(message, linesep="\r\n")
    finally:
        fp.close()
Пример #16
0
    def as_bytes(self):
        """
        converts the mail into a binary string

        @return     bytes

        See `Message.as_bytes <https://docs.python.org/3/library/email.message.html#email.message.Message.as_bytes>`_
        """
        fp = BytesIO()
        g = BytesGenerator(fp, mangle_from_=True, maxheaderlen=60)
        g.flatten(self)
        return fp.getvalue()
Пример #17
0
def main():
    last_month = datetime.date.today().replace(day=1) - datetime.timedelta(days=1)
    mails = get_mails()
    if not mails:
        print("No mails")
        return
    files = get_files(last_month)
    if not files:
        print("No files")
        return

    multipart = MIMEMultipart()
    multipart['Subject'] = last_month.strftime("Temp: %Y-%m")
    multipart['From'] = str(Address("Temperatura", addr_spec="*****@*****.**"))
    multipart['To'] = ', '.join(str(m) for m in mails)

    multipart.attach(MIMEText("""\
Witaj!

W załączeniu zapisy temperatury z ostatniego miesiąca.

--Temperatura"""))
    
    for filepath in files:
        if not filepath.is_file():
            continue
        ctype, encoding = mimetypes.guess_type(filepath.name)
        if ctype is None or encoding is not None:
            ctype = 'application/octet-stream'
        maintype, subtype = ctype.split('/', 1)
        with filepath.open('rb') as f:
            attachment = MIMEBase(maintype, subtype)
            attachment.set_payload(f.read())
        encoders.encode_base64(attachment)
        attachment.add_header('Content-Disposition', 'attachment', filename=filepath.name)
        multipart.attach(attachment)

    with open(datetime.datetime.now().strftime('email-%Y-%m-%d-%H-%M-%s.msg'), 'wb') as f:
        fp = BytesIO()
        g = BytesGenerator(fp, mangle_from_=True, maxheaderlen=60)
        g.flatten(multipart)
        text = fp.getvalue()
        f.write(text)
    try:
        with smtplib.SMTP_SSL('poczta.o2.pl', port=465) as s:
            s.login('*****@*****.**', 'shtiSlaidd')
            s.send_message(multipart)
    except smtplib.SMTPResponseException as e:
        if e.smtp_code == 250 and e.smtp_error == b'Ok':
            pass # o2.pl bug. Returns 250 Ok instead of 221
        else:
            raise
Пример #18
0
    def select(self, mailbox='INBOX.' + config.mailbox):
        """ Selects given mailbox or mailbox given in config gile. """

        logging.info("Selecting mailbox: " + mailbox)
        mbox = mailbox
        if mbox[0] != '"':
            mbox = '"' + mbox + '"'
        status, message = self.imap.select(mbox)
        if status == 'NO': # there's no such mailbox, let's create one
            self.imap.select()
            status, message = self.imap.create(mbox)
            if status != "OK":
                logging.error("Could not create mailbox: " + str(mbox))
            self.imap.subscribe(mbox)
            status, message = self.imap.select(mbox)
            if status != "OK":
                logging.error("Could not select mailbox: " + str(mbox))
            if mbox in ['"INBOX.testyarss2imap"', '"INBOX.' + config.mailbox + '"']:
                # The default yarss2imap mailbox was just created
                # Let's populate it with a README message.
                logging.info("Creating README message")
                msg = email.mime.multipart.MIMEMultipart('alternative')
                msg.set_charset("utf-8")
                msg['From'] = "*****@*****.**"
                msg['Subject'] = "Welcome to yarss2imap. README please."
                msg['To'] = config.username
                msg['Date'] = email.utils.format_datetime(
                                datetime.datetime.fromtimestamp(
                                    time.time()))
                f = open('README.md','r')
                content = f.read()
                f.close()
                part = email.mime.text.MIMEText(content, 'plain')
                msg.attach(part)
                bytesIO = BytesIO()
                bytesGenerator = BytesGenerator(bytesIO,
                                     mangle_from_=True,
                                     maxheaderlen=60)
                bytesGenerator.flatten(msg)
                text = bytesIO.getvalue() 
                status, error = self.imap.append(
                                    mbox,
                                    '',
                                    imaplib.Time2Internaldate(time.time()),
                                    text)
                if status != 'OK':
                    logging.error('Could not append README message: ' + error)
                self.imap.select(mbox)


        return status
Пример #19
0
    def as_bytes(self, unixfrom=False, policy=None):
        """Return the entire formatted message as a bytes object.

        Optional 'unixfrom', when true, means include the Unix From_ envelope
        header.  'policy' is passed to the BytesGenerator instance used to
        serialize the message; if not specified the policy associated with
        the message instance is used.
        """
        from email.generator import BytesGenerator
        policy = self.policy if policy is None else policy
        fp = BytesIO()
        g = BytesGenerator(fp, mangle_from_=False, policy=policy)
        g.flatten(self, unixfrom=unixfrom)
        return fp.getvalue()
Пример #20
0
    def as_bytes(self, unixfrom=False, policy=None):
        """Return the entire formatted message as a bytes object.

        Optional 'unixfrom', when true, means include the Unix From_ envelope
        header.  'policy' is passed to the BytesGenerator instance used to
        serialize the message; if not specified the policy associated with
        the message instance is used.
        """
        from email.generator import BytesGenerator
        policy = self.policy if policy is None else policy
        fp = BytesIO()
        g = BytesGenerator(fp, mangle_from_=False, policy=policy)
        g.flatten(self, unixfrom=unixfrom)
        return fp.getvalue()
Пример #21
0
    def as_bytes(self):
        """Return the entire formatted message as a bytes object."""
        # Instead of using self.message.as_bytes() directly,
        # we copy and edit the implementation of email.Message.as_bytes
        # since it does not accept maxheaderlen, which we wish to set to 0
        # for transparency.

        policy = self.message.policy
        fp = BytesIO()
        g = BytesGenerator(fp,
                           mangle_from_=False,
                           maxheaderlen=0,
                           policy=policy)
        g.flatten(self.message, unixfrom=None)
        return fp.getvalue()
Пример #22
0
def dump_message(file, headers, props=None, content=None):
    msg = Message()
    for (name, value) in headers:
        msg[name] = value
    payload = BytesIO()
    
    if props is not None:
        start = payload.tell()
        for (key, value) in props.items():
            payload.write("K {}\n".format(len(key)).encode("ascii"))
            payload.writelines((key.encode("ascii"), b"\n"))
            payload.write("V {}\n".format(len(value)).encode("ascii"))
            payload.writelines((value.encode("ascii"), b"\n"))
        payload.write(b"PROPS-END\n")
        
        msg["Prop-content-length"] = format(payload.tell() - start)
    
    if content is not None:
        msg["Text-content-length"] = format(len(content))
        payload.write(content)
    
    if props is not None or content is not None:
        payload = payload.getvalue()
        msg["Content-length"] = format(len(payload))
        
        # Workaround for Python issue 18324, "set_payload does not handle
        # binary payloads correctly", http://bugs.python.org/issue18324
        msg.set_payload(payload.decode("ascii", "surrogateescape"))
    
    BytesGenerator(file, mangle_from_=False).flatten(msg)
Пример #23
0
    def get_payload(self):
        """
        decode and return part payload. if I{type} is 'text/*' and I{charset}
        not C{None}, be careful to take care of the text encoding. Use
        something like C{part.get_payload().decode(part.charset)}
        """

        payload=None
        if self.type.startswith('message/'):
            # I don't use msg.as_string() because I want to use mangle_from_=False
            if sys.version_info<(3, 0):
                # python 2.x
                from email.generator import Generator
                fp = StringIO.StringIO()
                g = Generator(fp, mangle_from_=False)
                g.flatten(self.part, unixfrom=False)
                payload=fp.getvalue()
            else:
                # support only for python >= 3.2
                from email.generator import BytesGenerator
                import io
                fp = io.BytesIO()
                g = BytesGenerator(fp, mangle_from_=False)
                g.flatten(self.part, unixfrom=False)
                payload=fp.getvalue()

        else:
            payload=self.part.get_payload(decode=True)
        return payload
Пример #24
0
    def write_wheelfile(self,
                        wheelfile_base,
                        generator="bdist_wheel (" + wheel_version + ")"):
        from email.message import Message

        msg = Message()
        msg["Wheel-Version"] = "1.0"  # of the spec
        msg["Generator"] = generator
        msg["Root-Is-Purelib"] = str(self.root_is_pure).lower()
        if self.build_number is not None:
            msg["Build"] = self.build_number

        # Doesn't work for bdist_wininst
        impl_tag, abi_tag, plat_tag = self.get_tag()
        for impl in impl_tag.split("."):
            for abi in abi_tag.split("."):
                for plat in plat_tag.split("."):
                    msg["Tag"] = "-".join((impl, abi, plat))

        wheelfile_path = os.path.join(wheelfile_base, "WHEEL")
        log.info(f"creating {wheelfile_path}")
        buffer = BytesIO()
        BytesGenerator(buffer, maxheaderlen=0).flatten(msg)
        with open(wheelfile_path, "wb") as f:
            f.write(buffer.getvalue().replace(b"\r\n", b"\r"))
Пример #25
0
 def do_GET(self):
     """
     Echo a request without a body.
     """
     message = self.get_message()
     self.send_head()
     BytesGenerator(self.wfile).flatten(message, unixfrom=False)
Пример #26
0
    def write_wheelfile(self,
                        wheelfile_base,
                        generator='bdist_wheel (' + wheel_version + ')'):
        from email.message import Message

        # Workaround for Python 2.7 for when "generator" is unicode
        if sys.version_info < (3, ) and not isinstance(generator, str):
            generator = generator.encode('utf-8')

        msg = Message()
        msg['Wheel-Version'] = '1.0'  # of the spec
        msg['Generator'] = generator
        msg['Root-Is-Purelib'] = str(self.root_is_pure).lower()
        if self.build_number is not None:
            msg['Build'] = self.build_number

        # Doesn't work for bdist_wininst
        impl_tag, abi_tag, plat_tag = self.get_tag()
        for impl in impl_tag.split('.'):
            for abi in abi_tag.split('.'):
                for plat in plat_tag.split('.'):
                    msg['Tag'] = '-'.join((impl, abi, plat))

        wheelfile_path = os.path.join(wheelfile_base, 'WHEEL')
        logger.info('creating %s', wheelfile_path)
        buffer = BytesIO()
        BytesGenerator(buffer, maxheaderlen=0).flatten(msg)
        with open(wheelfile_path, 'wb') as f:
            f.write(buffer.getvalue().replace(b'\r\n', b'\r'))
Пример #27
0
 def _msg_generator(self, msg):
     outfp = BytesIO()
     if pycompat.PY3:
         BytesGenerator(outfp, policy=SMTP).flatten(msg, False)
         return outfp.getvalue()
     else:
         Generator(outfp).flatten(msg, False)
         return re.sub(_LINE_BREAK, b'\r\n', outfp.getvalue())
Пример #28
0
    def test_smtputf8_policy(self):
        msg = EmailMessage()
        msg['From'] = 'Páolo <fő[email protected]>'
        msg['To'] = 'Dinsdale'
        msg['Subject'] = 'Nudge nudge, wink, wink ὠ9'
        msg.set_content('oh là là, know what I mean, know what I mean?')
        expected = textwrap.dedent("""            From: Páolo <fő[email protected]>
            To: Dinsdale
            Subject: Nudge nudge, wink, wink ὠ9
            Content-Type: text/plain; charset="utf-8"
            Content-Transfer-Encoding: 8bit
            MIME-Version: 1.0

            oh là là, know what I mean, know what I mean?
            """).encode('utf-8').replace(b'\n', b'\r\n')
        s = io.BytesIO()
        g = BytesGenerator(s, policy=policy.SMTPUTF8)
        g.flatten(msg)
        self.assertEqual(s.getvalue(), expected)
Пример #29
0
    def test_smtputf8_policy(self):
        msg = EmailMessage()
        msg['From'] = "Páolo <fő[email protected]>"
        msg['To'] = 'Dinsdale'
        msg['Subject'] = 'Nudge nudge, wink, wink \u1F609'
        msg.set_content("oh là là, know what I mean, know what I mean?")
        expected = textwrap.dedent("""\
            From: Páolo <fő[email protected]>
            To: Dinsdale
            Subject: Nudge nudge, wink, wink \u1F609
            Content-Type: text/plain; charset="utf-8"
            Content-Transfer-Encoding: 8bit
            MIME-Version: 1.0

            oh là là, know what I mean, know what I mean?
            """).encode('utf-8').replace(b'\n', b'\r\n')
        s = io.BytesIO()
        g = BytesGenerator(s, policy=policy.SMTPUTF8)
        g.flatten(msg)
        self.assertEqual(s.getvalue(), expected)
Пример #30
0
    def test_smtp_policy(self):
        msg = EmailMessage()
        msg["From"] = Address(addr_spec="*****@*****.**", display_name="Páolo")
        msg["To"] = Address(addr_spec="*****@*****.**", display_name="Dinsdale")
        msg["Subject"] = "Nudge nudge, wink, wink"
        msg.set_content("oh boy, know what I mean, know what I mean?")
        expected = textwrap.dedent("""\
            From: =?utf-8?q?P=C3=A1olo?= <*****@*****.**>
            To: Dinsdale <*****@*****.**>
            Subject: Nudge nudge, wink, wink
            Content-Type: text/plain; charset="utf-8"
            Content-Transfer-Encoding: 7bit
            MIME-Version: 1.0

            oh boy, know what I mean, know what I mean?
            """).encode().replace(b"\n", b"\r\n")
        s = io.BytesIO()
        g = BytesGenerator(s, policy=policy.SMTP)
        g.flatten(msg)
        self.assertEqual(s.getvalue(), expected)
Пример #31
0
    def ingest(self, file_path, entity):
        mbox = mailbox.mbox(file_path)
        entity.schema = model.get('Package')
        entity.add('mimeType', self.DEFAULT_MIME)

        for i, msg in enumerate(mbox.itervalues(), 1):
            # Is there a risk of https://bugs.python.org/issue27321 ?
            try:
                msg_path = self.make_work_file('%s.eml' % i)
                with open(msg_path, 'wb') as fh:
                    gen = BytesGenerator(fh, policy=default)
                    gen.flatten(msg)
                checksum = self.manager.store(msg_path, mime_type=RFC822)
                msg_path.unlink()
                child = self.manager.make_entity('Email', parent=entity)
                child.make_id(checksum)
                child.add('contentHash', checksum)
                child.add('mimeType', RFC822)
                self.manager.queue_entity(child)
            except Exception:
                log.exception("[%r] Cannot extract message %s", entity, i)
Пример #32
0
 def do_POST(self):
     """ Echo a request with a body. """
     message = self.get_message()
     try:
         length = int(self.headers["Content-Length"])
     except (TypeError, ValueError) as exc:
         message.set_payload("Invalid Content-Length: {exc}".format(exc))
     else:
         message.set_payload(self.rfile.read(length))
     finally:
         self.send_head()
         BytesGenerator(self.wfile).flatten(message, unixfrom=False)
Пример #33
0
def encode_multipart_message(message):
    # The message must be multipart.
    assert message.is_multipart()
    # The body length cannot yet be known.
    assert "Content-Length" not in message
    # So line-endings can be fixed-up later on, component payloads must have
    # no Content-Length and their Content-Transfer-Encoding must be base64
    # (and not quoted-printable, which Django doesn't appear to understand).
    for part in message.get_payload():
        assert "Content-Length" not in part
        assert part["Content-Transfer-Encoding"] == "base64"
    # Flatten the message without headers.
    buf = BytesIO()
    generator = BytesGenerator(buf, False)  # Don't mangle "^From".
    generator._write_headers = lambda self: None  # Ignore.
    generator.flatten(message)
    # Ensure the body has CRLF-delimited lines. See
    # http://bugs.python.org/issue1349106.
    body = b"\r\n".join(buf.getvalue().splitlines())
    # Only now is it safe to set the content length.
    message.add_header("Content-Length", "%d" % len(body))
    return message.items(), body
Пример #34
0
def encode_multipart_message(message):
    # The message must be multipart.
    assert message.is_multipart()
    # The body length cannot yet be known.
    assert "Content-Length" not in message
    # So line-endings can be fixed-up later on, component payloads must have
    # no Content-Length and their Content-Transfer-Encoding must be base64
    # (and not quoted-printable, which Django doesn't appear to understand).
    for part in message.get_payload():
        assert "Content-Length" not in part
        assert part["Content-Transfer-Encoding"] == "base64"
    # Flatten the message without headers.
    buf = BytesIO()
    generator = BytesGenerator(buf, False)  # Don't mangle "^From".
    generator._write_headers = lambda self: None  # Ignore.
    generator.flatten(message)
    # Ensure the body has CRLF-delimited lines. See
    # http://bugs.python.org/issue1349106.
    body = b"\r\n".join(buf.getvalue().splitlines())
    # Only now is it safe to set the content length.
    message.add_header("Content-Length", "%d" % len(body))
    return message.items(), body
Пример #35
0
    def parse_msg(self, msg):
        """Parses the given :class:`~email.message.Message` to
        populate the :attr:`headers` and :attr:`message` attributes.

        :param data: The complete message, headers and message body.
        :type data: :class:`~email.message.Message`

        """
        # Can't use non-six BytesIO here cause python2 BytesGenerator will fail
        # to decode headers
        outfp = six.BytesIO()
        BytesGenerator(outfp).flatten(msg, False)
        data = outfp.getvalue()

        if six.PY2:
            data = data.encode()

        self.parse(data)
Пример #36
0
 def msg_as_input(self, msg):
     m = message_from_bytes(msg, policy=policy.SMTP)
     b = io.BytesIO()
     g = BytesGenerator(b)
     g.flatten(m)
     self.assertEqual(b.getvalue(), msg)
Пример #37
0
 def __init__(self, fp, root=True):
     # don't try to use super() here; in py2 Generator is not a
     # new-style class.  Yuck.
     TheGenerator.__init__(self, fp, mangle_from_=False,
                           maxheaderlen=0)
     self.root = root
Пример #38
0
 def msg_as_input(self, msg):
     m = message_from_bytes(msg, policy=policy.SMTP)
     b = io.BytesIO()
     g = BytesGenerator(b)
     g.flatten(m)
     self.assertEqual(b.getvalue(), msg)
Пример #39
0
 def write_pkg_info(path, message):
     with open(path, "wb") as out:
         BytesGenerator(out, maxheaderlen=0).flatten(message)
Пример #40
0
def msg2bytes(msg):
    f = MyBytesIO()
    BytesGenerator(f).flatten(msg)
    return f.getvalue()
Пример #41
0
    text = lsb_release + '\n' + '\n'.join(env)
    attachment = MIMEText(text, _charset='UTF-8')
    attachment.add_header('Content-Disposition', 'inline')
    message = MIMEMultipart()
    message.add_header('Tags', 'snap')
    message.attach(attachment)
    blob = message.as_string().encode('UTF-8')
    url = 'https://{}/+storeblob'.format(LAUNCHPAD)
    data = MIMEMultipart()
    submit = MIMEText('1')
    submit.add_header('Content-Disposition', 'form-data; name="FORM_SUBMIT"')
    data.attach(submit)
    form_blob = MIMEBase('application', 'octet-stream')
    form_blob.add_header('Content-Disposition',
                         'form-data; name="field.blob"; filename="x"')
    form_blob.set_payload(blob.decode('ascii'))
    data.attach(form_blob)
    data_flat = BytesIO()
    gen = BytesGenerator(data_flat, mangle_from_=False)
    gen.flatten(data)
    request = Request(url, data_flat.getvalue())
    request.add_header('Content-Type',
                       'multipart/form-data; boundary=' + data.get_boundary())
    opener = build_opener(HTTPSHandler)
    result = opener.open(request)
    handle = result.info().get('X-Launchpad-Blob-Token')
    summary = '[snap] SUMMARY HERE'.encode('UTF-8')
    params = urlencode({'field.title': summary})
    filebug_url = 'https://bugs.{}/ubuntu/+source/libreoffice/+filebug/{}?{}'
    subprocess.run(["xdg-open", filebug_url.format(LAUNCHPAD, handle, params)])