mirror of
https://github.com/Theodor-Springmann-Stiftung/musenalm.git
synced 2026-02-04 02:25:30 +00:00
BUGFIX: double entries for almanachse
This commit is contained in:
@@ -86,7 +86,8 @@ func init() {
|
|||||||
|
|
||||||
wg.Wait()
|
wg.Wait()
|
||||||
|
|
||||||
entries, err := seed.RecordsFromBände(app, *adb, placesmap)
|
contentCounts := seed.ContentCountsAfterFilter(adb.Inhalte)
|
||||||
|
entries, err := seed.RecordsFromBände(app, *adb, placesmap, contentCounts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|||||||
52
migrations/seed/content_filters.go
Normal file
52
migrations/seed/content_filters.go
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
package seed
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/Theodor-Springmann-Stiftung/musenalm/xmlmodels"
|
||||||
|
)
|
||||||
|
|
||||||
|
func CountContentsByBand(inhalte xmlmodels.Inhalte) map[int]int {
|
||||||
|
counts := make(map[int]int)
|
||||||
|
for _, inhalt := range inhalte.Inhalte {
|
||||||
|
counts[inhalt.Band]++
|
||||||
|
}
|
||||||
|
return counts
|
||||||
|
}
|
||||||
|
|
||||||
|
func ContentCountsAfterFilter(inhalte xmlmodels.Inhalte) map[int]int {
|
||||||
|
images := getImages(xmlmodels.IMG_PATH)
|
||||||
|
filteredCounts := make(map[int]int)
|
||||||
|
for _, inhalt := range inhalte.Inhalte {
|
||||||
|
if shouldSkipDummyContent(inhalt, images) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
filteredCounts[inhalt.Band]++
|
||||||
|
}
|
||||||
|
return filteredCounts
|
||||||
|
}
|
||||||
|
|
||||||
|
func shouldSkipDummyContent(inhalt xmlmodels.Inhalt, images map[int][]string) bool {
|
||||||
|
if len(inhalt.Typ.Value) != 1 || strings.TrimSpace(inhalt.Typ.Value[0]) != "Gedicht/Lied" {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
author := strings.TrimSpace(NormalizeString(inhalt.Urheberangabe))
|
||||||
|
if !strings.EqualFold(author, "unbezeichnet") {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
if strings.TrimSpace(NormalizeString(inhalt.Titelangabe)) != "" {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
if strings.TrimSpace(NormalizeString(inhalt.Incipit)) != "" {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(images[inhalt.ID]) > 0 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
@@ -34,6 +34,9 @@ func RecordsFromInhalte(
|
|||||||
for i := 0; i < len(inhalte.Inhalte); i++ {
|
for i := 0; i < len(inhalte.Inhalte); i++ {
|
||||||
record := dbmodels.NewContent(core.NewRecord(collection))
|
record := dbmodels.NewContent(core.NewRecord(collection))
|
||||||
inhalt := inhalte.Inhalte[i]
|
inhalt := inhalte.Inhalte[i]
|
||||||
|
if shouldSkipDummyContent(inhalt, images) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
band, ok := entries[inhalt.Band]
|
band, ok := entries[inhalt.Band]
|
||||||
if !ok {
|
if !ok {
|
||||||
app.Logger().Error("Band not found", "band", inhalt.Band)
|
app.Logger().Error("Band not found", "band", inhalt.Band)
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ func RecordsFromBände(
|
|||||||
adb xmlmodels.AccessDB,
|
adb xmlmodels.AccessDB,
|
||||||
// INFO: this is a string map, bc it's not by ID but by place name
|
// INFO: this is a string map, bc it's not by ID but by place name
|
||||||
places map[string]*dbmodels.Place,
|
places map[string]*dbmodels.Place,
|
||||||
|
contentCounts map[int]int,
|
||||||
) ([]*dbmodels.Entry, error) {
|
) ([]*dbmodels.Entry, error) {
|
||||||
collection, err := app.FindCollectionByNameOrId(dbmodels.ENTRIES_TABLE)
|
collection, err := app.FindCollectionByNameOrId(dbmodels.ENTRIES_TABLE)
|
||||||
records := make([]*dbmodels.Entry, 0, len(adb.Bände.Bände))
|
records := make([]*dbmodels.Entry, 0, len(adb.Bände.Bände))
|
||||||
@@ -64,16 +65,28 @@ func RecordsFromBände(
|
|||||||
record.SetYear(band.Jahr)
|
record.SetYear(band.Jahr)
|
||||||
}
|
}
|
||||||
|
|
||||||
if band.Erfasst {
|
contentCount := contentCounts[band.ID]
|
||||||
record.SetEditState(dbmodels.EDITORSTATE_VALUES[len(dbmodels.EDITORSTATE_VALUES)-1])
|
hasAutopsieFromData := entryHasAutopsieFromData(band)
|
||||||
} else if band.Gesichtet {
|
if band.Erfasst && contentCount == 0 {
|
||||||
|
record.SetEditState(dbmodels.EDITORSTATE_VALUES[2])
|
||||||
|
} else if band.Erfasst {
|
||||||
|
record.SetEditState(dbmodels.EDITORSTATE_VALUES[len(dbmodels.EDITORSTATE_VALUES)-1])
|
||||||
|
} else if band.Gesichtet || hasAutopsieFromData {
|
||||||
record.SetEditState(dbmodels.EDITORSTATE_VALUES[2])
|
record.SetEditState(dbmodels.EDITORSTATE_VALUES[2])
|
||||||
} else if band.BiblioID != 0 {
|
|
||||||
record.SetEditState(dbmodels.EDITORSTATE_VALUES[1])
|
|
||||||
} else {
|
} else {
|
||||||
record.SetEditState(dbmodels.EDITORSTATE_VALUES[0])
|
record.SetEditState(dbmodels.EDITORSTATE_VALUES[0])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if band.BiblioID != 0 && !band.Erfasst && !(band.Gesichtet || hasAutopsieFromData) {
|
||||||
|
appendEntryComment(record, "Weder erfasst noch autopsiert, obwohl eine Biblio-ID vergeben wurde; bitte überprüfen.")
|
||||||
|
}
|
||||||
|
if band.BiblioID == 0 && len(band.Status.Value) > 0 && !band.Erfasst && !(band.Gesichtet || hasAutopsieFromData) {
|
||||||
|
appendEntryComment(record, "Band ist als vorhanden markiert aber nicht autospiert.")
|
||||||
|
}
|
||||||
|
if band.BiblioID == 0 && len(band.Status.Value) == 0 && (band.Erfasst || band.Gesichtet || hasAutopsieFromData) {
|
||||||
|
appendEntryComment(record, "Quelle für autopsiert oder Erfassung fehlt.")
|
||||||
|
}
|
||||||
|
|
||||||
handlePreferredTitleEntry(record, band, rmap, relmap)
|
handlePreferredTitleEntry(record, band, rmap, relmap)
|
||||||
handleDeprecated(record, band)
|
handleDeprecated(record, band)
|
||||||
handleOrte(record, band, omap, app, ocoll, places)
|
handleOrte(record, band, omap, app, ocoll, places)
|
||||||
@@ -93,7 +106,7 @@ func handlePreferredTitleEntry(
|
|||||||
rels := rrelmap[band.ID]
|
rels := rrelmap[band.ID]
|
||||||
if len(rels) == 0 {
|
if len(rels) == 0 {
|
||||||
record.SetPreferredTitle(NormalizeString(band.ReihentitelALT))
|
record.SetPreferredTitle(NormalizeString(band.ReihentitelALT))
|
||||||
record.SetEditState(dbmodels.EDITORSTATE_VALUES[len(dbmodels.EDITORSTATE_VALUES)-2])
|
appendEntryComment(record, "Kein Reihentitel-Bezug; Reihentitel ALT verwendet.")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -118,6 +131,19 @@ func handlePreferredTitleEntry(
|
|||||||
record.SetPreferredTitle(NormalizeString(rmap[rels[0].Reihe].Titel) + jahr)
|
record.SetPreferredTitle(NormalizeString(rmap[rels[0].Reihe].Titel) + jahr)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func entryHasAutopsieFromData(band xmlmodels.Band) bool {
|
||||||
|
title := strings.TrimSpace(NormalizeString(band.Titelangabe))
|
||||||
|
if title == "" {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
responsibility := strings.TrimSpace(NormalizeString(band.Verantwortlichkeitsangabe))
|
||||||
|
place := strings.TrimSpace(NormalizeString(band.Ortsangabe))
|
||||||
|
notes := strings.TrimSpace(NormalizeString(band.Anmerkungen))
|
||||||
|
|
||||||
|
return responsibility != "" || place != "" || notes != ""
|
||||||
|
}
|
||||||
|
|
||||||
func handleOrte(
|
func handleOrte(
|
||||||
record *dbmodels.Entry,
|
record *dbmodels.Entry,
|
||||||
band xmlmodels.Band,
|
band xmlmodels.Band,
|
||||||
|
|||||||
26
migrations/seed/entry_comments.go
Normal file
26
migrations/seed/entry_comments.go
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
package seed
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/Theodor-Springmann-Stiftung/musenalm/dbmodels"
|
||||||
|
)
|
||||||
|
|
||||||
|
func appendEntryComment(entry *dbmodels.Entry, note string) {
|
||||||
|
note = strings.TrimSpace(note)
|
||||||
|
if note == "" {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
current := strings.TrimSpace(entry.Comment())
|
||||||
|
if current == "" {
|
||||||
|
entry.SetComment(note)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if strings.Contains(current, note) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
entry.SetComment(current + "\n" + note)
|
||||||
|
}
|
||||||
@@ -78,7 +78,7 @@ func ItemsFromBändeAndBIBLIO(
|
|||||||
message = appendMessage(e.NotizÄusseres, message)
|
message = appendMessage(e.NotizÄusseres, message)
|
||||||
message = appendMessage(e.NotizInhalt, message)
|
message = appendMessage(e.NotizInhalt, message)
|
||||||
message = appendMessage(e.Anmerkungen, message)
|
message = appendMessage(e.Anmerkungen, message)
|
||||||
exem.SetAnnotation(message)
|
exem.SetAnnotation(formatItemAnnotation(message))
|
||||||
}
|
}
|
||||||
|
|
||||||
records = append(records, exem)
|
records = append(records, exem)
|
||||||
@@ -100,7 +100,7 @@ func ItemsFromBändeAndBIBLIO(
|
|||||||
message = appendMessage(e.Anmerkungen, message)
|
message = appendMessage(e.Anmerkungen, message)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
exem.SetAnnotation(message)
|
exem.SetAnnotation(formatItemAnnotation(message))
|
||||||
|
|
||||||
if exem.Identifier() != "" {
|
if exem.Identifier() != "" {
|
||||||
records = append(records, exem)
|
records = append(records, exem)
|
||||||
@@ -144,3 +144,10 @@ func appendMessage(message string, toAppend string) string {
|
|||||||
}
|
}
|
||||||
return message
|
return message
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func formatItemAnnotation(message string) string {
|
||||||
|
if message == "" {
|
||||||
|
return message
|
||||||
|
}
|
||||||
|
return strings.ReplaceAll(message, "/)", "<br>")
|
||||||
|
}
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ func RecordsFromRelationBändeAkteure(
|
|||||||
ser := record.Agent()
|
ser := record.Agent()
|
||||||
|
|
||||||
if strings.TrimSpace(rel) == "" || strings.TrimSpace(ent) == "" || strings.TrimSpace(ser) == "" {
|
if strings.TrimSpace(rel) == "" || strings.TrimSpace(ent) == "" || strings.TrimSpace(ser) == "" {
|
||||||
entry.SetEditState(dbmodels.EDITORSTATE_VALUES[len(dbmodels.EDITORSTATE_VALUES)-2])
|
appendEntryComment(entry, "Unvollständige Relation Band–Akteur; bitte prüfen.")
|
||||||
_ = app.Save(entry)
|
_ = app.Save(entry)
|
||||||
}
|
}
|
||||||
records = append(records, record)
|
records = append(records, record)
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ func RecordsFromRelationBändeReihen(
|
|||||||
entries map[int]*dbmodels.Entry,
|
entries map[int]*dbmodels.Entry,
|
||||||
) ([]*dbmodels.REntriesSeries, error) {
|
) ([]*dbmodels.REntriesSeries, error) {
|
||||||
records := make([]*dbmodels.REntriesSeries, 0, len(relations.Relationen))
|
records := make([]*dbmodels.REntriesSeries, 0, len(relations.Relationen))
|
||||||
|
seen := make(map[string]int)
|
||||||
collection, err := app.FindCollectionByNameOrId(dbmodels.RelationTableName(dbmodels.ENTRIES_TABLE, dbmodels.SERIES_TABLE))
|
collection, err := app.FindCollectionByNameOrId(dbmodels.RelationTableName(dbmodels.ENTRIES_TABLE, dbmodels.SERIES_TABLE))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
app.Logger().Error("Error finding collection", "error", err, "collection", dbmodels.RelationTableName(dbmodels.ENTRIES_TABLE, dbmodels.SERIES_TABLE))
|
app.Logger().Error("Error finding collection", "error", err, "collection", dbmodels.RelationTableName(dbmodels.ENTRIES_TABLE, dbmodels.SERIES_TABLE))
|
||||||
@@ -62,10 +63,30 @@ func RecordsFromRelationBändeReihen(
|
|||||||
ser := record.Series()
|
ser := record.Series()
|
||||||
|
|
||||||
if strings.TrimSpace(rel) == "" || strings.TrimSpace(ent) == "" || strings.TrimSpace(ser) == "" {
|
if strings.TrimSpace(rel) == "" || strings.TrimSpace(ent) == "" || strings.TrimSpace(ser) == "" {
|
||||||
entry.SetEditState(dbmodels.EDITORSTATE_VALUES[len(dbmodels.EDITORSTATE_VALUES)-2])
|
appendEntryComment(entry, "Unvollständige Relation Band–Reihe; bitte prüfen.")
|
||||||
_ = app.Save(entry)
|
_ = app.Save(entry)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
key := entry.Id + "|" + series.Id
|
||||||
|
if idx, ok := seen[key]; ok {
|
||||||
|
existing := records[idx]
|
||||||
|
if existing.Type() == "Bevorzugter Reihentitel" {
|
||||||
|
appendEntryComment(entry, "Doppelte Relation Band–Reihe entfernt; bitte prüfen.")
|
||||||
|
_ = app.Save(entry)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if record.Type() == "Bevorzugter Reihentitel" {
|
||||||
|
records[idx] = record
|
||||||
|
appendEntryComment(entry, "Doppelte Relation Band–Reihe entfernt; bitte prüfen.")
|
||||||
|
_ = app.Save(entry)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
appendEntryComment(entry, "Doppelte Relation Band–Reihe entfernt; bitte prüfen.")
|
||||||
|
_ = app.Save(entry)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
seen[key] = len(records)
|
||||||
records = append(records, record)
|
records = append(records, record)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
TODO:
|
TODO:
|
||||||
- Input:
|
- Input:
|
||||||
- Titelauflage von/ hat TA
|
- Titelauflage von/ hat TA
|
||||||
- Status: Auopsiert, Erfasst etc.
|
|
||||||
- \) parse on input
|
|
||||||
- Hilfe-Texte für Felder
|
- Hilfe-Texte für Felder
|
||||||
- Seiteneditor: Bilder für die Startseite.
|
- Seiteneditor: Bilder für die Startseite.
|
||||||
- Datei-Upload-Manager
|
- Datei-Upload-Manager
|
||||||
@@ -10,7 +8,6 @@ TODO:
|
|||||||
|
|
||||||
BUGS:
|
BUGS:
|
||||||
- Schriftgröße Edit-Screens
|
- Schriftgröße Edit-Screens
|
||||||
- doppelte Einträge Reihen-Liste, Endpoint /reihen (siehe Abendstunden)
|
|
||||||
|
|
||||||
Features:
|
Features:
|
||||||
- Extra-DB für FTS5: ist eigentlich nichtTeil der Haupt-DB, sondern nur Suchindex
|
- Extra-DB für FTS5: ist eigentlich nichtTeil der Haupt-DB, sondern nur Suchindex
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -21,6 +21,26 @@
|
|||||||
[o.J.]
|
[o.J.]
|
||||||
{{- end -}}
|
{{- end -}}
|
||||||
|
|
||||||
|
{{- if $request.user -}}
|
||||||
|
<tool-tip position="right" class="inline">
|
||||||
|
<i class="status-icon ml-1 align-middle {{- if eq $bd.EditState "Edited" }} ri-checkbox-circle-line{{- else if eq $bd.EditState "Seen" }} ri-information-line{{- else if eq $bd.EditState "Review" }} ri-search-line{{- else if eq $bd.EditState "ToDo" }} ri-list-check{{- else }} ri-forbid-2-line{{- end }}" data-status="{{ $bd.EditState }}"></i>
|
||||||
|
<div class="data-tip">
|
||||||
|
{{- if eq $bd.EditState "Unknown" -}}
|
||||||
|
Gesucht
|
||||||
|
{{- else if eq $bd.EditState "ToDo" -}}
|
||||||
|
Zu erledigen
|
||||||
|
{{- else if eq $bd.EditState "Review" -}}
|
||||||
|
Überprüfen
|
||||||
|
{{- else if eq $bd.EditState "Seen" -}}
|
||||||
|
Autopsiert
|
||||||
|
{{- else if eq $bd.EditState "Edited" -}}
|
||||||
|
Vollständig Erfasst
|
||||||
|
{{- else -}}
|
||||||
|
{{ $bd.EditState }}
|
||||||
|
{{- end -}}
|
||||||
|
</div>
|
||||||
|
</tool-tip>
|
||||||
|
{{- else -}}
|
||||||
{{- if not $bd.TitleStmt -}}
|
{{- if not $bd.TitleStmt -}}
|
||||||
<tool-tip position="right" class="inline">
|
<tool-tip position="right" class="inline">
|
||||||
<i class="ri-forbid-2-line"></i>
|
<i class="ri-forbid-2-line"></i>
|
||||||
@@ -37,6 +57,7 @@
|
|||||||
<div class="data-tip">Mit genaueren Titelangaben</div>
|
<div class="data-tip">Mit genaueren Titelangaben</div>
|
||||||
</tool-tip>
|
</tool-tip>
|
||||||
{{- end -}}
|
{{- end -}}
|
||||||
|
{{- end -}}
|
||||||
</div>
|
</div>
|
||||||
{{- if not (eq $rel.Type "Bevorzugter Reihentitel") -}}
|
{{- if not (eq $rel.Type "Bevorzugter Reihentitel") -}}
|
||||||
<div class="text-xs whitespace-nowrap">
|
<div class="text-xs whitespace-nowrap">
|
||||||
|
|||||||
@@ -112,6 +112,26 @@
|
|||||||
@apply text-base;
|
@apply text-base;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.status-icon[data-status="Edited"] {
|
||||||
|
color: var(--color-green-900);
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-icon[data-status="Seen"] {
|
||||||
|
color: var(--color-blue-900);
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-icon[data-status="Review"] {
|
||||||
|
color: var(--color-orange-900);
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-icon[data-status="ToDo"] {
|
||||||
|
color: var(--color-red-900);
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-icon[data-status="Unknown"] {
|
||||||
|
color: var(--color-gray-900);
|
||||||
|
}
|
||||||
|
|
||||||
/* Comment content styling in view mode */
|
/* Comment content styling in view mode */
|
||||||
.comment-content {
|
.comment-content {
|
||||||
@apply italic;
|
@apply italic;
|
||||||
@@ -135,19 +155,18 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.form-with-action-bar {
|
.form-with-action-bar {
|
||||||
@apply pb-0;
|
@apply pb-24;
|
||||||
|
padding-bottom: calc(6rem + env(safe-area-inset-bottom));
|
||||||
}
|
}
|
||||||
|
|
||||||
.form-action-bar {
|
.form-action-bar {
|
||||||
@apply sticky bottom-0 z-30 border-t border-transparent bg-stone-50;
|
@apply fixed bottom-0 left-0 right-0 z-30 border-t border-slate-200 bg-stone-50;
|
||||||
box-shadow: none;
|
box-shadow: 0 -1px 6px rgba(15, 23, 42, 0.08);
|
||||||
width: calc(100% + 120px);
|
padding-bottom: env(safe-area-inset-bottom);
|
||||||
margin-left: -60px;
|
|
||||||
margin-right: -60px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.form-action-bar-inner {
|
.form-action-bar-inner {
|
||||||
@apply w-full max-w-(--breakpoint-xl) mx-auto px-8 py-3 flex items-center justify-between gap-4 flex-wrap;
|
@apply w-full px-20 py-3 flex items-center justify-between gap-4 flex-wrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
.form-action-bar-actions {
|
.form-action-bar-actions {
|
||||||
@@ -164,12 +183,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.form-action-bar.is-stuck {
|
.form-action-bar.is-stuck {
|
||||||
@apply border-t border-l border-r border-transparent;
|
@apply border-t border-slate-200;
|
||||||
background-color: rgb(250 250 249);
|
background-color: rgb(250 250 249);
|
||||||
border-color: rgba(15, 23, 42, 0.06);
|
|
||||||
box-shadow: 0 -1px 6px rgba(15, 23, 42, 0.06);
|
|
||||||
border-top-left-radius: 6px;
|
|
||||||
border-top-right-radius: 6px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.content-action-button {
|
.content-action-button {
|
||||||
|
|||||||
Reference in New Issue
Block a user