Beispiel #1
0
def safe_fix_maintainer(content, fieldname):
    """Wrapper for fix_maintainer() to handle unicode and string argument.

    It verifies the content type and transform it in a unicode with guess()
    before call ascii_smash(). Then we can safely call fix_maintainer().
    """
    if type(content) != unicode:
        content = guess_encoding(content)

    content = ascii_smash(content)

    return fix_maintainer(content, fieldname)
Beispiel #2
0
def safe_fix_maintainer(content, fieldname):
    """Wrapper for fix_maintainer() to handle unicode and string argument.

    It verifies the content type and transform it in a unicode with guess()
    before call ascii_smash(). Then we can safely call fix_maintainer().
    """
    if type(content) != unicode:
        content = guess_encoding(content)

    content = ascii_smash(content)

    return fix_maintainer(content, fieldname)
def send_mail(spr,
              archive,
              to_addrs,
              subject,
              mail_text,
              dry_run,
              from_addr=None,
              bcc=None,
              changesfile_content=None,
              attach_changes=False,
              logger=None):
    """Send an email to to_addrs with the given text and subject.

    :param spr: The `ISourcePackageRelease` to be notified about.
    :param archive: The target `IArchive`.
    :param to_addrs: A list of email addresses to be used as recipients.
        Each email must be a valid ASCII str instance or a unicode one.
    :param subject: The email's subject.
    :param mail_text: The text body of the email. Unicode is preserved in the
        email.
    :param dry_run: Whether or not an email should actually be sent. But
        please note that this flag is (largely) ignored.
    :param from_addr: The email address to be used as the sender. Must be a
        valid ASCII str instance or a unicode one.  Defaults to the email
        for config.uploader.
    :param bcc: Optional email Blind Carbon Copy address(es).
    :param param changesfile_content: The content of the actual changesfile.
    :param attach_changes: A flag governing whether the original changesfile
        content shall be attached to the email.
    """
    extra_headers = {'X-Katie': 'Launchpad actually'}

    # Include the 'X-Launchpad-PPA' header for PPA upload notfications
    # containing the PPA owner name.
    if archive.is_ppa:
        extra_headers['X-Launchpad-PPA'] = get_ppa_reference(archive)

    # Include a 'X-Launchpad-Component' header with the component and
    # the section of the source package uploaded in order to facilitate
    # filtering on the part of the email recipients.
    if spr:
        xlp_component_header = 'component=%s, section=%s' % (
            spr.component.name, spr.section.name)
        extra_headers['X-Launchpad-Component'] = xlp_component_header

    if from_addr is None:
        from_addr = format_address(config.uploader.default_sender_name,
                                   config.uploader.default_sender_address)

    # `sendmail`, despite handling unicode message bodies, can't
    # cope with non-ascii sender/recipient addresses, so ascii_smash
    # is used on all addresses.

    # All emails from here have a Bcc to the default recipient.
    bcc_text = format_address(config.uploader.default_recipient_name,
                              config.uploader.default_recipient_address)
    if bcc:
        bcc_text = "%s, %s" % (bcc_text, bcc)
    extra_headers['Bcc'] = ascii_smash(bcc_text)

    recipients = ascii_smash(", ".join(to_addrs))
    if isinstance(from_addr, unicode):
        # ascii_smash only works on unicode strings.
        from_addr = ascii_smash(from_addr)
    else:
        from_addr.encode('ascii')

    if dry_run and logger is not None:
        debug(logger, "Would have sent a mail:")
    else:
        debug(logger, "Sent a mail:")
    debug(logger, "  Subject: %s" % subject)
    debug(logger, "  Sender: %s" % from_addr)
    debug(logger, "  Recipients: %s" % recipients)
    if 'Bcc' in extra_headers:
        debug(logger, "  Bcc: %s" % extra_headers['Bcc'])
    debug(logger, "  Body:")
    for line in mail_text.splitlines():
        if isinstance(line, str):
            line = line.decode('utf-8', 'replace')
        debug(logger, line)

    if not dry_run:
        # Since we need to send the original changesfile as an
        # attachment the sendmail() method will be used as opposed to
        # simple_sendmail().
        message = MIMEMultipart()
        message['from'] = from_addr
        message['subject'] = subject
        message['to'] = recipients

        # Set the extra headers if any are present.
        for key, value in extra_headers.iteritems():
            message.add_header(key, value)

        # Add the email body.
        message.attach(
            MIMEText(
                sanitize_string(mail_text).encode('utf-8'), 'plain', 'utf-8'))

        if attach_changes:
            # Add the original changesfile as an attachment.
            if changesfile_content is not None:
                changesfile_text = sanitize_string(changesfile_content)
            else:
                changesfile_text = ("Sorry, changesfile not available.")

            attachment = MIMEText(changesfile_text.encode('utf-8'), 'plain',
                                  'utf-8')
            attachment.add_header('Content-Disposition',
                                  'attachment; filename="changesfile"')
            message.attach(attachment)

        # And finally send the message.
        sendmail(message)
