This commit is contained in:
2020-11-12 14:21:19 +01:00
parent 0aa7c05313
commit 3e42ca0bcd
7 changed files with 130 additions and 27 deletions

View File

@@ -22,7 +22,22 @@ WEEKDAYS = { 0: "Montag",
6: "Sonntag" } 6: "Sonntag" }
def decode_header(header): def decode_header(header):
return "".join([ x[0].decode(x[1] or "ascii") if isinstance(x[0], bytes) else x[0] for x in email.header.decode_header(header) ]) decoded_header = email.header.decode_header(header)[0]
encoding = decoded_header[1] or "ascii"
if encoding == "unknown-8bit":
encoding = "ascii"
return decoded_header[0].decode(encoding, errors="replace") if isinstance(decoded_header[0], bytes) else decoded_header[0]
def get_body_text(msg):
# from https://stackoverflow.com/a/1463144
for part in msg.walk():
# each part is a either non-multipart, or another multipart message
# that contains further parts... Message is organized like a tree
if part.get_content_type() == 'text/plain':
payload = part.get_payload()
if part["Content-Transfer-Encoding"] == "quoted-printable":
payload = quopri.decodestring(payload.encode("ascii")).decode(part.get_content_charset("utf-8"))
return payload
class Top: class Top:
def __init__(self, title=None, sender=None, body=None, protostub=None, message=None): def __init__(self, title=None, sender=None, body=None, protostub=None, message=None):
@@ -30,10 +45,8 @@ class Top:
self.title = decode_header(message["Subject"])[6:] self.title = decode_header(message["Subject"])[6:]
real_name, address = email.utils.parseaddr(message["From"]) real_name, address = email.utils.parseaddr(message["From"])
self.sender = real_name or address self.sender = real_name or address
payload = message.get_payload() payload = get_body_text(message)
if message["Content-Transfer-Encoding"] == "quoted-printable": self.body = str(payload.rpartition("\n--")[0] if "\n--" in payload else payload)
payload = quopri.decodestring(payload.encode("ascii")).decode("utf8")
self.body = payload.rpartition("\n--")[0] if "\n--" in payload else payload
elif title: elif title:
self.title = title self.title = title
self.sender = sender self.sender = sender
@@ -74,6 +87,14 @@ def time(intime):
def weekday(indate): def weekday(indate):
return WEEKDAYS[indate.weekday()] return WEEKDAYS[indate.weekday()]
def prototop(top):
if "protostub" in dir(top) and top.protostub:
return j2env.from_string(top.protostub).render(context, top=top)
elif top.body:
return j2env.from_string(top.body).render(context)
else:
return None
def conf2top(top): def conf2top(top):
sender = None sender = None
body = None body = None
@@ -127,6 +148,7 @@ if __name__ == "__main__":
j2env.filters["date"] = date j2env.filters["date"] = date
j2env.filters["time"] = time j2env.filters["time"] = time
j2env.filters["weekday"] = weekday j2env.filters["weekday"] = weekday
j2env.filters["prototop"] = prototop
template = j2env.from_string(open(template_file).read()) template = j2env.from_string(open(template_file).read())
mbox = mailbox.mbox(config["top_mbox_file"]) mbox = mailbox.mbox(config["top_mbox_file"])

67
generator.conf Normal file
View File

@@ -0,0 +1,67 @@
redeleitung:
name: Yannik Enss
email: yannik.enss@fsmi.uni-karlsruhe.de
protokoll:
name: Alina Valta
pre_tops:
- title: Begrüßung
protostub: Der FSR wird begrüßt
- title: Feststellung der Beschlussfähigkeit
protostub: Der FSR ist beschlussfähig
- title: Tagesordnung
body: '\tableofcontents'
protostub: '{% for top in to %}# {{top.title}}
{% endfor %}'
- title: Unveröffentlichte Protokolle
file: "data/uvproto.txt"
body: "* FSR-Protokoll vom {{last_date|date}}"
- title: Berichte
protostub:
post_tops:
- title: Unbeantwortete E-Mails
protostub: '<intern>
{{top.body}}
</intern>Die E-Mails wurden verteilt'
file: "data/ubemails.txt"
- title: Nächster FSR
body: 'Wann: {{next_date.strftime("%d.%m.%Y")}} {{time.strftime("%H:%M")}} \linebreak
Wo: {{place}} \linebreak
Redeleitung: ? \linebreak
Protokoll: ?'
protostub: '* Termin: {{next_date.strftime("%d.%m.%Y")}}
* Ort: {{place}}
* nächste Redeleitung: XXXXXXXX
* nächstes Protokoll: XXXXXXXX'
- title: Termine
file: "data/termine.txt"
protostub: '{|
{{"{{"}}Termin|was=AAAAAAAAAA|wann=XX.YY.{{"}}"}}
{{top.body}}
|}'
- title: Sonstiges
invite_template_file: templates/fsr_einladung.j2
presentation_template_file: templates/fsr_presentation.tex.j2
protocol_template_file: templates/fsr_protokoll.j2
top_mbox_file: data/fsr_tops.mbox
mbox_out: data/invitemail.mbox
default_weekday: 2 #Mittwoch
default_time: "17:30"
meeting_link: https://meet.vs.kit.edu/b/len-prm-rv4
place: Big Blue Button
invite_mail: fsr-einladung@fsmi.uni-karlsruhe.de
invite_subject: 'Einladung zum Fachschaftsrat am {{date|weekday}}, dem {{date|date}}'
# vim: filetype=yaml

