Datenbanken, erster Versuch

This commit is contained in:
Gonne 2022-08-29 22:58:19 +02:00
parent b26544756a
commit 766aedf22d
21 changed files with 678 additions and 320 deletions

77
controllers/handlers.go Normal file
View file

@ -0,0 +1,77 @@
package controllers
import (
"fmt"
"html/template"
"net/http"
"sprechstundentool/models"
"strconv"
)
// BaseHandler will hold everything that controller needs
type BaseHandler struct {
roomRepo models.RoomRepository
officeHourRepo models.OfficeHourRepository
courseRepo models.CourseRepository
tutorRepo models.TutorRepository
}
// NewBaseHandler returns a new BaseHandler
func NewBaseHandler(roomRepo models.RoomRepository, officeHourRepo models.OfficeHourRepository, courseRepo models.CourseRepository, tutorRepo models.TutorRepository) *BaseHandler {
return &BaseHandler{roomRepo, officeHourRepo, courseRepo, tutorRepo}
}
func (b *BaseHandler) RootHandler(w http.ResponseWriter, req *http.Request) {
b.writeTimetablePage(w, req, template.HTML(""))
}
func (b *BaseHandler) GetByRoomHandler(w http.ResponseWriter, req *http.Request) {
roomId, _ := strconv.Atoi(req.FormValue("raum"))
room, err := b.roomRepo.FindById(roomId)
if err != nil {
fmt.Println(err)
b.RootHandler(w, req)
return
}
officeHours, _ := b.officeHourRepo.FindByRoom(room)
b.writeTimetablePage(w, req, printTimetable(GetTimetable(officeHours)))
}
func (b *BaseHandler) GetByCourseHandler(w http.ResponseWriter, req *http.Request) {
courseid, err := strconv.Atoi(req.FormValue("veranstaltung"))
if err != nil {
b.RootHandler(w, req)
}
course, err := b.courseRepo.FindById(courseid)
if err != nil {
b.RootHandler(w, req)
return
}
officeHours, _ := b.officeHourRepo.FindByCourse(course)
b.writeTimetablePage(w, req, printTimetable(GetTimetable(officeHours)))
}
func (b *BaseHandler) writeTimetablePage(w http.ResponseWriter, req *http.Request, timetable template.HTML) {
courses, _ := b.courseRepo.GetAll()
rooms, _ := b.roomRepo.GetAll()
selectedRoom, _ := strconv.Atoi(req.FormValue("raum"))
selectedCourse, _ := strconv.Atoi(req.FormValue("veranstaltung"))
data := struct {
Courses []models.Course
Rooms []models.Room
Timetable template.HTML
SelectedRoom int
SelectedCourse int
}{courses, rooms, timetable, selectedRoom, selectedCourse}
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
}
}

137
controllers/timetable.go Normal file
View file

@ -0,0 +1,137 @@
// timetable.go
package controllers
import (
"bytes"
"fmt"
"html/template"
"sprechstundentool/models"
)
func GetTimetable(officeHours []models.OfficeHour) (timetable map[models.Date]map[int]models.OfficeHour, slots []int) {
var fullTimetable = make(map[models.Date]map[int]models.OfficeHour)
for _, officeHour := range officeHours {
var slot int = 0
for minute := 0; minute < officeHour.Duration; minute += models.MinuteGranularity { // find slot id
_, exists := fullTimetable[models.Date{officeHour.Day, officeHour.Hour + (officeHour.Minute+minute)/60, (officeHour.Minute + minute) % 60}]
if exists {
_, exists := fullTimetable[models.Date{officeHour.Day, officeHour.Hour + (officeHour.Minute+minute)/60, (officeHour.Minute + minute) % 60}][slot]
if exists {
slot += 1
minute = 0
continue
}
} else {
fullTimetable[models.Date{officeHour.Day, officeHour.Hour + (officeHour.Minute+minute)/60, (officeHour.Minute + minute) % 60}] = make(map[int]models.OfficeHour)
}
}
for minute := 0; minute < officeHour.Duration; minute += models.MinuteGranularity { // write officeHour id to timetable
fullTimetable[models.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[models.Date]map[int]models.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]models.OfficeHour)
timetable[officeHour.Date][slot] = officeHour
}
}
}
return fullTimetable, slots
}
func printTimetable(timetable map[models.Date]map[int]models.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 += models.MinuteGranularity {
tableBody += "<tr>"
if minute == 0 {
tableBody += fmt.Sprintf("<td>%d Uhr</td>\n", hour)
} else {
tableBody += "<td></td>\n"
}
for day := 0; day < 5; day += 1 {
for slot := 0; slot < slots[day]; slot += 1 {
current, currentExists := timetable[models.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 models.OfficeHour
if hour > 0 && minute < models.MinuteGranularity {
predecessor, predecessorExists = timetable[models.Date{day, hour - 1, 60 - models.MinuteGranularity}][slot]
} else {
predecessor, predecessorExists = timetable[models.Date{day, hour, minute - models.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 / models.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 += "<td style=\"border-right: 1px dotted\"></td>\n"
} else {
tableBody += "<td></td>\n"
}
}
}
}
tableBody += "</tr>\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())
}