From 31bc47340df9b98f8e5d5e7fde47f342a913706c Mon Sep 17 00:00:00 2001 From: "Peter J. Holzer" Date: Mon, 27 Jan 2025 00:42:35 +0100 Subject: [PATCH] Announce status changes to all voters --- announce_status_change | 82 ++++++++++++++++++++++++++++++++++++++++++ meeat.procrusql | 7 ++++ 2 files changed, 89 insertions(+) create mode 100755 announce_status_change diff --git a/announce_status_change b/announce_status_change new file mode 100755 index 0000000..97d0792 --- /dev/null +++ b/announce_status_change @@ -0,0 +1,82 @@ +#!/usr/bin/python3 +import datetime +import email.message +import smtplib + +import psycopg + +import config + +min_distance = datetime.timedelta(minutes=60) + +def simple_sum(meet_id, kind): + q = \ + f""" + select k.*, sum(preference) as preference + from {kind} k join {kind}_vote v on k.id = v.{kind} + where k.meet = %s + group by k.id order by preference desc + """ + csr.execute(q, (meet_id,)) + return csr.fetchall() + +db = psycopg.connect(dbname=config.dbname, user=config.dbuser) +csr = db.cursor(row_factory=psycopg.rows.namedtuple_row) + +csr.execute("select * from meet where active") +for meet in csr.fetchall(): + + csr.execute( + """ + select distinct email, short + from date_vote + join date on date_vote.date = date.id + join bod on date_vote.bod = bod.id + where meet = %s + order by email + """, + (meet.id,)) + voters = csr.fetchall() + dates = simple_sum(meet.id, "date") + times = simple_sum(meet.id, "time") + places = simple_sum(meet.id, "place") + + msg = "Aktueller Favorit:\n\n" \ + f" {dates[0].date}, {times[0].time}\n" \ + f" im {places[0].name}\n\n\n" \ + "Abgestimmt haben:\n\n" + for v in voters: + msg += f" * {v.email}\n" + + csr.execute( + """ + select *, now() - ts as age + from news + where meet = %s + order by ts desc + limit 1 + """, + (meet.id,)) + last_news = csr.fetchone() + if not last_news or last_news.content != msg and last_news.age >= min_distance: + print(msg) + + csr.execute( + """ + insert into news(meet, ts, content) values(%s, now(), %s) + returning id + """, + (meet.id, msg)) + new_news = csr.fetchone() + db.commit() + + emsg = email.message.EmailMessage() + emsg["From"] ="noreply@hjp.at" + emsg["To"] = ", ".join(v.email for v in voters) + emsg["Subject"] = "Neuer Zwischenstand: " + meet.title + emsg["Message-ID"] = f"" + if last_news: + emsg["In-Reply-To"] = f"" + emsg.set_content(msg) + mta = smtplib.SMTP(host="localhost") + mta.send_message(emsg) diff --git a/meeat.procrusql b/meeat.procrusql index cc24a48..b09f7e4 100644 --- a/meeat.procrusql +++ b/meeat.procrusql @@ -2,6 +2,7 @@ table meet column meet id serial primary key column meet title text not null column meet key text unique +column meet active boolean default true table date column date id serial primary key @@ -41,3 +42,9 @@ table place_vote column place_vote place int not null references place column place_vote bod int not null references bod column place_vote preference float4 + +table news +column news id serial primary key +column news meet int references meet not null +column news ts timestamptz not null default now() +column news content text not null