Compare commits
1 commit
main
...
configSupp
Author | SHA1 | Date | |
---|---|---|---|
83bc490740 |
23 changed files with 178 additions and 167 deletions
|
@ -7,8 +7,7 @@ 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 dummydata/rooms.sql
|
||||
sqlite> .read dummydata/summerCourses.sql
|
||||
sqlite> .read dummydatasqlite.sql
|
||||
|
||||
Now start the development webserver, note that you need to manually
|
||||
restart it to code changes take effect.
|
||||
|
|
|
@ -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"
|
||||
|
@ -68,13 +69,13 @@ type Config struct {
|
|||
func ReadConfigFile(filename string, conf *Config) error {
|
||||
configData, err := ioutil.ReadFile(filename)
|
||||
if err != nil {
|
||||
err = fmt.Errorf("error reading config file: %w", err)
|
||||
err = fmt.Errorf("Error reading config file: %w", err)
|
||||
log.Println(err.Error())
|
||||
return err
|
||||
}
|
||||
err = json.Unmarshal(configData, conf)
|
||||
if err != nil {
|
||||
err = fmt.Errorf("error parsing config file as json: %w", err)
|
||||
err = fmt.Errorf("Error parsing config file as json: %w", err)
|
||||
log.Println(err.Error())
|
||||
return err
|
||||
}
|
||||
|
@ -85,66 +86,75 @@ func ReadConfigFile(filename string, conf *Config) error {
|
|||
func validateConfig(conf *Config) error {
|
||||
var err error
|
||||
if !(conf.Server.ListenPort >= 1 && conf.Server.ListenPort <= 65535) {
|
||||
err = fmt.Errorf("validating config: Server port must be between 1 and 65535, but is %d.", conf.Server.ListenPort)
|
||||
err = fmt.Errorf("Validating config: Server port must be between 1 and 65535, but is %d.", conf.Server.ListenPort)
|
||||
log.Println(err.Error())
|
||||
}
|
||||
if !(conf.Server.Protocol == "http" || conf.Server.Protocol == "https") {
|
||||
err = fmt.Errorf("validating config: Server protocol must be 'http' or 'https', but is '%s'.", conf.Server.Protocol)
|
||||
err = fmt.Errorf("Validating config: Server protocol must be 'http' or 'https', but is '%s'.", conf.Server.Protocol)
|
||||
log.Println(err.Error())
|
||||
}
|
||||
if !(conf.Date.MinuteGranularity >= 1 && conf.Date.MinuteGranularity <= 60) {
|
||||
err = fmt.Errorf("validating config: Minute granularity must be between 1 and 60, but is %d.", conf.Date.MinuteGranularity)
|
||||
err = fmt.Errorf("Validating config: Minute granularity must be between 1 and 60, but is %d.", conf.Date.MinuteGranularity)
|
||||
log.Println(err.Error())
|
||||
}
|
||||
if !(conf.Date.EarliestStartTime.Hour >= 0 && conf.Date.EarliestStartTime.Hour <= 23) {
|
||||
err = fmt.Errorf("validating config: Earliest start time hour must be between 0 and 23, but is %d.", conf.Date.EarliestStartTime.Hour)
|
||||
err = fmt.Errorf("Validating config: Earliest start time hour must be between 0 and 23, but is %d.", conf.Date.EarliestStartTime.Hour)
|
||||
log.Println(err.Error())
|
||||
}
|
||||
if !(conf.Date.EarliestStartTime.Minute >= 0 && conf.Date.EarliestStartTime.Minute <= 60) {
|
||||
err = fmt.Errorf("validating config: Earliest start time minute must be between 0 and 60, but is %d.", conf.Date.EarliestStartTime.Minute)
|
||||
err = fmt.Errorf("Validating config: Earliest start time minute must be between 0 and 60, but is %d.", conf.Date.EarliestStartTime.Minute)
|
||||
log.Println(err.Error())
|
||||
}
|
||||
if !(conf.Date.MaxDuration >= conf.Date.MinuteGranularity && conf.Date.MaxDuration <= 4*60) {
|
||||
err = fmt.Errorf("validating config: Maximum duration must be between %d minute and 4 hours, but is %d.", conf.Date.MinuteGranularity, conf.Date.MaxDuration)
|
||||
err = fmt.Errorf("Validating config: Maximum duration must be between %d minute and 4 hours, but is %d.", conf.Date.MinuteGranularity, conf.Date.MaxDuration)
|
||||
log.Println(err.Error())
|
||||
}
|
||||
if !(conf.Date.LatestStartTime.Hour >= 0 && conf.Date.LatestStartTime.Hour <= 23) {
|
||||
err = fmt.Errorf("validating config: Latest start time hour must be between 0 and 23, but is %d.", conf.Date.LatestStartTime.Hour)
|
||||
err = fmt.Errorf("Validating config: Latest start time hour must be between 0 and 23, but is %d.", conf.Date.LatestStartTime.Hour)
|
||||
log.Println(err.Error())
|
||||
}
|
||||
if !(conf.Date.LatestStartTime.Minute >= 0 && conf.Date.LatestStartTime.Minute <= 60) {
|
||||
err = fmt.Errorf("validating config: Latest start time minute must be between 0 and 60, but is %d.", conf.Date.LatestStartTime.Minute)
|
||||
err = fmt.Errorf("Validating config: Latest start time minute must be between 0 and 60, but is %d.", conf.Date.LatestStartTime.Minute)
|
||||
log.Println(err.Error())
|
||||
}
|
||||
if !(conf.Date.EarliestStartTime.Hour < conf.Date.LatestStartTime.Hour || (conf.Date.EarliestStartTime.Hour == conf.Date.LatestStartTime.Hour && conf.Date.EarliestStartTime.Minute < conf.Date.LatestStartTime.Minute)) {
|
||||
err = fmt.Errorf("validating config: Latest start time minute must be after earliest start time.")
|
||||
err = fmt.Errorf("Validating config: Latest start time minute must be after earliest start time.")
|
||||
log.Println(err.Error())
|
||||
}
|
||||
if !(conf.Request.SecretLength >= 5 && conf.Request.SecretLength <= 50) {
|
||||
err = fmt.Errorf("validating config: Requests' secret length must be between 5 and 50, but is %d.", conf.Request.SecretLength)
|
||||
err = fmt.Errorf("Validating config: Requests' secret length must be between 5 and 50, but is %d.", conf.Request.SecretLength)
|
||||
log.Println(err.Error())
|
||||
}
|
||||
if !(conf.Mailer.Type == "Stdout" || conf.Mailer.Type == "Smtp") {
|
||||
err = fmt.Errorf("validating config: Mailer type must be 'Stdout' or 'Smtp', but is '%s'.", conf.Mailer.Type)
|
||||
err = fmt.Errorf("Validating config: Mailer type must be 'Stdout' or 'Smtp', but is '%s'.", conf.Mailer.Type)
|
||||
log.Println(err.Error())
|
||||
}
|
||||
mailFromAddress, mailFromAddressErr := mail.ParseAddress(conf.Mailer.FromAddress)
|
||||
if !(mailFromAddressErr == nil) {
|
||||
err = fmt.Errorf("validating config: Mail FromAddress could not be parsed (%w)", mailFromAddressErr)
|
||||
err = fmt.Errorf("Validating config: Mail FromAddress could not be parsed (%w)", mailFromAddressErr)
|
||||
log.Println(err)
|
||||
} else {
|
||||
if !(mailFromAddress.Name == "") {
|
||||
err = fmt.Errorf("validating config: Mail FromAddress must not contain a name value, but has '%s'", mailFromAddress.Name)
|
||||
err = fmt.Errorf("Validating config: Mail FromAddress must not contain a name value, but has '%s'", mailFromAddress.Name)
|
||||
log.Println(err)
|
||||
}
|
||||
}
|
||||
_, mailFromNameErr := mail.ParseAddress(string(conf.Mailer.FromName))
|
||||
if !(mailFromNameErr == nil) {
|
||||
err = fmt.Errorf("validating config: Mail FromName could not be parsed (%w)", mailFromNameErr)
|
||||
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)
|
||||
err = fmt.Errorf("Validating config: SQL type must be 'SQLite' or 'Mysql', but is '%s'.", conf.SQL.Type)
|
||||
log.Println(err.Error())
|
||||
}
|
||||
return err
|
||||
|
|
|
@ -28,7 +28,8 @@
|
|||
"smtpPort": 25,
|
||||
"smtpUseAuth": false,
|
||||
"smtpIdentity": "",
|
||||
"smtpPassword": ""
|
||||
"smtpPassword": "",
|
||||
"supportMail": "officeHoursSupport@localhost"
|
||||
},
|
||||
"SQL": {
|
||||
"type": "SQLite",
|
||||
|
|
|
@ -1,7 +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);
|
|
@ -1,37 +0,0 @@
|
|||
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');
|
|
@ -1,41 +0,0 @@
|
|||
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');
|
91
dummydatasqlite.sql
Normal file
91
dummydatasqlite.sql
Normal file
|
@ -0,0 +1,91 @@
|
|||
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'),
|
||||
('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'),
|
||||
('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');
|
6
go.mod
6
go.mod
|
@ -2,8 +2,6 @@ module officeHours
|
|||
|
||||
go 1.18
|
||||
|
||||
require github.com/mattn/go-sqlite3 v1.14.22
|
||||
require github.com/mattn/go-sqlite3 v1.14.19
|
||||
|
||||
require github.com/go-sql-driver/mysql v1.8.1
|
||||
|
||||
require filippo.io/edwards25519 v1.1.0 // indirect
|
||||
require github.com/go-sql-driver/mysql v1.7.1
|
||||
|
|
10
go.sum
10
go.sum
|
@ -1,6 +1,4 @@
|
|||
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=
|
||||
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=
|
||||
|
|
|
@ -30,7 +30,7 @@ func (r *CourseRepo) FindById(id int) (models.Course, error) {
|
|||
func (r *CourseRepo) GetAll() ([]models.Course, error) {
|
||||
rows, err := r.db.Query("SELECT * FROM course ORDER BY name ASC")
|
||||
if err != nil {
|
||||
log.Printf("error getting all courses: %s", err.Error())
|
||||
log.Printf("Error getting all courses: %s", err.Error())
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
|
@ -56,9 +56,9 @@ func (r *CourseRepo) getFromRows(rows *sql.Rows) ([]models.Course, error) {
|
|||
func (r *CourseRepo) getFromRow(row *sql.Row) (models.Course, error) {
|
||||
var course models.Course
|
||||
if err := row.Scan(&course.Id, &course.Name); err != nil {
|
||||
err = fmt.Errorf("error getting course row: %w", err)
|
||||
err = fmt.Errorf("Error getting course row: %w", err)
|
||||
if !errors.Is(err, sql.ErrNoRows) {
|
||||
log.Print(err.Error())
|
||||
log.Printf(err.Error())
|
||||
}
|
||||
return models.Course{}, err
|
||||
}
|
||||
|
|
|
@ -37,7 +37,7 @@ func (r *OfficeHourRepo) GetAll(activeOnly bool) ([]models.OfficeHour, error) {
|
|||
rows, err = r.db.Query("SELECT * FROM officeHour")
|
||||
}
|
||||
if err != nil {
|
||||
err = fmt.Errorf("error getting all officeHours from database: %w", err)
|
||||
err = fmt.Errorf("Error getting all officeHours from database: %w", err)
|
||||
if !errors.Is(err, sql.ErrNoRows) {
|
||||
log.Println(err.Error())
|
||||
}
|
||||
|
@ -57,7 +57,7 @@ func (r *OfficeHourRepo) FindByCourse(course models.Course, activeOnly bool) ([]
|
|||
}
|
||||
defer rows.Close()
|
||||
if err != nil {
|
||||
err = fmt.Errorf("error getting officeHours by course from database: %w", err)
|
||||
err = fmt.Errorf("Error getting officeHours by course from database: %w", err)
|
||||
if !errors.Is(err, sql.ErrNoRows) {
|
||||
log.Println(err.Error())
|
||||
}
|
||||
|
@ -75,7 +75,7 @@ func (r *OfficeHourRepo) FindByRoom(room models.Room, activeOnly bool) ([]models
|
|||
rows, err = r.db.Query("SELECT * FROM officeHour WHERE room=?", room.Id)
|
||||
}
|
||||
if err != nil {
|
||||
err = fmt.Errorf("error getting officeHours by room from database: %w", err)
|
||||
err = fmt.Errorf("Error getting officeHours by room from database: %w", err)
|
||||
if !errors.Is(err, sql.ErrNoRows) {
|
||||
log.Println(err.Error())
|
||||
}
|
||||
|
@ -101,7 +101,7 @@ func (r *OfficeHourRepo) Add(officeHour models.OfficeHour) (int, error) {
|
|||
}
|
||||
officeHour.Tutor, err = r.tutorRepo.FindByNameAndEmail(officeHour.Tutor.Name, officeHour.Tutor.Email)
|
||||
if err != nil {
|
||||
err = fmt.Errorf("newly added tutor not found: %w", err)
|
||||
err = fmt.Errorf("Newly added tutor not found: %w", err)
|
||||
log.Println(err.Error())
|
||||
return 0, err
|
||||
}
|
||||
|
@ -140,7 +140,7 @@ func (r *OfficeHourRepo) Add(officeHour models.OfficeHour) (int, error) {
|
|||
}
|
||||
id, lastInsertIdErr := sqlResult.LastInsertId()
|
||||
if lastInsertIdErr != nil {
|
||||
log.Printf("error getting Id for new tutor: %s", lastInsertIdErr.Error())
|
||||
log.Printf("Error getting Id for new tutor: %s", lastInsertIdErr.Error())
|
||||
}
|
||||
return int(id), err
|
||||
}
|
||||
|
@ -148,7 +148,7 @@ func (r *OfficeHourRepo) Add(officeHour models.OfficeHour) (int, error) {
|
|||
func (r *OfficeHourRepo) Delete(officeHour models.OfficeHour) error {
|
||||
_, err := r.db.Exec("DELETE FROM officeHour WHERE id=?", officeHour.Id)
|
||||
if err != nil {
|
||||
err = fmt.Errorf("error deleting officeHour from database: %w", err)
|
||||
err = fmt.Errorf("Error deleting officeHour from database: %w", err)
|
||||
log.Println(err.Error())
|
||||
return err
|
||||
}
|
||||
|
@ -160,26 +160,26 @@ func (r *OfficeHourRepo) getFromRow(row *sql.Row) (models.OfficeHour, error) {
|
|||
var week, day, hour, minute, tutorId, courseId, roomId int
|
||||
err := row.Scan(&officeHour.Id, &tutorId, &day, &hour, &minute, &roomId, &officeHour.RoomName, &courseId, &week, &officeHour.Info, &officeHour.Active, &officeHour.Duration)
|
||||
if err != nil {
|
||||
err = fmt.Errorf("error getting single officeHour row from database: %w", err)
|
||||
err = fmt.Errorf("Error getting single officeHour row from database: %w", err)
|
||||
log.Println(err.Error())
|
||||
return models.OfficeHour{}, err
|
||||
}
|
||||
officeHour.Date = models.Date{Week: week, Day: day, Hour: hour, Minute: minute}
|
||||
officeHour.Room, err = r.roomRepo.FindById(roomId)
|
||||
if err != nil {
|
||||
err = fmt.Errorf("error finding room by id %d for office hour: %w", roomId, err)
|
||||
err = fmt.Errorf("Error finding room by id %d for office hour: %w", roomId, err)
|
||||
log.Println(err.Error())
|
||||
return officeHour, err
|
||||
}
|
||||
officeHour.Tutor, err = r.tutorRepo.FindById(tutorId)
|
||||
if err != nil {
|
||||
err = fmt.Errorf("error finding tutor by id %d for office hour: %w", tutorId, err)
|
||||
err = fmt.Errorf("Error finding tutor by id %d for office hour: %w", tutorId, err)
|
||||
log.Println(err.Error())
|
||||
return officeHour, err
|
||||
}
|
||||
officeHour.Course, err = r.courseRepo.FindById(courseId)
|
||||
if err != nil {
|
||||
err = fmt.Errorf("error finding course by id %d for office hour: %w", courseId, err)
|
||||
err = fmt.Errorf("Error finding course by id %d for office hour: %w", courseId, err)
|
||||
log.Println(err.Error())
|
||||
return officeHour, err
|
||||
}
|
||||
|
@ -193,24 +193,24 @@ func (r *OfficeHourRepo) getFromRows(rows *sql.Rows) ([]models.OfficeHour, error
|
|||
var week, day, hour, minute, tutorId, roomId, courseId int
|
||||
var err error
|
||||
if err := rows.Scan(&officeHour.Id, &tutorId, &day, &hour, &minute, &roomId, &officeHour.RoomName, &courseId, &week, &officeHour.Info, &officeHour.Active, &officeHour.Duration); err != nil {
|
||||
return officeHours, fmt.Errorf("error getting multiple officeHour rows from database: %w", err)
|
||||
return officeHours, fmt.Errorf("Error getting multiple officeHour rows from database: %w", err)
|
||||
}
|
||||
officeHour.Date = models.Date{Week: week, Day: day, Hour: hour, Minute: minute}
|
||||
officeHour.Room, err = r.roomRepo.FindById(roomId)
|
||||
if err != nil {
|
||||
err = fmt.Errorf("error finding room by id %d for office hour: %w", roomId, err)
|
||||
err = fmt.Errorf("Error finding room by id %d for office hour: %w", roomId, err)
|
||||
log.Println(err.Error())
|
||||
return officeHours, err
|
||||
}
|
||||
officeHour.Tutor, err = r.tutorRepo.FindById(tutorId)
|
||||
if err != nil {
|
||||
err = fmt.Errorf("error finding tutor by id %d for office hour: %w", tutorId, err)
|
||||
err = fmt.Errorf("Error finding tutor by id %d for office hour: %w", tutorId, err)
|
||||
log.Println(err.Error())
|
||||
return officeHours, err
|
||||
}
|
||||
officeHour.Course, err = r.courseRepo.FindById(courseId)
|
||||
if err != nil {
|
||||
err = fmt.Errorf("error finding course by id %d for office hour: %w", courseId, err)
|
||||
err = fmt.Errorf("Error finding course by id %d for office hour: %w", courseId, err)
|
||||
log.Println(err.Error())
|
||||
return officeHours, err
|
||||
}
|
||||
|
@ -229,7 +229,7 @@ func (r *OfficeHourRepo) NumberByTimeSpanAndRoom(date models.Date, duration int,
|
|||
rows, err = r.db.Query("SELECT * FROM officeHour WHERE room=?", room.Id)
|
||||
}
|
||||
if err != nil {
|
||||
err = fmt.Errorf("error getting officeHours by timespan and room from database: %w", err)
|
||||
err = fmt.Errorf("Error getting officeHours by timespan and room from database: %w", err)
|
||||
log.Println(err.Error())
|
||||
return 0, err
|
||||
}
|
||||
|
|
|
@ -55,7 +55,7 @@ func (r *RequestRepo) FindByOfficeHour(officeHour models.OfficeHour) ([]models.R
|
|||
var request models.Request
|
||||
var officeHourId int
|
||||
if err := rows.Scan(&request.Id, &officeHourId, &request.Action, &request.Secret); err != nil {
|
||||
err = fmt.Errorf("error scanning request row: %w", err)
|
||||
err = fmt.Errorf("Error scanning request row: %w", err)
|
||||
log.Println(err.Error())
|
||||
return requests, err
|
||||
}
|
||||
|
@ -110,7 +110,7 @@ func (r *RequestRepo) Execute(request models.Request) error {
|
|||
r.db.Exec("DELETE FROM request WHERE officeHour=?", request.OfficeHour.Id)
|
||||
err = r.officeHourRepo.Delete(request.OfficeHour)
|
||||
default:
|
||||
log.Printf("executing request: Action type %d unknown.", request.Action)
|
||||
log.Printf("Executing request: Action type %d unknown.", request.Action)
|
||||
_, err = r.db.Exec("DELETE FROM request WHERE id=?", request.Id)
|
||||
}
|
||||
return err
|
||||
|
@ -140,7 +140,7 @@ func (r *RequestRepo) sendConfirmationMail(request models.Request) error {
|
|||
}{r.config, request, template.HTML("<" + randomString(15) + "@" + r.config.Server.Domain + ">")}
|
||||
err := templating.WriteTemplate(&message, "confirmationMail", data)
|
||||
if err != nil {
|
||||
err = fmt.Errorf("error parsing confirmation Mail: %w", err)
|
||||
err = fmt.Errorf("Error parsing confirmation Mail: %w", err)
|
||||
log.Println(err.Error())
|
||||
return err
|
||||
}
|
||||
|
@ -156,7 +156,7 @@ func (r *RequestRepo) sendConfirmationMail(request models.Request) error {
|
|||
}
|
||||
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)
|
||||
err = fmt.Errorf("Error sending mail by smtp: %w", err)
|
||||
log.Println(err.Error())
|
||||
}
|
||||
return err
|
||||
|
|
|
@ -31,7 +31,7 @@ func (r *RoomRepo) FindById(id int) (models.Room, error) {
|
|||
row := r.db.QueryRow("SELECT * FROM room WHERE id=?", id)
|
||||
var room models.Room
|
||||
if err := row.Scan(&room.Id, &room.Name, &room.MaxOccupy); err != nil {
|
||||
err = fmt.Errorf("error scanning row to get room: %w", err)
|
||||
err = fmt.Errorf("Error scanning row to get room: %w", err)
|
||||
if !errors.Is(err, sql.ErrNoRows) {
|
||||
log.Println(err.Error())
|
||||
}
|
||||
|
@ -43,7 +43,7 @@ func (r *RoomRepo) FindById(id int) (models.Room, error) {
|
|||
func (r *RoomRepo) GetAll() ([]models.Room, error) {
|
||||
rows, err := r.db.Query("SELECT * FROM room ORDER BY name ASC")
|
||||
if err != nil {
|
||||
err = fmt.Errorf("error getting all rooms: %w", err)
|
||||
err = fmt.Errorf("Error getting all rooms: %w", err)
|
||||
log.Println(err.Error())
|
||||
return nil, err
|
||||
}
|
||||
|
@ -53,7 +53,7 @@ func (r *RoomRepo) GetAll() ([]models.Room, error) {
|
|||
for rows.Next() {
|
||||
var room models.Room
|
||||
if err := rows.Scan(&room.Id, &room.Name, &room.MaxOccupy); err != nil {
|
||||
err = fmt.Errorf("error scanning row to get room: %w", err)
|
||||
err = fmt.Errorf("Error scanning row to get room: %w", err)
|
||||
return rooms, err
|
||||
}
|
||||
rooms = append(rooms, room)
|
||||
|
|
|
@ -58,7 +58,7 @@ func (r *TutorRepo) Add(tutor models.Tutor) (int, error) {
|
|||
}
|
||||
id, lastInsertIdErr := sqlResult.LastInsertId()
|
||||
if lastInsertIdErr != nil {
|
||||
log.Printf("error getting Id for new tutor: %s", lastInsertIdErr.Error())
|
||||
log.Printf("Error getting Id for new tutor: %s", lastInsertIdErr.Error())
|
||||
}
|
||||
return int(id), err
|
||||
}
|
||||
|
@ -80,7 +80,7 @@ func (r *TutorRepo) getFromRows(rows *sql.Rows) ([]models.Tutor, error) {
|
|||
for rows.Next() {
|
||||
var tutor models.Tutor
|
||||
if err := rows.Scan(&tutor.Id, &tutor.Name, &tutor.Email, &tutor.SubscribeToMailinglist); err != nil {
|
||||
err = fmt.Errorf("error scanning tutor row: %w", err)
|
||||
err = fmt.Errorf("Error scanning tutor row: %w", err)
|
||||
log.Println(err.Error())
|
||||
return tutors, err
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@ func Connect(config config.Config) (*sql.DB, error) {
|
|||
config.SQL.MysqlPort,
|
||||
config.SQL.MysqlDatabase)
|
||||
default:
|
||||
return nil, fmt.Errorf("type of database not recognised: %s", config.SQL.Type)
|
||||
return nil, fmt.Errorf("Type of database not recognised: %s", config.SQL.Type)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -29,7 +29,7 @@ func Connect(config config.Config) (*sql.DB, error) {
|
|||
func connectSQLite(file string) (*sql.DB, error) {
|
||||
db, err := sql.Open("sqlite3", file)
|
||||
if err != nil {
|
||||
return db, fmt.Errorf("error opening SQLite database: %w", err)
|
||||
return db, fmt.Errorf("Error opening SQLite database: %w", err)
|
||||
}
|
||||
return db, nil
|
||||
}
|
||||
|
@ -38,12 +38,12 @@ func connectSQLite(file string) (*sql.DB, error) {
|
|||
func connectMysql(user string, password string, address string, port int, database string) (*sql.DB, error) {
|
||||
db, err := sql.Open("mysql", fmt.Sprintf("%s:%s@tcp(%s:%d)/%s", user, password, address, port, database))
|
||||
if err != nil {
|
||||
return db, fmt.Errorf("error connecting to Mysql database: %w", err)
|
||||
return db, fmt.Errorf("Error connecting to Mysql database: %w", err)
|
||||
}
|
||||
|
||||
err = db.Ping()
|
||||
if err != nil {
|
||||
return db, fmt.Errorf("error pinging Mysql database: %w", err)
|
||||
return db, fmt.Errorf("Error pinging Mysql database: %w", err)
|
||||
}
|
||||
return db, nil
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
{{define "title"}}Sprechstunde anlegen – Fehler{{end}}
|
||||
|
||||
{{define "content"}}
|
||||
<div class="col-md-8 offset-md-2 alert alert-danger">
|
||||
Irgendetwas ist schief gegangen. Bitte sende folgende Daten an <a href="mailto:sprechstundentool@mathebau.de">sprechstundentool@mathebau.de</a> mit einer Beschreibung, was du tun wolltest.
|
||||
<div class="col-md-8 offset-md-2">
|
||||
Irgendetwas ist schief gegangen. Bitte sende folgende Daten an <a href="mailto:{{.Config.Mailer.SupportMail}}">{{.Config.Mailer.SupportMail}}</a> mit einer Beschreibung, was du tun wolltest.
|
||||
<br>
|
||||
{{.}}
|
||||
</div>
|
||||
|
|
|
@ -36,7 +36,7 @@
|
|||
<div class="form-floating mb-3">
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" name="subscribeToMailinglist" id="subscribeToMailinglist" type="checkbox" value="subscribe" {{if eq .SubscribeToMailinglist true}}checked{{end}}>
|
||||
<label class="form-check-label" for="subscribeToMailinglist"><a href="https://lists.mathebau.de/postorius/lists/shk.lists.mathebau.de/">Mailingliste für SHK</a> abonnieren</label>
|
||||
<label class="form-check-label" for="subscribeToMailinglist"><a href="https://lists.mathebau.de/postorius/lists/shk.mathebau.de/">Mailingliste für SHK</a> abbonieren</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -50,7 +50,7 @@
|
|||
<label for="veranstaltung">Veranstaltung</label>
|
||||
<div class="form-text">
|
||||
Wenn du eine Veranstaltung hier vermisst, schreibe an
|
||||
<a href="mailto:sprechstundentool@mathebau.de?subject=Sprechstundentool: Neue Veranstaltung&body=Hey liebe Sprechstundentool-Admins,%0D%0A%0D%0Ameine Veranstaltung fehlt im Auswahlmenü.%0D%0AEs ist die Veranstaltung%0D%0A%0D%0AViele Grüße%0D%0A" tabindex="-1">sprechstundentool@mathebau.de</a>.
|
||||
<a href="mailto:{{.Config.Mailer.SupportMail}}?subject=Sprechstundentool: Neue Veranstaltung&body=Hey liebe Sprechstundentool-Admins,%0D%0A%0D%0Ameine Veranstaltung fehlt im Auswahlmenü.%0D%0AEs ist die Veranstaltung%0D%0A%0D%0AViele Grüße%0D%0A" tabindex="-1">{{.Config.Mailer.SupportMail}}</a>.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
{{define "title"}}Sprechstunde anlegen{{end}}
|
||||
|
||||
{{define "content"}}
|
||||
<div class="col-md-8 offset-md-2 alert alert-success">
|
||||
<div class="col-md-8 offset-md-2">
|
||||
<div class="alert alert-danger">
|
||||
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 <a href="mailto:{{.Config.Mailer.SupportMail}}">{{.Config.Mailer.SupportMail}}</a>.
|
||||
</div>
|
||||
Die Sprechstunde wurde angelegt.
|
||||
Du solltest eine Mail mit einem Aktivierungslink erhalten haben.
|
||||
Klicke auf diesen, um die Sprechstunde öffentlich anzuzeigen.
|
||||
</div>
|
||||
<div class="col-md-8 offset-md-2 alert alert-warning">
|
||||
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 <a href="mailto:sprechstundentool@mathebau.de">sprechstundentool@mathebau.de</a>.
|
||||
</div>
|
||||
|
||||
{{end}}
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<nav class="col-md-8 offset-md-2 bg-secondary bg-gradient mt-3 mb-2 p-3 rounded" style="--bs-bg-opacity: .3;">
|
||||
<div class="col-md-8 offset-md-2 bg-secondary bg-gradient mt-3 mb-2 p-3 rounded" style="--bs-bg-opacity: .3;">
|
||||
<h5 class="text-center m-1">Sprechstunden für Matheveranstaltungen an der TU Darmstadt</h5>
|
||||
<p class="text-center mb-0">
|
||||
<a href="/">Startseite</a>
|
||||
|
@ -22,20 +22,19 @@
|
|||
•
|
||||
<a href="/deleteOfficeHour">Sprechstunde löschen</a>
|
||||
</p>
|
||||
</nav>
|
||||
</div>
|
||||
|
||||
<main id="content">
|
||||
<div id="content">
|
||||
<h1 class="h3 m-1 mb-3 text-center">{{template "title" .}}</h1>
|
||||
{{block "content" .}}Du solltest dies nicht sehen.{{end}}
|
||||
</main>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<footer class="container">
|
||||
<div class="col-md-8 offset-md-2 bg-secondary bg-gradient my-3 p-3 rounded" style="--bs-bg-opacity: .3;">
|
||||
© <a class="text-body" href="https://mathebau.de/">Fachschaft Mathematik, TU Darmstadt</a>
|
||||
<br>
|
||||
<!-- NOTE: when updating this hard coded email adress, also update it in addMask.html -->
|
||||
Technische Fragen an <a href="mailto:sprechstundentool@mathebau.de">sprechstundentool@mathebau.de</a>
|
||||
Technische Fragen an <a href="mailto:{{.Config.Mailer.SupportMail}}">{{.Config.Mailer.SupportMail}}</a>
|
||||
<br>
|
||||
Quellcode und Featurewünsche: <a href="https://gitea.mathebau.de/Fachschaft/sprechstunden-go">Gitea-Repository</a>
|
||||
</div>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{{define "title"}}Sprechstunde löschen – Fehler{{end}}
|
||||
|
||||
{{define "content"}}
|
||||
<div class="col-md-8 offset-md-2 alert alert-danger">
|
||||
<div class="col-md-8 offset-md-2">
|
||||
Das Löschen der Sprechstunde ist fehlgeschlagen: {{.Error}}
|
||||
</div>
|
||||
{{end}}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{{define "title"}}Sprechstunde löschen{{end}}
|
||||
|
||||
{{define "content"}}
|
||||
<div class="col-md-8 offset-md-2 alert alert-info">
|
||||
<div class="col-md-8 offset-md-2">
|
||||
Du solltest eine Mail mit einem Bestätigungslink erhalten haben.
|
||||
Klicke auf diesen, um die Sprechstunde endgültig zu löschen.
|
||||
</div>
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
{{define "title"}}Anfrage ausführen fehlgeschlagen{{end}}
|
||||
|
||||
{{define "content"}}
|
||||
<div class="col-md-8 offset-md-2 alert alert-danger">
|
||||
Irgendetwas ist schief gegangen. Bitte sende folgende Daten an <a href="mailto:sprechstundentool@mathebau.de">sprechstundentool@mathebau.de</a> mit einer Beschreibung, was du tun wolltest.
|
||||
<div class="col-md-8 offset-md-2">
|
||||
Irgendetwas ist schief gegangen. Bitte sende folgende Daten an <a href="mailto:{{.Config.Mailer.SupportMail}}">{{.Config.Mailer.SupportMail}}</a> mit einer Beschreibung, was du tun wolltest.
|
||||
<br>
|
||||
{{.}}
|
||||
</div>"
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{{define "title"}}Anfrage ausgeführt{{end}}
|
||||
|
||||
{{define "content"}}
|
||||
<div class="col-md-8 offset-md-2 alert alert-success">
|
||||
<div class="col-md-8 offset-md-2">
|
||||
Deine Anfrage wurde ausgeführt.
|
||||
</div>
|
||||
{{end}}
|
||||
|
|
Loading…
Reference in a new issue