update
This commit is contained in:
32
generate.py
32
generate.py
@@ -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
67
generator.conf
Normal 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
5
prepare_presentation.sh
Executable file
@@ -0,0 +1,5 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
./read_uvproto.sh
|
||||||
|
./read_ubmails.py
|
||||||
|
./generate.py --presentation > data/presentation_$(date +%Y-%m-%d).tex
|
||||||
|
|
||||||
@@ -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
11
read_uvproto.sh
Executable 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
|
||||||
@@ -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 %}
|
||||||
|
|||||||
@@ -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]]
|
||||||
|
|||||||
Reference in New Issue
Block a user