def test_address_domain_ro(self):
     self._test_attr_ro(Address('foo', 'bar', 'baz'), 'domain')
Пример #2
0
from email.headerregistry import Address
from email.message import EmailMessage
import os
import smtplib
import sys

# Gmail details
email_address = "*****@*****.**"
email_password = "******"

# Recipent
to_address = (
	Address(username='******', domain='hotmail.com'),
	Address(username='******', domain='lohjanpallo.fi')
)


def create_email_message(from_address, to_address, subject, body):
    msg = EmailMessage()
    msg['From'] = from_address
    msg['To'] = to_address
    msg['Subject'] = subject
    msg.set_content(body)
    return msg

if sys.argv[1] == '0':
	title='Sähkökatko on ohi'
	text='Sähkökatko ohi kuplahallissa!'
else:
	title='Sähkökatko'
	text='Sähkökatko kuplahallissa!'
Пример #3
0
def build_email(
    template_prefix: str,
    to_user_ids: Optional[List[int]] = None,
    to_emails: Optional[List[str]] = None,
    from_name: Optional[str] = None,
    from_address: Optional[str] = None,
    reply_to_email: Optional[str] = None,
    language: Optional[str] = None,
    context: Mapping[str, Any] = {},
    realm: Optional[Realm] = None,
) -> EmailMultiAlternatives:
    # Callers should pass exactly one of to_user_id and to_email.
    assert (to_user_ids is None) ^ (to_emails is None)
    if to_user_ids is not None:
        to_users = [
            get_user_profile_by_id(to_user_id) for to_user_id in to_user_ids
        ]
        if realm is None:
            assert len({to_user.realm_id for to_user in to_users}) == 1
            realm = to_users[0].realm
        to_emails = [
            str(
                Address(display_name=to_user.full_name,
                        addr_spec=to_user.delivery_email))
            for to_user in to_users
        ]

    extra_headers = {}
    if realm is not None:
        # formaddr is meant for formatting (display_name, email_address) pair for headers like "To",
        # but we can use its utility for formatting the List-Id header, as it follows the same format,
        # except having just a domain instead of an email address.
        extra_headers["List-Id"] = formataddr((realm.name, realm.host))

    context = {
        **context,
        "support_email": FromAddress.SUPPORT,
        "email_images_base_uri":
        settings.ROOT_DOMAIN_URI + "/static/images/emails",
        "physical_address": settings.PHYSICAL_ADDRESS,
    }

    def render_templates() -> Tuple[str, str, str]:
        email_subject = (loader.render_to_string(
            template_prefix + ".subject.txt",
            context=context,
            using="Jinja2_plaintext").strip().replace("\n", ""))
        message = loader.render_to_string(template_prefix + ".txt",
                                          context=context,
                                          using="Jinja2_plaintext")

        try:
            html_message = loader.render_to_string(template_prefix + ".html",
                                                   context)
        except TemplateDoesNotExist:
            emails_dir = os.path.dirname(template_prefix)
            template = os.path.basename(template_prefix)
            compiled_template_prefix = os.path.join(emails_dir, "compiled",
                                                    template)
            html_message = loader.render_to_string(
                compiled_template_prefix + ".html", context)
        return (html_message, message, email_subject)

    # The i18n story for emails is a bit complicated.  For emails
    # going to a single user, we want to use the language that user
    # has configured for their Zulip account.  For emails going to
    # multiple users or to email addresses without a known Zulip
    # account (E.g. invitations), we want to use the default language
    # configured for the Zulip organization.
    #
    # See our i18n documentation for some high-level details:
    # https://zulip.readthedocs.io/en/latest/translating/internationalization.html

    if not language and to_user_ids is not None:
        language = to_users[0].default_language
    if language:
        with override_language(language):
            # Make sure that we render the email using the target's native language
            (html_message, message, email_subject) = render_templates()
    else:
        (html_message, message, email_subject) = render_templates()
        logger.warning("Missing language for email template '%s'",
                       template_prefix)

    if from_name is None:
        from_name = "Zulip"
    if from_address is None:
        from_address = FromAddress.NOREPLY
    if from_address == FromAddress.tokenized_no_reply_placeholder:
        from_address = FromAddress.tokenized_no_reply_address()
    if from_address == FromAddress.no_reply_placeholder:
        from_address = FromAddress.NOREPLY
    if from_address == FromAddress.support_placeholder:
        from_address = FromAddress.SUPPORT

    # Set the "From" that is displayed separately from the envelope-from.
    extra_headers["From"] = str(
        Address(display_name=from_name, addr_spec=from_address))
    # Check ASCII encoding length.  Amazon SES rejects emails with
    # From names longer than 320 characters (which appears to be a
    # misinterpretation of the RFC); in that case we drop the name
    # from the From line, under the theory that it's better to send
    # the email with a simplified From field than not.
    if len(sanitize_address(extra_headers["From"], "utf-8")) > 320:
        extra_headers["From"] = str(Address(addr_spec=from_address))

    reply_to = None
    if reply_to_email is not None:
        reply_to = [reply_to_email]
    # Remove the from_name in the reply-to for noreply emails, so that users
    # see "noreply@..." rather than "Zulip" or whatever the from_name is
    # when they reply in their email client.
    elif from_address == FromAddress.NOREPLY:
        reply_to = [FromAddress.NOREPLY]

    envelope_from = FromAddress.NOREPLY
    mail = EmailMultiAlternatives(email_subject,
                                  message,
                                  envelope_from,
                                  to_emails,
                                  reply_to=reply_to,
                                  headers=extra_headers)
    if html_message is not None:
        mail.attach_alternative(html_message, "text/html")
    return mail
