Files
lenz-web/controllers/uebersicht.go
2025-11-17 14:59:32 +01:00

212 lines
4.8 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package controllers
import (
"encoding/json"
"sort"
"strconv"
"strings"
"github.com/Theodor-Springmann-Stiftung/lenz-web/xmlmodels"
"github.com/gofiber/fiber/v2"
)
type filterItem struct {
ID int `json:"id"`
Name string `json:"name"`
}
func GetLetters(c *fiber.Ctx) error {
lib := xmlmodels.Get()
_, yearmap := lib.Years()
rangeParam := c.Query("range", "")
personParam := strings.TrimSpace(c.Query("person", ""))
placeParam := strings.TrimSpace(c.Query("ort", ""))
personID := 0
if personParam != "" {
if id, err := strconv.Atoi(personParam); err == nil && id > 0 {
personID = id
} else {
personParam = ""
}
}
placeID := 0
if placeParam != "" {
if id, err := strconv.Atoi(placeParam); err == nil && id > 0 {
placeID = id
} else {
placeParam = ""
}
}
rawQuery := string(c.Context().URI().QueryString())
lastPerson := strings.LastIndex(rawQuery, "person=")
lastPlace := strings.LastIndex(rawQuery, "ort=")
if lastPerson >= 0 && lastPlace >= 0 {
if lastPlace > lastPerson {
personID = 0
personParam = ""
} else {
placeID = 0
placeParam = ""
}
}
if personID > 0 && placeID > 0 {
// Fallback if we couldn't determine query order.
placeID = 0
placeParam = ""
}
personOptions := make(map[int]filterItem)
placeOptions := make(map[int]filterItem)
addPerson := func(id int) {
if id <= 0 {
return
}
if _, ok := personOptions[id]; ok {
return
}
if def := lib.Person(id); def != nil {
name := strings.TrimSpace(def.Name)
if name == "" {
name = strings.TrimSpace(def.FirstName + " " + def.LastName)
}
if name == "" {
name = strings.TrimSpace(def.Ref)
}
if name == "" {
name = "Person " + strconv.Itoa(id)
}
personOptions[id] = filterItem{ID: id, Name: name}
}
}
addPlace := func(id int) {
if id <= 0 {
return
}
if _, ok := placeOptions[id]; ok {
return
}
if def := lib.Place(id); def != nil {
name := strings.TrimSpace(def.Name)
if name == "" {
name = strings.TrimSpace(def.Ref)
}
if name == "" {
name = "Ort " + strconv.Itoa(id)
}
placeOptions[id] = filterItem{ID: id, Name: name}
}
}
collectRefs := func(meta xmlmodels.Meta) {
for _, action := range meta.Sent {
for _, ref := range action.Persons {
addPerson(ref.Reference)
}
for _, ref := range action.Places {
addPlace(ref.Reference)
}
}
for _, action := range meta.Recieved {
for _, ref := range action.Persons {
addPerson(ref.Reference)
}
for _, ref := range action.Places {
addPlace(ref.Reference)
}
}
}
filterLetter := func(meta xmlmodels.Meta) bool {
if personID > 0 && !meta.HasPerson(personID) {
return false
}
if placeID > 0 && !meta.HasPlace(placeID) {
return false
}
return true
}
// TODO: does not work ATM
c.Locals("path", c.Path())
// Define the date ranges
ranges := []DateRange{
{Label: "17561770", Start: 1756, End: 1770, Letters: []xmlmodels.Meta{}},
{Label: "17711775", Start: 1771, End: 1775, Letters: []xmlmodels.Meta{}},
{Label: "1776", Start: 1776, End: 1776, Letters: []xmlmodels.Meta{}},
{Label: "17771779", Start: 1777, End: 1779, Letters: []xmlmodels.Meta{}},
{Label: "17801792", Start: 1780, End: 1792, Letters: []xmlmodels.Meta{}},
}
// Group letters by date ranges
for year, letters := range yearmap {
for i := range ranges {
if year >= ranges[i].Start && year <= ranges[i].End {
for _, letter := range letters {
collectRefs(letter)
if filterLetter(letter) {
ranges[i].Letters = append(ranges[i].Letters, letter)
}
}
break
}
}
}
if personID > 0 || placeID > 0 {
rangeParam = "all"
}
// Handle specific range selection
selectedRange := -1
for i, r := range ranges {
if r.Label == rangeParam {
selectedRange = i
break
}
}
querySuffix := ""
if personParam != "" {
querySuffix += "&person=" + personParam
}
if placeParam != "" {
querySuffix += "&ort=" + placeParam
}
personList := make([]filterItem, 0, len(personOptions))
for _, item := range personOptions {
personList = append(personList, item)
}
sort.Slice(personList, func(i, j int) bool {
return strings.ToLower(personList[i].Name) < strings.ToLower(personList[j].Name)
})
placeList := make([]filterItem, 0, len(placeOptions))
for _, item := range placeOptions {
placeList = append(placeList, item)
}
sort.Slice(placeList, func(i, j int) bool {
return strings.ToLower(placeList[i].Name) < strings.ToLower(placeList[j].Name)
})
personJSON, _ := json.Marshal(personList)
placeJSON, _ := json.Marshal(placeList)
return c.Render(LETTERS_URL+"/", fiber.Map{
"ranges": ranges,
"selectedRange": selectedRange,
"all": rangeParam == "all",
"person": personParam,
"ort": placeParam,
"query": querySuffix,
"personJSON": string(personJSON),
"placeJSON": string(placeJSON),
})
}