From ec6d34c1b97e6a9f83b22f54e969c74f53fd4541 Mon Sep 17 00:00:00 2001 From: Zarino Zappia Date: Thu, 29 Jun 2023 08:39:05 +0100 Subject: [PATCH] Management command for generating LGA conference meeting invites --- .../commands/generate_lga_conf_emails.py | 120 ++++++++++++++++++ 1 file changed, 120 insertions(+) create mode 100644 caps/management/commands/generate_lga_conf_emails.py diff --git a/caps/management/commands/generate_lga_conf_emails.py b/caps/management/commands/generate_lga_conf_emails.py new file mode 100644 index 000000000..0f9163bda --- /dev/null +++ b/caps/management/commands/generate_lga_conf_emails.py @@ -0,0 +1,120 @@ +from html import escape +from os.path import join + +from django.conf import settings +from django.core.management.base import BaseCommand +from django.template import Template, Context + +from tqdm import tqdm + +from caps.models import Council + +file_header = """ + + + + + + + +
+ + +
+
+""" + +file_footer = """ +
+ + + +""" + +email_template = Template( + """ +

Hi NAME,

+

You probably already know that the council most similar to yours in terms of emissions, deprivation and rural/urban factor is {{ twin.name }}.

+{% with n=twin.plan_overlap.just_in_b %}

But do you know which {% if n|length > 1 %}{{ n|length }} {% endif %}{{ n|pluralize:"topic appears,topics appear" }} in their climate plans and {{ n|pluralize:"doesn’t appear,don’t appear" }} in yours?

{% endwith %} +

…We do! I’m the climate lead at mySociety, a charity building free digital tools that enable local authorities to reach their net zero goals. Our topic-based council comparisons are just the latest feature we’ve added, and I’d love to get your feedback on it.

+

Book a 15 minute chat with me at the conference next week, or stop by stand T10A, and I’ll give you a demo. Hopefully you’ll also come away with some useful insights to share with your own teams at {{ council.name }}.

+

Thank you so much, I really appreciate your time.

+

Zarino Zappia
Climate Programme Lead, mySociety
mysociety.org

+

PS. This winter we’ll also be working with a few pilot councils on a community-led approach to domestic retrofit. I know incentivising domestic decarbonisation is a big challenge for local authorities – happy to share more when we meet!

""" +) + + +class Command(BaseCommand): + help = "generates HTML for one email per local authority, ready to copy-paste into the LGA conference message editor" + + def handle(self, *args, **options): + html_filepath = join(settings.MEDIA_ROOT, "data", "lga_conf_emails.html") + with open(html_filepath, "w") as f: + f.writelines(file_header) + + for council in tqdm(Council.current_councils()): + tqdm.write(f"Generating email for {council.name}") + + context = {"council": council} + + related_councils = council.get_related_councils() + related_councils_intersection = ( + council.related_council_keyphrase_intersection() + ) + for group in related_councils: + for c in group["councils"]: + c.plan_overlap = related_councils_intersection[c] + if group["type"].slug == "composite": + context["twin"] = group["councils"][0] + + email_html = email_template.render(Context(context)) + escaped_email_text = escape(email_html) + + if ( + "twin" in context + and len(context["twin"].plan_overlap.just_in_b) > 0 + ): + f.writelines("
") + f.writelines(f"

{council.name}

\n") + else: + f.writelines("
") + f.writelines(f"

{council.name} (no twins)

\n") + + f.writelines( + "\n" + ) + + if "twin" in context: + f.writelines( + f"\n" + ) + else: + f.writelines( + "
No twin for this council
" + ) + + f.writelines("
\n") + + f.writelines(file_footer) + + print(f"output written to {html_filepath}")