commit b26544756a67a2bcd0e2bb49a20d18aa03e28157 Author: Gonne Date: Wed Aug 24 08:16:27 2022 +0200 Erster Commit 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 +}