Neues Konzept: Eine PDF Datei pro Lerngruppe

This commit is contained in:
2026-04-19 12:37:42 +02:00
parent 6c4e7120dc
commit 79ec1acf94
32 changed files with 2646 additions and 47283 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -35,10 +35,7 @@ device = paperpro
# Bezeichnung der Lerngruppe
bezeichnung = Mathe 5a
# Kurzbezeichnung der Lerngruppe (für Stundenplan)
kurzbezeichnung = Mathe 5a
# Abkürzende Bezeichnung der Lerngruppe (für Stundenplan und Navileiste auf kleinen Geräten)
# Abkürzende Bezeichnung der Lerngruppe (für Navileiste auf kleinen Geräten)
abkuerzung = M 5a
# Anzahl Arbeiten oder Klausuren: 0, 1, 2, ... (0=keine Arbeiten/Klausuren)
@@ -71,10 +68,7 @@ checkliste_seiten = 2
# Bezeichnung der Lerngruppe
bezeichnung = Mathe 6b
# Kurzbezeichnung der Lerngruppe (für Stundenplan)
kurzbezeichnung = Mathe 6b
# Abkürzende Bezeichnung der Lerngruppe (für Stundenplan und Navileiste auf kleinen Geräten)
# Abkürzende Bezeichnung der Lerngruppe (für Navileiste auf kleinen Geräten)
abkuerzung = M 6b
# Anzahl Arbeiten oder Klausuren: 0, 1, 2, ... (0=keine Arbeiten/Klausuren)
@@ -107,10 +101,7 @@ checkliste_seiten = 2
# Bezeichnung der Lerngruppe
bezeichnung = Informatik 9
# Kurzbezeichnung der Lerngruppe (für Stundenplan)
kurzbezeichnung = Info 9
# Abkürzende Bezeichnung der Lerngruppe (für Stundenplan und Navileiste auf kleinen Geräten)
# Abkürzende Bezeichnung der Lerngruppe (für Navileiste auf kleinen Geräten)
abkuerzung = If 9
# Anzahl Arbeiten oder Klausuren: 0, 1, 2, ... (0=keine Arbeiten/Klausuren)
@@ -143,10 +134,7 @@ checkliste_seiten = 2
# Bezeichnung der Lerngruppe
bezeichnung = Informatik EF
# Kurzbezeichnung der Lerngruppe (für Stundenplan)
kurzbezeichnung = Info EF
# Abkürzende Bezeichnung der Lerngruppe (für Stundenplan und Navileiste auf kleinen Geräten)
# Abkürzende Bezeichnung der Lerngruppe (für Navileiste auf kleinen Geräten)
abkuerzung = If EF
# Anzahl Arbeiten oder Klausuren: 0, 1, 2, ... (0=keine Arbeiten/Klausuren)

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

755
src/data/klasse-5a.pdf Normal file

File diff suppressed because one or more lines are too long

736
src/data/klasse-6b.pdf Normal file

File diff suppressed because one or more lines are too long

490
src/data/kurs-if-9.pdf Normal file

File diff suppressed because one or more lines are too long

603
src/data/kurs-if-ef.pdf Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1,8 +0,0 @@
| St. | Montag | Dienstag | Mittwoch | Donnerstag | Freitag |
| :------: | :----------: | :----------: | :----------: | :----------: | :----------: |
| 1.<br>2. | [klasse-5a] | | | [klasse-5a] | [klasse-6b] |
| 3.<br>4. | [klasse-6b] | [kurs-if-ef] | [klasse-5a] | [klasse-6b] | |
| 5.<br>6. | [kurs-if-9] | [[VERT]] | [kurs-if-ef] | | |
| 7. | | | | | |
| 8.<br>9. | | [kurs-if-9] | | | |

View File

