Relationen, fehlt -PreferredTitle für Entries -Überflüssige Felder in Contents

This commit is contained in:
Simon Martens
2025-02-08 23:04:32 +01:00
parent cfce7a2dc7
commit 851de285aa
19 changed files with 844 additions and 203 deletions

1
.gitignore vendored
View File

@@ -1 +1,2 @@
pb_data/
musenalm

View File

@@ -1,6 +1,14 @@
package dbmodels
var EDITORSTATE_VALUES = []string{"Unknown", "ToDo", "Seen", "Partially Edited", "Waiting", "Edited"}
var EDITORSTATE_VALUES = []string{"Unknown", "ToDo", "Seen", "Partially Edited", "Waiting", "Review", "Edited"}
var ITEM_TYPE_VALUES = []string{
"Original",
"Reproduktion",
"Mikrofiche",
"Digitalisat",
"URL",
}
var MEDIA_TYPE_VALUES = []string{
"audio",
@@ -319,27 +327,28 @@ var MUSENALM_TYPE_VALUES = []string{
"Widmung",
}
var MUSENALM_PAGINATION_VALUES = []string{
"Römische Seitenzählung",
"Arabische Seitenzählung",
"Alphabetische Seitenzählung",
"Sonstige Seitenzählung",
"1. Arabische Seitenzählung",
"2. Arabische Seitenzählung",
"3. Arabische Seitenzählung",
"4. Arabische Seitenzählung",
"5. Arabische Seitenzählung",
"6. Arabische Seitenzählung",
"7. Arabische Seitenzählung",
"8. Arabische Seitenzählung",
"1. Römische Seitenzählung",
"2. Römische Seitenzählung",
"3. Römische Seitenzählung",
"4. Römische Seitenzählung",
"5. Römische Seitenzählung",
"6. Römische Seitenzählung",
"7. Römische Seitenzählung",
"8. Römische Seitenzählung",
var MUSENALM_PAGINATION_VALUES = map[string]string{
"": "",
"röm": "Römische Seitenzählung",
"ar": "Arabische Seitenzählung",
"alph": "Alphabetische Seitenzählung",
"sonst": "Sonstige Seitenzählung",
"ar1": "1. Arabische Seitenzählung",
"ar2": "2. Arabische Seitenzählung",
"ar3": "3. Arabische Seitenzählung",
"ar4": "4. Arabische Seitenzählung",
"ar5": "5. Arabische Seitenzählung",
"ar6": "6. Arabische Seitenzählung",
"ar7": "7. Arabische Seitenzählung",
"ar8": "8. Arabische Seitenzählung",
"röm1": "1. Römische Seitenzählung",
"röm2": "2. Römische Seitenzählung",
"röm3": "3. Römische Seitenzählung",
"röm4": "4. Römische Seitenzählung",
"röm5": "5. Römische Seitenzählung",
"röm6": "6. Römische Seitenzählung",
"röm7": "7. Römische Seitenzählung",
"röm8": "8. Römische Seitenzählung",
}
var MUSENALM_MIME_TYPES = []string{
@@ -377,6 +386,7 @@ var MUSENALM_MIME_TYPES = []string{
}
var AGENT_RELATIONS = []string{
"Schöpfer",
"Autor:in",
"Herausgeber:in",
"Verlag",
@@ -384,7 +394,12 @@ var AGENT_RELATIONS = []string{
"Vertrieb",
"Stecher:in",
"Zeichner:in",
"Komponist:in",
"Künstler:in",
"Übersetzer:in",
"Redakteur:in",
"Kartograf:in",
"Kupferstecher:in",
}
var SERIES_RELATIONS = []string{
@@ -402,7 +417,7 @@ const (
AGENTS_TABLE = "agents"
SERIES_TABLE = "series"
ENTRIES_TABLE = "entries"
PARTIALS_TABLE = "partials"
CONTENTS_TABLE = "contents"
ITEMS_TABLE = "items"
ANNOTATION_FIELD = "annotation"
@@ -462,6 +477,12 @@ const (
NUMBERING_FIELD = "numbering"
SCAN_FIELD = "scans"
ITEMS_LOCATION_FIELD = "location"
ITEMS_OWNER_FIELD = "owner"
ITEMS_MEDIA_FIELD = "media"
ITEMS_CONDITION_FIELD = "condition"
ITEMS_IDENTIFIER_FIELD = "identifier"
)
func RelationTableName(collection1, collection2 string) string {

View File

@@ -0,0 +1,73 @@
package migrations
import (
"github.com/Theodor-Springmann-Stiftung/musenalm/dbmodels"
"github.com/pocketbase/pocketbase/core"
m "github.com/pocketbase/pocketbase/migrations"
)
func init() {
m.Register(func(app core.App) error {
items := itemsTable()
items.Fields = itemsFields(app)
itemsIndexes(items)
return app.Save(items)
}, func(app core.App) error {
items, err := app.FindCollectionByNameOrId(dbmodels.ITEMS_TABLE)
if err != nil {
return nil
}
return app.Delete(items)
})
}
func itemsTable() *core.Collection {
collection := core.NewBaseCollection(dbmodels.ITEMS_TABLE)
setBasicPublicRules(collection)
return collection
}
func itemsFields(app core.App) core.FieldsList {
bcoll, err := app.FindCollectionByNameOrId(dbmodels.ENTRIES_TABLE)
if err != nil {
panic(err)
}
fields := core.NewFieldsList(
&core.RelationField{Name: dbmodels.ENTRIES_TABLE, CollectionId: bcoll.Id, Required: false},
&core.TextField{Name: dbmodels.ITEMS_IDENTIFIER_FIELD, Required: true, Presentable: true},
&core.TextField{Name: dbmodels.ITEMS_LOCATION_FIELD, Required: false, Presentable: true},
&core.TextField{Name: dbmodels.ITEMS_OWNER_FIELD, Required: false, Presentable: false},
&core.SelectField{
Name: dbmodels.ITEMS_MEDIA_FIELD,
Required: false,
Presentable: true,
Values: dbmodels.ITEM_TYPE_VALUES,
MaxSelect: len(dbmodels.ITEM_TYPE_VALUES) - 1,
},
&core.TextField{Name: dbmodels.ITEMS_CONDITION_FIELD, Required: false, Presentable: true},
&core.FileField{
Name: dbmodels.SCAN_FIELD,
Required: false,
MaxSize: 100 * 1024 * 1024,
MaxSelect: 1000,
MimeTypes: dbmodels.MUSENALM_MIME_TYPES,
Thumbs: []string{"0x300", "0x500", "0x1000", "300x0", "500x0", "1000x0"},
}, // 100 MB a file
&core.URLField{Name: dbmodels.URI_FIELD, Required: false, Presentable: false},
)
setNotesAndAnnotationsField(&fields)
return fields
}
func itemsIndexes(collection *core.Collection) {
addIndex(collection, dbmodels.ITEMS_CONDITION_FIELD, false)
addIndex(collection, dbmodels.ITEMS_OWNER_FIELD, false)
addIndex(collection, dbmodels.ITEMS_LOCATION_FIELD, false)
addIndex(collection, dbmodels.ITEMS_IDENTIFIER_FIELD, false)
addIndex(collection, dbmodels.URI_FIELD, false)
}

View File

@@ -2,6 +2,8 @@ package migrations
import (
"errors"
"maps"
"slices"
"github.com/Theodor-Springmann-Stiftung/musenalm/dbmodels"
"github.com/pocketbase/pocketbase/core"
@@ -21,7 +23,7 @@ func init() {
return app.Save(partials)
}, func(app core.App) error {
partials, err := app.FindCollectionByNameOrId(dbmodels.PARTIALS_TABLE)
partials, err := app.FindCollectionByNameOrId(dbmodels.CONTENTS_TABLE)
if err != nil {
return nil
}
@@ -31,7 +33,7 @@ func init() {
}
func partialsTable() *core.Collection {
collection := core.NewBaseCollection(dbmodels.PARTIALS_TABLE)
collection := core.NewBaseCollection(dbmodels.CONTENTS_TABLE)
setBasicPublicRules(collection)
return collection
}
@@ -46,7 +48,7 @@ func partialsFields(app core.App) *core.FieldsList {
// Title information
&core.TextField{Name: dbmodels.PREFERRED_TITLE_FIELD, Required: true, Presentable: true},
&core.TextField{Name: dbmodels.VARIANT_TITLE_FIELD, Required: false, Presentable: false},
&core.BoolField{Name: dbmodels.PARALLEL_TITLE_FIELD, Required: false},
&core.TextField{Name: dbmodels.PARALLEL_TITLE_FIELD, Required: false},
// Transcribed information
&core.TextField{Name: dbmodels.TITLE_STMT_FIELD, Required: false, Presentable: false},
@@ -101,7 +103,7 @@ func partialsFields(app core.App) *core.FieldsList {
&core.SelectField{
Name: dbmodels.MUSENALM_PAGINATION_FIELD,
Required: false,
Values: dbmodels.MUSENALM_PAGINATION_VALUES,
Values: slices.Collect(maps.Values(dbmodels.MUSENALM_PAGINATION_VALUES)),
MaxSelect: len(dbmodels.MUSENALM_PAGINATION_VALUES),
},
&core.FileField{

View File

@@ -8,14 +8,14 @@ import (
func init() {
m.Register(func(app core.App) error {
collections, err := basicRelationCollection(app, dbmodels.PARTIALS_TABLE, dbmodels.AGENTS_TABLE, dbmodels.AGENT_RELATIONS)
collections, err := basicRelationCollection(app, dbmodels.CONTENTS_TABLE, dbmodels.AGENTS_TABLE, dbmodels.AGENT_RELATIONS)
if err != nil {
return err
}
return app.Save(collections)
}, func(app core.App) error {
collection, err := app.FindCollectionByNameOrId(dbmodels.RelationTableName(dbmodels.PARTIALS_TABLE, dbmodels.AGENTS_TABLE))
collection, err := app.FindCollectionByNameOrId(dbmodels.RelationTableName(dbmodels.CONTENTS_TABLE, dbmodels.AGENTS_TABLE))
if err != nil {
return nil
}

View File

@@ -1,6 +1,8 @@
package migrations
import (
"sync"
"github.com/Theodor-Springmann-Stiftung/musenalm/dbmodels"
"github.com/Theodor-Springmann-Stiftung/musenalm/migrations/seed"
"github.com/Theodor-Springmann-Stiftung/musenalm/xmlmodels"
@@ -10,17 +12,98 @@ import (
func init() {
m.Register(func(app core.App) error {
adb, err := xmlmodels.ReadAccessDB(xmlmodels.DATA_PATH)
adb, err := xmlmodels.ReadAccessDB(xmlmodels.DATA_PATH, app.Logger())
if err != nil {
return err
}
*adb.Reihen = xmlmodels.SanitizeReihen(*adb.Reihen, *adb.Relationen_Bände_Reihen)
adb.Reihen = xmlmodels.SanitizeReihen(adb.Reihen, adb.Relationen_Bände_Reihen)
wg := sync.WaitGroup{}
wg.Add(3)
go func() {
if records, err := seed.RecordsFromAkteure(app, adb.Akteure); err == nil {
if err = seed.BatchSave(app, records); err != nil {
panic(err)
}
} else {
panic(err)
}
wg.Done()
}()
go func() {
if records, err := seed.RecordsFromOrte(app, adb.Orte); err == nil {
if err = seed.BatchSave(app, records); err != nil {
panic(err)
}
} else {
panic(err)
}
wg.Done()
}()
go func() {
if records, err := seed.RecordsFromReihentitel(app, adb.Reihen); err == nil {
if err = seed.BatchSave(app, records); err != nil {
panic(err)
}
} else {
panic(err)
}
wg.Done()
}()
wg.Wait()
if records, err := seed.RecordsFromBände(app, adb.Bände, adb.Orte); err == nil {
if err = seed.BatchSave(app, records); err != nil {
panic(err)
}
} else {
panic(err)
}
if records, err := seed.ItemsFromBändeAndBIBLIO(app, adb.Bände, adb.BIBLIO); err == nil {
if err = seed.BatchSave(app, records); err != nil {
panic(err)
}
} else {
panic(err)
}
if records, err := seed.RecordsFromInhalte(app, adb.Inhalte); err == nil {
if err = seed.BatchSave(app, records); err != nil {
panic(err)
}
} else {
panic(err)
}
if records, err := seed.RecordsFromRelationBändeReihen(app, adb.Relationen_Bände_Reihen); err == nil {
if err = seed.BatchSave(app, records); err != nil {
panic(err)
}
} else {
panic(err)
}
if records, err := seed.RecordsFromRelationBändeAkteure(app, adb.Relationen_Bände_Akteure); err == nil {
if err = seed.BatchSave(app, records); err != nil {
panic(err)
}
} else {
panic(err)
}
if records, err := seed.RecordsFromRelationInhalteAkteure(app, adb.Relationen_Inhalte_Akteure); err == nil {
if err = seed.BatchSave(app, records); err != nil {
panic(err)
}
} else {
panic(err)
}
seed.SeedTableAgents(app, *adb.Akteure)
seed.SeedTablePlaces(app, *adb.Orte)
seed.SeedTableSeries(app, *adb.Reihen)
seed.SeedTableEntries(app, *adb.Bände, *adb.BIBLIO, *adb.Orte)
return nil
}, func(app core.App) error {
return delete_data(app)
@@ -30,8 +113,8 @@ func init() {
func delete_data(app core.App) error {
_ = deleteTableContents(app, dbmodels.RelationTableName(dbmodels.ENTRIES_TABLE, dbmodels.SERIES_TABLE))
_ = deleteTableContents(app, dbmodels.RelationTableName(dbmodels.ENTRIES_TABLE, dbmodels.AGENTS_TABLE))
_ = deleteTableContents(app, dbmodels.RelationTableName(dbmodels.PARTIALS_TABLE, dbmodels.AGENTS_TABLE))
_ = deleteTableContents(app, dbmodels.PARTIALS_TABLE)
_ = deleteTableContents(app, dbmodels.RelationTableName(dbmodels.CONTENTS_TABLE, dbmodels.AGENTS_TABLE))
_ = deleteTableContents(app, dbmodels.CONTENTS_TABLE)
_ = deleteTableContents(app, dbmodels.ENTRIES_TABLE)
_ = deleteTableContents(app, dbmodels.SERIES_TABLE)
_ = deleteTableContents(app, dbmodels.AGENTS_TABLE)

View File

@@ -8,11 +8,12 @@ import (
"github.com/pocketbase/pocketbase/core"
)
func SeedTableAgents(app core.App, akteure xmlmodels.Akteure) error {
func RecordsFromAkteure(app core.App, akteure xmlmodels.Akteure) ([]*core.Record, error) {
collection, err := app.FindCollectionByNameOrId(dbmodels.AGENTS_TABLE)
records := make([]*core.Record, 0, len(akteure.Akteure))
if err != nil {
fmt.Println(err)
return records, err
}
for i := 0; i < len(akteure.Akteure); i++ {
@@ -37,5 +38,5 @@ func SeedTableAgents(app core.App, akteure xmlmodels.Akteure) error {
records = append(records, record)
}
return batchSave(app, records)
return records, nil
}

View File

@@ -13,7 +13,7 @@ func NormalizeString(s string) string {
return s
}
func batchSave(app core.App, records []*core.Record) error {
func BatchSave(app core.App, records []*core.Record) error {
app.RunInTransaction(func(txapp core.App) error {
for _, record := range records {
if err := txapp.Save(record); err != nil {

View File

@@ -2,8 +2,6 @@ package seed
import (
"fmt"
"regexp"
"strconv"
"strings"
"github.com/Theodor-Springmann-Stiftung/musenalm/dbmodels"
@@ -12,24 +10,23 @@ import (
"github.com/pocketbase/pocketbase/core"
)
func SeedTableEntries(
func RecordsFromBände(
app core.App,
entries xmlmodels.Bände,
biblio map[int]xmlmodels.BIBLIOEintrag,
orte xmlmodels.Orte,
) error {
) ([]*core.Record, error) {
collection, err := app.FindCollectionByNameOrId(dbmodels.ENTRIES_TABLE)
records := make([]*core.Record, 0, len(entries.Bände))
r := regexp.MustCompile("\\d{6}")
if err != nil {
fmt.Println(err)
return records, err
}
omap := datatypes.MakeMap(orte.Orte, func(o xmlmodels.Ort) string { return o.ID })
ocoll, err := app.FindCollectionByNameOrId(dbmodels.PLACES_TABLE)
if err != nil {
app.Logger().Error("Error finding collection", "error", err, "collection", dbmodels.PLACES_TABLE)
return err
return records, err
}
for i := 0; i < len(entries.Bände); i++ {
@@ -68,13 +65,12 @@ func SeedTableEntries(
}
handleDeprecated(record, band)
handleItems(r, band, &biblio, record)
handleOrte(record, band, omap, app, ocoll)
records = append(records, record)
}
return batchSave(app, records)
return records, nil
}
func handleOrte(
@@ -134,91 +130,3 @@ func handleDeprecated(record *core.Record, band xmlmodels.Band) {
record.Set(dbmodels.MUSENALM_DEPRECATED_FIELD, depr)
}
func handleItems(r *regexp.Regexp, band xmlmodels.Band, biblio *map[int]xmlmodels.BIBLIOEintrag, record *core.Record) {
nst := NormalizeString(band.Norm)
matches := r.FindAllStringSubmatchIndex(nst, -1)
t := map[string]string{}
for i, m := range matches {
nr := nst[m[0]:m[1]]
end := len(nst)
if m[1] >= len(nst) {
t[nr] = ""
continue
}
if len(matches)-1 > i {
end = matches[i+1][0]
}
rest := nst[m[1]:end]
var last []rune
for y, c := range rest {
if c == '\\' && y < len(rest)-1 && rest[y+1] == ')' {
break
}
if c != '(' && c != ')' {
last = append(last, c)
}
}
if last != nil && len(last) > 0 {
t[nr] = string(last)
}
}
var exemlist []dbmodels.Exemplar
if band.BiblioID != 0 {
exem := dbmodels.Exemplar{Identifier: strconv.Itoa(band.BiblioID)}
if e, ok := (*biblio)[band.BiblioID]; ok {
exem.Location = strings.TrimSpace(e.Standort)
exem.Condition = strings.TrimSpace(e.Zustand)
message := ""
message = appendMessage(e.NotizÄusseres, message)
message = appendMessage(e.NotizInhalt, message)
message = appendMessage(e.Anmerkungen, message)
exem.Annotation = message
}
exemlist = append(exemlist, exem)
}
for nr, m := range t {
exem := dbmodels.Exemplar{Identifier: nr}
no, err := strconv.Atoi(strings.TrimSpace(nr))
message := strings.TrimSpace(m)
if err != nil {
if e, ok := (*biblio)[no]; ok {
exem.Location = strings.TrimSpace(e.Standort)
exem.Condition = strings.TrimSpace(e.Zustand)
message = appendMessage(e.NotizÄusseres, message)
message = appendMessage(e.NotizInhalt, message)
message = appendMessage(e.Anmerkungen, message)
}
}
exem.Annotation = message
if exem.Identifier != "" {
exemlist = append(exemlist, exem)
}
}
if len(exemlist) > 0 {
record.Set(dbmodels.ITEMS_TABLE, exemlist)
}
}
func appendMessage(message string, toAppend string) string {
notiza := strings.TrimSpace(toAppend)
if notiza != "" {
if message != "" {
message += "\n"
}
message += notiza
}
return message
}

144
migrations/seed/items.go Normal file
View File

@@ -0,0 +1,144 @@
package seed
import (
"fmt"
"regexp"
"slices"
"strconv"
"strings"
"github.com/Theodor-Springmann-Stiftung/musenalm/dbmodels"
"github.com/Theodor-Springmann-Stiftung/musenalm/xmlmodels"
"github.com/pocketbase/pocketbase/core"
)
func ItemsFromBändeAndBIBLIO(
app core.App,
entries xmlmodels.Bände,
biblio map[int]xmlmodels.BIBLIOEintrag,
) ([]*core.Record, error) {
collection, err := app.FindCollectionByNameOrId(dbmodels.ITEMS_TABLE)
records := make([]*core.Record, 0, len(entries.Bände))
r := regexp.MustCompile("\\d{6}")
if err != nil {
fmt.Println(err)
return records, err
}
for i := 0; i < len(entries.Bände); i++ {
band := entries.Bände[i]
banddb, err := app.FindFirstRecordByData(dbmodels.ENTRIES_TABLE, dbmodels.MUSENALMID_FIELD, band.ID)
if err != nil {
app.Logger().Error("Error finding record", "error", err, "collection", dbmodels.ENTRIES_TABLE, "field", dbmodels.MUSENALMID_FIELD, "value", band.ID)
continue
}
nst := NormalizeString(band.Norm)
matches := r.FindAllStringSubmatchIndex(nst, -1)
t := map[string]string{}
for i, m := range matches {
nr := nst[m[0]:m[1]]
end := len(nst)
if m[1] >= len(nst) {
t[nr] = ""
continue
}
if len(matches)-1 > i {
end = matches[i+1][0]
}
rest := nst[m[1]:end]
var last []rune
for y, c := range rest {
if c == '\\' && y < len(rest)-1 && rest[y+1] == ')' {
break
}
if c != '(' && c != ')' {
last = append(last, c)
}
}
if last != nil && len(last) > 0 {
t[nr] = string(last)
}
}
var exemlist []dbmodels.Exemplar
if band.BiblioID != 0 {
exem := dbmodels.Exemplar{Identifier: strconv.Itoa(band.BiblioID)}
if e, ok := biblio[band.BiblioID]; ok {
exem.Location = strings.TrimSpace(e.Standort)
exem.Condition = strings.TrimSpace(e.Zustand)
message := ""
message = appendMessage(e.NotizÄusseres, message)
message = appendMessage(e.NotizInhalt, message)
message = appendMessage(e.Anmerkungen, message)
exem.Annotation = message
}
exemlist = append(exemlist, exem)
}
for nr, m := range t {
exem := dbmodels.Exemplar{Identifier: nr}
no, err := strconv.Atoi(strings.TrimSpace(nr))
message := strings.TrimSpace(m)
if err != nil {
if e, ok := biblio[no]; ok {
exem.Location = strings.TrimSpace(e.Standort)
exem.Condition = strings.TrimSpace(e.Zustand)
message = appendMessage(e.NotizÄusseres, message)
message = appendMessage(e.NotizInhalt, message)
message = appendMessage(e.Anmerkungen, message)
}
}
exem.Annotation = message
if exem.Identifier != "" {
exemlist = append(exemlist, exem)
}
}
if len(exemlist) > 0 {
for _, exem := range exemlist {
record := core.NewRecord(collection)
record.Set(dbmodels.ENTRIES_TABLE, banddb.Id)
record.Set(dbmodels.ITEMS_IDENTIFIER_FIELD, exem.Identifier)
record.Set(dbmodels.ITEMS_LOCATION_FIELD, exem.Location)
record.Set(dbmodels.ITEMS_OWNER_FIELD, "Theodor Springmann Stiftung")
record.Set(dbmodels.ITEMS_CONDITION_FIELD, exem.Condition)
if slices.Contains(band.Status.Value, "Original vorhanden") {
record.Set(dbmodels.ITEMS_MEDIA_FIELD, dbmodels.ITEM_TYPE_VALUES[0])
}
if slices.Contains(band.Status.Value, "Reprint vorhanden") {
med := record.GetStringSlice(dbmodels.ITEMS_MEDIA_FIELD)
record.Set(dbmodels.ITEMS_MEDIA_FIELD, append(med, dbmodels.ITEM_TYPE_VALUES[1]))
}
record.Set(dbmodels.ANNOTATION_FIELD, exem.Annotation)
records = append(records, record)
}
}
}
return records, nil
}
func appendMessage(message string, toAppend string) string {
notiza := strings.TrimSpace(toAppend)
if notiza != "" {
if message != "" {
message += "\n"
}
message += notiza
}
return message
}

View File

@@ -0,0 +1,98 @@
package seed
import (
"fmt"
"strings"
"github.com/Theodor-Springmann-Stiftung/musenalm/dbmodels"
"github.com/Theodor-Springmann-Stiftung/musenalm/xmlmodels"
"github.com/pocketbase/pocketbase/core"
)
func RecordsFromInhalte(app core.App, inhalte xmlmodels.Inhalte) ([]*core.Record, error) {
collection, err := app.FindCollectionByNameOrId(dbmodels.CONTENTS_TABLE)
records := make([]*core.Record, 0, len(inhalte.Inhalte))
if err != nil {
fmt.Println(err)
return records, err
}
for i := 0; i < len(inhalte.Inhalte); i++ {
record := core.NewRecord(collection)
inhalt := inhalte.Inhalte[i]
band, err := app.FindFirstRecordByData(dbmodels.ENTRIES_TABLE, dbmodels.MUSENALMID_FIELD, inhalt.Band)
if err != nil {
app.Logger().Error("Error finding band record for inhalt", "error", err, "inhalt", inhalt)
continue
}
record.Set(dbmodels.ENTRIES_TABLE, band.Id)
record.Set(dbmodels.ANNOTATION_FIELD, NormalizeString(inhalt.Anmerkungen))
record.Set(dbmodels.MUSENALMID_FIELD, inhalt.ID)
record.Set(dbmodels.RESPONSIBILITY_STMT_FIELD, NormalizeString(inhalt.Urheberangabe))
record.Set(dbmodels.MUSENALM_INHALTE_TYPE_FIELD, inhalt.Typ.Value)
record.Set(dbmodels.EXTENT_FIELD, NormalizeString(inhalt.Seite))
record.Set(dbmodels.TITLE_STMT_FIELD, NormalizeString(inhalt.Titelangabe))
record.Set(dbmodels.INCIPIT_STMT_FIELD, NormalizeString(inhalt.Incipit))
counting, ok := dbmodels.MUSENALM_PAGINATION_VALUES[inhalt.Paginierung]
if ok {
record.Set(dbmodels.MUSENALM_PAGINATION_FIELD, counting)
}
record.Set(dbmodels.NUMBERING_FIELD, NormalizeString(inhalt.Objektnummer))
handlePreferredTitle(inhalt, record)
n := record.GetString(dbmodels.PREFERRED_TITLE_FIELD)
if n == "" || n == "No Title" {
record.Set(dbmodels.EDITSTATE_FIELD, dbmodels.EDITORSTATE_VALUES[1])
} else {
record.Set(dbmodels.EDITSTATE_FIELD, dbmodels.EDITORSTATE_VALUES[len(dbmodels.EDITORSTATE_VALUES)-1])
}
records = append(records, record)
}
return records, nil
}
func handlePreferredTitle(inhalt xmlmodels.Inhalt, record *core.Record) {
if inhalt.Titelangabe != "" {
record.Set(dbmodels.PREFERRED_TITLE_FIELD, NormalizeString(inhalt.Titelangabe))
return
}
if inhalt.Incipit != "" {
record.Set(dbmodels.PREFERRED_TITLE_FIELD, NormalizeString(inhalt.Incipit)+"…")
return
}
if len(inhalt.Typ.Value) > 0 {
str := commatizeArray(inhalt.Typ.Value)
if str != "" {
if inhalt.Urheberangabe != "" &&
!strings.Contains(inhalt.Urheberangabe, "unbezeichnet") &&
!strings.Contains(inhalt.Urheberangabe, "unbekannt") &&
!strings.Contains(inhalt.Urheberangabe, "unleserlich") {
urhh := NormalizeString(inhalt.Urheberangabe)
urhh = strings.ReplaceAll(urhh, "#", "")
urhh = NormalizeString(urhh)
str += " (" + urhh + ")"
}
record.Set(dbmodels.PREFERRED_TITLE_FIELD, "["+str+"]")
return
}
}
record.Set(dbmodels.PREFERRED_TITLE_FIELD, "[Kein Titel]")
}
func commatizeArray(array []string) string {
if len(array) == 0 {
return ""
}
res := array[0]
for i := 1; i < len(array)-1; i++ {
res += ", " + array[i]
}
return array[0]
}

View File

@@ -8,11 +8,12 @@ import (
"github.com/pocketbase/pocketbase/core"
)
func SeedTablePlaces(app core.App, orte xmlmodels.Orte) error {
func RecordsFromOrte(app core.App, orte xmlmodels.Orte) ([]*core.Record, error) {
collection, err := app.FindCollectionByNameOrId(dbmodels.PLACES_TABLE)
records := make([]*core.Record, 0, len(orte.Orte))
if err != nil {
fmt.Println(err)
return records, err
}
for i := 0; i < len(orte.Orte); i++ {
@@ -33,5 +34,5 @@ func SeedTablePlaces(app core.App, orte xmlmodels.Orte) error {
records = append(records, record)
}
return batchSave(app, records)
return records, nil
}

View File

@@ -0,0 +1,144 @@
package seed
import (
"slices"
"strings"
"github.com/Theodor-Springmann-Stiftung/musenalm/dbmodels"
"github.com/Theodor-Springmann-Stiftung/musenalm/xmlmodels"
"github.com/pocketbase/pocketbase/core"
)
func RecordsFromRelationInhalteAkteure(app core.App, relations xmlmodels.Relationen_Inhalte_Akteure) ([]*core.Record, error) {
records := make([]*core.Record, 0, len(relations.Relationen))
collection, err := app.FindCollectionByNameOrId(dbmodels.RelationTableName(dbmodels.CONTENTS_TABLE, dbmodels.AGENTS_TABLE))
if err != nil {
app.Logger().Error("Error finding collection", "error", err, "collection", dbmodels.RelationTableName(dbmodels.CONTENTS_TABLE, dbmodels.AGENTS_TABLE))
return nil, err
}
for _, relation := range relations.Relationen {
content, err := app.FindFirstRecordByData(dbmodels.CONTENTS_TABLE, dbmodels.MUSENALMID_FIELD, relation.Inhalt)
if err != nil {
app.Logger().Error("Error finding Inhalt", "error", err, "relation", relation)
continue
}
agent, err := app.FindFirstRecordByData(dbmodels.AGENTS_TABLE, dbmodels.MUSENALMID_FIELD, relation.Akteur)
if err != nil {
app.Logger().Error("Error finding Content", "error", err, "relation", relation)
continue
}
record := core.NewRecord(collection)
record.Set(dbmodels.CONTENTS_TABLE, content.Id)
record.Set(dbmodels.AGENTS_TABLE, agent.Id)
switch relation.Relation {
case "1":
record.Set(dbmodels.RELATION_TYPE_FIELD, "Schöpfer")
cat := content.GetStringSlice(dbmodels.MUSENALM_INHALTE_TYPE_FIELD)
ber := agent.GetString(dbmodels.AGENTS_PROFESSION_FIELD)
probt := 0
probm := 0
probg := 0
if slices.ContainsFunc(cat, isProse) {
probt += 1
} else {
probt -= 1
}
if Text(ber) {
if probt > 0 {
probt += 1
}
probt += 1
}
if slices.ContainsFunc(cat, isMusic) {
probm += 1
} else {
probm -= 1
}
if Musik(ber) {
if probm > 0 {
probm += 1
}
probm += 1
}
if slices.ContainsFunc(cat, isGraph) {
probg += 1
} else {
probg -= 1
}
if Graphiker(ber) {
if probg > 0 {
probg += 1
}
probg += 1
}
if probt == 3 && probm <= 1 && probg <= 1 {
record.Set(dbmodels.RELATION_TYPE_FIELD, "Autor:in")
break
}
if probm == 3 && probt <= 1 && probg <= 1 {
record.Set(dbmodels.RELATION_TYPE_FIELD, "Komponist:in")
break
}
if probg == 3 && probt <= 1 && probm <= 1 {
record.Set(dbmodels.RELATION_TYPE_FIELD, "Künstler:in")
break
}
record.Set(dbmodels.RELATION_TYPE_FIELD, "Schöpfer")
case "2":
record.Set(dbmodels.RELATION_TYPE_FIELD, "Autor:in")
case "3":
record.Set(dbmodels.RELATION_TYPE_FIELD, "Zeichner:in")
case "4":
record.Set(dbmodels.RELATION_TYPE_FIELD, "Kupferstecher:in")
}
rel := record.GetString(dbmodels.RELATION_TYPE_FIELD)
ent := record.GetString(dbmodels.CONTENTS_TABLE)
ser := record.GetString(dbmodels.AGENTS_TABLE)
if strings.TrimSpace(rel) == "" || strings.TrimSpace(ent) == "" || strings.TrimSpace(ser) == "" {
content.Set(dbmodels.EDITSTATE_FIELD, dbmodels.EDITORSTATE_VALUES[len(dbmodels.EDITORSTATE_VALUES)-2])
_ = app.Save(content)
}
records = append(records, record)
}
return records, err
}
func isProse(cat string) bool {
return cat == "Corrigenda" || cat == "Gedicht/Lied" || cat == "Motto" || cat == "Kalendarium" || cat == "Tabelle" || cat == "Inhaltsverzeichnis" || cat == "Text" || cat == "Prosa"
}
func isGraph(cat string) bool {
return strings.HasPrefix(cat, "graph") || cat == "Graphik"
}
func Graphiker(beruf string) bool {
return strings.Contains(beruf, "Graphik")
}
func Text(beruf string) bool {
return strings.Contains(beruf, "Text")
}
func Musik(beruf string) bool {
return strings.Contains(beruf, "Musik")
}
func isMusic(cat string) bool {
return cat == "Gedicht/Lied" || cat == "Musikbeigabe"
}

View File

@@ -0,0 +1,59 @@
package seed
import (
"strings"
"github.com/Theodor-Springmann-Stiftung/musenalm/dbmodels"
"github.com/Theodor-Springmann-Stiftung/musenalm/xmlmodels"
"github.com/pocketbase/pocketbase/core"
)
func RecordsFromRelationBändeAkteure(app core.App, relations xmlmodels.Relationen_Bände_Akteure) ([]*core.Record, error) {
records := make([]*core.Record, 0, len(relations.Relationen))
collection, err := app.FindCollectionByNameOrId(dbmodels.RelationTableName(dbmodels.ENTRIES_TABLE, dbmodels.AGENTS_TABLE))
if err != nil {
app.Logger().Error("Error finding collection", "error", err, "collection", dbmodels.RelationTableName(dbmodels.CONTENTS_TABLE, dbmodels.AGENTS_TABLE))
return nil, err
}
for _, relation := range relations.Relationen {
entry, err := app.FindFirstRecordByData(dbmodels.ENTRIES_TABLE, dbmodels.MUSENALMID_FIELD, relation.Band)
if err != nil {
app.Logger().Error("Error finding Entry", "error", err, "relation", relation)
continue
}
agent, err := app.FindFirstRecordByData(dbmodels.AGENTS_TABLE, dbmodels.MUSENALMID_FIELD, relation.Akteur)
if err != nil {
app.Logger().Error("Error finding Agent", "error", err, "relation", relation)
continue
}
record := core.NewRecord(collection)
record.Set(dbmodels.ENTRIES_TABLE, entry.Id)
record.Set(dbmodels.AGENTS_TABLE, agent.Id)
switch relation.Relation {
case "8":
record.Set(dbmodels.RELATION_TYPE_FIELD, "Vertrieb")
case "7":
record.Set(dbmodels.RELATION_TYPE_FIELD, "Druck")
case "6":
record.Set(dbmodels.RELATION_TYPE_FIELD, "Verlag")
case "5":
record.Set(dbmodels.RELATION_TYPE_FIELD, "Herausgeber:in")
}
rel := record.GetString(dbmodels.RELATION_TYPE_FIELD)
ent := record.GetString(dbmodels.ENTRIES_TABLE)
ser := record.GetString(dbmodels.AGENTS_TABLE)
if strings.TrimSpace(rel) == "" || strings.TrimSpace(ent) == "" || strings.TrimSpace(ser) == "" {
entry.Set(dbmodels.EDITSTATE_FIELD, dbmodels.EDITORSTATE_VALUES[len(dbmodels.EDITORSTATE_VALUES)-2])
_ = app.Save(entry)
}
records = append(records, record)
}
return records, nil
}

View File

@@ -0,0 +1,68 @@
package seed
import (
"strings"
"github.com/Theodor-Springmann-Stiftung/musenalm/dbmodels"
"github.com/Theodor-Springmann-Stiftung/musenalm/xmlmodels"
"github.com/pocketbase/pocketbase/core"
)
func RecordsFromRelationBändeReihen(app core.App, relations xmlmodels.Relationen_Bände_Reihen) ([]*core.Record, error) {
records := make([]*core.Record, 0, len(relations.Relationen))
collection, err := app.FindCollectionByNameOrId(dbmodels.RelationTableName(dbmodels.ENTRIES_TABLE, dbmodels.SERIES_TABLE))
if err != nil {
app.Logger().Error("Error finding collection", "error", err, "collection", dbmodels.RelationTableName(dbmodels.ENTRIES_TABLE, dbmodels.SERIES_TABLE))
return nil, err
}
for _, relation := range relations.Relationen {
entry, err := app.FindFirstRecordByData(dbmodels.ENTRIES_TABLE, dbmodels.MUSENALMID_FIELD, relation.Band)
if err != nil {
app.Logger().Error("Error finding Entry", "error", err, "relation", relation)
continue
}
series, err := app.FindFirstRecordByData(dbmodels.SERIES_TABLE, dbmodels.MUSENALMID_FIELD, relation.Reihe)
if err != nil {
app.Logger().Error("Error finding Series", "error", err, "relation", relation)
continue
}
record := core.NewRecord(collection)
record.Set(dbmodels.ENTRIES_TABLE, entry.Id)
record.Set(dbmodels.SERIES_TABLE, series.Id)
switch relation.Relation {
case "1":
record.Set(dbmodels.RELATION_TYPE_FIELD, "Bevorzugter Reihentitel")
case "2":
record.Set(dbmodels.RELATION_TYPE_FIELD, "Alternativer Reihentitel")
case "3":
record.Set(dbmodels.RELATION_TYPE_FIELD, "In anderer Sprache")
case "4":
entry.Set(dbmodels.LANGUAGE_FIELD, "fre")
_ = app.Save(entry)
record.Set(dbmodels.RELATION_TYPE_FIELD, "In anderer Sprache")
case "5":
record.Set(dbmodels.RELATION_TYPE_FIELD, "Alternativer Reihentitel")
case "6":
record.Set(dbmodels.RELATION_TYPE_FIELD, "Früherer Reihentitel")
case "7":
record.Set(dbmodels.RELATION_TYPE_FIELD, "Späterer Reihentitel")
}
rel := record.GetString(dbmodels.RELATION_TYPE_FIELD)
ent := record.GetString(dbmodels.ENTRIES_TABLE)
ser := record.GetString(dbmodels.SERIES_TABLE)
if strings.TrimSpace(rel) == "" || strings.TrimSpace(ent) == "" || strings.TrimSpace(ser) == "" {
entry.Set(dbmodels.EDITSTATE_FIELD, dbmodels.EDITORSTATE_VALUES[len(dbmodels.EDITORSTATE_VALUES)-2])
_ = app.Save(entry)
}
records = append(records, record)
}
return records, nil
}

View File

@@ -8,11 +8,12 @@ import (
"github.com/pocketbase/pocketbase/core"
)
func SeedTableSeries(app core.App, reihen xmlmodels.Reihentitel) error {
func RecordsFromReihentitel(app core.App, reihen xmlmodels.Reihentitel) ([]*core.Record, error) {
collection, err := app.FindCollectionByNameOrId(dbmodels.SERIES_TABLE)
records := make([]*core.Record, 0, len(reihen.Reihen))
if err != nil {
fmt.Println(err)
return records, err
}
for i := 0; i < len(reihen.Reihen); i++ {
@@ -39,5 +40,5 @@ func SeedTableSeries(app core.App, reihen xmlmodels.Reihentitel) error {
records = append(records, record)
}
return batchSave(app, records)
return records, nil
}

3
scripts/reset.sh Executable file
View File

@@ -0,0 +1,3 @@
#!/bin/bash
rm -rf pb_data/

View File

@@ -4,24 +4,26 @@ import (
"encoding/xml"
"fmt"
"io"
"log/slog"
"os"
"sync"
"github.com/Theodor-Springmann-Stiftung/musenalm/helpers/datatypes"
)
type AccessDB struct {
Orte *Orte
Akteure *Akteure
Reihen *Reihentitel
Bände *Bände
Inhalte *Inhalte
Relationen_Bände_Akteure *Relationen_Bände_Akteure
Relationen_Inhalte_Akteure *Relationen_Inhalte_Akteure
Relationen_Bände_Reihen *Relationen_Bände_Reihen
BIBLIO *map[int]BIBLIOEintrag
Orte Orte
Akteure Akteure
Reihen Reihentitel
Bände Bände
Inhalte Inhalte
Relationen_Bände_Akteure Relationen_Bände_Akteure
Relationen_Inhalte_Akteure Relationen_Inhalte_Akteure
Relationen_Bände_Reihen Relationen_Bände_Reihen
BIBLIO map[int]BIBLIOEintrag
}
func ReadAccessDB(path string) (*AccessDB, error) {
func ReadAccessDB(path string, logger *slog.Logger) (*AccessDB, error) {
var Akteure Akteure
var Reihentitel Reihentitel
var Bände Bände
@@ -32,57 +34,89 @@ func ReadAccessDB(path string) (*AccessDB, error) {
var Relationen_Inhalte_Akteure Relationen_Inhalte_Akteure
var BIBLIO BIBLIOEinträge
if err := unmarshalFile(path+"Akteure.xml", &Akteure); err != nil {
return nil, err
}
if err := unmarshalFile(path+"Orte.xml", &Orte); err != nil {
return nil, err
}
if err := unmarshalFile(path+"Reihen.xml", &Reihentitel); err != nil {
return nil, err
}
if err := unmarshalFile(path+"Baende.xml", &Bände); err != nil {
return nil, err
}
if err := unmarshalFile(path+"Inhalte.xml", &Inhalte); err != nil {
return nil, err
}
if err := unmarshalFile(path+"_RELATION_BaendeAkteure.xml", &Relationen_Bände_Akteure); err != nil {
return nil, err
}
if err := unmarshalFile(path+"_RELATION_BaendeReihen.xml", &Relationen_Bände_Reihen); err != nil {
return nil, err
}
if err := unmarshalFile(path+"_RELATION_InhalteAkteure.xml", &Relationen_Inhalte_Akteure); err != nil {
return nil, err
}
var DB AccessDB
wg := sync.WaitGroup{}
wg.Add(9)
go func() {
if err := unmarshalFile(path+"GM-BIBLIO.xml", &BIBLIO); err != nil {
return nil, err
logger.Error("Error while unmarshalling GM-BIBLIO.xml: ", "error", err, "path", path+"GM-BIBLIO.xml")
}
DB.BIBLIO = datatypes.MakeMap(BIBLIO.Einträge, func(e BIBLIOEintrag) int { return e.Nummer })
wg.Done()
}()
go func() {
if err := unmarshalFile(path+"Akteure.xml", &Akteure); err != nil {
logger.Error("Error while unmarshalling Akteure.xml: ", "error", err, "path", path+"Akteure.xml")
}
DB.Akteure = Akteure
wg.Done()
}()
go func() {
if err := unmarshalFile(path+"Orte.xml", &Orte); err != nil {
logger.Error("Error while unmarshalling Orte.xml: ", "error", err, "path", path+"Orte.xml")
}
DB.Orte = Orte
wg.Done()
}()
go func() {
if err := unmarshalFile(path+"Reihen.xml", &Reihentitel); err != nil {
logger.Error("Error while unmarshalling Reihen.xml: ", "error", err, "path", path+"Reihen.xml")
}
DB.Reihen = Reihentitel
wg.Done()
}()
go func() {
if err := unmarshalFile(path+"Baende.xml", &Bände); err != nil {
logger.Error("Error while unmarshalling Baende.xml: ", "error", err, "path", path+"Baende.xml")
}
DB.Bände = Bände
wg.Done()
}()
go func() {
if err := unmarshalFile(path+"Inhalte.xml", &Inhalte); err != nil {
logger.Error("Error while unmarshalling Inhalte.xml: ", "error", err, "path", path+"Inhalte.xml")
}
DB.Inhalte = Inhalte
wg.Done()
}()
go func() {
if err := unmarshalFile(path+"_RELATION_BaendeAkteure.xml", &Relationen_Bände_Akteure); err != nil {
logger.Error("Error while unmarshalling RELATION_BaendeAkteure.xml: ", "error", err, "path", path+"_RELATION_BaendeAkteure.xml")
}
DB.Relationen_Bände_Akteure = Relationen_Bände_Akteure
wg.Done()
}()
go func() {
if err := unmarshalFile(path+"_RELATION_BaendeReihen.xml", &Relationen_Bände_Reihen); err != nil {
logger.Error("Error while unmarshalling RELATION_BaendeReihen.xml: ", "error", err, "path", path+"_RELATION_BaendeReihen.xml")
}
DB.Relationen_Bände_Reihen = Relationen_Bände_Reihen
wg.Done()
}()
go func() {
if err := unmarshalFile(path+"_RELATION_InhalteAkteure.xml", &Relationen_Inhalte_Akteure); err != nil {
logger.Error("Error while unmarshalling RELATION_InhalteAkteure.xml: ", "error", err, "path", path+"_RELATION_InhalteAkteure.xml")
}
DB.Relationen_Inhalte_Akteure = Relationen_Inhalte_Akteure
wg.Done()
}()
wg.Wait()
if len(DB.BIBLIO) == 0 || len(DB.Akteure.Akteure) == 0 || len(DB.Orte.Orte) == 0 || len(DB.Reihen.Reihen) == 0 || len(DB.Bände.Bände) == 0 || len(DB.Inhalte.Inhalte) == 0 || len(DB.Relationen_Bände_Akteure.Relationen) == 0 || len(DB.Relationen_Bände_Reihen.Relationen) == 0 || len(DB.Relationen_Inhalte_Akteure.Relationen) == 0 {
return nil, fmt.Errorf("Source files could not be read")
}
var BIBLIOM = datatypes.MakeMap(BIBLIO.Einträge, func(e BIBLIOEintrag) int { return e.Nummer })
lib := AccessDB{
Orte: &Orte,
Akteure: &Akteure,
Reihen: &Reihentitel,
Bände: &Bände,
Inhalte: &Inhalte,
Relationen_Bände_Akteure: &Relationen_Bände_Akteure,
Relationen_Bände_Reihen: &Relationen_Bände_Reihen,
Relationen_Inhalte_Akteure: &Relationen_Inhalte_Akteure,
BIBLIO: &BIBLIOM,
}
return &lib, nil
return &DB, nil
}
func unmarshalFile[T any](filename string, data *T) error {

View File

@@ -16,12 +16,12 @@ type Relation_Band_Reihe struct {
type Relationen_Inhalte_Akteure struct {
XMLName xml.Name `xml:"dataroot"`
Relationen []Relation_Inhalt_akteur `xml:"_x002A_RELATION_InhalteAkteure"`
Relationen []Relation_Inhalt_Akteur `xml:"_x002A_RELATION_InhalteAkteure"`
}
type Relation_Inhalt_akteur struct {
type Relation_Inhalt_Akteur struct {
ID string `xml:"ID"`
Band string `xml:"INHALT"`
Inhalt string `xml:"INHALT"`
Relation string `xml:"BEZIEHUNG"`
Akteur string `xml:"AKTEUR"`
}