diff --git a/kgpz_web.go b/kgpz_web.go index 4734f16..bf3b57b 100644 --- a/kgpz_web.go +++ b/kgpz_web.go @@ -2,6 +2,7 @@ package main import ( "os" + "path/filepath" "githib.com/Theodor-Springmann-Stiftung/kgpz_web/helpers" "githib.com/Theodor-Springmann-Stiftung/kgpz_web/providers" @@ -14,9 +15,19 @@ import ( // - Setup GitHub webhook if set // 3. Serialize XML DATA +const ( + AGENTS_PATH = "XML/akteure.xml" + PLACES_PATH = "XML/orte.xml" + WORKS_PATH = "XML/werke.xml" + CATEGORIES_PATH = "XML/kategorien.xml" +) + type KGPZ struct { Config *providers.ConfigProvider Repo *providers.GitProvider + Agents *providers.AgentProvider + Places *providers.PlaceProvider + Works *providers.WorkProvider } func NewKGPZ(config *providers.ConfigProvider) *KGPZ { @@ -63,7 +74,58 @@ func (k *KGPZ) InitRepo() { helpers.LogOnDebug(gp, "GitProvider") } } +} +func (k *KGPZ) InitAgents() { + ap := providers.NewAgentProvider([]string{filepath.Join(k.Config.FolderPath, AGENTS_PATH)}) + if ap != nil { + if err := ap.Load(); err != nil { + helpers.LogOnErr(ap, err, "Error loading agents") + } + + if k.IsDebug() { + helpers.LogOnDebug(ap, "AgentProvider") + } + } +} + +func (k *KGPZ) InitPlaces() { + pp := providers.NewPlaceProvider([]string{filepath.Join(k.Config.FolderPath, PLACES_PATH)}) + if pp != nil { + if err := pp.Load(); err != nil { + helpers.LogOnErr(pp, err, "Error loading places") + } + + if k.IsDebug() { + helpers.LogOnDebug(pp, "PlaceProvider") + } + } +} + +func (k *KGPZ) InitWorks() { + wp := providers.NewWorkProvider([]string{filepath.Join(k.Config.FolderPath, WORKS_PATH)}) + if wp != nil { + if err := wp.Load(); err != nil { + helpers.LogOnErr(wp, err, "Error loading works") + } + + if k.IsDebug() { + helpers.LogOnDebug(wp, "WorkProvider") + } + } +} + +func (k *KGPZ) InitCategories() { + cp := providers.NewCategoryProvider([]string{filepath.Join(k.Config.FolderPath, CATEGORIES_PATH)}) + if cp != nil { + if err := cp.Load(); err != nil { + helpers.LogOnErr(cp, err, "Error loading categories") + } + + if k.IsDebug() { + helpers.LogOnDebug(cp, "CategoryProvider") + } + } } func main() { @@ -74,5 +136,8 @@ func main() { kgpz := NewKGPZ(cfg) kgpz.InitRepo() - + kgpz.InitAgents() + kgpz.InitPlaces() + kgpz.InitWorks() + kgpz.InitCategories() } diff --git a/providers/agents.go b/providers/agents.go new file mode 100644 index 0000000..ccbd839 --- /dev/null +++ b/providers/agents.go @@ -0,0 +1,47 @@ +package providers + +import ( + "encoding/xml" + "fmt" +) + +type AgentProvider struct { + XMLProvider[Agents] +} + +type Agent struct { + XMLName xml.Name `xml:"akteur"` + ID string `xml:"id,attr"` + Names []string `xml:"name"` + SortName string `xml:"sortiername"` + Life string `xml:"lebensdaten"` + GND string `xml:"gnd"` + AnnotationNote +} + +type Agents struct { + XMLName xml.Name `xml:"akteure"` + Agents []Agent `xml:"akteur"` +} + +func (a Agents) String() string { + var res []string + for _, agent := range a.Agents { + res = append(res, agent.String()) + } + + return fmt.Sprintf("Agents: %v", res) +} + +func (a Agents) Append(data Agents) Agents { + a.Agents = append(a.Agents, data.Agents...) + return a +} + +func (a *Agent) String() string { + return fmt.Sprintf("ID: %s\nNames: %v\nSortName: %s\nLife: %s\nGND: %s\nAnnotations: %v\nNotes: %v\n", a.ID, a.Names, a.SortName, a.Life, a.GND, a.Annotations, a.Notes) +} + +func NewAgentProvider(paths []string) *AgentProvider { + return &AgentProvider{XMLProvider: XMLProvider[Agents]{paths: paths}} +} diff --git a/providers/categories.go b/providers/categories.go new file mode 100644 index 0000000..4c6c0bd --- /dev/null +++ b/providers/categories.go @@ -0,0 +1,44 @@ +package providers + +import ( + "encoding/xml" + "fmt" +) + +type CategoryProvider struct { + XMLProvider[Categories] +} + +type Categories struct { + XMLName xml.Name `xml:"kategorien"` + Category []Category `xml:"kategorie"` +} + +type Category struct { + ID string `xml:"id,attr"` + Names []string `xml:"name"` + SortName string `xml:"sortiername"` + AnnotationNote +} + +func (c Categories) Append(data Categories) Categories { + c.Category = append(c.Category, data.Category...) + return c +} + +func (c Categories) String() string { + var res []string + for _, category := range c.Category { + res = append(res, category.String()) + } + + return fmt.Sprintf("Categories: %v", res) +} + +func (c *Category) String() string { + return fmt.Sprintf("ID: %s\nNames: %v\nSortName: %s\nAnnotations: %v\nNotes: %v\n", c.ID, c.Names, c.SortName, c.Annotations, c.Notes) +} + +func NewCategoryProvider(paths []string) *CategoryProvider { + return &CategoryProvider{XMLProvider: XMLProvider[Categories]{paths: paths}} +} diff --git a/providers/issues.go b/providers/issues.go new file mode 100644 index 0000000..f9f48f3 --- /dev/null +++ b/providers/issues.go @@ -0,0 +1,67 @@ +package providers + +import ( + "encoding/xml" + "fmt" +) + +type IssueProvider struct { + XMLProvider[Issues] +} + +type Issues struct { + XMLName xml.Name `xml:"stuecke"` + Issue []Issue `xml:"stueck"` +} + +type Issue struct { + ID string `xml:"id,attr"` + Number IssueNumber `xml:"nummer"` + Datum KGPZDate `xml:"datum"` + Von string `xml:"von"` + Bis string `xml:"bis"` + Additionals []Additional `xml:"beilage"` +} + +type IssueNumber struct { + XMLName xml.Name `xml:"nummer"` + Value string `xml:",chardata"` + Corrected string `xml:"korrigiert,attr"` +} + +type KGPZDate struct { + When string `xml:"when,attr"` + NotBefore string `xml:"notBefore,attr"` + NotAfter string `xml:"notAfter,attr"` + From string `xml:"from,attr"` + To string `xml:"to,attr"` +} + +type Additional struct { + XMLName xml.Name `xml:"beilage"` + Nummer string `xml:"nummer,attr"` + Von string `xml:"von"` + Bis string `xml:"bis"` +} + +func (i Issues) Append(data Issues) Issues { + i.Issue = append(i.Issue, data.Issue...) + return i +} + +func (i Issues) String() string { + var res []string + for _, issue := range i.Issue { + res = append(res, issue.String()) + } + + return fmt.Sprintf("Issues: %v", res) +} + +func (i *Issue) String() string { + return fmt.Sprintf("ID: %s\nNumber: %v\nDatum: %v\nVon: %s\nBis: %s\nAdditionals: %v\n", i.ID, i.Number, i.Datum, i.Von, i.Bis, i.Additionals) +} + +func NewIssueProvider(paths []string) *IssueProvider { + return &IssueProvider{XMLProvider: XMLProvider[Issues]{paths: paths}} +} diff --git a/providers/pieces.go b/providers/pieces.go new file mode 100644 index 0000000..84d7c9f --- /dev/null +++ b/providers/pieces.go @@ -0,0 +1,92 @@ +package providers + +import ( + "encoding/xml" + "fmt" +) + +type PieceProvider struct { + XMLProvider[Pieces] +} + +type Pieces struct { + XMLName xml.Name `xml:"beitraege"` + Piece []Piece `xml:"beitrag"` +} + +type Piece struct { + ID string `xml:"id,attr"` + IssueRefs []IssueRef `xml:"stueck"` + PlaceRefs []PlaceRef `xml:"ort"` + CategoryRefs []CategoryRef `xml:"kategorie"` + AgentRefs []AgentRef `xml:"akteur"` + WorkRefs []WorkRef `xml:"werk"` + PieceRefs []PieceRef `xml:"beitrag"` + AdditionalRef []AdditionalRef `xml:"beilage"` + Incipit []string `xml:"incipit"` + Title []string `xml:"titel"` + AnnotationNote +} + +type AdditionalRef struct { + Datum string `xml:"datum,attr"` + Nr string `xml:"nr,attr"` + Von string `xml:"von,attr"` + Bis string `xml:"bis,attr"` + Value string `xml:",chardata"` +} + +type IssueRef struct { + Datum string `xml:"datum,attr"` + Nr string `xml:"nr,attr"` + Von string `xml:"von,attr"` + Bis string `xml:"bis,attr"` + Value string `xml:",chardata"` + Category string `xml:"kat,attr"` +} + +type PlaceRef struct { + Ref string `xml:"ref,attr"` + Value string `xml:",chardata"` + Category string `xml:"kat,attr"` +} + +type CategoryRef struct { + Ref string `xml:"ref,attr"` + Value string `xml:",chardata"` +} + +type WorkRef struct { + Ref string `xml:"ref,attr"` + Value string `xml:",chardata"` + Category string `xml:"kat,attr"` + Page string `xml:"s,attr"` +} + +type PieceRef struct { + Ref string `xml:"ref,attr"` + Category string `xml:"kat,attr"` + Value string `xml:",chardata"` +} + +func (p Pieces) Append(data Pieces) Pieces { + p.Piece = append(p.Piece, data.Piece...) + return p +} + +func (p Pieces) String() string { + var res []string + for _, piece := range p.Piece { + res = append(res, piece.String()) + } + + return fmt.Sprintf("Pieces: %v", res) +} + +func (p *Piece) String() string { + return fmt.Sprintf("ID: %s\nIssueRefs: %v\nPlaceRefs: %v\nCategoryRefs: %v\nAgentRefs: %v\nWorkRefs: %v\nPieceRefs: %v\nAdditionalRef: %v\nIncipit: %v\nTitle: %v\nAnnotations: %v\nNotes: %v\n", p.ID, p.IssueRefs, p.PlaceRefs, p.CategoryRefs, p.AgentRefs, p.WorkRefs, p.PieceRefs, p.AdditionalRef, p.Incipit, p.Title, p.Annotations, p.Notes) +} + +func NewPieceProvider(paths []string) *PieceProvider { + return &PieceProvider{XMLProvider: XMLProvider[Pieces]{paths: paths}} +} diff --git a/providers/places.go b/providers/places.go new file mode 100644 index 0000000..97442fd --- /dev/null +++ b/providers/places.go @@ -0,0 +1,45 @@ +package providers + +import ( + "encoding/xml" + "fmt" +) + +type PlaceProvider struct { + XMLProvider[Places] +} + +type Places struct { + XMLName xml.Name `xml:"orte"` + Place []Place `xml:"ort"` +} + +type Place struct { + ID string `xml:"id,attr"` + Names []string `xml:"name"` + SortName string `xml:"sortiername"` + Geo string `xml:"geonames"` + AnnotationNote +} + +func (p Places) Append(data Places) Places { + p.Place = append(p.Place, data.Place...) + return p +} + +func (p Places) String() string { + var res []string + for _, place := range p.Place { + res = append(res, place.String()) + } + + return fmt.Sprintf("Places: %v", res) +} + +func (p *Place) String() string { + return fmt.Sprintf("ID: %s\nNames: %v\nSortName: %s\nGeo: %s\nAnnotations: %v\nNotes: %v\n", p.ID, p.Names, p.SortName, p.Geo, p.Annotations, p.Notes) +} + +func NewPlaceProvider(paths []string) *PlaceProvider { + return &PlaceProvider{XMLProvider: XMLProvider[Places]{paths: paths}} +} diff --git a/providers/scans.go b/providers/scans.go new file mode 100644 index 0000000..cf2a3ba --- /dev/null +++ b/providers/scans.go @@ -0,0 +1 @@ +package providers diff --git a/providers/works.go b/providers/works.go new file mode 100644 index 0000000..f81f8c4 --- /dev/null +++ b/providers/works.go @@ -0,0 +1,56 @@ +package providers + +import ( + "encoding/xml" + "fmt" +) + +type WorkProvider struct { + XMLProvider[Works] +} + +type Works struct { + XMLName xml.Name `xml:"werke"` + Work []Work `xml:"werk"` +} + +type Work struct { + ID string `xml:"id,attr"` + URLs []URL `xml:"url"` + Citation []string `xml:"zitation"` + Akteur []AgentRef `xml:"akteur"` + AnnotationNote +} + +type AgentRef struct { + Ref string `xml:"ref,attr"` + Category string `xml:"Kat,attr"` + Value string `xml:",chardata"` +} + +type URL struct { + Address string `xml:"address,attr"` + Value string `xml:",chardata"` +} + +func (w Works) Append(data Works) Works { + w.Work = append(w.Work, data.Work...) + return w +} + +func (w Works) String() string { + var res []string + for _, work := range w.Work { + res = append(res, work.String()) + } + + return fmt.Sprintf("Works: %v", res) +} + +func (w *Work) String() string { + return fmt.Sprintf("ID: %s\nURLs: %v\nCitation: %v\nAnnotations: %v\nNotes: %v\n", w.ID, w.URLs, w.Citation, w.Annotations, w.Notes) +} + +func NewWorkProvider(paths []string) *WorkProvider { + return &WorkProvider{XMLProvider: XMLProvider[Works]{paths: paths}} +} diff --git a/providers/xmlcommon.go b/providers/xmlcommon.go new file mode 100644 index 0000000..55c38af --- /dev/null +++ b/providers/xmlcommon.go @@ -0,0 +1,65 @@ +package providers + +import ( + "encoding/xml" + "fmt" + "io" + "os" + "sync" +) + +type KGPZXML[T any] interface { + Append(data T) T + fmt.Stringer +} + +type XMLProvider[T KGPZXML[T]] struct { + mu sync.Mutex + paths []string + Items T +} + +func (p *XMLProvider[T]) Load() error { + var wg sync.WaitGroup + for _, path := range p.paths { + wg.Add(1) + go func(path string) { + defer wg.Done() + var data T + if err := UnmarshalFile(path, &data); err != nil { + fmt.Println(err) + return + } + p.mu.Lock() + p.Items = p.Items.Append(data) + p.mu.Unlock() + }(path) + } + wg.Wait() + return nil +} + +func (a *XMLProvider[T]) String() string { + a.mu.Lock() + defer a.mu.Unlock() + return fmt.Sprintf("Items: %s", a.Items) +} + +type AnnotationNote struct { + Annotations []string `xml:"anmerkung"` + Notes []string `xml:"vermerk"` +} + +func UnmarshalFile[T any](filename string, data *T) error { + xmlFile, err := os.Open(filename) + if err != nil { + fmt.Println(err) + return err + } + fmt.Println("Successfully opened " + filename) + defer xmlFile.Close() + byteValue, _ := io.ReadAll(xmlFile) + xml.Unmarshal(byteValue, data) + + return nil +}