mirror of
https://github.com/Theodor-Springmann-Stiftung/musenalm.git
synced 2025-10-29 09:15:33 +00:00
Alle Abfragen für Reihen-Seite
This commit is contained in:
17
dbmodels/agents.go
Normal file
17
dbmodels/agents.go
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
package dbmodels
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/pocketbase/dbx"
|
||||||
|
"github.com/pocketbase/pocketbase/core"
|
||||||
|
)
|
||||||
|
|
||||||
|
func AgentForId(app core.App, id string) (*Agent, error) {
|
||||||
|
agent := &Agent{}
|
||||||
|
err := app.RecordQuery(AGENTS_TABLE).
|
||||||
|
Where(dbx.HashExp{ID_FIELD: id}).
|
||||||
|
One(agent)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return agent, nil
|
||||||
|
}
|
||||||
@@ -423,6 +423,7 @@ const (
|
|||||||
CONTENTS_TABLE = "contents"
|
CONTENTS_TABLE = "contents"
|
||||||
ITEMS_TABLE = "items"
|
ITEMS_TABLE = "items"
|
||||||
|
|
||||||
|
ID_FIELD = "id"
|
||||||
ANNOTATION_FIELD = "annotation"
|
ANNOTATION_FIELD = "annotation"
|
||||||
|
|
||||||
MUSENALMID_FIELD = "musenalm_id"
|
MUSENALMID_FIELD = "musenalm_id"
|
||||||
|
|||||||
90
dbmodels/entries.go
Normal file
90
dbmodels/entries.go
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
package dbmodels
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/pocketbase/dbx"
|
||||||
|
"github.com/pocketbase/pocketbase/core"
|
||||||
|
)
|
||||||
|
|
||||||
|
type EntriesAgents map[string][]*REntriesAgents
|
||||||
|
|
||||||
|
func YearsForEntries(app core.App) ([]int, error) {
|
||||||
|
rec := []core.Record{}
|
||||||
|
err := app.RecordQuery(ENTRIES_TABLE).
|
||||||
|
Select(YEAR_FIELD + " AS id").
|
||||||
|
Distinct(true).
|
||||||
|
OrderBy("id").
|
||||||
|
All(&rec)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
years := []int{}
|
||||||
|
for _, r := range rec {
|
||||||
|
years = append(years, r.GetInt("id"))
|
||||||
|
}
|
||||||
|
|
||||||
|
return years, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func EntriesForYear(app core.App, year int) ([]*Entry, error) {
|
||||||
|
entries := []*Entry{}
|
||||||
|
err := app.RecordQuery(ENTRIES_TABLE).
|
||||||
|
Where(dbx.HashExp{YEAR_FIELD: year}).
|
||||||
|
All(&entries)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return entries, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func EntriesForAgent(app core.App, agentId string) ([]*Entry, EntriesAgents, error) {
|
||||||
|
relations := []*core.Record{}
|
||||||
|
err := app.RecordQuery(RelationTableName(ENTRIES_TABLE, AGENTS_TABLE)).
|
||||||
|
Where(dbx.HashExp{AGENTS_TABLE: agentId}).
|
||||||
|
All(&relations)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
app.ExpandRecords(relations, []string{ENTRIES_TABLE}, nil)
|
||||||
|
entries := []*Entry{}
|
||||||
|
for _, r := range relations {
|
||||||
|
record := r.ExpandedOne(ENTRIES_TABLE)
|
||||||
|
if record == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
entries = append(entries, NewEntry(record))
|
||||||
|
}
|
||||||
|
|
||||||
|
agents := map[string][]*REntriesAgents{}
|
||||||
|
for _, r := range relations {
|
||||||
|
agent := NewREntriesAgents(r)
|
||||||
|
agents[agent.Entry()] = append(agents[agent.Entry()], agent)
|
||||||
|
}
|
||||||
|
|
||||||
|
return entries, agents, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func EntriesForPlace(app core.App, placeId string) ([]*Entry, error) {
|
||||||
|
entries := []*Entry{}
|
||||||
|
err := app.RecordQuery(ENTRIES_TABLE).
|
||||||
|
Where(dbx.Like(PLACES_TABLE, placeId).Match(true, true)).
|
||||||
|
All(&entries)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return entries, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func EntryForId(app core.App, id string) (*Entry, error) {
|
||||||
|
entry := &Entry{}
|
||||||
|
err := app.RecordQuery(ENTRIES_TABLE).
|
||||||
|
Where(dbx.HashExp{ID_FIELD: id}).
|
||||||
|
One(entry)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return entry, nil
|
||||||
|
}
|
||||||
@@ -82,14 +82,18 @@ func BasicRelationCollection(app core.App, sourcetablename, targettablename stri
|
|||||||
return collection, nil
|
return collection, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type IDable interface {
|
func GetIDs(records []*core.Record) []any {
|
||||||
ID() string
|
ids := []any{}
|
||||||
}
|
|
||||||
|
|
||||||
func GetIDs(records []IDable) []string {
|
|
||||||
ids := []string{}
|
|
||||||
for _, r := range records {
|
for _, r := range records {
|
||||||
ids = append(ids, r.ID())
|
ids = append(ids, r.Id)
|
||||||
}
|
}
|
||||||
return ids
|
return ids
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func GetFields(records []*core.Record, field string) []any {
|
||||||
|
fields := []any{}
|
||||||
|
for _, r := range records {
|
||||||
|
fields = append(fields, r.GetString(field))
|
||||||
|
}
|
||||||
|
return fields
|
||||||
|
}
|
||||||
|
|||||||
40
dbmodels/places.go
Normal file
40
dbmodels/places.go
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
package dbmodels
|
||||||
|
|
||||||
|
import (
|
||||||
|
"slices"
|
||||||
|
|
||||||
|
"github.com/pocketbase/dbx"
|
||||||
|
"github.com/pocketbase/pocketbase/core"
|
||||||
|
"golang.org/x/text/collate"
|
||||||
|
"golang.org/x/text/language"
|
||||||
|
)
|
||||||
|
|
||||||
|
func AllPlaces(app core.App) ([]*Place, error) {
|
||||||
|
places := []*Place{}
|
||||||
|
err := app.RecordQuery(PLACES_TABLE).
|
||||||
|
OrderBy(PLACES_NAME_FIELD).
|
||||||
|
All(&places)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return places, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func SortPlacesByName(places []*Place) {
|
||||||
|
collator := collate.New(language.German)
|
||||||
|
slices.SortFunc(places, func(i, j *Place) int {
|
||||||
|
return collator.CompareString(i.Name(), j.Name())
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func PlaceForId(app core.App, id string) (*Place, error) {
|
||||||
|
place := &Place{}
|
||||||
|
err := app.RecordQuery(PLACES_TABLE).
|
||||||
|
Where(dbx.HashExp{ID_FIELD: id}).
|
||||||
|
One(place)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return place, nil
|
||||||
|
}
|
||||||
@@ -1,11 +1,7 @@
|
|||||||
package dbmodels
|
package dbmodels
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"slices"
|
|
||||||
|
|
||||||
"github.com/pocketbase/pocketbase/core"
|
"github.com/pocketbase/pocketbase/core"
|
||||||
"golang.org/x/text/collate"
|
|
||||||
"golang.org/x/text/language"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var _ core.RecordProxy = (*Series)(nil)
|
var _ core.RecordProxy = (*Series)(nil)
|
||||||
@@ -91,10 +87,3 @@ func (s *Series) Frequency() string {
|
|||||||
func (s *Series) SetFrequency(frequency string) {
|
func (s *Series) SetFrequency(frequency string) {
|
||||||
s.Set(SERIES_FREQUENCY_FIELD, frequency)
|
s.Set(SERIES_FREQUENCY_FIELD, frequency)
|
||||||
}
|
}
|
||||||
|
|
||||||
func SortSeriesByTitle(series []*Series) {
|
|
||||||
collator := collate.New(language.German)
|
|
||||||
slices.SortFunc(series, func(i, j *Series) int {
|
|
||||||
return collator.CompareString(i.Title(), j.Title())
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|||||||
248
dbmodels/seriesses.go
Normal file
248
dbmodels/seriesses.go
Normal file
@@ -0,0 +1,248 @@
|
|||||||
|
package dbmodels
|
||||||
|
|
||||||
|
import (
|
||||||
|
"slices"
|
||||||
|
|
||||||
|
"github.com/pocketbase/dbx"
|
||||||
|
"github.com/pocketbase/pocketbase/core"
|
||||||
|
"golang.org/x/text/collate"
|
||||||
|
"golang.org/x/text/language"
|
||||||
|
)
|
||||||
|
|
||||||
|
type SeriesEntries map[string][]*REntriesSeries
|
||||||
|
|
||||||
|
func SortSeriessesByTitle(series []*Series) {
|
||||||
|
collator := collate.New(language.German)
|
||||||
|
slices.SortFunc(series, func(i, j *Series) int {
|
||||||
|
return collator.CompareString(i.Title(), j.Title())
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func BasicSearchSeries(app core.App, query string) ([]*Series, []*Series, error) {
|
||||||
|
series, err := TitleSearchSeries(app, query)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
altseries, err := AltSearchSeries(app, query)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
return series, altseries, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func TitleSearchSeries(app core.App, query string) ([]*Series, error) {
|
||||||
|
series := []*Series{}
|
||||||
|
err := app.RecordQuery(SERIES_TABLE).
|
||||||
|
Where(dbx.Like(SERIES_TITLE_FIELD, query).Match(true, true)).
|
||||||
|
OrderBy(SERIES_TITLE_FIELD).
|
||||||
|
All(&series)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return series, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func AltSearchSeries(app core.App, query string) ([]*Series, error) {
|
||||||
|
series := []*Series{}
|
||||||
|
err := app.RecordQuery(SERIES_TABLE).
|
||||||
|
Where(dbx.Like(ANNOTATION_FIELD, query).Match(true, true)).
|
||||||
|
OrderBy(SERIES_TITLE_FIELD).
|
||||||
|
All(&series)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return series, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func IDsForSeriesses(series []*Series) []any {
|
||||||
|
ids := []any{}
|
||||||
|
for _, s := range series {
|
||||||
|
ids = append(ids, s.Id)
|
||||||
|
}
|
||||||
|
return ids
|
||||||
|
}
|
||||||
|
|
||||||
|
func makeMapForEnrySeries(relations []*REntriesSeries, entries map[string]*Entry) SeriesEntries {
|
||||||
|
m := map[string][]*REntriesSeries{}
|
||||||
|
for _, r := range relations {
|
||||||
|
m[r.Id] = append(m[r.Id], r)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, rel := range m {
|
||||||
|
slices.SortFunc(rel, func(i, j *REntriesSeries) int {
|
||||||
|
ientry := entries[i.Entry()]
|
||||||
|
jentry := entries[j.Entry()]
|
||||||
|
return ientry.Year() - jentry.Year()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return m
|
||||||
|
}
|
||||||
|
|
||||||
|
func EntriesForSeriesses(app core.App, series []*Series) (
|
||||||
|
SeriesEntries,
|
||||||
|
map[string]*Entry,
|
||||||
|
error) {
|
||||||
|
ids := IDsForSeriesses(series)
|
||||||
|
relations := []*core.Record{}
|
||||||
|
|
||||||
|
err := app.RecordQuery(RelationTableName(ENTRIES_TABLE, SERIES_TABLE)).
|
||||||
|
Where(dbx.HashExp{
|
||||||
|
SERIES_TABLE: ids,
|
||||||
|
}).
|
||||||
|
All(&relations)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
app.ExpandRecords(relations, []string{ENTRIES_TABLE}, nil)
|
||||||
|
bmap := map[string]*Entry{}
|
||||||
|
for _, r := range relations {
|
||||||
|
record := r.ExpandedOne(ENTRIES_TABLE)
|
||||||
|
if record == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
entry := NewEntry(record)
|
||||||
|
bmap[entry.Id] = entry
|
||||||
|
}
|
||||||
|
|
||||||
|
smap := map[string][]*REntriesSeries{}
|
||||||
|
for _, r := range relations {
|
||||||
|
series := NewREntriesSeries(r)
|
||||||
|
smap[series.Id] = append(smap[series.Id], series)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, rel := range smap {
|
||||||
|
slices.SortFunc(rel, func(i, j *REntriesSeries) int {
|
||||||
|
ientry := bmap[i.Entry()]
|
||||||
|
jentry := bmap[j.Entry()]
|
||||||
|
return ientry.Year() - jentry.Year()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return smap, bmap, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func LettersForSeries(app core.App) ([]string, error) {
|
||||||
|
letters := []core.Record{}
|
||||||
|
ids := []string{}
|
||||||
|
|
||||||
|
err := app.RecordQuery(SERIES_TABLE).
|
||||||
|
Select("upper(substr(" + SERIES_TITLE_FIELD + ", 1, 1)) AS id").
|
||||||
|
Distinct(true).
|
||||||
|
All(&letters)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, l := range letters {
|
||||||
|
ids = append(ids, l.GetString("id"))
|
||||||
|
}
|
||||||
|
return ids, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func AllAgentsForSeries(app core.App) ([]*Agent, error) {
|
||||||
|
rels := []*core.Record{}
|
||||||
|
// INFO: we could just fetch all relations here
|
||||||
|
err := app.RecordQuery(RelationTableName(ENTRIES_TABLE, AGENTS_TABLE)).
|
||||||
|
GroupBy(AGENTS_TABLE).
|
||||||
|
All(&rels)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
app.ExpandRecords(rels, []string{AGENTS_TABLE}, nil)
|
||||||
|
agents := []*Agent{}
|
||||||
|
for _, r := range rels {
|
||||||
|
record := r.ExpandedOne(AGENTS_TABLE)
|
||||||
|
if record == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
agent := NewAgent(record)
|
||||||
|
agents = append(agents, agent)
|
||||||
|
}
|
||||||
|
|
||||||
|
SortAgentsByName(agents)
|
||||||
|
|
||||||
|
return agents, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func SeriesForLetter(app core.App, letter string) ([]*Series, error) {
|
||||||
|
series := []*Series{}
|
||||||
|
err := app.RecordQuery(SERIES_TABLE).
|
||||||
|
Where(dbx.Like(SERIES_TITLE_FIELD, letter).Match(false, true)).
|
||||||
|
OrderBy(SERIES_TITLE_FIELD).
|
||||||
|
All(&series)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return series, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func SeriesForAgent(app core.App, id string) ([]*Series, SeriesEntries, map[string]*Entry, error) {
|
||||||
|
entries, _, err := EntriesForAgent(app, id)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return SeriesForEntries(app, entries)
|
||||||
|
}
|
||||||
|
|
||||||
|
func SeriesForPlace(app core.App, id string) ([]*Series, SeriesEntries, map[string]*Entry, error) {
|
||||||
|
entries, err := EntriesForPlace(app, id)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return SeriesForEntries(app, entries)
|
||||||
|
}
|
||||||
|
|
||||||
|
func SeriesForEntries(app core.App, entries []*Entry) ([]*Series, SeriesEntries, map[string]*Entry, error) {
|
||||||
|
bids := make([]any, 0, len(entries))
|
||||||
|
for _, e := range entries {
|
||||||
|
bids = append(bids, e.Id)
|
||||||
|
}
|
||||||
|
|
||||||
|
srels := []*REntriesSeries{}
|
||||||
|
err := app.RecordQuery(RelationTableName(ENTRIES_TABLE, SERIES_TABLE)).
|
||||||
|
Where(dbx.HashExp{ENTRIES_TABLE: bids}).
|
||||||
|
All(&srels)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
sids := []any{}
|
||||||
|
for _, s := range srels {
|
||||||
|
sids = append(sids, s.Series())
|
||||||
|
}
|
||||||
|
|
||||||
|
series := []*Series{}
|
||||||
|
err = app.RecordQuery(SERIES_TABLE).
|
||||||
|
Where(dbx.HashExp{ID_FIELD: sids}).
|
||||||
|
All(&series)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
bmap := make(map[string]*Entry, len(entries))
|
||||||
|
for _, e := range entries {
|
||||||
|
bmap[e.Id] = e
|
||||||
|
}
|
||||||
|
|
||||||
|
smap := makeMapForEnrySeries(srels, bmap)
|
||||||
|
|
||||||
|
return series, smap, bmap, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func SeriesForYear(app core.App, year int) ([]*Series, SeriesEntries, map[string]*Entry, error) {
|
||||||
|
series, err := EntriesForYear(app, year)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return SeriesForEntries(app, series)
|
||||||
|
}
|
||||||
2
go.mod
2
go.mod
@@ -1,6 +1,6 @@
|
|||||||
module github.com/Theodor-Springmann-Stiftung/musenalm
|
module github.com/Theodor-Springmann-Stiftung/musenalm
|
||||||
|
|
||||||
go 1.23.6
|
go 1.24
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/fsnotify/fsnotify v1.7.0
|
github.com/fsnotify/fsnotify v1.7.0
|
||||||
|
|||||||
279
pages/reihen.go
279
pages/reihen.go
@@ -2,22 +2,25 @@ package pages
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"net/http"
|
"net/http"
|
||||||
"slices"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/Theodor-Springmann-Stiftung/musenalm/app"
|
"github.com/Theodor-Springmann-Stiftung/musenalm/app"
|
||||||
"github.com/Theodor-Springmann-Stiftung/musenalm/dbmodels"
|
"github.com/Theodor-Springmann-Stiftung/musenalm/dbmodels"
|
||||||
"github.com/Theodor-Springmann-Stiftung/musenalm/pagemodels"
|
"github.com/Theodor-Springmann-Stiftung/musenalm/pagemodels"
|
||||||
"github.com/Theodor-Springmann-Stiftung/musenalm/templating"
|
"github.com/Theodor-Springmann-Stiftung/musenalm/templating"
|
||||||
"github.com/pocketbase/dbx"
|
|
||||||
"github.com/pocketbase/pocketbase/core"
|
"github.com/pocketbase/pocketbase/core"
|
||||||
"github.com/pocketbase/pocketbase/tools/router"
|
"github.com/pocketbase/pocketbase/tools/router"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
URL_REIHEN = "/reihen/"
|
URL_REIHEN = "/reihen/"
|
||||||
|
URL_REIHE = "/reihen/{id}/"
|
||||||
PARAM_LETTER = "letter"
|
PARAM_LETTER = "letter"
|
||||||
PARAM_SEARCH = "search"
|
PARAM_SEARCH = "search"
|
||||||
|
PARAM_PERSON = "agent"
|
||||||
|
PARAM_PLACE = "place"
|
||||||
|
PARAM_YEAR = "year"
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
@@ -47,179 +50,177 @@ func (p *ReihenPage) Setup(router *router.Router[*core.RequestEvent], app core.A
|
|||||||
if search != "" {
|
if search != "" {
|
||||||
return p.SearchRequest(app, engine, e)
|
return p.SearchRequest(app, engine, e)
|
||||||
}
|
}
|
||||||
|
person := e.Request.URL.Query().Get(PARAM_PERSON)
|
||||||
|
if person != "" {
|
||||||
|
return p.PersonRequest(app, engine, e)
|
||||||
|
}
|
||||||
|
place := e.Request.URL.Query().Get(PARAM_PLACE)
|
||||||
|
if place != "" {
|
||||||
|
return p.PlaceRequest(app, engine, e)
|
||||||
|
}
|
||||||
|
year := e.Request.URL.Query().Get(PARAM_YEAR)
|
||||||
|
if year != "" {
|
||||||
|
return p.YearRequest(app, engine, e)
|
||||||
|
}
|
||||||
|
|
||||||
return p.LetterRequest(app, engine, e)
|
return p.LetterRequest(app, engine, e)
|
||||||
})
|
})
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *ReihenPage) YearRequest(app core.App, engine *templating.Engine, e *core.RequestEvent) error {
|
||||||
|
year := e.Request.URL.Query().Get(PARAM_YEAR)
|
||||||
|
data := map[string]interface{}{}
|
||||||
|
data[PARAM_YEAR] = year
|
||||||
|
|
||||||
|
y, err := strconv.Atoi(year)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
series, relations, entries, err := dbmodels.SeriesForYear(app, y)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
data["entries"] = entries
|
||||||
|
data["relations"] = relations
|
||||||
|
data["series"] = series
|
||||||
|
|
||||||
|
return p.Get(e, engine, data)
|
||||||
|
}
|
||||||
|
|
||||||
func (p *ReihenPage) LetterRequest(app core.App, engine *templating.Engine, e *core.RequestEvent) error {
|
func (p *ReihenPage) LetterRequest(app core.App, engine *templating.Engine, e *core.RequestEvent) error {
|
||||||
letter := e.Request.URL.Query().Get(PARAM_LETTER)
|
letter := e.Request.URL.Query().Get(PARAM_LETTER)
|
||||||
|
data := map[string]interface{}{}
|
||||||
if letter == "" {
|
if letter == "" {
|
||||||
letter = "A"
|
letter = "A"
|
||||||
}
|
}
|
||||||
series := []*dbmodels.Series{}
|
data[PARAM_LETTER] = letter
|
||||||
err := app.RecordQuery(dbmodels.SERIES_TABLE).
|
|
||||||
Where(dbx.Like(dbmodels.SERIES_TITLE_FIELD, letter).Match(false, true)).
|
series, err := dbmodels.SeriesForLetter(app, letter)
|
||||||
OrderBy(dbmodels.SERIES_TITLE_FIELD).
|
|
||||||
All(&series)
|
|
||||||
// INFO: this does not return an error if the result set is empty
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// INFO: We sort again since the query can't sort german umlauts correctly
|
// INFO: We sort again since the query can't sort german umlauts correctly
|
||||||
dbmodels.SortSeriesByTitle(series)
|
dbmodels.SortSeriessesByTitle(series)
|
||||||
|
data["series"] = series
|
||||||
|
|
||||||
smap, bmap := p.EntriesForSeries(app, series)
|
rmap, bmap, err := dbmodels.EntriesForSeriesses(app, series)
|
||||||
agents, _ := p.GetAgents(app)
|
|
||||||
|
|
||||||
var builder strings.Builder
|
|
||||||
err = engine.Render(&builder, URL_REIHEN, map[string]interface{}{
|
|
||||||
PARAM_LETTER: letter,
|
|
||||||
"series": series,
|
|
||||||
"letters": p.Letters(app),
|
|
||||||
"entries": bmap,
|
|
||||||
"relations": smap,
|
|
||||||
"agents": agents,
|
|
||||||
})
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
data["entries"] = bmap
|
||||||
|
data["relations"] = rmap
|
||||||
|
|
||||||
return e.HTML(http.StatusOK, builder.String())
|
return p.Get(e, engine, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *ReihenPage) PersonRequest(app core.App, engine *templating.Engine, e *core.RequestEvent) error {
|
||||||
|
person := e.Request.URL.Query().Get(PARAM_PERSON)
|
||||||
|
data := map[string]interface{}{}
|
||||||
|
data[PARAM_PERSON] = person
|
||||||
|
|
||||||
|
agent, err := dbmodels.AgentForId(app, person)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
data["a"] = agent
|
||||||
|
|
||||||
|
series, relations, entries, err := dbmodels.SeriesForAgent(app, person)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
data["series"] = series
|
||||||
|
data["relations"] = relations
|
||||||
|
data["entries"] = entries
|
||||||
|
|
||||||
|
return p.Get(e, engine, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *ReihenPage) PlaceRequest(app core.App, engine *templating.Engine, e *core.RequestEvent) error {
|
||||||
|
place := e.Request.URL.Query().Get(PARAM_PLACE)
|
||||||
|
data := map[string]interface{}{}
|
||||||
|
data[PARAM_PLACE] = place
|
||||||
|
|
||||||
|
pl, err := dbmodels.PlaceForId(app, place)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
data["p"] = pl
|
||||||
|
|
||||||
|
series, relations, entries, err := dbmodels.SeriesForPlace(app, place)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
data["series"] = series
|
||||||
|
data["relations"] = relations
|
||||||
|
data["entries"] = entries
|
||||||
|
|
||||||
|
return p.Get(e, engine, data)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *ReihenPage) SearchRequest(app core.App, engine *templating.Engine, e *core.RequestEvent) error {
|
func (p *ReihenPage) SearchRequest(app core.App, engine *templating.Engine, e *core.RequestEvent) error {
|
||||||
search := e.Request.URL.Query().Get(PARAM_SEARCH)
|
search := e.Request.URL.Query().Get(PARAM_SEARCH)
|
||||||
series := []*dbmodels.Series{}
|
data := map[string]interface{}{}
|
||||||
err := app.RecordQuery(dbmodels.SERIES_TABLE).
|
data[PARAM_SEARCH] = search
|
||||||
Where(dbx.Like(dbmodels.SERIES_TITLE_FIELD, search).Match(true, true)).
|
series, altseries, err := dbmodels.BasicSearchSeries(app, search)
|
||||||
OrderBy(dbmodels.SERIES_TITLE_FIELD).
|
|
||||||
All(&series)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
dbmodels.SortSeriessesByTitle(series)
|
||||||
|
dbmodels.SortSeriessesByTitle(altseries)
|
||||||
|
data["series"] = series
|
||||||
|
data["altseries"] = altseries
|
||||||
|
|
||||||
altseries := []*dbmodels.Series{}
|
rmap, bmap, err := dbmodels.EntriesForSeriesses(app, series)
|
||||||
err = app.RecordQuery(dbmodels.SERIES_TABLE).
|
|
||||||
Where(dbx.Like(dbmodels.ANNOTATION_FIELD, search).Match(true, true)).
|
|
||||||
OrderBy(dbmodels.SERIES_TITLE_FIELD).
|
|
||||||
All(&altseries)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
data["entries"] = bmap
|
||||||
|
data["relations"] = rmap
|
||||||
|
|
||||||
dbmodels.SortSeriesByTitle(series)
|
return p.Get(e, engine, data)
|
||||||
dbmodels.SortSeriesByTitle(altseries)
|
}
|
||||||
|
|
||||||
smap, bmap := p.EntriesForSeries(app, series)
|
func (p *ReihenPage) CommonData(app core.App, data map[string]interface{}) error {
|
||||||
agents, _ := p.GetAgents(app)
|
agents, err := dbmodels.AllAgentsForSeries(app)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
data["agents"] = agents
|
||||||
|
|
||||||
|
letters, err := dbmodels.LettersForSeries(app)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
data["letters"] = letters
|
||||||
|
|
||||||
|
places, err := dbmodels.AllPlaces(app)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
dbmodels.SortPlacesByName(places)
|
||||||
|
data["places"] = places
|
||||||
|
|
||||||
|
years, err := dbmodels.YearsForEntries(app)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
data["years"] = years
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *ReihenPage) Get(request *core.RequestEvent, engine *templating.Engine, data map[string]interface{}) error {
|
||||||
|
err := p.CommonData(request.App, data)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
var builder strings.Builder
|
var builder strings.Builder
|
||||||
err = engine.Render(&builder, URL_REIHEN, map[string]interface{}{
|
err = engine.Render(&builder, URL_REIHEN, data)
|
||||||
PARAM_SEARCH: search,
|
|
||||||
"series": series,
|
|
||||||
"altseries": altseries,
|
|
||||||
"letters": p.Letters(app),
|
|
||||||
"entries": bmap,
|
|
||||||
"relations": smap,
|
|
||||||
"agents": agents,
|
|
||||||
})
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
return request.HTML(http.StatusOK, builder.String())
|
||||||
return e.HTML(http.StatusOK, builder.String())
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *ReihenPage) Letters(app core.App) []string {
|
|
||||||
letters := []core.Record{}
|
|
||||||
ids := []string{}
|
|
||||||
|
|
||||||
err := app.RecordQuery(dbmodels.SERIES_TABLE).
|
|
||||||
Select("upper(substr(" + dbmodels.SERIES_TITLE_FIELD + ", 1, 1)) AS id").
|
|
||||||
Distinct(true).
|
|
||||||
All(&letters)
|
|
||||||
if err != nil {
|
|
||||||
return ids
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, l := range letters {
|
|
||||||
ids = append(ids, l.GetString("id"))
|
|
||||||
}
|
|
||||||
return ids
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *ReihenPage) EntriesForSeries(app core.App, series []*dbmodels.Series) (
|
|
||||||
map[string][]*dbmodels.REntriesSeries,
|
|
||||||
map[string]*dbmodels.Entry) {
|
|
||||||
ids := []any{}
|
|
||||||
for _, s := range series {
|
|
||||||
ids = append(ids, s.Id)
|
|
||||||
}
|
|
||||||
|
|
||||||
relations := []*core.Record{}
|
|
||||||
|
|
||||||
err := app.RecordQuery(dbmodels.RelationTableName(dbmodels.ENTRIES_TABLE, dbmodels.SERIES_TABLE)).
|
|
||||||
Where(dbx.HashExp{
|
|
||||||
dbmodels.SERIES_TABLE: ids,
|
|
||||||
}).
|
|
||||||
All(&relations)
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
app.ExpandRecords(relations, []string{dbmodels.ENTRIES_TABLE}, nil)
|
|
||||||
bmap := map[string]*dbmodels.Entry{}
|
|
||||||
for _, r := range relations {
|
|
||||||
record := r.ExpandedOne(dbmodels.ENTRIES_TABLE)
|
|
||||||
if record == nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
entry := dbmodels.NewEntry(record)
|
|
||||||
bmap[entry.Id] = entry
|
|
||||||
}
|
|
||||||
|
|
||||||
smap := map[string][]*dbmodels.REntriesSeries{}
|
|
||||||
for _, r := range relations {
|
|
||||||
series := dbmodels.NewREntriesSeries(r)
|
|
||||||
smap[series.Id] = append(smap[series.Id], series)
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, rel := range smap {
|
|
||||||
slices.SortFunc(rel, func(i, j *dbmodels.REntriesSeries) int {
|
|
||||||
ientry := bmap[i.Entry()]
|
|
||||||
jentry := bmap[j.Entry()]
|
|
||||||
return ientry.Year() - jentry.Year()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
return smap, bmap
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *ReihenPage) GetAgents(app core.App) ([]*dbmodels.Agent, error) {
|
|
||||||
rels := []*core.Record{}
|
|
||||||
// INFO: we could just fetch all relations here
|
|
||||||
err := app.RecordQuery(dbmodels.RelationTableName(dbmodels.ENTRIES_TABLE, dbmodels.AGENTS_TABLE)).
|
|
||||||
GroupBy(dbmodels.AGENTS_TABLE).
|
|
||||||
All(&rels)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
app.ExpandRecords(rels, []string{dbmodels.AGENTS_TABLE}, nil)
|
|
||||||
agents := []*dbmodels.Agent{}
|
|
||||||
for _, r := range rels {
|
|
||||||
record := r.ExpandedOne(dbmodels.AGENTS_TABLE)
|
|
||||||
if record == nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
agent := dbmodels.NewAgent(record)
|
|
||||||
agents = append(agents, agent)
|
|
||||||
}
|
|
||||||
|
|
||||||
dbmodels.SortAgentsByName(agents)
|
|
||||||
|
|
||||||
return agents, err
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -100,10 +100,13 @@ func (e *Engine) AddFuncs(funcs map[string]interface{}) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (e *Engine) Render(out io.Writer, path string, ld map[string]interface{}, layout ...string) error {
|
func (e *Engine) Render(out io.Writer, path string, ld map[string]interface{}, layout ...string) error {
|
||||||
// TODO: check if a reload is needed if files on disk have changed
|
|
||||||
gd := e.GlobalData
|
gd := e.GlobalData
|
||||||
for k, v := range ld {
|
// INFO: don't pollute the global data space
|
||||||
gd[k] = v
|
for k, v := range gd {
|
||||||
|
_, ok := ld[k]
|
||||||
|
if !ok {
|
||||||
|
ld[k] = v
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
e.mu.Lock()
|
e.mu.Lock()
|
||||||
@@ -135,7 +138,7 @@ func (e *Engine) Render(out io.Writer, path string, ld map[string]interface{}, l
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
err = lay.Execute(out, gd)
|
err = lay.Execute(out, ld)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,15 +15,55 @@
|
|||||||
</div>
|
</div>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
|
|
||||||
{{ if .search }}
|
|
||||||
<div class="mt-8">
|
<div class="flex flex-row">
|
||||||
{{ range $id, $r := .altseries }}
|
{{ if .search }}
|
||||||
<div>
|
<div class="mt-8">
|
||||||
{{ $r.Title }}
|
{{ range $id, $r := .altseries }}
|
||||||
<div>
|
<div>
|
||||||
{{ Safe $r.Annotation }}
|
{{ $r.Title }}
|
||||||
|
<div>
|
||||||
|
{{ Safe $r.Annotation }}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
{{ end }}
|
||||||
{{ end }}
|
</div>
|
||||||
</div>
|
{{ end }}
|
||||||
{{ end }}
|
|
||||||
|
{{ if .agents }}
|
||||||
|
<div class="mt-8">
|
||||||
|
{{ range $id, $r := .agents }}
|
||||||
|
<div>
|
||||||
|
<a href="/reihen?agent={{ $r.Id }}">{{ $r.Name }}</a>
|
||||||
|
</div>
|
||||||
|
{{ end }}
|
||||||
|
</div>
|
||||||
|
{{ end }}
|
||||||
|
|
||||||
|
{{ if .places }}
|
||||||
|
<div class="mt-8">
|
||||||
|
{{ range $id, $r := .places }}
|
||||||
|
<div>
|
||||||
|
<a href="/reihen?place={{ $r.Id }}">{{ $r.Name }}</a>
|
||||||
|
</div>
|
||||||
|
{{ end }}
|
||||||
|
</div>
|
||||||
|
{{ end }}
|
||||||
|
|
||||||
|
{{ if .years }}
|
||||||
|
<div class="mt-8">
|
||||||
|
{{ range $id, $r := .years }}
|
||||||
|
{{ if eq $r 0 }}
|
||||||
|
<div>
|
||||||
|
<a href="/reihen?year=0">ohne Jahr</a>
|
||||||
|
</div>
|
||||||
|
{{ else }}
|
||||||
|
<div>
|
||||||
|
<a href="/reihen?year={{ $r }}">{{ $r }}</a>
|
||||||
|
</div>
|
||||||
|
{{ end }}
|
||||||
|
{{ end }}
|
||||||
|
</div>
|
||||||
|
{{ end }}
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user