From b26544756a67a2bcd0e2bb49a20d18aa03e28157 Mon Sep 17 00:00:00 2001 From: Gonne Date: Wed, 24 Aug 2022 08:16:27 +0200 Subject: [PATCH] Erster Commit --- .gitignore | 19 +++ course.go | 15 +++ date.go | 8 ++ doc.go | 6 + main.go | 68 +++++++++++ officeHour.go | 217 +++++++++++++++++++++++++++++++++ room.go | 20 +++ templates/index.html | 27 ++++ templates/officeHourTable.html | 11 ++ templates/td.html | 6 + tutor.go | 8 ++ 11 files changed, 405 insertions(+) create mode 100644 .gitignore create mode 100644 course.go create mode 100644 date.go create mode 100644 doc.go create mode 100644 main.go create mode 100644 officeHour.go create mode 100644 room.go create mode 100644 templates/index.html create mode 100644 templates/officeHourTable.html create mode 100644 templates/td.html create mode 100644 tutor.go diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2ca337e --- /dev/null +++ b/.gitignore @@ -0,0 +1,19 @@ +# Binaries for programs and plugins +*.exe +*.exe~ +*.dll +*.so +*.dylib +sprechstundentool + +# Test binary, built with `go test -c` +*.test + +# Output of the go coverage tool, specifically when used with LiteIDE +*.out + +# Dependency directories (remove the comment below to include it) +vendor/ + +# Go workspace file +go.work diff --git a/course.go b/course.go new file mode 100644 index 0000000..b6dccbf --- /dev/null +++ b/course.go @@ -0,0 +1,15 @@ +// course +package main + +type Course struct { + Id int + Name string + Active bool +} + +func getCourses() []Course { + return []Course{ + Course{1, "Dummyveranstaltung", true}, + Course{2, "Dummyveranstaltung 2", true}, + } +} diff --git a/date.go b/date.go new file mode 100644 index 0000000..be16b80 --- /dev/null +++ b/date.go @@ -0,0 +1,8 @@ +// date +package main + +type Date struct { + Day int + Hour int + Minute int +} diff --git a/doc.go b/doc.go new file mode 100644 index 0000000..f961580 --- /dev/null +++ b/doc.go @@ -0,0 +1,6 @@ +// sprechstundentool project doc.go + +/* +sprechstundentool document +*/ +package main diff --git a/main.go b/main.go new file mode 100644 index 0000000..d2b00e4 --- /dev/null +++ b/main.go @@ -0,0 +1,68 @@ +package main + +import ( + "fmt" + "html/template" + "net/http" + "strconv" +) + +func root(w http.ResponseWriter, req *http.Request) { + writeTimetablePage(w, req, template.HTML("")) +} + +func getByRoom(w http.ResponseWriter, req *http.Request) { + room, err := strconv.Atoi(req.FormValue("raum")) + if err != nil || room == 0 { + root(w, req) + return + } + writeTimetablePage(w, req, printTimetable(getTimetable(getOfficeHoursByRoom(room)))) +} + +func getByCourse(w http.ResponseWriter, req *http.Request) { + course, err := strconv.Atoi(req.FormValue("veranstaltung")) + if err != nil || course == 0 { + root(w, req) + return + } + writeTimetablePage(w, req, printTimetable(getTimetable(getOfficeHoursByCourse(course)))) +} + +func writeTimetablePage(w http.ResponseWriter, req *http.Request, timetable template.HTML) { + room, err := strconv.Atoi(req.FormValue("raum")) + if err != nil { + room = 0 + } + course, err := strconv.Atoi(req.FormValue("veranstaltung")) + if err != nil { + course = 0 + } + data := struct { + Courses []Course + Rooms []Room + Timetable template.HTML + SelectedRoom int + SelectedCourse int + }{getCourses(), getRooms(), timetable, room, course} + tmpl, err := template.ParseFiles("templates/index.html") + if err != nil { + w.WriteHeader(http.StatusInternalServerError) + w.Write([]byte(fmt.Sprintf("Template konnte nicht geparst werden : %s", string(err.Error())))) + return + } + err = tmpl.Execute(w, data) + if err != nil { + w.Write([]byte(fmt.Sprintf("Template konnte nicht geparst werden : %s", string(err.Error())))) + return + } +} + +func main() { + http.HandleFunc("/getByRoom", getByRoom) + http.HandleFunc("/getByCourse", getByCourse) + + http.HandleFunc("/", root) + + http.ListenAndServe(":8080", nil) +} diff --git a/officeHour.go b/officeHour.go new file mode 100644 index 0000000..08425f1 --- /dev/null +++ b/officeHour.go @@ -0,0 +1,217 @@ +// officeHour +package main + +import ( + "bytes" + "fmt" + "html/template" +) + +const minuteGranularity int = 5 + +type OfficeHour struct { + Id int + Tutor Tutor + Week int + Date + Room Room + Course Course + Info string + Active bool + Duration int +} + +func getOfficeHours() []OfficeHour { + return []OfficeHour{ + OfficeHour{ + Id: 1, + Tutor: Tutor{1, "Dummy", "dummy@mathebau.de"}, + Week: 0, + Date: Date{ + Day: 0, + Hour: 12, + Minute: 0}, + Room: getRooms()[0], + Course: getCourses()[0], + Info: "", + Active: true, + Duration: 60}, + OfficeHour{ + Id: 2, + Tutor: Tutor{1, "Dummy", "dummy@mathebau.de"}, + Week: 0, + Date: Date{ + Day: 0, + Hour: 13, + Minute: 30}, + Room: getRooms()[0], + Course: getCourses()[1], + Info: "", + Active: true, + Duration: 90}, + OfficeHour{ + Id: 3, + Tutor: Tutor{1, "Dummy", "dummy@mathebau.de"}, + Week: 0, + Date: Date{Day: 0, + Hour: 12, + Minute: 45}, + Room: getRooms()[1], + Course: getCourses()[1], + Info: "", + Active: true, + Duration: 60}} + +} + +func getOfficeHoursByCourse(courseId int) []OfficeHour { + var result []OfficeHour + for _, option := range getOfficeHours() { + if option.Course.Id == courseId { + result = append(result, option) + } + } + return result +} + +func getOfficeHoursByRoom(roomId int) []OfficeHour { + var result []OfficeHour + for _, option := range getOfficeHours() { + if option.Room.Id == roomId { + result = append(result, option) + } + } + return result +} + +func getOfficeHourById(id int) OfficeHour { + return OfficeHour{} +} + +func getTimetable(officeHours []OfficeHour) (timetable map[Date]map[int]OfficeHour, slots []int) { + var fullTimetable = make(map[Date]map[int]OfficeHour) + for _, officeHour := range officeHours { + var slot int = 0 + for minute := 0; minute < officeHour.Duration; minute += minuteGranularity { // find slot id + _, exists := fullTimetable[Date{officeHour.Day, officeHour.Hour + (officeHour.Minute+minute)/60, (officeHour.Minute + minute) % 60}] + if exists { + _, exists := fullTimetable[Date{officeHour.Day, officeHour.Hour + (officeHour.Minute+minute)/60, (officeHour.Minute + minute) % 60}][slot] + if exists { + slot += 1 + minute = 0 + continue + } + } else { + fullTimetable[Date{officeHour.Day, officeHour.Hour + (officeHour.Minute+minute)/60, (officeHour.Minute + minute) % 60}] = make(map[int]OfficeHour) + } + } + for minute := 0; minute < officeHour.Duration; minute += minuteGranularity { // write officeHour id to timetable + fullTimetable[Date{officeHour.Day, officeHour.Hour + (officeHour.Minute+minute)/60, (officeHour.Minute + minute) % 60}][slot] = officeHour + } + } + slots = []int{1, 1, 1, 1, 1} + for date, _ := range fullTimetable { + if slots[date.Day] < len(fullTimetable[date]) { + slots[date.Day] = len(fullTimetable[date]) + } + } + timetable = make(map[Date]map[int]OfficeHour) + for _, officeHour := range officeHours { + for slot := 0; slot < slots[officeHour.Date.Day]; slot += 1 { + if fullTimetable[officeHour.Date][slot] == officeHour { + timetable[officeHour.Date] = make(map[int]OfficeHour) + timetable[officeHour.Date][slot] = officeHour + } + } + } + return fullTimetable, slots +} + +func printTimetable(timetable map[Date]map[int]OfficeHour, slots []int) template.HTML { + var tableBody string + + tableCell, _ := template.ParseFiles("templates/td.html") + for hour := 8; hour < 19; hour += 1 { + for minute := 0; minute < 60; minute += minuteGranularity { + tableBody += "" + if minute == 0 { + tableBody += fmt.Sprintf("%d Uhr\n", hour) + } else { + tableBody += "\n" + } + for day := 0; day < 5; day += 1 { + for slot := 0; slot < slots[day]; slot += 1 { + current, currentExists := timetable[Date{day, hour, minute}][slot] + + if currentExists { // This slot is taken by some office hour + var continued bool = false // is this slot occupied by the same office hour the previous minute? + var predecessorExists bool + var predecessor OfficeHour + if hour > 0 && minute < minuteGranularity { + predecessor, predecessorExists = timetable[Date{day, hour - 1, 60 - minuteGranularity}][slot] + } else { + predecessor, predecessorExists = timetable[Date{day, hour, minute - minuteGranularity}][slot] + } + if predecessorExists { + continued = (predecessor == current) + } else { + continued = false + } + if continued { + continue + } else { + var celldata bytes.Buffer + data := struct { + Rowspan int + StartHour int + StartMinute int + EndHour int + EndMinute int + CourseName string + TutorName string + RoomName string + }{current.Duration / minuteGranularity, + current.Hour, + current.Minute, + current.Hour + ((current.Minute + current.Duration) / 60), + (current.Minute + current.Duration) % 60, + template.HTMLEscapeString(current.Course.Name), + current.Tutor.Name, + current.Room.Name, + } + tableCell.Execute(&celldata, data) + tableBody += celldata.String() + } + } else { + if slot+1 == slots[day] { + tableBody += "\n" + } else { + tableBody += "\n" + } + } + } + } + tableBody += "\n" + } + } + var table bytes.Buffer + tableTemplate, _ := template.ParseFiles("templates/officeHourTable.html") + + tableData := struct { + ColspanMon int + ColspanTue int + ColspanWed int + ColspanThu int + ColspanFri int + TableBody template.HTML + }{ + slots[0], + slots[1], + slots[2], + slots[3], + slots[4], + template.HTML(tableBody), + } + tableTemplate.Execute(&table, tableData) + return template.HTML(table.String()) +} diff --git a/room.go b/room.go new file mode 100644 index 0000000..1022fc4 --- /dev/null +++ b/room.go @@ -0,0 +1,20 @@ +// raum +package main + +type Room struct { + Id int + Name string + Max_occupy int + Active bool +} + +func getRooms() []Room { + return []Room{ + Room{1, "S2 15 345", 2, true}, + Room{2, "S2 15 415", 1, true}, + Room{3, "S2 15 336", 2, true}, + Room{4, "S2 15 444", 1, true}, + Room{5, "S2 15 333", 1, true}, + Room{6, "S2 14 420", 1, false}, + Room{7, "Sonstige", 255, true}} +} diff --git a/templates/index.html b/templates/index.html new file mode 100644 index 0000000..c02cd48 --- /dev/null +++ b/templates/index.html @@ -0,0 +1,27 @@ + + + Sprechstunden + + +
+ + + +
+
+ + + +
+ {{.Timetable}} + Technische Fragen an sprechstundentool@mathebau.de + + \ No newline at end of file diff --git a/templates/officeHourTable.html b/templates/officeHourTable.html new file mode 100644 index 0000000..6dc6057 --- /dev/null +++ b/templates/officeHourTable.html @@ -0,0 +1,11 @@ + + + + + + + + + +{{.TableBody}} +
 MontagDienstagMittwochDonnerstagFreitag
\ No newline at end of file diff --git a/templates/td.html b/templates/td.html new file mode 100644 index 0000000..c822ed5 --- /dev/null +++ b/templates/td.html @@ -0,0 +1,6 @@ + + {{.StartHour}}:{{printf "%02d" .StartMinute}} - {{.EndHour}}:{{printf "%02d" .EndMinute}}
+ {{.CourseName}}
+ {{.TutorName}}
+ {{.RoomName}} + \ No newline at end of file diff --git a/tutor.go b/tutor.go new file mode 100644 index 0000000..bbdf75b --- /dev/null +++ b/tutor.go @@ -0,0 +1,8 @@ +// tutor +package main + +type Tutor struct { + Id int + Name string + Email string +}