From 0965f9e11543b5a1581e42312c6e7509d2f549c2 Mon Sep 17 00:00:00 2001 From: nikurasu Date: Sun, 3 Mar 2024 22:55:50 +0100 Subject: [PATCH] feat(display-attendies): split list Split up suiter list in attendies and suiterWaitingList and added localization with goi18n, btw --- .vscode/launch.json | 4 +- .../images/production/backend/Dockerfile | 4 +- src/.env.test | 6 -- src/app/controller/attendies_controller.go | 46 ++++++++++- src/app/service/db_attendie.go | 2 +- src/app/util/attendiesList.go | 28 +++++++ src/app/util/pretix.go | 3 + src/app/views/index.html | 2 + src/app/views/table.html | 8 +- src/config/localization.go | 79 +++++++++++++++++++ src/entities/attendiesList.go | 13 +++ src/entities/db_attendies.go | 21 ++++- src/entities/db_event.go | 1 + src/entities/pretix.go | 3 + src/go.mod | 1 + src/localization/active.de.json | 21 +++++ src/localization/active.en.json | 38 +++++++++ src/localization/translate.de.json | 39 +++++++++ src/main.go | 4 + src/translate.de.json | 21 +++++ src/translate.de.toml | 18 +++++ 21 files changed, 345 insertions(+), 17 deletions(-) delete mode 100644 src/.env.test create mode 100644 src/app/util/attendiesList.go create mode 100644 src/config/localization.go create mode 100644 src/entities/attendiesList.go create mode 100644 src/localization/active.de.json create mode 100644 src/localization/active.en.json create mode 100644 src/localization/translate.de.json create mode 100644 src/translate.de.json create mode 100644 src/translate.de.toml diff --git a/.vscode/launch.json b/.vscode/launch.json index c69e394..39bfd8e 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -8,8 +8,8 @@ "name": "Launch Package", "type": "go", "request": "launch", - "mode": "auto", - "program": "src/main.go" + "mode": "debug", + "program": "src/main.go", } ] } \ No newline at end of file diff --git a/dev/docker/images/production/backend/Dockerfile b/dev/docker/images/production/backend/Dockerfile index 11ebf9e..55afa00 100644 --- a/dev/docker/images/production/backend/Dockerfile +++ b/dev/docker/images/production/backend/Dockerfile @@ -2,9 +2,9 @@ FROM golang:alpine3.17 AS build WORKDIR /build COPY ./src ./src WORKDIR /build/src -RUN ls +RUN apk add gcc libc-dev RUN go get . -RUN go build -o /build/pretix-proxy +RUN CGO_ENABLED=1 go build -o /build/pretix-proxy FROM alpine:3.17 AS final COPY --from=build /build/pretix-proxy /bin/pretix-proxy diff --git a/src/.env.test b/src/.env.test deleted file mode 100644 index 84fa7aa..0000000 --- a/src/.env.test +++ /dev/null @@ -1,6 +0,0 @@ -DOMAIN="reg.ulmer-furs.de" -API_KEY="NeedForEep" -DEBUG="true" -DATABASE_PATH="/home/tamaki/Documents/coding/pretix-proxy/main.db" -API_KEY_PRETIX="ktb7ahh2dzkultyk2vqkafkd7s06fj25lie55a9tx9g2is682an55v1wx8zsh4ij" -SECRET="dfdsfdsfdsfsdfsf" \ No newline at end of file diff --git a/src/app/controller/attendies_controller.go b/src/app/controller/attendies_controller.go index 4281d29..69a5098 100644 --- a/src/app/controller/attendies_controller.go +++ b/src/app/controller/attendies_controller.go @@ -2,9 +2,15 @@ package controller import ( "fmt" + "sort" "github.com/gofiber/fiber/v2" + "github.com/nicksnyder/go-i18n/v2/i18n" + "golang.org/x/text/language" "ulmer-furs.de/pretix-proxy/v2/app/service" + "ulmer-furs.de/pretix-proxy/v2/app/util" + "ulmer-furs.de/pretix-proxy/v2/config" + "ulmer-furs.de/pretix-proxy/v2/entities" ) // @Description Get the attendies of an event by the name @@ -23,6 +29,13 @@ func GetAttendiesByEventPublic(c *fiber.Ctx) error { } func GetAttendiesByEventPublicTable(c *fiber.Ctx) error { + siteLang := c.Query("lang") + var localizer *i18n.Localizer + if siteLang == "de-DE" { + localizer = i18n.NewLocalizer(config.LocaleBundle, language.German.String()) + } else { + localizer = i18n.NewLocalizer(config.LocaleBundle) + } name := c.Params("name") event, err := service.Get_db_event_by_event(name) if err != nil { @@ -32,8 +45,37 @@ func GetAttendiesByEventPublicTable(c *fiber.Ctx) error { if err != nil { return c.Status(fiber.ErrNotFound.Code).SendString("attendies not found") } + localizations := map[string]string{ + "Attendie": localizer.MustLocalize(&i18n.LocalizeConfig{ + MessageID: "Attendie", + PluralCount: 2, + }), + "HelloWorld": localizer.MustLocalize(&i18n.LocalizeConfig{ + MessageID: "HelloWorld", + }), + "Role": localizer.MustLocalize(&i18n.LocalizeConfig{ + MessageID: "Role", + PluralCount: 1, + }), + "Name": localizer.MustLocalize(&i18n.LocalizeConfig{ + MessageID: "Name", + PluralCount: 1, + }), + } + sort.Sort(entities.ByRegistrationTime(attendies)) + roleSuiter, _ := service.GetRoleByName("Suiter") + roleSpotter, _ := service.GetRoleByName("Spotter") + suiterWaitingList := util.CreateSuiterWaitingList( + &attendies, + event.SuiterPerSpotter, + &roleSuiter, + &roleSpotter, + ) + fmt.Printf("len(attendies): %v\n", len(attendies)) return c.Render("app/views/index", fiber.Map{ - "Title": fmt.Sprintf("%s Attendies", *event.Event), - "Attendies": attendies, + "Event Name": event.Name, + "Attendies": attendies, + "SuiterWaitingList": suiterWaitingList, + "Locals": localizations, }) } diff --git a/src/app/service/db_attendie.go b/src/app/service/db_attendie.go index e93ad9c..b18cc56 100644 --- a/src/app/service/db_attendie.go +++ b/src/app/service/db_attendie.go @@ -44,7 +44,7 @@ func GetAttendiesByEvent(event entities.Db_Event) ([]entities.Db_Attendies, erro return attendies, nil } -func GetAttendiesByEventPrivacy(event entities.Db_Event, privacy bool) ([]entities.Db_Attendies, error) { +func GetAttendiesByEventPrivacy(event entities.Db_Event, privacy bool) (entities.AttendiesList, error) { var attendies []entities.Db_Attendies result := config.Database.Model(&entities.Db_Attendies{}).Preload("Event").Preload("Role").Where("event_id = ?", event.ID).Where("privacy = ?", privacy).Find(&attendies) if result.Error != nil { diff --git a/src/app/util/attendiesList.go b/src/app/util/attendiesList.go new file mode 100644 index 0000000..4dbbcdc --- /dev/null +++ b/src/app/util/attendiesList.go @@ -0,0 +1,28 @@ +package util + +import ( + "fmt" + + "ulmer-furs.de/pretix-proxy/v2/entities" +) + +func CreateSuiterWaitingList(attendiesList *entities.AttendiesList, suiterPerSpotter *int, suiter, spotter *entities.Role) entities.AttendiesList { + spotterCount := attendiesList.CountByRole(*spotter) + suiterCount := spotterCount * *suiterPerSpotter + var suiterCounter int + var suiterWatinglist entities.AttendiesList + var i int + for i < len(*attendiesList) { + if (*attendiesList)[i].Role == *suiter { + suiterCounter++ + } + if suiterCounter > suiterCount && (*attendiesList)[i].Role == *suiter { + suiterWatinglist = append(suiterWatinglist, (*attendiesList)[i]) + *attendiesList = append((*attendiesList)[:i], (*attendiesList)[i+1:]...) + } else { + i++ + } + } + fmt.Printf("len(a): %v\n", len(*attendiesList)) + return suiterWatinglist +} diff --git a/src/app/util/pretix.go b/src/app/util/pretix.go index c284248..a6bc844 100644 --- a/src/app/util/pretix.go +++ b/src/app/util/pretix.go @@ -41,6 +41,7 @@ func GetAttendieListFromPretixJson(pretixEvent entities.Pretix_Event, event enti var name string for _, order := range pretixEvent.Results { + indexParticipation := slices.IndexFunc(order.Positions, func(p entities.Pretix_Position) bool { return p.Item == *event.ItemIdParticipation }) indexBadge := slices.IndexFunc(order.Positions, func(p entities.Pretix_Position) bool { return p.Item == *event.ItemIdBadge }) indexRestaurant := slices.IndexFunc(order.Positions, func(p entities.Pretix_Position) bool { return p.Item == *event.ItemIdRestaurant }) @@ -125,6 +126,8 @@ func GetAttendiesFromPretixJsonWithRoleQuestion(pretixEvent *entities.Pretix_Eve return attendies, err } + attendie.RegistrationTime = order.Datetime + attendies = append(attendies, attendie) } return attendies, nil diff --git a/src/app/views/index.html b/src/app/views/index.html index a411dfa..f916198 100644 --- a/src/app/views/index.html +++ b/src/app/views/index.html @@ -10,6 +10,8 @@

