mirror of
https://github.com/Theodor-Springmann-Stiftung/lenz-web.git
synced 2025-10-29 01:05:32 +00:00
Index functions
This commit is contained in:
@@ -17,3 +17,23 @@ type Date struct {
|
||||
Cert string `xml:"cert,attr"`
|
||||
Text string `xml:",chardata"`
|
||||
}
|
||||
|
||||
func (d *Date) Sort() *xmlparsing.XSDDate {
|
||||
if d.NotBefore.Validate() {
|
||||
return &d.NotBefore
|
||||
}
|
||||
if d.From.Validate() {
|
||||
return &d.From
|
||||
}
|
||||
if d.When.Validate() {
|
||||
return &d.When
|
||||
}
|
||||
if d.To.Validate() {
|
||||
return &d.To
|
||||
}
|
||||
if d.NotAfter.Validate() {
|
||||
return &d.NotAfter
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -2,8 +2,11 @@ package xmlmodels
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"html/template"
|
||||
"log/slog"
|
||||
"maps"
|
||||
"path/filepath"
|
||||
"slices"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
@@ -30,6 +33,8 @@ type Library struct {
|
||||
Letters *xmlparsing.XMLParser[Letter]
|
||||
Traditions *xmlparsing.XMLParser[Tradition]
|
||||
Metas *xmlparsing.XMLParser[Meta]
|
||||
|
||||
cache sync.Map
|
||||
}
|
||||
|
||||
func (l *Library) String() string {
|
||||
@@ -89,6 +94,7 @@ func (l *Library) Parse(source xmlparsing.ParseSource, baseDir, commit string) e
|
||||
// INFO: this lock prevents multiple parses from happening at the same time.
|
||||
l.mu.Lock()
|
||||
defer l.mu.Unlock()
|
||||
l.cache.Clear()
|
||||
|
||||
wg := sync.WaitGroup{}
|
||||
meta := xmlparsing.ParseMeta{
|
||||
@@ -233,3 +239,73 @@ func (l *Library) cleanup(meta xmlparsing.ParseMeta) {
|
||||
|
||||
wg.Wait()
|
||||
}
|
||||
|
||||
func (l *Library) Years() ([]int, map[int][]Meta) {
|
||||
if years, ok := l.cache.Load("years"); ok {
|
||||
if yearmap, ok := l.cache.Load("yearmap"); ok {
|
||||
return years.([]int), yearmap.(map[int][]Meta)
|
||||
}
|
||||
}
|
||||
|
||||
mapYears := make(map[int][]Meta)
|
||||
for item := range l.Metas.Iterate() {
|
||||
earliest := item.Earliest()
|
||||
if earliest != nil {
|
||||
mapYears[earliest.Sort().Year] = append(mapYears[earliest.Sort().Year], item)
|
||||
}
|
||||
}
|
||||
|
||||
ret := slices.Collect(maps.Keys(mapYears))
|
||||
slices.Sort(ret)
|
||||
|
||||
for _, items := range mapYears {
|
||||
slices.SortFunc(items, func(a, b Meta) int {
|
||||
return a.Earliest().Sort().Compare(b.Earliest().Sort())
|
||||
})
|
||||
}
|
||||
l.cache.Store("years", ret)
|
||||
l.cache.Store("yearmap", mapYears)
|
||||
return ret, mapYears
|
||||
}
|
||||
|
||||
func (l *Library) LettersForYear(year int) (ret []Meta) {
|
||||
for l := range l.Metas.Filter(func(item Meta) bool {
|
||||
return item.Earliest().Sort().Year == year
|
||||
}) {
|
||||
ret = append(ret, l)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (l *Library) Person(id int) (ret *PersonDef) {
|
||||
ret = l.Persons.Item(id)
|
||||
return
|
||||
}
|
||||
|
||||
func (l *Library) Place(id int) (ret *LocationDef) {
|
||||
ret = l.Places.Item(id)
|
||||
return
|
||||
}
|
||||
|
||||
func (l *Library) GetPersons(id []int) (ret []*PersonDef) {
|
||||
for _, i := range id {
|
||||
ret = append(ret, l.Person(i))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (l *Library) GetPlaces(id []int) (ret []*LocationDef) {
|
||||
for _, i := range id {
|
||||
ret = append(ret, l.Place(i))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (l *Library) FuncMap() template.FuncMap {
|
||||
return template.FuncMap{
|
||||
"Person": l.Person,
|
||||
"Place": l.Place,
|
||||
"Persons": l.GetPersons,
|
||||
"Places": l.GetPlaces,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package xmlmodels
|
||||
import (
|
||||
"encoding/json"
|
||||
"encoding/xml"
|
||||
"iter"
|
||||
|
||||
xmlparsing "github.com/Theodor-Springmann-Stiftung/lenz-web/xml"
|
||||
)
|
||||
@@ -17,6 +18,28 @@ type Meta struct {
|
||||
Recieved []Action `xml:"recieved"`
|
||||
}
|
||||
|
||||
func (m *Meta) Earliest() *Date {
|
||||
var earliest *Date
|
||||
|
||||
for _, action := range m.Sent {
|
||||
if earliest == nil || action.Earliest().Sort().Before(*earliest.Sort()) {
|
||||
earliest = action.Earliest()
|
||||
}
|
||||
}
|
||||
|
||||
if earliest != nil {
|
||||
return earliest
|
||||
}
|
||||
|
||||
for _, action := range m.Recieved {
|
||||
if earliest == nil || action.Earliest().Sort().Before(*earliest.Sort()) {
|
||||
earliest = action.Earliest()
|
||||
}
|
||||
}
|
||||
|
||||
return earliest
|
||||
}
|
||||
|
||||
func (m Meta) Keys() []any {
|
||||
return []any{m.Letter}
|
||||
}
|
||||
@@ -33,8 +56,30 @@ func (m Meta) String() string {
|
||||
return string(json)
|
||||
}
|
||||
|
||||
func (m Meta) SendRecieved() iter.Seq2[*Action, *Action] {
|
||||
return func(yield func(*Action, *Action) bool) {
|
||||
for i, sent := range m.Sent {
|
||||
var rec *Action
|
||||
if i < len(m.Recieved) {
|
||||
rec = &m.Recieved[i]
|
||||
}
|
||||
if !yield(&sent, rec) {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type Action struct {
|
||||
Dates []Date `xml:"date,attr"`
|
||||
Dates []Date `xml:"date"`
|
||||
Places []RefElement `xml:"place"`
|
||||
Persons []RefElement `xml:"person"`
|
||||
}
|
||||
|
||||
func (a *Action) Earliest() *Date {
|
||||
if len(a.Dates) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
return &a.Dates[0]
|
||||
}
|
||||
|
||||
@@ -27,14 +27,14 @@ func Get() *Library {
|
||||
return lib
|
||||
}
|
||||
|
||||
func New(dir, hash string) error {
|
||||
Set(NewLibrary())
|
||||
return Parse(dir, hash)
|
||||
}
|
||||
|
||||
func Parse(dir, hash string) error {
|
||||
if hash == "" {
|
||||
return lib.Parse(xmlparsing.Path, dir, hash)
|
||||
func Parse(dir, hash string) (*Library, error) {
|
||||
if lib == nil {
|
||||
Set(NewLibrary())
|
||||
}
|
||||
return lib.Parse(xmlparsing.Commit, dir, hash)
|
||||
|
||||
if hash == "" {
|
||||
return Get(), lib.Parse(xmlparsing.Path, dir, hash)
|
||||
}
|
||||
|
||||
return Get(), lib.Parse(xmlparsing.Commit, dir, hash)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user