Пример #4
0
from email.headerregistry import Address
import pytest
from mailbits import parse_address


@pytest.mark.parametrize(
    "s,addr",
    [
        ("*****@*****.**", Address("", addr_spec="*****@*****.**")),
        ("<*****@*****.**>", Address("", addr_spec="*****@*****.**")),
        (
            "Linus User <*****@*****.**>",
            Address("Linus User", addr_spec="*****@*****.**"),
        ),
        (
            '"Linus User" <*****@*****.**>',
            Address("Linus User", addr_spec="*****@*****.**"),
        ),
        (
            "Zoë Façade <zoe.facade@naïveté.fr>",
            Address("Zoë Façade", addr_spec="zoe.facade@naïveté.fr"),
        ),
        (
            "=?ISO-8859-1?Q?Keld_J=F8rn_Simonsen?= <*****@*****.**>",
            Address("Keld Jørn Simonsen", addr_spec="*****@*****.**"),
        ),
    ],
)
def test_parse_address(s: str, addr: Address) -> None:
    assert parse_address(s) == addr
Пример #5
0
def _format_sender(sitename, sender):
    if sender is not None:
        return str(Address(sitename, addr_spec=sender))
Пример #6
0
#!/anaconda3/bin/python

import smtplib

from email.message import EmailMessage
from email.headerregistry import Address
from email.utils import make_msgid

FEMAIL = '*****@*****.**'

# Create the base text message.
msg = EmailMessage()
msg['Subject'] = "Printheads beach"
msg['From'] = Address("Mike Mueller", "muellerm111", "frontier.com")
# msg['To'] = (Address("Muellers", "m2", "themuellers.us"),
#             Address("beach 5520", "88b34hjm", "hpeprint.com"),
#             Address("warehouse 5520", "998wtp3379x", "hpeprint.com"))

msg['To'] = (Address("Muellers", "m2", "themuellers.us"),
             Address("beach 5520", "88b34hjm", "hpeprint.com"))