def send_mail(
    spr, archive, to_addrs, subject, mail_text, dry_run, from_addr=None,
    bcc=None, changesfile_content=None, attach_changes=False, logger=None):
    """Send an email to to_addrs with the given text and subject.

    :param spr: The `ISourcePackageRelease` to be notified about.
    :param archive: The target `IArchive`.
    :param to_addrs: A list of email addresses to be used as recipients.
        Each email must be a valid ASCII str instance or a unicode one.
    :param subject: The email's subject.
    :param mail_text: The text body of the email. Unicode is preserved in the
        email.
    :param dry_run: Whether or not an email should actually be sent. But
        please note that this flag is (largely) ignored.
    :param from_addr: The email address to be used as the sender. Must be a
        valid ASCII str instance or a unicode one.  Defaults to the email
        for config.uploader.
    :param bcc: Optional email Blind Carbon Copy address(es).
    :param param changesfile_content: The content of the actual changesfile.
    :param attach_changes: A flag governing whether the original changesfile
        content shall be attached to the email.
    """
    extra_headers = {'X-Katie': 'Launchpad actually'}

    # Include the 'X-Launchpad-PPA' header for PPA upload notfications
    # containing the PPA owner name.
    if archive.is_ppa:
        extra_headers['X-Launchpad-PPA'] = get_ppa_reference(archive)

    # Include a 'X-Launchpad-Component' header with the component and
    # the section of the source package uploaded in order to facilitate
    # filtering on the part of the email recipients.
    if spr:
        xlp_component_header = 'component=%s, section=%s' % (
            spr.component.name, spr.section.name)
        extra_headers['X-Launchpad-Component'] = xlp_component_header

    if from_addr is None:
        from_addr = format_address(
            config.uploader.default_sender_name,
            config.uploader.default_sender_address)

    # `sendmail`, despite handling unicode message bodies, can't
    # cope with non-ascii sender/recipient addresses, so ascii_smash
    # is used on all addresses.

    # All emails from here have a Bcc to the default recipient.
    bcc_text = format_address(
        config.uploader.default_recipient_name,
        config.uploader.default_recipient_address)
    if bcc:
        bcc_text = "%s, %s" % (bcc_text, bcc)
    extra_headers['Bcc'] = ascii_smash(bcc_text)

    recipients = ascii_smash(", ".join(to_addrs))
    if isinstance(from_addr, unicode):
        # ascii_smash only works on unicode strings.
        from_addr = ascii_smash(from_addr)
    else:
        from_addr.encode('ascii')

    if dry_run and logger is not None:
        debug(logger, "Would have sent a mail:")
    else:
        debug(logger, "Sent a mail:")
    debug(logger, "  Subject: %s" % subject)
    debug(logger, "  Sender: %s" % from_addr)
    debug(logger, "  Recipients: %s" % recipients)
    if 'Bcc' in extra_headers:
        debug(logger, "  Bcc: %s" % extra_headers['Bcc'])
    debug(logger, "  Body:")
    for line in mail_text.splitlines():
        if isinstance(line, str):
            line = line.decode('utf-8', 'replace')
        debug(logger, line)

    if not dry_run:
        # Since we need to send the original changesfile as an
        # attachment the sendmail() method will be used as opposed to
        # simple_sendmail().
        message = MIMEMultipart()
        message['from'] = from_addr
        message['subject'] = subject
        message['to'] = recipients

        # Set the extra headers if any are present.
        for key, value in extra_headers.iteritems():
            message.add_header(key, value)

        # Add the email body.
        message.attach(
            MIMEText(sanitize_string(mail_text).encode('utf-8'),
                'plain', 'utf-8'))

        if attach_changes:
            # Add the original changesfile as an attachment.
            if changesfile_content is not None:
                changesfile_text = sanitize_string(changesfile_content)
            else:
                changesfile_text = ("Sorry, changesfile not available.")

            attachment = MIMEText(
                changesfile_text.encode('utf-8'), 'plain', 'utf-8')
            attachment.add_header(
                'Content-Disposition',
                'attachment; filename="changesfile"')
            message.attach(attachment)

        # And finally send the message.
        sendmail(message)