@@ -7,7 +7,7 @@ from configparser import ConfigParser
from xhtml2pdf import pisa
sys.path.append(os.path.abspath("./pages"))
import start, halbjahr, birthday, uebersicht, korrektur, somi, ha, checkliste
import halbjahr, birthday, uebersicht, korrektur, somi, ha, checkliste
# 1. Eingabeverzeichnis bestimmen
@@ -154,26 +154,22 @@ except KeyError:
exit(0)
# 5. Baue die Ausgabe aus den einzelnen Bestandteilen zusammen
# 5. Verarbeite nacheinander alle Eingabedateien = Lerngruppen
body = ''
# Startseite einbinden
body = body + start.erstelleStartseite(lerngruppen, path, config, inputs)
# Verarbeite nacheinander alle Eingabedateien = Lerngruppen
for datei in dateien:
print(" - Verarbeite Datei: "+datei)
body = ''
if (not(os.path.exists(datei))):
print("Datei "+datei+" nicht vorhanden!")
exit(0)
# Implizite Konfiguration der aktuellen Lerngruppe aus Benutzerconfig auslesen
# a) Implizite Konfiguration der aktuellen Lerngruppe aus Benutzerconfig auslesen
dateiname = datei.replace(path,"")
kursid = dateiname.replace(".csv","")
print(" - Erzeuge PDF-Datei: " + kursid + '.pdf')
try:
kurs_inputs = inputs[kursid]
except KeyError:
@@ -186,7 +182,7 @@ for datei in dateien:
print('Der Schlüssel "bezeichnung" fehlt im Bereich "'+kursid+'" der Input-Datei!')
exit(0)
# CSV Datei mit Schülernamen einlesen und aufbereiten
# b) CSV Datei mit Schülernamen einlesen und aufbereiten
csvdaten = open(datei, encoding="utf8")
csvdatenReader = csv.reader(csvdaten, delimiter=csv_trenner)
@@ -219,14 +215,14 @@ for datei in dateien:
gebdatum = row[2]
gebdaten.append(gebdatum)
except IndexError:
print(' - Einträge für Geburtstag fehlen für Lerngruppe "'+kursid+'"!')
print(' - Geburtstage fehlen für die Lerngruppe.')
gebdaten = []
gebdaten_all = False
# Übersichtsseite Noten zusammenbauen
# c) Übersichtsseite Noten zusammenbauen
body = body + uebersicht.erstelleUebersicht(kursid, klassekurs_name, lerngruppen, path, namen, gebdaten, config, inputs, kurs_inputs)
# optional: Korrekturbögen zusammenbauen
# d) optional: Korrekturbögen zusammenbauen
try:
schr_anzahl = int(kurs_inputs["schriftlich_anzahl"])
except KeyError:
@@ -235,10 +231,10 @@ for datei in dateien:
if (schr_anzahl>0):
body = body + korrektur.erstelleKorrekturbogen(kursid, klassekurs_name, lerngruppen, path, namen, gebdaten, config, inputs, kurs_inputs)
# SoMi-Bogen zusammenbauen
# e) SoMi-Bogen zusammenbauen
body = body + somi.erstelleSoMiBogen(kursid, klassekurs_name, lerngruppen, path, namen, gebdaten, config, inputs, kurs_inputs)
# optional: HA-Bogen zusammenbauen
# f) optional: HA-Bogen zusammenbauen
try:
ha_zeilen = int(kurs_inputs["ha_zeilen"])
except KeyError:
@@ -247,42 +243,40 @@ for datei in dateien:
if (ha_zeilen>0):
body = body + ha.erstelleHABogen(kursid, klassekurs_name, lerngruppen, path, namen, gebdaten, config, inputs, kurs_inputs)
# Checkliste(n) zusammenbauen
# g) Checkliste(n) zusammenbauen
body = body + checkliste.erstelleCheckliste(kursid, klassekurs_name, lerngruppen, path, namen, gebdaten, config, inputs, kurs_inputs)
# Geburtstagsseite zusammenbauen
if (len(gebdaten)==0):
print(' - Geburtstagsliste wird weggelassen.')
else:
# h) Geburtstagsseite zusammenbauen
if (len(gebdaten)>0):
if (namen_kurzlang=="lang"):
body = body + birthday.erstelleGeburtstagsBogen(kursid, klassekurs_name, lerngruppen, path, namen, gebdaten, config, inputs, kurs_inputs)
else:
body = body + birthday.erstelleGeburtstagsBogen(kursid, klassekurs_name, lerngruppen, path, namen2, gebdaten, config, inputs, kurs_inputs)
# Planungsseite für das Halbjahr zusammenbauen
# i) Planungsseite für das Halbjahr zusammenbauen
body = body + halbjahr.erstelleHalbjahresuebersicht(kursid, klassekurs_name, lerngruppen, path, namen, gebdaten, config, inputs, kurs_inputs)
# 6. Abschluss: PDF Generierung
html_source = '<html><head>'
html_source += '<link rel="stylesheet" href="'+css_devicefile+'">'
html_source += '</head><body>'+body+'</body></html>'
# j) PDF Generierung
html_source = '<html><head>'
html_source += '<link rel="stylesheet" href="'+css_devicefile+'">'
html_source += '</head><body>'+body+'</body></html>'
pisa.showLogging()
pisa.showLogging()
datei_ausgabe = path + device + '.pdf'
print("Erzeuge PDF-Datei: " + device + '.pdf')
datei_ausgabe = path + kursid + '.pdf'
with open(datei_ausgabe, "w+b") as result_file:
with open(datei_ausgabe, "w+b") as result_file:
# convert HTML to PDF
pisa_status = pisa.CreatePDF(
html_source, # page data
dest=result_file, # destination file
)
# convert HTML to PDF
pisa_status = pisa.CreatePDF(
html_source, # page data
dest=result_file, # destination file
)
# Check for errors
if pisa_status.err:
print("Fehler bei der Erzeugung der PDF aus HTML!")
# Check for errors
if pisa_status.err:
print("Fehler bei der Erzeugung der PDF aus HTML!")
print("Fertig!")