msg.set_content('...........')  # Not at all sure what this does
# Add the html version.  This converts the message into a multipart/alternative
# container, with the original text message as the first part and the new html
# message as the second part.
colors_cid = make_msgid()
msg.add_alternative("""\
<html>
  <head></head>
  <body>
    <p>Hello printer!</p>
Пример #7
0
def add_recipients(msg: EmailMessage):
    """Add the recipients listed in the local config file to the email"""
    with open(email_recipients_filepath, 'r') as recipient_file:
        recipients = json.load(recipient_file)['recipients']
    msg['To'] = Group('Report Group',
                      list(map(lambda x: Address(**x), recipients)))
 def test_group_with_one_address_no_display_name(self):
     addrs = [Address('b', 'b', 'c')]
     g = Group(addresses=addrs)
     self.assertIsNone(g.display_name)
     self.assertEqual(g.addresses, tuple(addrs))
     self.assertEqual(str(g), 'b <b@c>')
 def test_set_message_header_from_address(self):
     a = Address('foo', 'bar', 'example.com')
     m = Message(policy=policy.default)
     m['To'] = a
     self.assertEqual(m['to'], 'foo <*****@*****.**>')
     self.assertEqual(m['to'].addresses, (a,))
 def test_bad_addr_sepc_raises(self):
     with self.assertRaises(ValueError):
         Address('foo', addr_spec='name@ex[]ample.com')
 def test_group_with_addresses(self):
     addrs = [Address('b', 'b', 'c'), Address('a', 'b', 'c')]
     g = Group('foo', addrs)
     self.assertEqual(g.display_name, 'foo')
     self.assertEqual(g.addresses, tuple(addrs))
     self.assertEqual(str(g), 'foo: b <b@c>, a <b@c>;')
 def test_space_in_addr_spec_username_raises(self):
     with self.assertRaises(ValueError):
         Address('foo', addr_spec='bad [email protected]')
 def test_address_addr_spec_and_username_and_domain_raises(self):
     with self.assertRaises(TypeError):
         Address('foo', username='******', domain='bing', addr_spec='bar@baz')
 def test_non_ascii_username_in_addr_spec_raises(self):
     with self.assertRaises(ValueError):
         Address('foo', addr_spec='wő[email protected]')
Пример #15
0
def do_send_missedmessage_events_reply_in_zulip(user_profile: UserProfile,
                                                missed_messages: List[Dict[
                                                    str, Any]],
                                                message_count: int) -> None:
    """
    Send a reminder email to a user if she's missed some PMs by being offline.

    The email will have its reply to address set to a limited used email
    address that will send a Zulip message to the correct recipient. This
    allows the user to respond to missed PMs, huddles, and @-mentions directly
    from the email.

    `user_profile` is the user to send the reminder to
    `missed_messages` is a list of dictionaries to Message objects and other data
                      for a group of messages that share a recipient (and topic)
    """
    from zerver.context_processors import common_context

    recipients = {(msg["message"].recipient_id, msg["message"].topic_name())
                  for msg in missed_messages}
    if len(recipients) != 1:
        raise ValueError(
            f"All missed_messages must have the same recipient and topic {recipients!r}",
        )

    # This link is no longer a part of the email, but keeping the code in case
    # we find a clean way to add it back in the future
    unsubscribe_link = one_click_unsubscribe_link(user_profile,
                                                  "missed_messages")
    context = common_context(user_profile)
    context.update(
        name=user_profile.full_name,
        message_count=message_count,
        unsubscribe_link=unsubscribe_link,
        realm_name_in_notifications=user_profile.realm_name_in_notifications,
    )

    mentioned_user_group_name = get_mentioned_user_group_name(
        missed_messages, user_profile)
    triggers = [message["trigger"] for message in missed_messages]
    unique_triggers = set(triggers)

    context.update(
        mention="mentioned" in unique_triggers
        or "wildcard_mentioned" in unique_triggers,
        stream_email_notify="stream_email_notify" in unique_triggers,
        mention_count=triggers.count("mentioned") +
        triggers.count("wildcard_mentioned"),
        mentioned_user_group_name=mentioned_user_group_name,
    )

    # If this setting (email mirroring integration) is enabled, only then
    # can users reply to email to send message to Zulip. Thus, one must
    # ensure to display warning in the template.
    if settings.EMAIL_GATEWAY_PATTERN:
        context.update(reply_to_zulip=True, )
    else:
        context.update(reply_to_zulip=False, )

    from zerver.lib.email_mirror import create_missed_message_address

    reply_to_address = create_missed_message_address(
        user_profile, missed_messages[0]["message"])
    if reply_to_address == FromAddress.NOREPLY:
        reply_to_name = ""
    else:
        reply_to_name = "Zulip"

    narrow_url = get_narrow_url(user_profile, missed_messages[0]["message"])
    context.update(narrow_url=narrow_url, )

    senders = list({m["message"].sender for m in missed_messages})
    if missed_messages[0]["message"].recipient.type == Recipient.HUDDLE:
        display_recipient = get_display_recipient(
            missed_messages[0]["message"].recipient)
        # Make sure that this is a list of strings, not a string.
        assert not isinstance(display_recipient, str)
        other_recipients = [
            r["full_name"] for r in display_recipient
            if r["id"] != user_profile.id
        ]
        context.update(group_pm=True)
        if len(other_recipients) == 2:
            huddle_display_name = " and ".join(other_recipients)
            context.update(huddle_display_name=huddle_display_name)
        elif len(other_recipients) == 3:
            huddle_display_name = (
                f"{other_recipients[0]}, {other_recipients[1]}, and {other_recipients[2]}"
            )
            context.update(huddle_display_name=huddle_display_name)
        else:
            huddle_display_name = "{}, and {} others".format(
                ", ".join(other_recipients[:2]),
                len(other_recipients) - 2)
            context.update(huddle_display_name=huddle_display_name)
    elif missed_messages[0]["message"].recipient.type == Recipient.PERSONAL:
        context.update(private_message=True)
    elif context["mention"] or context["stream_email_notify"]:
        # Keep only the senders who actually mentioned the user
        if context["mention"]:
            senders = list({
                m["message"].sender
                for m in missed_messages if m["trigger"] == "mentioned"
                or m["trigger"] == "wildcard_mentioned"
            })
        message = missed_messages[0]["message"]
        stream = Stream.objects.only("id",
                                     "name").get(id=message.recipient.type_id)
        stream_header = f"{stream.name} > {message.topic_name()}"
        context.update(stream_header=stream_header, )
    else:
        raise AssertionError("Invalid messages!")

    # If message content is disabled, then flush all information we pass to email.
    if not message_content_allowed_in_missedmessage_emails(user_profile):
        realm = user_profile.realm
        context.update(
            reply_to_zulip=False,
            messages=[],
            sender_str="",
            realm_str=realm.name,
            huddle_display_name="",
            show_message_content=False,
            message_content_disabled_by_user=not user_profile.
            message_content_in_email_notifications,
            message_content_disabled_by_realm=not realm.
            message_content_allowed_in_email_notifications,
        )
    else:
        context.update(
            messages=build_message_list(
                user=user_profile,
                messages=[m["message"] for m in missed_messages],
                stream_map={},
            ),
            sender_str=", ".join(sender.full_name for sender in senders),
            realm_str=user_profile.realm.name,
            show_message_content=True,
        )

    with override_language(user_profile.default_language):
        from_name: str = _("Zulip notifications")
    from_address = FromAddress.NOREPLY
    if len(senders) == 1 and settings.SEND_MISSED_MESSAGE_EMAILS_AS_USER:
        # If this setting is enabled, you can reply to the Zulip
        # message notification emails directly back to the original sender.
        # However, one must ensure the Zulip server is in the SPF
        # record for the domain, or there will be spam/deliverability
        # problems.
        #
        # Also, this setting is not really compatible with
        # EMAIL_ADDRESS_VISIBILITY_ADMINS.
        sender = senders[0]
        from_name, from_address = (sender.full_name, sender.email)
        context.update(reply_to_zulip=False, )

    email_dict = {
        "template_prefix":
        "zerver/emails/missed_message",
        "to_user_ids": [user_profile.id],
        "from_name":
        from_name,
        "from_address":
        from_address,
        "reply_to_email":
        str(Address(display_name=reply_to_name, addr_spec=reply_to_address)),
        "context":
        context,
    }
    queue_json_publish("email_senders", email_dict)

    user_profile.last_reminder = timezone_now()
    user_profile.save(update_fields=["last_reminder"])
Пример #16
0
 def decode(self, s):
     try:
         return Address(display_name=s["display_name"],
                        addr_spec=s["addr_spec"])
     except InvalidHeaderDefect:
         return ""
Пример #17
0
import smtplib
import imghdr
from email.message import EmailMessage
from email.headerregistry import Address

MY_ADDRESS = '*****@*****.**'
PASSWORD = '******'

to_addr = Address(display_name='Reli Salazar',
                  username='******',
                  domain='gmail.com')

msg = EmailMessage()
msg['Subject'] = 'Testing Testing 1.2.3'
msg['From'] = 'Reli'
msg['To'] = to_addr
msg.set_content("""Hola yo

Esto es un test para enviar correos utilizando SMTP.

Con mucho odio
Yo""")

with open('img_test.jpeg', 'rb') as fp:
    img_data = fp.read()

msg.add_attachment(img_data,
                   maintype='image',
                   subtype=imghdr.what(None, img_data),
                   filename='img_test.jpeg')
Пример #18
0
def _get_recipients(receivers):
    return [
        Address(item["name"], addr_spec=item["email"])
        for item in receivers
    ]
Пример #19
0
def build_email(
    template_prefix: str,
    to_user_ids: Optional[List[int]] = None,
    to_emails: Optional[List[str]] = None,
    from_name: Optional[str] = None,
    from_address: Optional[str] = None,
    reply_to_email: Optional[str] = None,
    language: Optional[str] = None,
    context: Mapping[str, Any] = {},
) -> EmailMultiAlternatives:
    # Callers should pass exactly one of to_user_id and to_email.
    assert (to_user_ids is None) ^ (to_emails is None)
    if to_user_ids is not None:
        to_users = [
            get_user_profile_by_id(to_user_id) for to_user_id in to_user_ids
        ]
        to_emails = [
            str(
                Address(display_name=to_user.full_name,
                        addr_spec=to_user.delivery_email))
            for to_user in to_users
        ]

    context = {
        **context,
        'support_email': FromAddress.SUPPORT,
        'email_images_base_uri':
        settings.ROOT_DOMAIN_URI + '/static/images/emails',
        'physical_address': settings.PHYSICAL_ADDRESS,
    }

    def render_templates() -> Tuple[str, str, str]:
        email_subject = loader.render_to_string(
            template_prefix + '.subject.txt',
            context=context,
            using='Jinja2_plaintext').strip().replace('\n', '')
        message = loader.render_to_string(template_prefix + '.txt',
                                          context=context,
                                          using='Jinja2_plaintext')

        try:
            html_message = loader.render_to_string(template_prefix + '.html',
                                                   context)
        except TemplateDoesNotExist:
            emails_dir = os.path.dirname(template_prefix)
            template = os.path.basename(template_prefix)
            compiled_template_prefix = os.path.join(emails_dir, "compiled",
                                                    template)
            html_message = loader.render_to_string(
                compiled_template_prefix + '.html', context)
        return (html_message, message, email_subject)

    if not language and to_user_ids is not None:
        language = to_users[0].default_language
    if language:
        with override_language(language):
            # Make sure that we render the email using the target's native language
            (html_message, message, email_subject) = render_templates()
    else:
        (html_message, message, email_subject) = render_templates()
        logger.warning("Missing language for email template '%s'",
                       template_prefix)

    if from_name is None:
        from_name = "Zulip"
    if from_address is None:
        from_address = FromAddress.NOREPLY
    if from_address == FromAddress.tokenized_no_reply_placeholder:
        from_address = FromAddress.tokenized_no_reply_address()
    if from_address == FromAddress.no_reply_placeholder:
        from_address = FromAddress.NOREPLY
    if from_address == FromAddress.support_placeholder:
        from_address = FromAddress.SUPPORT

    from_email = str(Address(display_name=from_name, addr_spec=from_address))
    reply_to = None
    if reply_to_email is not None:
        reply_to = [reply_to_email]
    # Remove the from_name in the reply-to for noreply emails, so that users
    # see "noreply@..." rather than "Zulip" or whatever the from_name is
    # when they reply in their email client.
    elif from_address == FromAddress.NOREPLY:
        reply_to = [FromAddress.NOREPLY]

    mail = EmailMultiAlternatives(email_subject,
                                  message,
                                  from_email,
                                  to_emails,
                                  reply_to=reply_to)
    if html_message is not None:
        mail.attach_alternative(html_message, 'text/html')
    return mail
Пример #20
0
    date = arguments['--filter']
    if date:
        try:
            subscriptions = subscriptions[subscriptions.index > date]
        except ValueError as e:
            logging.exception('Could not filter subscriptions' + pr(e))
            sys.exit()

    logging.info(subscriptions.describe())

    year, month = get_year_month()
    server = build_smtp_server(cfg['smtp_server']['name'],
                               cfg['smtp_server'].getint('port'))
    server.login(cfg['sender']['mailbox'], cfg['sender']['password'])
    sender = Address(cfg['sender']['display_name'], cfg['sender']['username'],
                     cfg['sender']['domain'])
    sensor_ids = {}

    for index, row in subscriptions.iterrows():
        receiver, sensor_id = row

        if not (sensor_id in sensor_ids):
            sensor = luftdaten.Sensor(sensor_id)
            if sensor.metadata is None:
                logging.error('could not create sensor %s', sensor_id)
                continue
            logging.info('generate overview for sensor %s', sensor_id)

            figs = report.report_basic_month_overview(sensor,
                                                      year,
                                                      month,
Пример #21
0
def build_email(template_prefix: str,
                to_user_ids: Optional[List[int]] = None,
                to_emails: Optional[List[str]] = None,
                from_name: Optional[str] = None,
                from_address: Optional[str] = None,
                reply_to_email: Optional[str] = None,
                language: Optional[str] = None,
                context: Mapping[str, Any] = {},
                realm: Optional[Realm] = None) -> EmailMultiAlternatives:
    # Callers should pass exactly one of to_user_id and to_email.
    assert (to_user_ids is None) ^ (to_emails is None)
    if to_user_ids is not None:
        to_users = [
            get_user_profile_by_id(to_user_id) for to_user_id in to_user_ids
        ]
        if realm is None:
            assert len({to_user.realm_id for to_user in to_users}) == 1
            realm = to_users[0].realm
        to_emails = [
            str(
                Address(display_name=to_user.full_name,
                        addr_spec=to_user.delivery_email))
            for to_user in to_users
        ]

    extra_headers = {}
    if realm is not None:
        # formaddr is meant for formatting (display_name, email_address) pair for headers like "To",
        # but we can use its utility for formatting the List-Id header, as it follows the same format,
        # except having just a domain instead of an email address.
        extra_headers['List-Id'] = formataddr((realm.name, realm.host))

    context = {
        **context,
        'support_email': FromAddress.SUPPORT,
        'email_images_base_uri':
        settings.ROOT_DOMAIN_URI + '/static/images/emails',
        'physical_address': settings.PHYSICAL_ADDRESS,
    }

    def render_templates() -> Tuple[str, str, str]:
        email_subject = loader.render_to_string(
            template_prefix + '.subject.txt',
            context=context,
            using='Jinja2_plaintext').strip().replace('\n', '')
        message = loader.render_to_string(template_prefix + '.txt',
                                          context=context,
                                          using='Jinja2_plaintext')

        try:
            html_message = loader.render_to_string(template_prefix + '.html',
                                                   context)
        except TemplateDoesNotExist:
            emails_dir = os.path.dirname(template_prefix)
            template = os.path.basename(template_prefix)
            compiled_template_prefix = os.path.join(emails_dir, "compiled",
                                                    template)
            html_message = loader.render_to_string(
                compiled_template_prefix + '.html', context)
        return (html_message, message, email_subject)

    # The i18n story for emails is a bit complicated.  For emails
    # going to a single user, we want to use the language that user
    # has configured for their Zulip account.  For emails going to
    # multiple users or to email addresses without a known Zulip
    # account (E.g. invitations), we want to use the default language
    # configured for the Zulip organization.
    #
    # See our i18n documentation for some high-level details:
    # https://zulip.readthedocs.io/en/latest/translating/internationalization.html

    if not language and to_user_ids is not None:
        language = to_users[0].default_language
    if language:
        with override_language(language):
            # Make sure that we render the email using the target's native language
            (html_message, message, email_subject) = render_templates()
    else:
        (html_message, message, email_subject) = render_templates()
        logger.warning("Missing language for email template '%s'",
                       template_prefix)

    if from_name is None:
        from_name = "Zulip"
    if from_address is None:
        from_address = FromAddress.NOREPLY
    if from_address == FromAddress.tokenized_no_reply_placeholder:
        from_address = FromAddress.tokenized_no_reply_address()
    if from_address == FromAddress.no_reply_placeholder:
        from_address = FromAddress.NOREPLY
    if from_address == FromAddress.support_placeholder:
        from_address = FromAddress.SUPPORT

    from_email = str(Address(display_name=from_name, addr_spec=from_address))
    reply_to = None
    if reply_to_email is not None:
        reply_to = [reply_to_email]
    # Remove the from_name in the reply-to for noreply emails, so that users
    # see "noreply@..." rather than "Zulip" or whatever the from_name is
    # when they reply in their email client.
    elif from_address == FromAddress.NOREPLY:
        reply_to = [FromAddress.NOREPLY]

    mail = EmailMultiAlternatives(email_subject,
                                  message,
                                  from_email,
                                  to_emails,
                                  reply_to=reply_to,
                                  headers=extra_headers)
    if html_message is not None:
        mail.attach_alternative(html_message, 'text/html')
    return mail
Пример #22
0
from email.headerregistry import Address
from email.message import EmailMessage
import os
import smtplib

# Gmail details
email_address = os.getenv('EMAIL_ADDRESS')
email_password = os.getenv('EMAIL_PASSWORD')

# Recipent
to_address = (
    Address(display_name='Daily update', username='******', domain='gmail.com'),
)


def create_email_message(from_address, to_address, subject, body):
    msg = EmailMessage()
    msg['From'] = from_address
    msg['To'] = to_address
    msg['Subject'] = subject
    msg.set_content(body)
    return msg


if __name__ == '__main__':
    msg = create_email_message(
        from_address=email_address,
        to_address=to_address,
        subject='Daily tasks',
        body="Let me know what you did today using Python and Linux, I want every day mail of your daily updates",
    )
Пример #23
0
    async def _format_email(self,
                            name: str,
                            address: str,
                            timestamp: datetime,
                            subject: str,
                            body: str,
                            message_id: str,
                            *,
                            in_reply_to: str = "",
                            references: str = "",
                            html: Optional[str] = None) -> str:
        body = body.replace("\r\n", "\n")

        cols = self.wrap or 0
        if cols > 0:
            body = "\n".join(
                textwrap.fill(line,
                              cols,
                              expand_tabs=False,
                              replace_whitespace=False,
                              break_long_words=False,
                              break_on_hyphens=False,
                              subsequent_indent=(
                                  "> " if line.startswith("> ") else
                                  ">" if line.startswith(">") else ""))
                for line in body.splitlines())

        # Replace "From" at the beginning of a line with ">From"
        # (see https://www.jwz.org/doc/content-length.html)
        body = REGEX_FROM.sub(r">From", body)

        msg = EmailMessage(policy=self.policy)
        msg.set_content(body)

        if html:
            msg.add_alternative(html, subtype="html")

        # Identify image URLs and add the images as attachments
        try:
            for url in get_image_urls(body):
                async with self.session.get(url) as resp:
                    assert resp.status == 200
                    img_data: bytes = await resp.read()
                    maintype, subtype = (mimetypes.guess_type(url)[0] or
                                         "application/octet-stream").split("/")
                    filename = posixpath.basename(urlparse(url).path)
                    msg.add_attachment(img_data,
                                       maintype=maintype,
                                       subtype=subtype,
                                       filename=filename)
        except:
            pass

        try:
            msg["From"] = Address(name, addr_spec=address)
        except IndexError:
            msg["From"] = Address(name)
        msg["Date"] = timestamp
        msg["Subject"] = subject
        if message_id:
            msg["Message-ID"] = message_id
        if in_reply_to:
            msg["In-Reply-To"] = in_reply_to

        if references and in_reply_to:
            msg["References"] = f"{references} {in_reply_to}"
        elif references:
            msg["References"] = references
        elif in_reply_to:
            msg["References"] = in_reply_to

        # For some reason as_string does not include the unixfrom line
        # and as_bytes uses the quoted-printable encoding despite purportedly
        # supporting native Unicode.
        return msg.as_bytes(policy=self.policy, unixfrom=True).decode()
Пример #24
0
                'error logging in to email server.\nmake sure your email account is properly configured for remote access via smtp.'
            )
            msg = 'try a different password? [y/n]'
            print(msg, end=' ', flush=True)
            response = ''
            while response not in ['y', 'n']:
                response = getch().lower()
            print(response)
            if response == 'y':
                my_pass = ''
            else:
                print('aborted by user. bye~!')
                exit()

    sender = Address(my_name,
                     my_email.split('@', 1)[0],
                     my_email.split('@', 1)[1])

    csv_location = get_file_location('Recipients file', ['.csv'])
    clean_up_csv(csv_location)
    recipients = read_csv(csv_location)

    while True:
        # get html body
        email_location = get_file_location('Email body', ['.htm', '.html'])
        try:
            with open(email_location, 'r') as fht:
                email_html = fht.read()
        except UnicodeDecodeError:
            with open(email_location, 'r', encoding='ISO-8859-1') as fht:
                email_html = fht.read()
Пример #25
0
def _compute_recipient(user, email):
    # We want to try and use the user's name, then their username, and finally
    # nothing to display a "Friendly" name for the recipient.
    return str(
        Address(first([user.name, user.username], default=""),
                addr_spec=email))
#!/usr/bin/env python3

import smtplib

from email.message import EmailMessage
from email.headerregistry import Address
from email.utils import make_msgid

# Create the base text message.
msg = EmailMessage()
msg['Subject'] = "Ayons asperges pour le déjeuner"
msg['From'] = Address("Pepé Le Pew", "pepe", "example.com")
msg['To'] = (Address("Penelope Pussycat", "penelope", "example.com"),
             Address("Fabrette Pussycat", "fabrette", "example.com"))
msg.set_content("""\
Salut!

Cela ressemble à un excellent recipie[1] déjeuner.

[1] http://www.yummly.com/recipe/Roasted-Asparagus-Epicurious-203718

--Pepé
""")

# Add the html version.  This converts the message into a multipart/alternative
# container, with the original text message as the first part and the new html
# message as the second part.
asparagus_cid = make_msgid()
msg.add_alternative("""\
<html>
  <head></head>
Пример #27
0
 def test_find_email_addresses_single_header_finds_one_address(self):
     text = """From: John Doe <*****@*****.**>"""
     addrs = find_email_addresses(text, ["from"])
     expected = [Address(display_name="John Doe",
                         username="******", domain="machine.example")]
     self.assertEqual(expected, addrs)
Пример #28
0
from django.core.mail import send_mail
from django.core.signing import TimestampSigner
from django.db import transaction
from django.template import TemplateDoesNotExist
from django.template.loader import get_template
from django.test import override_settings, RequestFactory
from email.headerregistry import Address
import logging

logger = logging.getLogger(__name__)

organizers = Address("Outreachy Organizers", "organizers", "outreachy.org")
applicant_help = Address("Outreachy Applicant Helpers", "applicant-help",
                         "outreachy.org")


def send_template_mail(template_name,
                       context,
                       recipient_list,
                       request=None,
                       **kwargs):
    # Only load the template once, no matter how many messages we're sending.
    template = get_template(template_name, using='plaintext')
    for recipient in recipient_list:
        # Templates used with this function expect the 'recipient' context
        # variable to contain a single address, not a list, so override
        # send_group_template_mail's default.
        context['recipient'] = recipient
        send_group_template_mail(template, context, [recipient], request,
                                 **kwargs)
Пример #29
0
from django.core.mail import send_mail
from django.core.signing import TimestampSigner
from django.db import transaction
from django.template import TemplateDoesNotExist
from django.template.loader import get_template
from django.test import override_settings, RequestFactory
from email.headerregistry import Address
import logging

logger = logging.getLogger(__name__)

organizers = Address("Outreachy Organizers", "organizers", "outreachy.org")
applicant_help = Address("Outreachy Applicant Helpers", "applicant-help",
                         "outreachy.org")
mentors_mailing_list = Address("Outreachy mentors list", "mentors",
                               "lists.outreachy.org")


def send_template_mail(template_name,
                       context,
                       recipient_list,
                       request=None,
                       **kwargs):
    # Only load the template once, no matter how many messages we're sending.
    template = get_template(template_name, using='plaintext')
    for recipient in recipient_list:
        # Templates used with this function expect the 'recipient' context
        # variable to contain a single address, not a list, so override
        # send_group_template_mail's default.
        context['recipient'] = recipient
        send_group_template_mail(template, context, [recipient], request,
 def test_address_username_ro(self):
     self._test_attr_ro(Address('foo', 'bar', 'baz'), 'username')