5
prepare_presentation.sh Executable file
View File

@@ -0,0 +1,5 @@
#!/bin/bash
./read_uvproto.sh
./read_ubmails.py
./generate.py --presentation > data/presentation_$(date +%Y-%m-%d).tex

View File

@@ -13,10 +13,14 @@ from pprint import pprint
from dateutil import parser from dateutil import parser
MAILDIR = "/home/yannik/mail/INBOX/" MAILDIR = "/home/yannik/mail/INBOX/"
OUTFILE = "ubemails.txt" OUTFILE = "data/ubemails.txt"
def decode_header(header): def decode_header(header):
return "".join([ x[0].decode(x[1] or "ascii") if isinstance(x[0], bytes) else x[0] for x in email.header.decode_header(header) ]) decoded_header = email.header.decode_header(header)[0]
encoding = decoded_header[1] or "ascii"
if encoding == "unknown-8bit":
encoding = "ascii"
return decoded_header[0].decode(encoding, errors="replace") if isinstance(decoded_header[0], bytes) else decoded_header[0]
if __name__ == "__main__": if __name__ == "__main__":
mbox = mailbox.Maildir(MAILDIR) mbox = mailbox.Maildir(MAILDIR)
@@ -35,7 +39,12 @@ if __name__ == "__main__":
latest = message latest = message
latest_date = date latest_date = date
if not latest:
print("ERROR: No Mail found", file=sys.stderr)
sys.exit(1)
if latest_date.date() != datetime.date.today(): if latest_date.date() != datetime.date.today():
print("WARNING: Mail is not from today", file=os.stderr) print("WARNING: Mail is not from today", file=sys.stderr)
payload = latest.get_payload(decode=True).decode("utf8").strip() payload = latest.get_payload(decode=True).decode("utf8").strip()
print(payload.rpartition("\n--")[0].strip() if "\n--" in payload else payload) result = (payload.rpartition("\n--")[0].strip() if "\n--" in payload else payload)
with open(OUTFILE, "w") as f:
f.write(result+"\n")

11
read_uvproto.sh Executable file
View File

@@ -0,0 +1,11 @@
#!/bin/bash -e
read -s -p "DB-Passwort: " password;
echo
raw_proto=$(echo $password | ssh fsmi "psql -A -t -h fsmi-db fsmi -c \"select datum from protokolle where ist_veroeffentlicht='f'\"" 2> /dev/null)
for proto in $raw_proto;
do
echo "* FSR-Protokoll vom $proto"
done | tee data/uvproto.txt
echo File has been written

View File

@@ -5,33 +5,23 @@ am:
{{date|weekday}}, den {{date|date}} um {{time|time}} Uhr {{date|weekday}}, den {{date|date}} um {{time|time}} Uhr
via Microsoft Teams[0] (App, Chrome, Edge oder Safari; nicht Firefox) via Big Blue Button[0]
Es ist keine Anmeldung über das KIT notwendig,
mehr Informationen unter [1]
Bitte auch die Nettiquette beachten [2]: {% if email_tops %}Die Antragstexte für die eingereichten TOPs sind unten angehangen.{% endif %}
- Rechtzeitig da sein
- Mikro aus machen wenn man nicht redet
- Video aus wg. Bandbreite
- Wenn möglich Headset verwendet
Die Antragstexte für die eingereichten TOPs sind unten angehangen.
Die vorläufige Tagesordnung lautet: Die vorläufige Tagesordnung lautet:
{% for top in to %}{{ "%02d" % loop.index}} {{top.title}} {% for top in to %}{{ "%02d" % loop.index}} {{top.title}}
{% endfor %} {% endfor %}
Bitte sendet vorher die Berichte an das Protokollamt[3] zu. Bitte sendet vorher die Berichte an das Protokollamt[1] zu.
[0] {{meeting_link}} [0] {{meeting_link}}
[1] https://www.scc.kit.edu/dienste/ms-teams.php [1] protokollant@fsmi.uni-karlsruhe.de
[2] Auszug vom SCC https://www.scc.kit.edu/dienste/ms-teams.php
[3] protokollant@fsmi.uni-karlsruhe.de
Viele Grüße, Viele Grüße,
{{redeleitung.name}} {{redeleitung.name}}
{% if email_tops %}
Eingereichte TOPs: Eingereichte TOPs:
{% for top in email_tops %} {% for top in email_tops %}
= {{top.title}} = = {{top.title}} =
@@ -39,3 +29,4 @@ Eingereicht von: {{top.sender}}
{{top.body}} {{top.body}}
{% endfor %} {% endfor %}
{% endif %}

View File

@@ -18,9 +18,7 @@
= {{top.title}} = = {{top.title}} =
{%if top.sender%}Eingereicht von: {{top.sender}} {%if top.sender%}Eingereicht von: {{top.sender}}
{%endif%}{%if top.protostub%}{{top.protostub|j2replace}} {%endif%}{{top|prototop}}
{% elif top.body %}{{top.body|j2replace}}
{% endif %}
{% endfor %} {% endfor %}
[[Kategorie:Protokoll]] [[Kategorie:Protokoll]]