Example #1
0
def send_custom_email(users: List[UserProfile], options: Dict[str, Any]) -> None:
    """
    Can be used directly with from a management shell with
    send_custom_email(user_profile_list, dict(
        markdown_template_path="/path/to/markdown/file.md",
        subject="Email Subject",
        from_name="Sender Name")
    )
    """

    with open(options["markdown_template_path"]) as f:
        text = f.read()
        parsed_email_template = Parser(policy=default).parsestr(text)
        email_template_hash = hashlib.sha256(text.encode('utf-8')).hexdigest()[0:32]

    email_filename = "custom/custom_email_%s.source.html" % (email_template_hash,)
    email_id = "zerver/emails/custom/custom_email_%s" % (email_template_hash,)
    markdown_email_base_template_path = "templates/zerver/emails/custom_email_base.pre.html"
    html_source_template_path = "templates/%s.source.html" % (email_id,)
    plain_text_template_path = "templates/%s.txt" % (email_id,)
    subject_path = "templates/%s.subject.txt" % (email_id,)
    os.makedirs(os.path.dirname(html_source_template_path), exist_ok=True)

    # First, we render the markdown input file just like our
    # user-facing docs with render_markdown_path.
    with open(plain_text_template_path, "w") as f:
        f.write(parsed_email_template.get_payload())

    from zerver.templatetags.app_filters import render_markdown_path
    rendered_input = render_markdown_path(plain_text_template_path.replace("templates/", ""))

    # And then extend it with our standard email headers.
    with open(html_source_template_path, "w") as f:
        with open(markdown_email_base_template_path) as base_template:
            # Note that we're doing a hacky non-Jinja2 substitution here;
            # we do this because the normal render_markdown_path ordering
            # doesn't commute properly with inline_email_css.
            f.write(base_template.read().replace('{{ rendered_input }}',
                                                 rendered_input))

    with open(subject_path, "w") as f:
        f.write(get_header(options.get("subject"),
                           parsed_email_template.get("subject"), "subject"))

    inline_template(email_filename)

    # Finally, we send the actual emails.
    for user_profile in filter(lambda user:
                               not options.get('admins_only') or user.is_realm_admin, users):
        context = {
            'realm_uri': user_profile.realm.uri,
            'realm_name': user_profile.realm.name,
        }
        send_email(email_id, to_user_ids=[user_profile.id],
                   from_address=FromAddress.SUPPORT,
                   reply_to_email=options.get("reply_to"),
                   from_name=get_header(options.get("from_name"),
                                        parsed_email_template.get("from"),
                                        "from_name"),
                   context=context)
Example #2
0
def send_custom_email(users: List[UserProfile], options: Dict[str, Any]) -> None:
    """
    Can be used directly with from a management shell with
    send_custom_email(user_profile_list, dict(
        markdown_template_path="/path/to/markdown/file.md",
        subject="Email Subject",
        from_name="Sender Name")
    )
    """

    with open(options["markdown_template_path"]) as f:
        email_template_hash = hashlib.sha256(f.read().encode('utf-8')).hexdigest()[0:32]

    email_filename = "custom_email_%s.source.html" % (email_template_hash,)
    email_id = "zerver/emails/custom_email_%s" % (email_template_hash,)
    markdown_email_base_template_path = "templates/zerver/emails/custom_email_base.pre.html"
    html_source_template_path = "templates/%s.source.html" % (email_id,)
    plain_text_template_path = "templates/%s.txt" % (email_id,)
    subject_path = "templates/%s.subject.txt" % (email_id,)

    # First, we render the markdown input file just like our
    # user-facing docs with render_markdown_path.
    shutil.copyfile(options['markdown_template_path'], plain_text_template_path)

    from zerver.templatetags.app_filters import render_markdown_path
    rendered_input = render_markdown_path(plain_text_template_path.replace("templates/", ""))

    # And then extend it with our standard email headers.
    with open(html_source_template_path, "w") as f:
        with open(markdown_email_base_template_path) as base_template:
            # Note that we're doing a hacky non-Jinja2 substitution here;
            # we do this because the normal render_markdown_path ordering
            # doesn't commute properly with inline_email_css.
            f.write(base_template.read().replace('{{ rendered_input }}',
                                                 rendered_input))

    with open(subject_path, "w") as f:
        f.write(options["subject"])

    # Then, we compile the email template using inline_email_css to
    # add our standard styling to the paragraph tags (etc.).
    inline_template(email_filename)

    # Finally, we send the actual emails.
    for user_profile in users:
        context = {
            'realm_uri': user_profile.realm.uri,
            'realm_name': user_profile.realm.name,
        }
        send_email(email_id, to_user_ids=[user_profile.id],
                   from_address=FromAddress.SUPPORT,
                   reply_to_email=options.get("reply_to"),
                   from_name=options["from_name"], context=context)
Example #3
0
def send_custom_email(users: List[UserProfile], options: Dict[str,
                                                              Any]) -> None:
    """
    Can be used directly with from a management shell with
    send_custom_email(user_profile_list, dict(
        markdown_template_path="/path/to/markdown/file.md",
        subject="Email subject",
        from_name="Sender Name")
    )
    """

    with open(options["markdown_template_path"]) as f:
        text = f.read()
        parsed_email_template = Parser(policy=default).parsestr(text)
        email_template_hash = hashlib.sha256(text.encode()).hexdigest()[0:32]

    email_filename = f"custom/custom_email_{email_template_hash}.source.html"
    email_id = f"zerver/emails/custom/custom_email_{email_template_hash}"
    markdown_email_base_template_path = "templates/zerver/emails/custom_email_base.pre.html"
    html_source_template_path = f"templates/{email_id}.source.html"
    plain_text_template_path = f"templates/{email_id}.txt"
    subject_path = f"templates/{email_id}.subject.txt"
    os.makedirs(os.path.dirname(html_source_template_path), exist_ok=True)

    # First, we render the Markdown input file just like our
    # user-facing docs with render_markdown_path.
    with open(plain_text_template_path, "w") as f:
        f.write(parsed_email_template.get_payload())

    from zerver.lib.templates import render_markdown_path

    rendered_input = render_markdown_path(
        plain_text_template_path.replace("templates/", ""))

    # And then extend it with our standard email headers.
    with open(html_source_template_path, "w") as f:
        with open(markdown_email_base_template_path) as base_template:
            # Note that we're doing a hacky non-Jinja2 substitution here;
            # we do this because the normal render_markdown_path ordering
            # doesn't commute properly with inline_email_css.
            f.write(base_template.read().replace("{{ rendered_input }}",
                                                 rendered_input))

    with open(subject_path, "w") as f:
        f.write(
            get_header(options.get("subject"),
                       parsed_email_template.get("subject"), "subject"))

    inline_template(email_filename)

    # Finally, we send the actual emails.
    for user_profile in users:
        if options.get("admins_only") and not user_profile.is_realm_admin:
            continue
        context = {
            "realm_uri":
            user_profile.realm.uri,
            "realm_name":
            user_profile.realm.name,
            "unsubscribe_link":
            one_click_unsubscribe_link(user_profile, "marketing"),
        }
        send_email(
            email_id,
            to_user_ids=[user_profile.id],
            from_address=FromAddress.SUPPORT,
            reply_to_email=options.get("reply_to"),
            from_name=get_header(options.get("from_name"),
                                 parsed_email_template.get("from"),
                                 "from_name"),
            context=context,
            dry_run=options["dry_run"],
        )

        if options["dry_run"]:
            break