def test_address_domain_ro(self): self._test_attr_ro(Address('foo', 'bar', 'baz'), 'domain')
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!'
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
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
def _format_sender(sitename, sender): if sender is not None: return str(Address(sitename, addr_spec=sender))
#!/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>
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]')
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"])
def decode(self, s): try: return Address(display_name=s["display_name"], addr_spec=s["addr_spec"]) except InvalidHeaderDefect: return ""
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')
def _get_recipients(receivers): return [ Address(item["name"], addr_spec=item["email"]) for item in receivers ]
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
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,
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
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", )
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()
'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()
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>
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)
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)
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')