From 83bc4907405db4786fa110eb7b782465d51942a9 Mon Sep 17 00:00:00 2001 From: Gonne Date: Tue, 16 Jan 2024 10:27:44 +0100 Subject: [PATCH 01/16] Make support mail contact configurable Still fails because the config is not available in the base template. --- config/config.go | 10 ++++++++++ config/config.json | 3 ++- templating/templates/addFailure.html | 2 +- templating/templates/addMask.html | 2 +- templating/templates/addSuccess.html | 5 +++++ templating/templates/base.html | 3 +-- templating/templates/executeFailure.html | 2 +- 7 files changed, 21 insertions(+), 6 deletions(-) diff --git a/config/config.go b/config/config.go index c284627..afd0c89 100644 --- a/config/config.go +++ b/config/config.go @@ -46,6 +46,7 @@ type Config struct { SmtpUseAuth bool // Set whether to use authentication on the smarthosthost SmtpIdentity string // Smarthost username SmtpPassword string // Smarthost password + SupportMail string // separate mail address for support contact } SQL struct { Type string // Can be "SQLite" or "Mysql" @@ -143,6 +144,15 @@ func validateConfig(conf *Config) error { err = fmt.Errorf("Validating config: Mail FromName could not be parsed (%w)", mailFromNameErr) log.Println(err) } + supportMail, mailSupportMailErr := mail.ParseAddress(string(conf.Mailer.SupportMail)) + if !(mailSupportMailErr == nil) { + err = fmt.Errorf("Validating config: SupportMail could not be parsed (%w)", mailSupportMailErr) + log.Println(err) + } + if !(supportMail.Name == "") { + err = fmt.Errorf("Validating config: SupportMail must not contain a name") + log.Println(err) + } if !(conf.SQL.Type == "SQLite" || conf.SQL.Type == "Mysql") { err = fmt.Errorf("Validating config: SQL type must be 'SQLite' or 'Mysql', but is '%s'.", conf.SQL.Type) log.Println(err.Error()) diff --git a/config/config.json b/config/config.json index 2e78982..78ff627 100644 --- a/config/config.json +++ b/config/config.json @@ -28,7 +28,8 @@ "smtpPort": 25, "smtpUseAuth": false, "smtpIdentity": "", - "smtpPassword": "" + "smtpPassword": "", + "supportMail": "officeHoursSupport@localhost" }, "SQL": { "type": "SQLite", diff --git a/templating/templates/addFailure.html b/templating/templates/addFailure.html index 8ca8fd9..07b10c1 100644 --- a/templating/templates/addFailure.html +++ b/templating/templates/addFailure.html @@ -2,7 +2,7 @@ {{define "content"}}
- Irgendetwas ist schief gegangen. Bitte sende folgende Daten an sprechstundentool@mathebau.de mit einer Beschreibung, was du tun wolltest. + Irgendetwas ist schief gegangen. Bitte sende folgende Daten an {{.Config.Mailer.SupportMail}} mit einer Beschreibung, was du tun wolltest.
{{.}}
diff --git a/templating/templates/addMask.html b/templating/templates/addMask.html index 51f74cd..e99bc10 100644 --- a/templating/templates/addMask.html +++ b/templating/templates/addMask.html @@ -50,7 +50,7 @@
Wenn du eine Veranstaltung hier vermisst, schreibe an - sprechstundentool@mathebau.de. + {{.Config.Mailer.SupportMail}}.
diff --git a/templating/templates/addSuccess.html b/templating/templates/addSuccess.html index 83182f8..be5bb2c 100644 --- a/templating/templates/addSuccess.html +++ b/templating/templates/addSuccess.html @@ -2,6 +2,11 @@ {{define "content"}}
+
+ Die Mailzustellung an Web und GMX ist gerade gestört. + Falls deine Mailadresse dorthin weiterleitet und du die Bestätigung nicht erhältst, + melde dich bei {{.Config.Mailer.SupportMail}}. +
Die Sprechstunde wurde angelegt. Du solltest eine Mail mit einem Aktivierungslink erhalten haben. Klicke auf diesen, um die Sprechstunde öffentlich anzuzeigen. diff --git a/templating/templates/base.html b/templating/templates/base.html index 6bf31d7..8c7a3e9 100644 --- a/templating/templates/base.html +++ b/templating/templates/base.html @@ -34,8 +34,7 @@
© Fachschaft Mathematik, TU Darmstadt
- - Technische Fragen an sprechstundentool@mathebau.de + Technische Fragen an {{.Config.Mailer.SupportMail}}
Quellcode und Featurewünsche: Gitea-Repository
diff --git a/templating/templates/executeFailure.html b/templating/templates/executeFailure.html index 21d68e5..2185df5 100644 --- a/templating/templates/executeFailure.html +++ b/templating/templates/executeFailure.html @@ -2,7 +2,7 @@ {{define "content"}}
- Irgendetwas ist schief gegangen. Bitte sende folgende Daten an sprechstundentool@mathebau.de mit einer Beschreibung, was du tun wolltest. + Irgendetwas ist schief gegangen. Bitte sende folgende Daten an {{.Config.Mailer.SupportMail}} mit einer Beschreibung, was du tun wolltest.
{{.}}
" From 51ce1e896a261582eb053ffd9cd5ed6ac4d9b00c Mon Sep 17 00:00:00 2001 From: Johannes Date: Sun, 18 Feb 2024 11:27:21 +0000 Subject: [PATCH 02/16] fix typo --- templating/templates/addMask.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templating/templates/addMask.html b/templating/templates/addMask.html index 51f74cd..6f2fc9c 100644 --- a/templating/templates/addMask.html +++ b/templating/templates/addMask.html @@ -36,7 +36,7 @@
- +
From 9b211a0dd36285b2294f04df44114a263d135977 Mon Sep 17 00:00:00 2001 From: Gonne Date: Mon, 8 Apr 2024 12:16:18 +0200 Subject: [PATCH 03/16] Dependency updates --- go.mod | 6 ++++-- go.sum | 10 ++++++---- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/go.mod b/go.mod index ba75534..0086f33 100644 --- a/go.mod +++ b/go.mod @@ -2,6 +2,8 @@ module officeHours go 1.18 -require github.com/mattn/go-sqlite3 v1.14.19 +require github.com/mattn/go-sqlite3 v1.14.22 -require github.com/go-sql-driver/mysql v1.7.1 +require github.com/go-sql-driver/mysql v1.8.1 + +require filippo.io/edwards25519 v1.1.0 // indirect diff --git a/go.sum b/go.sum index 5a09e82..210a61a 100644 --- a/go.sum +++ b/go.sum @@ -1,4 +1,6 @@ -github.com/go-sql-driver/mysql v1.7.1 h1:lUIinVbN1DY0xBg0eMOzmmtGoHwWBbvnWubQUrtU8EI= -github.com/go-sql-driver/mysql v1.7.1/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI= -github.com/mattn/go-sqlite3 v1.14.19 h1:fhGleo2h1p8tVChob4I9HpmVFIAkKGpiukdrgQbWfGI= -github.com/mattn/go-sqlite3 v1.14.19/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg= +filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= +filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= +github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y= +github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg= +github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU= +github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= From 3ce88f7e982f47b3fccef8a47d5fdc1d17f19ee3 Mon Sep 17 00:00:00 2001 From: Gonne Date: Mon, 15 Apr 2024 08:11:14 +0200 Subject: [PATCH 04/16] SHK mailinglist link update --- templating/templates/addMask.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templating/templates/addMask.html b/templating/templates/addMask.html index 6f2fc9c..98152d7 100644 --- a/templating/templates/addMask.html +++ b/templating/templates/addMask.html @@ -36,7 +36,7 @@
- +
From ddd08a2d003594aeb0c2f090e321917c90298e4f Mon Sep 17 00:00:00 2001 From: Gonne Date: Sat, 20 Apr 2024 21:34:07 +0200 Subject: [PATCH 05/16] Info zu GMX und Web.de --- templating/templates/addFailure.html | 2 +- templating/templates/addSuccess.html | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/templating/templates/addFailure.html b/templating/templates/addFailure.html index 8ca8fd9..11eb31c 100644 --- a/templating/templates/addFailure.html +++ b/templating/templates/addFailure.html @@ -1,7 +1,7 @@ {{define "title"}}Sprechstunde anlegen – Fehler{{end}} {{define "content"}} -
+
Irgendetwas ist schief gegangen. Bitte sende folgende Daten an sprechstundentool@mathebau.de mit einer Beschreibung, was du tun wolltest.
{{.}} diff --git a/templating/templates/addSuccess.html b/templating/templates/addSuccess.html index 83182f8..849a20f 100644 --- a/templating/templates/addSuccess.html +++ b/templating/templates/addSuccess.html @@ -1,9 +1,14 @@ {{define "title"}}Sprechstunde anlegen{{end}} {{define "content"}} -
+
Die Sprechstunde wurde angelegt. Du solltest eine Mail mit einem Aktivierungslink erhalten haben. Klicke auf diesen, um die Sprechstunde öffentlich anzuzeigen.
+
+ Wir haben vermehrt erfahren, dass Mails, die an GMX oder Web.de weitergeleitet werden, nicht zugestellt werden. + Falls du davon betroffen bist, melde dich bei sprechstundentool@mathebau.de. +
+ {{end}} From 4bffdb53e9b204c671e476e102b9b61c6cea689d Mon Sep 17 00:00:00 2001 From: Gonne Date: Sat, 20 Apr 2024 21:54:05 +0200 Subject: [PATCH 06/16] Mehr Module --- dummydatasqlite.sql | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dummydatasqlite.sql b/dummydatasqlite.sql index b6948e5..0b4a452 100644 --- a/dummydatasqlite.sql +++ b/dummydatasqlite.sql @@ -40,6 +40,7 @@ INSERT INTO `course` (name) VALUES ('Funktionalanalysis II'), ('Geometrie für Lehramt'), ('Gewöhnliche Differentialgleichungen'), +('Graph Theory'), ('Höhere Mathematik I'), ('Höhere Mathematik II'), ('Integrationstheorie'), @@ -73,6 +74,7 @@ INSERT INTO `course` (name) VALUES ('Mathematik im Kontext'), ('Mathematische Grundlagen der Quantenmechanik'), ('Mathematische Statistik'), +('Model Theory'), ('Nichtlineare Optimierung'), ('Numerik gewöhnlicher Differentialgleichungen'), ('Numerische Lineare Algebra'), From 46dfa2a1522ed07bf85d7367cdb2d8651e1c6d84 Mon Sep 17 00:00:00 2001 From: Gonne Date: Sun, 12 May 2024 18:38:14 +0200 Subject: [PATCH 07/16] Split courses by semester --- README.md | 3 +- dummydata/rooms.sql | 7 +++ dummydata/summerCourses.sql | 37 +++++++++++++++ dummydata/winterCourses.sql | 41 ++++++++++++++++ dummydatasqlite.sql | 93 ------------------------------------- 5 files changed, 87 insertions(+), 94 deletions(-) create mode 100644 dummydata/rooms.sql create mode 100644 dummydata/summerCourses.sql create mode 100644 dummydata/winterCourses.sql delete mode 100644 dummydatasqlite.sql diff --git a/README.md b/README.md index cd4a9c2..7e516d5 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,8 @@ e.g. by executing `go version`. Initialize the database. For developing, we recommend using sqlite: user@host:path/to/repo$ sqlite3 officeHours.db -init officeHoursSQLite.sql - sqlite> .read dummydatasqlite.sql + sqlite> .read dummydata/rooms.sql + sqlite> .read dummydata/summerCourses.sql Now start the development webserver, note that you need to manually restart it to code changes take effect. diff --git a/dummydata/rooms.sql b/dummydata/rooms.sql new file mode 100644 index 0000000..1a06c1a --- /dev/null +++ b/dummydata/rooms.sql @@ -0,0 +1,7 @@ +INSERT INTO `room` (name, max_occupy) VALUES +('S2|15-333', 1), +('S2|15-336', 2), +('S2|15-345', 2), +('S2|15-415', 1), +('S2|15-444', 1), +('Sonstige', 1024); diff --git a/dummydata/summerCourses.sql b/dummydata/summerCourses.sql new file mode 100644 index 0000000..ca13de7 --- /dev/null +++ b/dummydata/summerCourses.sql @@ -0,0 +1,37 @@ +INSERT INTO `course` (name) VALUES +('Algorithmic Discrete Mathematics'), +('Analysis II'), +('Analysis II (engl.)'), +('Aussagen- und Prädikatenlogik'), +('Discrete Optimization'), +('Einführung in die Algebra'), +('Einführung in die Finanzmathematik'), +('Einführung in die mathematische Modellierung'), +('Einführung in die Programmierung'), +('Einführung in die Stochastik'), +('Elementare PDE'), +('Elementare Zahlentheorie'), +('Graph Theory'), +('Höhere Mathematik II'), +('Integrationstheorie'), +('LA für Physik und Lehramt'), +('Linear Algebra II (engl.)'), +('Lineare Algebra II'), +('Logik und Grundlagen'), +('Mathe für Chemiker'), +('Mathe II für Informatik'), +('Mathe II für Bauwesen'), +('Mathe II für ET'), +('Mathe II für Maschinenbau'), +('Mathe IV für Maschinenbau'), +('Mathe IV (ET) / Mathe III (Inf) / Praktische Mathe (MEd)'), +('Mathe für MINT'), +('Mathe & Statistik für Biologen'), +('Mathematik im Kontext'), +('Model Theory'), +('Nichtlineare Optimierung'), +('Numerische Lineare Algebra'), +('Riemannsche Flächen'), +('Sobolev Spaces'), +('Topologie'), +('Vertrauenspersonen'); diff --git a/dummydata/winterCourses.sql b/dummydata/winterCourses.sql new file mode 100644 index 0000000..67a3bd7 --- /dev/null +++ b/dummydata/winterCourses.sql @@ -0,0 +1,41 @@ +INSERT INTO `course` (name) VALUES +('Algebra'), +('Analysis I'), +('Analysis I (engl.)'), +('Applied Proof Theory'), +('Automaten, Formale Sprachen und Entscheidbarkeit'), +('Complex Analysis'), +('Differentialgeometrie'), +('Einführung in die Numerische Mathematik'), +('Einführung in die Optimierung'), +('Einführung in die Programmierung'), +('Funktionalanalysis'), +('Geometrie für Lehramt'), +('Gewöhnliche Differentialgleichungen'), +('Höhere Mathematik I'), +('Introduction to mathematical logic'), +('LA für Physik und Lehramt'), +('Linear Algebra I (engl.)'), +('Lineare Algebra I'), +('Mathe für Chemiker'), +('Mathe I für Informatik'), +('Mathe I für Maschinenbau'), +('Mathe I für Bau'), +('Mathe I für ET'), +('Mathe III für Maschinenbau'), +('Mathe III für Bau'), +('Mathe III ET'), +('Mathe IV für Maschinenbau'), +('Mathe IV (ET) / Mathe III (Inf) / Praktische Mathe (MEd)'), +('Mathe für MINT'), +('Mathe & Statistik für Biologen'), +('Mathematik als gemeinsame Sprache der Naturwissenschaften'), +('Numerik gewöhnlicher Differentialgleichungen'), +('Numerische Mathe für MB (IV)'), +('Parabolische PDEs'), +('Partial Differential Equations'), +('Probability Theory'), +('Statistik I für Humanwissenschaftler'), +('Statistik I für WI'), +('Vertrauenspersonen'), +('Wahrscheinlichkeitstheorie'); diff --git a/dummydatasqlite.sql b/dummydatasqlite.sql deleted file mode 100644 index 0b4a452..0000000 --- a/dummydatasqlite.sql +++ /dev/null @@ -1,93 +0,0 @@ -INSERT INTO `room` (name, max_occupy) VALUES -('S2|15-333', 1), -('S2|15-336', 2), -('S2|15-345', 2), -('S2|15-415', 1), -('S2|15-444', 1), -('Sonstige', 1024); -INSERT INTO `course` (name) VALUES -('Algebra'), -('Algebraische Geometrie'), -('Algebraische Kurven'), -('Algebraische Topologie'), -('Algorithmic Discrete Mathematics'), -('Analysis I (engl.)'), -('Analysis I'), -('Analysis II (engl.)'), -('Analysis II'), -('Applied Proof Theory'), -('Aussagen- und Prädikatenlogik'), -('Automaten, Formale Sprachen und Entscheidbarkeit'), -('Banach- und C*-Algebren'), -('Classical and Non-Classical Model Theory'), -('Complex Analysis'), -('Darstellende Geometrie'), -('Darstellungstheorie'), -('Differentialgeometrie'), -('Differentialgeometrie für VI'), -('Diskrete Mathematik'), -('Diskrete Optimierung'), -('Einführung in die Algebra'), -('Einführung in die Finanzmathematik'), -('Einführung in die Numerische Mathematik'), -('Einführung in die Optimierung'), -('Einführung in die Programmierung'), -('Einführung in die Stochastik'), -('Einführung in die mathematische Modellierung'), -('Elementare PDE'), -('Elementare Zahlentheorie'), -('Funktionalanalysis'), -('Funktionalanalysis II'), -('Geometrie für Lehramt'), -('Gewöhnliche Differentialgleichungen'), -('Graph Theory'), -('Höhere Mathematik I'), -('Höhere Mathematik II'), -('Integrationstheorie'), -('Introduction to mathematical logic'), -('Kurvenschätzung'), -('LA für Physik und Lehramt'), -('Lebensversicherungsmathematik'), -('Linear Algebra I (engl.)'), -('Lineare Algebra I'), -('Linear Algebra II (engl.)'), -('Lineare Algebra II'), -('Logics of Knowledge and Information'), -('Manifolds'), -('Mathe für Chemiker'), -('Mathe I für Informatik'), -('Mathe I für Maschinenbau'), -('Mathe I für Bau'), -('Mathe I für ET'), -('Mathe II für Informatik'), -('Mathe II für Bauwesen'), -('Mathe II für ET'), -('Mathe II für Maschinenbau'), -('Mathe III für Maschinenbau'), -('Mathe III für Bau'), -('Mathe III ET'), -('Mathe IV für Maschinenbau'), -('Mathe IV (ET) / Mathe III (Inf) / Praktische Mathe (MEd)'), -('Mathe für MINT'), -('Mathe & Statistik für Biologen'), -('Mathematik als gemeinsame Sprache der Naturwissenschaften'), -('Mathematik im Kontext'), -('Mathematische Grundlagen der Quantenmechanik'), -('Mathematische Statistik'), -('Model Theory'), -('Nichtlineare Optimierung'), -('Numerik gewöhnlicher Differentialgleichungen'), -('Numerische Lineare Algebra'), -('Numerische Mathe für MB (IV)'), -('Parabolische PDEs'), -('Partial Differential Equations I'), -('Probability Theory'), -('Riemannsche Flächen'), -('Schadenversicherungsmathematik'), -('Sobolev Spaces'), -('Spieltheorie'), -('Statistik I für Humanwissenschaftler'), -('Statistik I für WI'), -('Stochastische Prozesse I'), -('Topologie'), -('Wahrscheinlichkeitstheorie'); From e3b69e8f834598cef9c724a904e4f17019580d2b Mon Sep 17 00:00:00 2001 From: Gonne Date: Sun, 12 May 2024 18:47:57 +0200 Subject: [PATCH 08/16] Set more info boxes --- templating/templates/base.html | 8 ++++---- templating/templates/deleteFailure.html | 2 +- templating/templates/deleteSuccess.html | 2 +- templating/templates/executeFailure.html | 2 +- templating/templates/executeSuccess.html | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/templating/templates/base.html b/templating/templates/base.html index 6bf31d7..f7748ab 100644 --- a/templating/templates/base.html +++ b/templating/templates/base.html @@ -13,7 +13,7 @@
-
+
+ -
+

{{template "title" .}}

{{block "content" .}}Du solltest dies nicht sehen.{{end}} -
+
+ + From 22a079e10fb95be79cf17a57724286113919eb6f Mon Sep 17 00:00:00 2001 From: Gonne Date: Tue, 25 Mar 2025 19:59:17 +0100 Subject: [PATCH 12/16] =?UTF-8?q?Updates=20f=C3=BCr=20SoSe?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dummydata/rooms.sql | 2 +- dummydata/summerCourses.sql | 17 +++++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/dummydata/rooms.sql b/dummydata/rooms.sql index 1a06c1a..7416dc3 100644 --- a/dummydata/rooms.sql +++ b/dummydata/rooms.sql @@ -3,5 +3,5 @@ INSERT INTO `room` (name, max_occupy) VALUES ('S2|15-336', 2), ('S2|15-345', 2), ('S2|15-415', 1), -('S2|15-444', 1), +('S2|15-444', 0), ('Sonstige', 1024); diff --git a/dummydata/summerCourses.sql b/dummydata/summerCourses.sql index ca13de7..fb322ce 100644 --- a/dummydata/summerCourses.sql +++ b/dummydata/summerCourses.sql @@ -1,8 +1,14 @@ INSERT INTO `course` (name) VALUES +('Algebraic Geometry'), ('Algorithmic Discrete Mathematics'), ('Analysis II'), ('Analysis II (engl.)'), ('Aussagen- und Prädikatenlogik'), +('Automorphic Forms'), +('Basic Applied Proof Theory'), +('Computational Complexity'), +('Data Assimilation for Fluid Dynamics'), +('Deep Learning Lab'), ('Discrete Optimization'), ('Einführung in die Algebra'), ('Einführung in die Finanzmathematik'), @@ -17,7 +23,9 @@ INSERT INTO `course` (name) VALUES ('LA für Physik und Lehramt'), ('Linear Algebra II (engl.)'), ('Lineare Algebra II'), +('Logics of Knowledge and Information'), ('Logik und Grundlagen'), +('Machine Learning for Fluid Dynamics'), ('Mathe für Chemiker'), ('Mathe II für Informatik'), ('Mathe II für Bauwesen'), @@ -27,11 +35,20 @@ INSERT INTO `course` (name) VALUES ('Mathe IV (ET) / Mathe III (Inf) / Praktische Mathe (MEd)'), ('Mathe für MINT'), ('Mathe & Statistik für Biologen'), +('Mathematical Modelling of Fluid Interfaces'), +('Mathematical Statistics'), ('Mathematik im Kontext'), ('Model Theory'), +('Nonsmooth Optimization'), ('Nichtlineare Optimierung'), +('Numerics of Fluid Dynamics (incompressible)'), +('Numerics of Hyperbolic Equations'), ('Numerische Lineare Algebra'), +('PDE II'), ('Riemannsche Flächen'), +('Seitenkanalangriffe gegen IT-Systeme'), ('Sobolev Spaces'), +('Spin Systems and Statistical Mechanics'), ('Topologie'), +('Variations of geometric energies'), ('Vertrauenspersonen'); From a05407eba01a80e8a2ec294a110232eb61223ce2 Mon Sep 17 00:00:00 2001 From: Gonne Date: Tue, 25 Mar 2025 21:18:13 +0100 Subject: [PATCH 13/16] Change to more powerful mail library that especially adds a correct `Date` heeader for us. --- go.mod | 7 ++- go.sum | 68 +++++++++++++++++++++++++++ repositories/request.go | 55 +++++++++++++++------- templating/templates/confirmationMail | 5 -- 4 files changed, 111 insertions(+), 24 deletions(-) diff --git a/go.mod b/go.mod index bef8ddc..dfba090 100644 --- a/go.mod +++ b/go.mod @@ -6,4 +6,9 @@ require github.com/mattn/go-sqlite3 v1.14.24 require github.com/go-sql-driver/mysql v1.8.1 -require filippo.io/edwards25519 v1.1.0 // indirect +require ( + filippo.io/edwards25519 v1.1.0 // indirect + github.com/wneessen/go-mail v0.6.2 // indirect + golang.org/x/crypto v0.33.0 // indirect + golang.org/x/text v0.22.0 // indirect +) diff --git a/go.sum b/go.sum index 201a2b0..a11fb32 100644 --- a/go.sum +++ b/go.sum @@ -2,7 +2,75 @@ filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y= github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU= github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= github.com/mattn/go-sqlite3 v1.14.24 h1:tpSp2G2KyMnnQu99ngJ47EIkWVmliIizyZBfPrBWDRM= github.com/mattn/go-sqlite3 v1.14.24/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= +github.com/wneessen/go-mail v0.6.2 h1:c6V7c8D2mz868z9WJ+8zDKtUyLfZ1++uAZmo2GRFji8= +github.com/wneessen/go-mail v0.6.2/go.mod h1:L/PYjPK3/2ZlNb2/FjEBIn9n1rUWjW+Toy531oVmeb4= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= +golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= +golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= +golang.org/x/crypto v0.33.0 h1:IOBPskki6Lysi0lo9qQvbxiQ+FvsCC/YWOecCHAixus= +golang.org/x/crypto v0.33.0/go.mod h1:bVdXmD7IV/4GdElGPozy6U7lWdRXA4qyRVGJV57uQ5M= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= +golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= +golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= +golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= +golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= +golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= +golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= +golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY= +golang.org/x/term v0.29.0/go.mod h1:6bl4lRlvVuDgSf3179VpIxBF0o10JUpXWOnI7nErv7s= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM= +golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= +golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= +golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/repositories/request.go b/repositories/request.go index 47e418d..0d88dda 100644 --- a/repositories/request.go +++ b/repositories/request.go @@ -7,10 +7,9 @@ import ( "database/sql" "errors" "fmt" - "html/template" + "github.com/wneessen/go-mail" "log" "math/big" - "net/smtp" "officeHours/config" "officeHours/models" "officeHours/templating" @@ -132,13 +131,12 @@ func (r *RequestRepo) newSecret() (string, error) { } func (r *RequestRepo) sendConfirmationMail(request models.Request) error { - var message bytes.Buffer + var messageText bytes.Buffer var data = struct { - Config config.Config - Request models.Request - MessageId template.HTML - }{r.config, request, template.HTML("<" + randomString(15) + "@" + r.config.Server.Domain + ">")} - err := templating.WriteTemplate(&message, "confirmationMail", data) + Config config.Config + Request models.Request + }{r.config, request} + err := templating.WriteTemplate(&messageText, "confirmationMail", data) if err != nil { err = fmt.Errorf("error parsing confirmation Mail: %w", err) log.Println(err.Error()) @@ -147,19 +145,40 @@ func (r *RequestRepo) sendConfirmationMail(request models.Request) error { switch r.config.Mailer.Type { case "Stdout": - fmt.Println(message.String()) + fmt.Println(messageText.String()) case "Smtp": - to := []string{request.OfficeHour.Tutor.Email} - var auth smtp.Auth - if r.config.Mailer.SmtpUseAuth { - auth = smtp.PlainAuth(r.config.Mailer.SmtpIdentity, r.config.Mailer.FromAddress, r.config.Mailer.SmtpPassword, r.config.Mailer.SmtpHost) - } - err = smtp.SendMail(fmt.Sprintf("%s:%d", r.config.Mailer.SmtpHost, r.config.Mailer.SmtpPort), auth, string(r.config.Mailer.FromName), to, message.Bytes()) - if err != nil { - err = fmt.Errorf("error sending mail by smtp: %w", err) + message := mail.NewMsg() + if err := message.From(r.config.Mailer.FromAddress); err != nil { log.Println(err.Error()) + return err + } + if err := message.To(request.OfficeHour.Tutor.Email); err != nil { + log.Println(err.Error()) + return err + } + switch request.Action { + case models.RequestActivate: + message.Subject("Sprechstunde anlegen") + case models.RequestDelete: + message.Subject("Sprechstunde löschen") + } + message.SetBodyString(mail.TypeTextPlain, messageText.String()) + + var options []mail.Option + if r.config.Mailer.SmtpUseAuth { + options = append(options, mail.WithSMTPAuth(mail.SMTPAuthPlain)) + options = append(options, mail.WithUsername(r.config.Mailer.SmtpIdentity)) + options = append(options, mail.WithPassword(r.config.Mailer.SmtpPassword)) + } + client, err := mail.NewClient(r.config.Mailer.SmtpHost, mail.WithPort(r.config.Mailer.SmtpPort)) + if err != nil { + log.Println(err.Error()) + return err + } + if err := client.DialAndSend(message); err != nil { + log.Println(err.Error()) + return err } - return err } return nil } diff --git a/templating/templates/confirmationMail b/templating/templates/confirmationMail index f996ee7..30205e1 100644 --- a/templating/templates/confirmationMail +++ b/templating/templates/confirmationMail @@ -1,8 +1,3 @@ -From: {{.Config.Mailer.FromName}} -To: {{.Request.OfficeHour.Tutor.Email}} -Subject: Sprechstunde {{if eq .Request.Action 0}}anlegen{{end}}{{if eq .Request.Action 1}}löschen{{end}} -Message-ID: {{.MessageId}} - Hallo {{.Request.OfficeHour.Tutor.Name}}, mit deiner Emailadresse soll eine Sprechstunde mit folgenden Daten {{if eq .Request.Action 0}}angelegt werden{{end}}{{if eq .Request.Action 1}}gelöscht werden{{end}}: From 6ef93951406eaf982c9baa2fe52ff8381411bdf1 Mon Sep 17 00:00:00 2001 From: Gonne Date: Wed, 26 Mar 2025 13:32:51 +0100 Subject: [PATCH 14/16] Apply all options to smtp session --- repositories/request.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/repositories/request.go b/repositories/request.go index 0d88dda..011f015 100644 --- a/repositories/request.go +++ b/repositories/request.go @@ -165,12 +165,13 @@ func (r *RequestRepo) sendConfirmationMail(request models.Request) error { message.SetBodyString(mail.TypeTextPlain, messageText.String()) var options []mail.Option + options = append(options, mail.WithPort(r.config.Mailer.SmtpPort)) if r.config.Mailer.SmtpUseAuth { options = append(options, mail.WithSMTPAuth(mail.SMTPAuthPlain)) options = append(options, mail.WithUsername(r.config.Mailer.SmtpIdentity)) options = append(options, mail.WithPassword(r.config.Mailer.SmtpPassword)) } - client, err := mail.NewClient(r.config.Mailer.SmtpHost, mail.WithPort(r.config.Mailer.SmtpPort)) + client, err := mail.NewClient(r.config.Mailer.SmtpHost, options...) if err != nil { log.Println(err.Error()) return err From 5e954ca751c08394713282e558fe041ae8ac96c3 Mon Sep 17 00:00:00 2001 From: Gonne Date: Wed, 26 Mar 2025 13:33:18 +0100 Subject: [PATCH 15/16] Remove deliverability hint There are no forwards anymore and we have deployed DKIM which should help. --- templating/templates/addSuccess.html | 4 ---- 1 file changed, 4 deletions(-) diff --git a/templating/templates/addSuccess.html b/templating/templates/addSuccess.html index 849a20f..ef4c343 100644 --- a/templating/templates/addSuccess.html +++ b/templating/templates/addSuccess.html @@ -6,9 +6,5 @@ Du solltest eine Mail mit einem Aktivierungslink erhalten haben. Klicke auf diesen, um die Sprechstunde öffentlich anzuzeigen.
- {{end}} From b1eba08dd99ec5ce4897e07bcfad2de9e60df853 Mon Sep 17 00:00:00 2001 From: Gonne Date: Wed, 2 Apr 2025 14:50:42 +0200 Subject: [PATCH 16/16] =?UTF-8?q?=C3=84ndere=20Wochenfeld=20zu=20mehr=20Au?= =?UTF-8?q?swahl.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Closes #28 --- controllers/addOfficeHourHandler.go | 4 ++-- models/date.go | 2 +- repositories/officeHour.go | 4 +--- templating/templates/addMask.html | 9 ++++++--- templating/templates/confirmationMail | 1 + templating/templates/deleteMailForm.html | 2 +- templating/templates/td.html | 2 +- 7 files changed, 13 insertions(+), 11 deletions(-) diff --git a/controllers/addOfficeHourHandler.go b/controllers/addOfficeHourHandler.go index 20c3b8d..4e498e1 100644 --- a/controllers/addOfficeHourHandler.go +++ b/controllers/addOfficeHourHandler.go @@ -73,8 +73,8 @@ func (b *BaseHandler) AddOfficeHourHandler(w http.ResponseWriter, req *http.Requ if err != nil { errors = append(errors, "Die Vorlesungswoche muss eine ganze Zahl sein.") } - if !(week >= 0 && week <= 2) { - errors = append(errors, "Sprechstunden müssen jede, jede gerade oder jede ungerade Vorlesungswoche stattfinden.") + if !(week >= 0 && week <= 5) { + errors = append(errors, "Bitte wähle eine der vorgegebenen Optionen für Vorlesungswochen.") } day, err := strconv.Atoi(req.FormValue("tag")) if err != nil { diff --git a/models/date.go b/models/date.go index 61ce6a3..bea4dc4 100644 --- a/models/date.go +++ b/models/date.go @@ -5,7 +5,7 @@ import ( ) type Date struct { - Week int // Set whether the date is all weeks (0), odd weeks (1) or even weeks (2). + Week int // Set whether the date is all weeks (0), weeks with exercise session (1) or weeks without exercise session (2), even weeks (3), odd weeks (4) or other (5). Day int Hour int Minute int diff --git a/repositories/officeHour.go b/repositories/officeHour.go index 27ccd86..4a0243a 100644 --- a/repositories/officeHour.go +++ b/repositories/officeHour.go @@ -245,9 +245,7 @@ func (r *OfficeHourRepo) NumberByTimeSpanAndRoom(date models.Date, duration int, for _, officeHour := range officeHours { // increase count if officehour starts before this point in time and ends later if models.DateLess(officeHour.Date, models.GetEndDate(date, minute, false)) && models.DateLess(models.GetEndDate(date, minute, false), models.GetEndDate(officeHour.Date, officeHour.Duration, false)) { - if date.Week == 0 || officeHour.Week == 0 || date.Week == officeHour.Week { // office hours in alternating weeks should not collide - minuteCount += 1 - } + minuteCount += 1 } } if minuteCount > count { diff --git a/templating/templates/addMask.html b/templating/templates/addMask.html index 98152d7..634a4f4 100644 --- a/templating/templates/addMask.html +++ b/templating/templates/addMask.html @@ -59,9 +59,12 @@
diff --git a/templating/templates/confirmationMail b/templating/templates/confirmationMail index 30205e1..1d61fdb 100644 --- a/templating/templates/confirmationMail +++ b/templating/templates/confirmationMail @@ -5,6 +5,7 @@ mit deiner Emailadresse soll eine Sprechstunde mit folgenden Daten {{if eq .Requ {{.Request.OfficeHour.Course.Name}} {{DayName .Request.OfficeHour.Date.Day}} {{printf "%02d" .Request.OfficeHour.Date.Hour}}:{{printf "%02d" .Request.OfficeHour.Date.Minute}} Uhr bis {{printf "%02d" .Request.OfficeHour.EndDate.Hour}}:{{printf "%02d" .Request.OfficeHour.EndDate.Minute}} Uhr +{{if eq 0 .Request.OfficeHour.Date.Week}}Jede Woche{{end}}{{if eq 1 .Request.OfficeHour.Date.Week}}In Wochen mit Übung{{end}}{{if eq 2 .Request.OfficeHour.Date.Week}}In Wochen ohne Übung{{end}}{{if eq 3 .Request.OfficeHour.Date.Week}}In geraden Vorlesungswochen{{end}}{{if eq 4 .Request.OfficeHour.Date.Week}}In ungeraden Vorlesungswochen{{end}} {{.Request.OfficeHour.Tutor.Name}} {{.Request.OfficeHour.Room.Name}} diff --git a/templating/templates/deleteMailForm.html b/templating/templates/deleteMailForm.html index 378e6e7..11a8119 100644 --- a/templating/templates/deleteMailForm.html +++ b/templating/templates/deleteMailForm.html @@ -11,7 +11,7 @@

Willst du die Sprechstunde
{{printf "%02d" .OfficeHour.Date.Hour}}:{{printf "%02d" .OfficeHour.Date.Minute}} - {{printf "%02d" .OfficeHour.EndDate.Hour}}:{{printf "%02d" .OfficeHour.EndDate.Minute}}
- {{if eq .OfficeHour.Date.Week 1}}in ungeraden Vorlesungswochen
{{end}}{{if eq .OfficeHour.Date.Week 2}}in geraden Vorlesungswochen
{{end}} + {{if eq 0 $.Date.Week}}>Jede Woche
{{end}}{{if eq 1 $.Date.Week}}In Wochen mit Übung
{{end}}{{if eq 2 $.Date.Week}}In Wochen ohne Übung
{{end}}{{if eq 3 $.Date.Week}}In geraden Vorlesungswochen
{{end}}{{if eq 4 $.Date.Week}}In ungeraden Vorlesungswochen
{{end}} {{.OfficeHour.Course.Name}}
{{.OfficeHour.Tutor.Name}}
{{.OfficeHour.Room.Name}}
diff --git a/templating/templates/td.html b/templating/templates/td.html index cb1f041..76fc5e1 100644 --- a/templating/templates/td.html +++ b/templating/templates/td.html @@ -1,7 +1,7 @@ {{if .DeleteIcons}}

{{end}} {{printf "%02d" .OfficeHour.Date.Hour}}:{{printf "%02d" .OfficeHour.Date.Minute}} - {{printf "%02d" .OfficeHour.EndDate.Hour}}:{{printf "%02d" .OfficeHour.EndDate.Minute}}
- {{if eq .OfficeHour.Date.Week 1}}in ungeraden Vorlesungswochen
{{end}}{{if eq .OfficeHour.Date.Week 2}}in geraden Vorlesungswochen
{{end}} + {{if eq 1 .OfficeHour.Date.Week}}In Wochen mit Übung
{{end}}{{if eq 2 .OfficeHour.Date.Week}}In Wochen ohne Übung
{{end}}{{if eq 3 .OfficeHour.Date.Week}}In geraden Vorlesungswochen
{{end}}{{if eq 4 .OfficeHour.Date.Week}}In ungeraden Vorlesungswochen
{{end}} {{.OfficeHour.Course.Name}}
{{.OfficeHour.Tutor.Name}}
{{.OfficeHour.Room.Name}}