View File

@@ -1,55 +1,6 @@
import os
def erstelleHauptnavigation(lerngruppen, path, config, inputs):
try:
rand = inputs["Allgemein"]["rand"]
except KeyError:
print('Der Schlüssel Allgemein oder "rand" existiert nicht in der Input-Datei!')
exit(0)
if (rand=="rechts"):
navi = "&nbsp;&nbsp;&nbsp;" # Platz für Schließen-Symbol schaffen
else:
navi = ""
count = 0
for kursid in lerngruppen:
count = count + 1
try:
kurs_inputs_aktuell = inputs[kursid]
except KeyError:
print('Der Bereichsschlüssel "'+kursid+'" (zur entsprechenden Datei) existiert nicht in der Input-Datei (3).')
exit(0)
try:
bezeichnung = config["Navigation"]["bezeichnung"]
except KeyError:
print('Der Schlüssel Navigation oder "kurzbezeichnung" existiert nicht in der Device-Datei!')
exit(0)
try:
klassekurs_aktuell = kurs_inputs_aktuell["bezeichnung"]
if (bezeichnung=='kurz'):
klassekurs_print = kurs_inputs_aktuell["kurzbezeichnung"]
elif (bezeichnung=='abgekuerzt'):
klassekurs_print = kurs_inputs_aktuell["abkuerzung"]
else:
klassekurs_print = kurs_inputs_aktuell["bezeichnung"]
except KeyError:
print('Der Schlüssel "bezeichnung" o.ä. fehlt im Bereich "'+kursid+'" der Input-Datei!')
exit(0)
myclass = ' n'+str(count) # Navileisten-CSS nX
navi += '<span class="hn-part"><a href="#'+klassekurs_aktuell+'">&nbsp;<img class="icon" src="img/user-multiple-4.svg"/><span class="'+myclass+'">'+klassekurs_print+'</span></a>&nbsp;</span>'
navileiste = '<p class="hn">'+navi+'</p>'
return navileiste
def erstelleKursnavigation(kursid, line, current, klassekurs_name, gebdaten, lerngruppen, path, config, inputs, kurs_inputs):
@@ -72,15 +23,9 @@ def erstelleKursnavigation(kursid, line, current, klassekurs_name, gebdaten, ler
try:
bezeichnung = config["Navigation"]["bezeichnung"]
except KeyError:
print('Der Schlüssel Navigation oder "kurzbezeichnung" existiert nicht in der Device-Datei!')
print('Der Schlüssel Navigation oder "bezeichnung" existiert nicht in der Device-Datei!')
exit(0)
# Link zur Startseite
if (bezeichnung=='abgekuerzt'):
navi += '<span class="kn-part"><a href="#Home">&nbsp;<img class="icon" src="img/chevron-up-circle.svg"/></a></span>&nbsp;&nbsp;&nbsp;&nbsp;'
else:
navi += '<span class="kn-part"><a href="#Home">&nbsp;<img class="icon" src="img/chevron-up-circle.svg"/>zurück</a></span>&nbsp;&nbsp;&nbsp;&nbsp;'
# Notenübersicht
if (bezeichnung=='abgekuerzt'):
if (current=='übersicht'):
@@ -89,9 +34,9 @@ def erstelleKursnavigation(kursid, line, current, klassekurs_name, gebdaten, ler
navi += '<span class="kn-part"><a href="#'+klassekurs_name+'Overview">&nbsp;<img class="icon" src="img/user-multiple-4.svg"/></a>&nbsp;</span>'
else:
if (current=='übersicht'):
navi += '<span class="kn-part">&nbsp;<img class="icon" src="img/user-multiple-4-current.svg"/><span class="kn-current">Übersicht</span></span>'
navi += '<span class="kn-part">&nbsp;<img class="icon" src="img/user-multiple-4-current.svg"/><span class="kn-current">Start</span></span>'
else:
navi += '<span class="kn-part"><a href="#'+klassekurs_name+'Overview">&nbsp;<img class="icon" src="img/user-multiple-4.svg"/>Übersicht</a></span>'
navi += '<span class="kn-part"><a href="#'+klassekurs_name+'Overview">&nbsp;<img class="icon" src="img/user-multiple-4.svg"/>Start</a></span>'
# Arbeiten/Klausuren
schr_anzahl = int(kurs_inputs["schriftlich_anzahl"])
@@ -141,9 +86,9 @@ def erstelleKursnavigation(kursid, line, current, klassekurs_name, gebdaten, ler
navi += '<span class="kn-part"><a href="#'+klassekurs_name+'HA">&nbsp;<img class="icon" src="img/home-2.svg"/></a>&nbsp;</span>'
else:
if (current=='ha'):
navi += '<span class="kn-part">&nbsp;<img class="icon" src="img/home-2-current.svg"/><span class="kn-current">Haus</span></span>'
navi += '<span class="kn-part">&nbsp;<img class="icon" src="img/home-2-current.svg"/><span class="kn-current">Hausaufgaben</span></span>'
else:
navi += '<span class="kn-part"><a href="#'+klassekurs_name+'HA">&nbsp;<img class="icon" src="img/home-2.svg"/>Haus</a></span>'
navi += '<span class="kn-part"><a href="#'+klassekurs_name+'HA">&nbsp;<img class="icon" src="img/home-2.svg"/>Hausaufgaben</a></span>'
# Checklisten
if (bezeichnung=='abgekuerzt'):
@@ -153,9 +98,9 @@ def erstelleKursnavigation(kursid, line, current, klassekurs_name, gebdaten, ler
navi += '<span class="kn-part"><a href="#'+klassekurs_name+'Check">&nbsp;<img class="icon" src="img/check-square-2.svg"/></a>&nbsp;</span>'
else:
if (current=='check'):
navi += '<span class="kn-part">&nbsp;<img class="icon" src="img/check-square-2-current.svg"/><span class="kn-current">Check</span></span>'
navi += '<span class="kn-part">&nbsp;<img class="icon" src="img/check-square-2-current.svg"/><span class="kn-current">Checklisten</span></span>'
else:
navi += '<span class="kn-part"><a href="#'+klassekurs_name+'Check">&nbsp;<img class="icon" src="img/check-square-2.svg"/>Check</a></span>'
navi += '<span class="kn-part"><a href="#'+klassekurs_name+'Check">&nbsp;<img class="icon" src="img/check-square-2.svg"/>Checklisten</a></span>'
# Geburtstagsseite
if (len(gebdaten)>0):
@@ -166,9 +111,9 @@ def erstelleKursnavigation(kursid, line, current, klassekurs_name, gebdaten, ler
navi += '<span class="kn-part"><a href="#'+klassekurs_name+'Birthday">&nbsp;<img class="icon" src="img/balloons.svg"/></a>&nbsp;</span>'
else:
if (current=='gebtag'):
navi += '<span class="kn-part">&nbsp;<img class="icon" src="img/balloons-current.svg"/><span class="kn-current">Gebtag</a></span>'
navi += '<span class="kn-part">&nbsp;<img class="icon" src="img/balloons-current.svg"/><span class="kn-current">Geburtstage</a></span>'
else:
navi += '<span class="kn-part"><a href="#'+klassekurs_name+'Birthday">&nbsp;<img class="icon" src="img/balloons.svg"/>Gebtag</a></span>'
navi += '<span class="kn-part"><a href="#'+klassekurs_name+'Birthday">&nbsp;<img class="icon" src="img/balloons.svg"/>Geburtstage</a></span>'
# Halbjahresseite
if (bezeichnung=='abgekuerzt'):
@@ -191,14 +136,6 @@ def erstelleKursnavigation(kursid, line, current, klassekurs_name, gebdaten, ler
else:
myline = str(zschuljahr) + '/' + str((zschuljahr-2000)+1) + ', ' + halbjahr + '. Hj.'
count = 0
for gruppe in lerngruppen:
count = count + 1
if (gruppe==kursid):
break
mycss = 'h'+str(count) # Headline-CSS hX
headline = '<p class="kn-headline"><span class="'+mycss+'">'+klassekurs_name+'</span> - '+myline+'</p>'
headline = '<p class="kn-headline">'+klassekurs_name+' - '+myline+'</p>'
return navileiste + headline

View File

@@ -1,117 +0,0 @@
import os
import markdown
import header
import re
def erstelleStartseite(lerngruppen, path, config, inputs):
table = ''
table += '<a name="Home"></a>'
table += header.erstelleHauptnavigation(lerngruppen, path, config, inputs)
allg = inputs["Allgemein"]
schuljahr = allg["schuljahr"]
zschuljahr = int(schuljahr)
halbjahr = allg["halbjahr"]
myline = 'Schuljahr ' + str(zschuljahr) + '/' + str((zschuljahr-2000)+1) + ', ' + halbjahr + '. Hj.'
table += '<h1 class="start">'+myline+'</h1>'
table += '<div class="tt">'
# Markdowndatei einlesen
try:
stundenplandatei = allg['stundenplandatei']
except KeyError:
print('Der Bereichsschlüssel "stundenplandatei" im allgemeinen Bereich existiert nicht in der Input-Datei!')
exit(0)
tt_file = path+stundenplandatei
if (len(stundenplandatei)==0):
print("Stundenplan in der Konfiguration ausgeschaltet, erzeuge Startseite ohne Stundenplan.")
elif (not(os.path.exists(tt_file))):
print("Angegebene Stundenplandatei nicht vorhanden, erzeuge Startseite ohne Stundenplan.")
else:
f = open(tt_file)
text = f.read()
# nach HTML konvertieren
html = markdown.markdown(text, extensions=['tables'])
# mit Markup anreichern zur CSS Formatierung
html = html.replace('<table>','<table class="timetable">')
html = html.replace('''<th style="text-align: center;">''','''<th class="tag">''')
html = html.replace('''<td style="text-align: center;">''','''<td class="tag">''')
html = html.replace('''<tr>
<th class="tag">''','''<tr><th class="stunde">''')
html = html.replace('''<tr>
<td class="tag">''','''<tr><td class="stunde">''')
# ggf. Links zu Lerngruppen einfügen
count = 0
for kursid in lerngruppen:
count = count + 1
mycss = 't'+str(count) # Timetable-CSS tX
try:
kurs_inputs_aktuell = inputs[kursid]
except KeyError:
print('Der Bereichsschlüssel "'+kursid+'" (zur entsprechenden Datei) existiert nicht in der Input-Datei (2)!')
exit(0)
try:
bezeichnung = config["Navigation"]["bezeichnung"]
except KeyError:
print('Der Schlüssel Navigation oder "kurzbezeichnung" existiert nicht in der Device-Datei!')
exit(0)
try:
klassekurs_aktuell = kurs_inputs_aktuell["bezeichnung"]
if (bezeichnung=='kurz'):
klassekurs_print = kurs_inputs_aktuell["kurzbezeichnung"]
elif (bezeichnung=='abgekuerzt'):
klassekurs_print = kurs_inputs_aktuell["abkuerzung"]
else:
klassekurs_print = kurs_inputs_aktuell["bezeichnung"]
except KeyError:
print('Der Schlüssel "bezeichnung" o.ä. fehlt im Bereich "'+kursid+'" der Input-Datei!')
exit(0)
if (bezeichnung=='abgekuerzt'):
html = re.sub('Montag','Mo',html)
html = re.sub('Dienstag','Di',html)
html = re.sub('Mittwoch','Mi',html)
html = re.sub('Donnerstag','Do',html)
html = re.sub('Freitag','Fr',html)
html = re.sub('\\['+kursid+'\\](.+)?<br>','<div class="'+mycss+'"><a href="#'+klassekurs_aktuell+'">'+klassekurs_print+'</a>\\1</div>',html)
html = re.sub('\\['+kursid+'\\](.+)?</td>','<div class="'+mycss+'"><a href="#'+klassekurs_aktuell+'">'+klassekurs_print+'</a>\\1</div></td>',html)
html = re.sub('\\[\\[(.+)?\\]\\](.+)?<br>','<div class="t-empty">\\1 \\2</div>',html)
html = re.sub('\\[\\[(.+)?\\]\\](.+)?</td>','<div class="t-empty">\\1 \\2</div></td>',html)
table += html
table += '</div>'
# Vermerk zum Projekt
table += '<div class="footer">Dieses PDF-Dokument wurde mithilfe des Python-Skripts <a href="https://www.wolfganglezius.de/lehrerpdf/">LehrerPDF</a> von Wolfgang Lezius erzeugt.</div>'
table += '<pdf:nextpage />'
return table

View File

@@ -34,7 +34,7 @@ def erstelleUebersicht(kursid, klassekurs_name, dateien, path, namen, gebdaten,
else:
beschriftung_name = "Vorname N."
table += header.erstelleKursnavigation(kursid, 'Übersicht', 'übersicht', klassekurs_name, gebdaten, dateien, path, config, inputs, kurs_inputs)
table += header.erstelleKursnavigation(kursid, '', 'übersicht', klassekurs_name, gebdaten, dateien, path, config, inputs, kurs_inputs)
schr_bez = kurs_inputs["schriftlich_bez"]
schr_anzahl = int(kurs_inputs["schriftlich_anzahl"])