def assert_forward_content_equal(self, content):
     """
     Asserts that the content of the forwarded message is equal to the given
     ``content``.
     """
     msg = mail.outbox[0].message()
     self.assertEqual(get_decoded_message_payload(msg), content)
Example #2
0
def _get_message_body(msg):
    """
    Returns the message body, joining together all parts into one string.

    :param msg: The original received package message
    :type msg: :py:class:`email.message.Message`
    """
    return '\n'.join(get_decoded_message_payload(part)
                     for part in msg.walk() if not part.is_multipart())
Example #3
0
def process(message):
    """
    The function which actually processes a received command email message.

    :param message: The received command email message.
    :type message: ``bytes``
    """
    assert isinstance(message, six.binary_type), 'Message must be given as bytes'
    msg = message_from_bytes(message)
    # msg = message_from_string(message)
    if 'X-Loop' in msg and PTS_CONTROL_EMAIL in msg.get_all('X-Loop'):
        return
    # Get the first plain-text part of the message
    plain_text_part = next(typed_subpart_iterator(msg, 'text', 'plain'), None)
    if not plain_text_part:
        # There is no plain text in the email
        send_plain_text_warning(msg)
        return

    # Decode the plain text into a unicode string
    try:
        text = get_decoded_message_payload(plain_text_part)
    except UnicodeDecodeError:
        send_plain_text_warning(msg)
        return

    lines = extract_command_from_subject(msg) + text.splitlines()
    # Process the commands
    factory = CommandFactory({
        'email': extract_email_address_from_header(msg['From']),
    })
    confirmation_set = ConfirmationSet()
    processor = CommandProcessor(factory)
    processor.confirmation_set = confirmation_set
    processor.process(lines)

    confirmation_set.ask_confirmation_all()
    # Send a response only if there were some commands processed
    if processor.is_success():
        send_response(
            msg, processor.get_output(), set(confirmation_set.get_emails()))
Example #4
0
def create_news_from_email_message(message):
    """
    In Debian's implementation, this function creates news when the received
    mail's origin is either the testing watch or katie.
    """
    subject = message.get("Subject", None)
    if not subject:
        return
    subject_words = subject.split()

    # Source upload?
    if len(subject_words) > 1 and subject_words[0] in ('Accepted', 'Installed'):
        if 'source' not in subject:
            # Only source uploads should be considered.
            return
        package_name = subject_words[1]
        package = get_or_none(SourcePackageName, name=package_name)
        if package:
            return [EmailNews.objects.create_email_news(message, package)]
    # DAK rm?
    elif 'X-DAK' in message:
        x_dak = message['X-DAK']
        katie = x_dak.split()[1]

        if katie != 'rm':
            # Only rm mails are processed.
            return

        body = get_decoded_message_payload(message)
        if not body:
            # The content cannot be decoded.
            return
        # Find all lines giving information about removed source packages
        re_rmline = re.compile(r"^\s*(\S+)\s*\|\s*(\S+)\s*\|.*source", re.M)
        source_removals = re_rmline.findall(body)
        # Find the suite from which the packages have been removed
        suite = re.search(r"have been removed from (\S+):", body).group(1)
        news_from = message.get('Sender', '')
        # Add a news item for each source removal.
        created_news = []
        for removal in source_removals:
            package_name, version = removal
            package = get_or_none(SourcePackageName, name=package_name)
            if not package:
                # This package is not tracked by the PTS
                continue
            title = "Removed {ver} from {suite}".format(ver=version, suite=suite)
            created_news.append(EmailNews.objects.create_email_news(
                title=title,
                message=message,
                package=package,
                created_by=news_from))
        return created_news
    # Testing Watch?
    elif 'X-Testing-Watch-Package' in message:
        package_name = message['X-Testing-Watch-Package']
        package = get_or_none(SourcePackageName, name=package_name)
        if not package:
            # This package is not tracked by the PTS
            return
        title = message.get('Subject', '')
        if not title:
            title = 'Testing Watch Message'
        return [
            EmailNews.objects.create_email_news(
                title=title,
                message=message,
                package=package,
                created_by='Britney')
        ]