added UserDefined Module Naming

This commit is contained in:
Elmar Kresse
2023-09-22 15:54:34 +02:00
parent 20ec88d8d2
commit 99618c57c1
15 changed files with 249 additions and 150 deletions

View File

@@ -0,0 +1,3 @@
package model
type Events []*Event

View File

@@ -22,4 +22,8 @@ type Entry struct {
// Entries is a collection of entries
type Entries []*Entry
type Events []*Event
type FeedCollection struct {
Name string `db:"Name" json:"Name"`
Course string `db:"course" json:"Course"`
UserDefinedName string `db:"userDefinedName" json:"UserDefinedName"`
}

View File

@@ -1,15 +1,11 @@
package db
import (
"github.com/jordic/goics"
"github.com/pocketbase/dbx"
"github.com/pocketbase/pocketbase"
"github.com/pocketbase/pocketbase/models"
"htwkalender/model"
"log"
"strings"
"time"
"unicode"
)
func SaveEvents(seminarGroup []model.SeminarGroup, collection *models.Collection, app *pocketbase.PocketBase) ([]*models.Record, error) {
@@ -81,60 +77,10 @@ func findEventByDayWeekStartEndNameCourse(event model.Event, course string, app
return &event, err
}
func contains(s []string, e string) bool {
for _, a := range s {
if a == e {
return true
}
}
return false
}
// GetRooms function to get all rooms from database that are stored as a string in the Event struct
func GetRooms(app *pocketbase.PocketBase) []string {
var events []struct {
Rooms string `db:"Rooms" json:"Rooms"`
}
// get all rooms from event records in the events collection
err := app.Dao().DB().Select("Rooms").From("events").All(&events)
if err != nil {
print("Error while getting rooms from database: ", err)
return nil
}
var roomArray []string
for _, event := range events {
var room = strings.Split(event.Rooms, " ")
//split string room by space and add each room to array if it is not already in there
for _, r := range room {
var text = strings.TrimSpace(r)
if !contains(roomArray, text) && !strings.Contains(text, " ") && len(text) >= 1 {
roomArray = append(roomArray, text)
}
}
}
return roomArray
}
func GetRoomScheduleForDay(app *pocketbase.PocketBase, room string, date string) []model.Event {
var events []model.Event
// get all events from event records in the events collection
err := app.Dao().DB().Select("*").From("events").Where(dbx.Like("Rooms", room)).AndWhere(dbx.Like("Start", date)).All(&events)
if err != nil {
print("Error while getting events from database: ", err)
return nil
}
return events
}
// gets all events for specific course and semester
// TODO add filter for year
func GetPlanForCourseAndSemester(app *pocketbase.PocketBase, course string, semester string) Events {
var events Events
func GetPlanForCourseAndSemester(app *pocketbase.PocketBase, course string, semester string) model.Events {
var events model.Events
// get all events from event records in the events collection
err := app.Dao().DB().Select("*").From("events").Where(dbx.NewExp("course = {:course} AND semester = {:semester}", dbx.Params{"course": course, "semester": semester})).All(&events)
if err != nil {
@@ -144,12 +90,9 @@ func GetPlanForCourseAndSemester(app *pocketbase.PocketBase, course string, seme
return events
}
func GetPlanForModules(app *pocketbase.PocketBase, modules []struct {
Name string `db:"Name" json:"Name"`
Course string `db:"course" json:"Course"`
}) Events {
func GetPlanForModules(app *pocketbase.PocketBase, modules []model.FeedCollection) model.Events {
// build query string with name equals elements in modules for dbx query
// build query functions with name equals elements in modules for dbx query
var queryString string
for i, module := range modules {
@@ -160,7 +103,7 @@ func GetPlanForModules(app *pocketbase.PocketBase, modules []struct {
}
}
var events Events
var events model.Events
// get all events from event records in the events collection
err := app.Dao().DB().Select("*").From("events").Where(dbx.NewExp(queryString)).All(&events)
if err != nil {
@@ -218,59 +161,3 @@ func GetAllModulesDistinct(app *pocketbase.PocketBase) ([]struct {
}
return eventArray, nil
}
type Events []*model.Event
// EmitICal implements the interface for goics
func (e Events) EmitICal() goics.Componenter {
layout := "2006-01-02 15:04:05 -0700 MST"
c := goics.NewComponent()
c.SetType("VCALENDAR")
c.AddProperty("VERSION", "2.0")
c.AddProperty("CALSCAL", "GREGORIAN")
c.AddProperty("TZID", "Europe/Berlin")
c.AddProperty("X-WR-CALNAME", "HTWK Kalender")
c.AddProperty("X-WR-TIMEZONE", "Europe/Berlin")
c.AddProperty("X-LIC-LOCATION", "Europe/Berlin")
for _, event := range e {
s := goics.NewComponent()
s.SetType("VEVENT")
timeEnd, _ := time.Parse(layout, event.End)
timeStart, _ := time.Parse(layout, event.Start)
k, v := goics.FormatDateTime("DTEND;TZID=Europe/Berlin", timeEnd)
s.AddProperty(k, v)
k, v = goics.FormatDateTime("DTSTART;TZID=Europe/Berlin", timeStart)
s.AddProperty(k, v)
s.AddProperty("SUMMARY", event.Name)
s.AddProperty("DESCRIPTION", generateDescription(event))
s.AddProperty("LOCATION", event.Rooms)
c.AddComponent(s)
}
return c
}
func generateDescription(event *model.Event) string {
var description string
if !CheckIfOnlyWhitespace(event.Notes) {
description += "Notizen: " + event.Notes + "\n"
}
if !CheckIfOnlyWhitespace(event.Prof) {
description += "Prof: " + event.Prof + "\n"
}
if !CheckIfOnlyWhitespace(event.Course) {
description += "Gruppe: " + event.Course + "\n"
}
return description
}
// check if course is empty or contains only whitespaces
func CheckIfOnlyWhitespace(word string) bool {
for _, letter := range word {
if !unicode.IsSpace(letter) || !(letter == int32(160)) {
return false
}
}
return true
}

View File

@@ -0,0 +1,49 @@
package db
import (
"github.com/pocketbase/dbx"
"github.com/pocketbase/pocketbase"
"htwkalender/model"
"htwkalender/service/functions"
"strings"
)
func GetRooms(app *pocketbase.PocketBase) []string {
var events []struct {
Rooms string `db:"Rooms" json:"Rooms"`
}
// get all rooms from event records in the events collection
err := app.Dao().DB().Select("Rooms").From("events").All(&events)
if err != nil {
print("Error while getting rooms from database: ", err)
return nil
}
var roomArray []string
for _, event := range events {
var room = strings.Split(event.Rooms, " ")
//split functions room by space and add each room to array if it is not already in there
for _, r := range room {
var text = strings.TrimSpace(r)
if !functions.Contains(roomArray, text) && !strings.Contains(text, " ") && len(text) >= 1 {
roomArray = append(roomArray, text)
}
}
}
return roomArray
}
func GetRoomScheduleForDay(app *pocketbase.PocketBase, room string, date string) []model.Event {
var events []model.Event
// get all events from event records in the events collection
err := app.Dao().DB().Select("*").From("events").Where(dbx.Like("Rooms", room)).AndWhere(dbx.Like("Start", date)).All(&events)
if err != nil {
print("Error while getting events from database: ", err)
return nil
}
return events
}

View File

@@ -4,6 +4,7 @@ import (
"github.com/labstack/echo/v5"
"github.com/pocketbase/pocketbase"
"htwkalender/service/db"
"htwkalender/service/functions"
)
func GetModulesForCourseDistinct(app *pocketbase.PocketBase, c echo.Context, course string, semester string) error {
@@ -19,9 +20,9 @@ func GetModulesForCourseDistinct(app *pocketbase.PocketBase, c echo.Context, cou
}
func replaceEmptyEntryInStringArray(modules []string, replacement string) {
//replace empty string with "Sonderveranstaltungen"
//replace empty functions with "Sonderveranstaltungen"
for i, module := range modules {
if db.CheckIfOnlyWhitespace(module) {
if functions.CheckIfOnlyWhitespace(module) {
modules[i] = replacement
}
}
@@ -31,9 +32,9 @@ func replaceEmptyEntry(modules []struct {
Name string
Course string
}, replacement string) {
//replace empty string with "Sonderveranstaltungen"
//replace empty functions with "Sonderveranstaltungen"
for i, module := range modules {
if db.CheckIfOnlyWhitespace(module.Name) {
if functions.CheckIfOnlyWhitespace(module.Name) {
modules[i].Name = replacement
}
}

View File

@@ -118,7 +118,7 @@ func convertWeeksToDates(events []model.Event, semester string, year string) []m
func addTimeToDate(date time.Time, timeString string) time.Time {
europeTime, _ := time.LoadLocation("Europe/Berlin")
//convert time string to time
//convert time functions to time
timeParts := strings.Split(timeString, ":")
hour, _ := strconv.Atoi(timeParts[0])
minute, _ := strconv.Atoi(timeParts[1])

View File

@@ -0,0 +1,22 @@
package functions
import "unicode"
// check if course is empty or contains only whitespaces
func CheckIfOnlyWhitespace(word string) bool {
for _, letter := range word {
if !unicode.IsSpace(letter) || !(letter == int32(160)) {
return false
}
}
return true
}
func Contains(s []string, e string) bool {
for _, a := range s {
if a == e {
return true
}
}
return false
}

View File

@@ -7,8 +7,8 @@ import (
"github.com/labstack/echo/v5"
"github.com/pocketbase/pocketbase"
"github.com/pocketbase/pocketbase/apis"
model "htwkalender/model"
db "htwkalender/service/db"
"htwkalender/model"
"htwkalender/service/db"
"io"
"net/http"
"time"
@@ -28,10 +28,7 @@ func Feed(c echo.Context, app *pocketbase.PocketBase, token string) error {
created, _ := time.Parse(layout, feed.Created)
var modules []struct {
Name string `db:"Name" json:"Name"`
Course string `db:"course" json:"Course"`
}
var modules []model.FeedCollection
_ = json.Unmarshal([]byte(feed.Modules), &modules)
if created.Add(time.Hour * 265).Before(time.Now()) {
newFeed, err := createFeedForToken(app, modules)
@@ -50,30 +47,26 @@ func Feed(c echo.Context, app *pocketbase.PocketBase, token string) error {
return nil
}
func createFeedForToken(app *pocketbase.PocketBase, modules []struct {
Name string `db:"Name" json:"Name"`
Course string `db:"course" json:"Course"`
}) (*model.FeedModel, error) {
func createFeedForToken(app *pocketbase.PocketBase, modules []model.FeedCollection) (*model.FeedModel, error) {
res := db.GetPlanForModules(app, modules)
b := bytes.Buffer{}
goics.NewICalEncode(&b).Encode(res)
goics.NewICalEncode(&b).Encode(IcalModel{Events: res, Mapping: modules})
feed := &model.FeedModel{Content: b.String(), ExpiresAt: time.Now().Add(expirationTime)}
return feed, nil
}
func writeSuccess(message string, w http.ResponseWriter) {
w.WriteHeader(http.StatusOK)
w.Write([]byte(message))
_, err := w.Write([]byte(message))
if err != nil {
return
}
}
func CreateIndividualFeed(c echo.Context, app *pocketbase.PocketBase) error {
// read json from request body
var modules []struct {
Name string `db:"Name" json:"Name"`
Course string `db:"course" json:"Course"`
}
var modules []model.FeedCollection
requestBodyBytes, err := io.ReadAll(c.Request().Body)
if err != nil {
return apis.NewApiError(400, "Could not bind request body", err)

View File

@@ -0,0 +1,67 @@
package ical
import (
"github.com/jordic/goics"
"htwkalender/model"
"htwkalender/service/functions"
"time"
)
// local type for EmitICal function
type IcalModel struct {
Events model.Events
Mapping []model.FeedCollection
}
// EmitICal implements the interface for goics
func (icalModel IcalModel) EmitICal() goics.Componenter {
layout := "2006-01-02 15:04:05 -0700 MST"
c := goics.NewComponent()
c.SetType("VCALENDAR")
c.AddProperty("VERSION", "2.0")
c.AddProperty("CALSCAL", "GREGORIAN")
c.AddProperty("TZID", "Europe/Berlin")
c.AddProperty("X-WR-CALNAME", "HTWK Kalender")
c.AddProperty("X-WR-TIMEZONE", "Europe/Berlin")
c.AddProperty("X-LIC-LOCATION", "Europe/Berlin")
for _, event := range icalModel.Events {
s := goics.NewComponent()
s.SetType("VEVENT")
timeEnd, _ := time.Parse(layout, event.End)
timeStart, _ := time.Parse(layout, event.Start)
k, v := goics.FormatDateTime("DTEND;TZID=Europe/Berlin", timeEnd)
s.AddProperty(k, v)
k, v = goics.FormatDateTime("DTSTART;TZID=Europe/Berlin", timeStart)
s.AddProperty(k, v)
s.AddProperty("SUMMARY", replaceNameIfUserDefined(event.Name, icalModel.Mapping))
s.AddProperty("DESCRIPTION", generateDescription(event))
s.AddProperty("LOCATION", event.Rooms)
c.AddComponent(s)
}
return c
}
func replaceNameIfUserDefined(name string, mapping []model.FeedCollection) string {
for _, mapEntry := range mapping {
if mapEntry.Name == name {
return mapEntry.UserDefinedName
}
}
return name
}
func generateDescription(event *model.Event) string {
var description string
if !functions.CheckIfOnlyWhitespace(event.Notes) {
description += "Notizen: " + event.Notes + "\n"
}
if !functions.CheckIfOnlyWhitespace(event.Prof) {
description += "Prof: " + event.Prof + "\n"
}
if !functions.CheckIfOnlyWhitespace(event.Course) {
description += "Gruppe: " + event.Course + "\n"
}
return description
}