{{.Title}}

{{template "table" .}} +

Test:

+

{{.Locals.HelloWorld}}

\ No newline at end of file diff --git a/src/app/views/table.html b/src/app/views/table.html index 109cdd5..1c12fc7 100644 --- a/src/app/views/table.html +++ b/src/app/views/table.html @@ -1,9 +1,12 @@ {{define "table"}} +

{{ index . "Event Name" }} {{ .Locals.Attendie }}

+

- - + + + @@ -11,6 +14,7 @@ + {{end}} diff --git a/src/config/localization.go b/src/config/localization.go new file mode 100644 index 0000000..0fa60c5 --- /dev/null +++ b/src/config/localization.go @@ -0,0 +1,79 @@ +package config + +import ( + "embed" + "encoding/json" + + "github.com/nicksnyder/go-i18n/v2/i18n" + "golang.org/x/text/language" +) + +var LocaleBundle *i18n.Bundle + +func SetupLocalization(locaizationFS *embed.FS) { + LocaleBundle = i18n.NewBundle(language.English) + for _, message := range defaultMessages { + LocaleBundle.AddMessages(language.English, &message) + } + LocaleBundle.RegisterUnmarshalFunc("json", json.Unmarshal) + LocaleBundle.LoadMessageFileFS(locaizationFS, "localization/active.de.json") +} + +var defaultMessages = []i18n.Message{ + { + ID: "HelloWorld", + Other: "Hello newer World", + }, + { + ID: "Attendie", + One: "Attendie", + Other: "Attendies", + }, + { + ID: "Role", + One: "Role", + Other: "Roles", + }, + { + ID: "Name", + One: "Name", + Other: "Names", + }, + { + ID: "Registered", + Other: "Registered", + }, + { + ID: "SuiterWatinglist", + Other: "Suiter Watinglist", + }, + { + ID: "WatinglistDesc", + Other: "We set a ratio of Suiters per Spotter for each event in order to keep the count of suiters manageble for them. If you are listed here we sadly don't have enough spotters yet.", + }, + { + ID: "Suiter", + One: "Suiter", + Other: "Suiters", + }, + { + ID: "Guest", + One: "Guest", + Other: "Guets", + }, + { + ID: "Spotter", + One: "Spotter", + Other: "Spotters", + }, + { + ID: "Photographer", + One: "Photographer", + Other: "Photographers", + }, + { + ID: "SpecialAnimal", + One: "#SpecialAnimal", + Other: "#SpecialAnimals", + }, +} diff --git a/src/entities/attendiesList.go b/src/entities/attendiesList.go new file mode 100644 index 0000000..fd49b78 --- /dev/null +++ b/src/entities/attendiesList.go @@ -0,0 +1,13 @@ +package entities + +type AttendiesList []Db_Attendies + +func (a AttendiesList) CountByRole(role Role) int { + var count int + for _, attendie := range a { + if attendie.Role == role { + count++ + } + } + return count +} diff --git a/src/entities/db_attendies.go b/src/entities/db_attendies.go index c85cd1e..e998df9 100644 --- a/src/entities/db_attendies.go +++ b/src/entities/db_attendies.go @@ -1,9 +1,25 @@ package entities import ( + "time" + "gorm.io/gorm" ) +type ByRegistrationTime AttendiesList + +func (a ByRegistrationTime) Len() int { + return len(a) +} + +func (a ByRegistrationTime) Less(i, j int) bool { + return a[i].RegistrationTime.Unix() < a[j].RegistrationTime.Unix() +} + +func (a ByRegistrationTime) Swap(i, j int) { + a[i], a[j] = a[j], a[i] +} + type Db_Attendies struct { gorm.Model Nickname string `gorm:"column:nickname;not null"` @@ -11,6 +27,7 @@ type Db_Attendies struct { Event Db_Event RoleID int `gorm:"not null"` Role Role - AttendsRestaurant bool `gorm:"column:attends_restaurant;not null"` - Privacy bool `gorm:"column:privacy;not null"` + AttendsRestaurant bool `gorm:"column:attends_restaurant;not null"` + Privacy bool `gorm:"column:privacy;not null"` + RegistrationTime time.Time `gorm:"column:registration_time;not null;default:CURRENT_TIMESTAMP"` } diff --git a/src/entities/db_event.go b/src/entities/db_event.go index 69635a2..fff0eff 100644 --- a/src/entities/db_event.go +++ b/src/entities/db_event.go @@ -27,6 +27,7 @@ type Db_Event struct { VariationIdPhotograph *int `gorm:"variation_id_photograph"` VariationIdSpecialAnimal *int `gorm:"variation_id_special_animal"` EventType *string `gorm:"cloumn:event_type;not null" validate:"required"` + SuiterPerSpotter *int `gorm:"column:suiter_per_spotter;not null;default:5" validate:"required"` } type Db_Event_Public struct { diff --git a/src/entities/pretix.go b/src/entities/pretix.go index 83e4567..4dc397b 100644 --- a/src/entities/pretix.go +++ b/src/entities/pretix.go @@ -1,5 +1,7 @@ package entities +import "time" + type Pretix_Event struct { Count int `json:"count"` Results []Pretix_Result `json:"results"` @@ -8,6 +10,7 @@ type Pretix_Event struct { type Pretix_Result struct { Status string `json:"status"` Positions []Pretix_Position `json:"positions"` + Datetime time.Time `json:"datetime"` } type Pretix_Position struct { diff --git a/src/go.mod b/src/go.mod index 9a0fb32..a6f9999 100644 --- a/src/go.mod +++ b/src/go.mod @@ -20,6 +20,7 @@ require ( github.com/go-playground/locales v0.14.1 // indirect github.com/go-playground/universal-translator v0.18.1 // indirect github.com/leodido/go-urn v1.2.4 // indirect + github.com/nicksnyder/go-i18n/v2 v2.4.0 // indirect golang.org/x/net v0.10.0 // indirect golang.org/x/text v0.14.0 // indirect ) diff --git a/src/localization/active.de.json b/src/localization/active.de.json new file mode 100644 index 0000000..244d7e8 --- /dev/null +++ b/src/localization/active.de.json @@ -0,0 +1,21 @@ +{ + "Attendie": { + "hash": "sha1-4c29d6c952ccd2b114d1792c7b18fa7f7052ebed", + "one": "Teilnehmer*in", + "other": "Teilnehmende" + }, + "HelloWorld": { + "hash": "sha1-6225ffc638ce81e53cdf7868fe0c7435594f11e4", + "other": "Hallo neuere Welt" + }, + "Name": { + "hash": "sha1-2b7c08c3ab75f37e2da656c1aab228f5f3a793b1", + "one": "Name", + "other": "Namen" + }, + "Role": { + "hash": "sha1-47dcc27d6e87ece8baebe7e3877a261a5467093d", + "one": "Rolle", + "other": "Rollen" + } +} \ No newline at end of file diff --git a/src/localization/active.en.json b/src/localization/active.en.json new file mode 100644 index 0000000..27e8163 --- /dev/null +++ b/src/localization/active.en.json @@ -0,0 +1,38 @@ +{ + "Attendie": { + "one": "Attendie", + "other": "Attendies" + }, + "Guest": { + "one": "Guest", + "other": "Guets" + }, + "HelloWorld": "Hello newer World", + "Name": { + "one": "Name", + "other": "Names" + }, + "Photographer": { + "one": "Photographer", + "other": "Photographers" + }, + "Registered": "Registered", + "Role": { + "one": "Role", + "other": "Roles" + }, + "SpecialAnimal": { + "one": "#SpecialAnimal", + "other": "#SpecialAnimals" + }, + "Spotter": { + "one": "Spotter", + "other": "Spotters" + }, + "Suiter": { + "one": "Suiter", + "other": "Suiters" + }, + "SuiterWatinglist": "Suiter Watinglist", + "WatinglistDesc": "We set a ratio of Suiters per Spotter for each event in order to keep the count of suiters manageble for them. If you are listed here we sadly don't have enough spotters yet." +} diff --git a/src/localization/translate.de.json b/src/localization/translate.de.json new file mode 100644 index 0000000..b87fe29 --- /dev/null +++ b/src/localization/translate.de.json @@ -0,0 +1,39 @@ +{ + "Guest": { + "hash": "sha1-7b7f214bbd4af36f25668b0ddade965422d342fd", + "one": "Guest", + "other": "Guets" + }, + "Photographer": { + "hash": "sha1-dc41992cfe878fe6744f94c3a3fc5843d9f1bc11", + "one": "Photographer", + "other": "Photographers" + }, + "Registered": { + "hash": "sha1-a844fcf834e7d026e7936e042c0ce2777b7fb4d9", + "other": "Registered" + }, + "SpecialAnimal": { + "hash": "sha1-7f937e9e4906c8f52977132faa76b81f3a331e45", + "one": "#SpecialAnimal", + "other": "#SpecialAnimals" + }, + "Spotter": { + "hash": "sha1-6f53dff03ced62b694851ffe37aab682b4b2b227", + "one": "Spotter", + "other": "Spotters" + }, + "Suiter": { + "hash": "sha1-eb6248e60da77b4df76de9b35efe44178ee34ead", + "one": "Suiter", + "other": "Suiters" + }, + "SuiterWatinglist": { + "hash": "sha1-a5d3dc94fc4f3f0604f0cc5e077c0c9eb43340d4", + "other": "Suiter Watinglist" + }, + "WatinglistDesc": { + "hash": "sha1-aadc433a212fca8d927e9134520f5a10aa7e4263", + "other": "We set a ratio of Suiters per Spotter for each event in order to keep the count of suiters manageble for them. If you are listed here we sadly don't have enough spotters yet." + } +} diff --git a/src/main.go b/src/main.go index 7fcc24d..d392be3 100644 --- a/src/main.go +++ b/src/main.go @@ -15,6 +15,9 @@ var viewFS embed.FS //go:embed app/static/* var staticFS embed.FS +//go:embed localization/active.*.json +var locaizationFS embed.FS + func main() { config.LoadEnv() config.Connect() @@ -23,6 +26,7 @@ func main() { config.SetupFiber(viewFS, staticFS) config.SetupCors() config.SetupHttp() + config.SetupLocalization(&locaizationFS) if config.Env.Debug { config.App.Use(cors.New(cors.Config{ diff --git a/src/translate.de.json b/src/translate.de.json new file mode 100644 index 0000000..a36c1da --- /dev/null +++ b/src/translate.de.json @@ -0,0 +1,21 @@ +{ + "Attendie": { + "hash": "sha1-4c29d6c952ccd2b114d1792c7b18fa7f7052ebed", + "one": "Attendie", + "other": "Attendies" + }, + "HelloWorld": { + "hash": "sha1-6225ffc638ce81e53cdf7868fe0c7435594f11e4", + "other": "Hello newer World" + }, + "Name": { + "hash": "sha1-2b7c08c3ab75f37e2da656c1aab228f5f3a793b1", + "one": "Name", + "other": "Names" + }, + "Role": { + "hash": "sha1-47dcc27d6e87ece8baebe7e3877a261a5467093d", + "one": "Role", + "other": "Roles" + } +} diff --git a/src/translate.de.toml b/src/translate.de.toml new file mode 100644 index 0000000..e491b0d --- /dev/null +++ b/src/translate.de.toml @@ -0,0 +1,18 @@ +[Attendie] +hash = "sha1-4c29d6c952ccd2b114d1792c7b18fa7f7052ebed" +one = "Attendie" +other = "Attendies" + +[HelloWorld] +hash = "sha1-6225ffc638ce81e53cdf7868fe0c7435594f11e4" +other = "Hello newer World" + +[Name] +hash = "sha1-2b7c08c3ab75f37e2da656c1aab228f5f3a793b1" +one = "Name" +other = "Names" + +[Role] +hash = "sha1-47dcc27d6e87ece8baebe7e3877a261a5467093d" +one = "Role" +other = "Roles"
NameRole{{ .Locals.Name }}{{ .Locals.Role }}Time
{{.Nickname}} {{.Role.Name}}{{.RegistrationTime}}