mirror of
https://github.com/Theodor-Springmann-Stiftung/kgpz_web.git
synced 2025-10-28 16:45:32 +00:00
restructured viewmodels, better serialization
This commit is contained in:
@@ -13,7 +13,7 @@ tmp_dir = "tmp"
|
||||
exclude_unchanged = false
|
||||
follow_symlink = false
|
||||
full_bin = ""
|
||||
include_dir = []
|
||||
include_dir = [ "views/assets" ]
|
||||
include_ext = ["go", "tpl", "tmpl", "html"]
|
||||
include_file = []
|
||||
kill_delay = "0s"
|
||||
@@ -42,9 +42,9 @@ tmp_dir = "tmp"
|
||||
clean_on_exit = false
|
||||
|
||||
[proxy]
|
||||
app_port = 0
|
||||
app_port = 8080
|
||||
enabled = false
|
||||
proxy_port = 0
|
||||
proxy_port = 8081
|
||||
|
||||
[screen]
|
||||
clear_on_rebuild = false
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
"github.com/Theodor-Springmann-Stiftung/kgpz_web/helpers"
|
||||
"github.com/Theodor-Springmann-Stiftung/kgpz_web/helpers/logging"
|
||||
"github.com/Theodor-Springmann-Stiftung/kgpz_web/providers"
|
||||
"github.com/Theodor-Springmann-Stiftung/kgpz_web/providers/xmlprovider"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -25,7 +26,7 @@ type KGPZ struct {
|
||||
gmu sync.Mutex
|
||||
Config *providers.ConfigProvider
|
||||
Repo *providers.GitProvider
|
||||
Library *providers.Library
|
||||
Library *xmlprovider.Library
|
||||
}
|
||||
|
||||
func (k *KGPZ) Init() {
|
||||
@@ -68,7 +69,7 @@ func (k *KGPZ) Serialize() {
|
||||
pieces, err := getXMLFiles(filepath.Join(k.Config.FolderPath, PIECES_DIR))
|
||||
helpers.Assert(err, "Error getting pieces")
|
||||
|
||||
lib := providers.NewLibrary(
|
||||
lib := xmlprovider.NewLibrary(
|
||||
[]string{filepath.Join(k.Config.FolderPath, AGENTS_PATH)},
|
||||
[]string{filepath.Join(k.Config.FolderPath, PLACES_PATH)},
|
||||
[]string{filepath.Join(k.Config.FolderPath, WORKS_PATH)},
|
||||
@@ -135,7 +136,7 @@ func (k *KGPZ) Pull() {
|
||||
k.gmu.Unlock()
|
||||
|
||||
if changed {
|
||||
logging.ObjDebug(&k.Repo, "Remote changed. Reparsing...")
|
||||
logging.ObjDebug(&k.Repo, "Remote changed. Reparsing")
|
||||
k.Serialize()
|
||||
}
|
||||
}()
|
||||
|
||||
33
controllers/issue.go
Normal file
33
controllers/issue.go
Normal file
@@ -0,0 +1,33 @@
|
||||
package controllers
|
||||
|
||||
import (
|
||||
"github.com/Theodor-Springmann-Stiftung/kgpz_web/app"
|
||||
"github.com/Theodor-Springmann-Stiftung/kgpz_web/helpers/logging"
|
||||
"github.com/Theodor-Springmann-Stiftung/kgpz_web/viewmodels"
|
||||
"github.com/gofiber/fiber/v2"
|
||||
)
|
||||
|
||||
func GetIssue(kgpz *app.KGPZ) fiber.Handler {
|
||||
return func(c *fiber.Ctx) error {
|
||||
y := c.Params("year")
|
||||
if len(y) != 4 {
|
||||
logging.Error(nil, "Year is not 4 characters long")
|
||||
return c.SendStatus(fiber.StatusNotFound)
|
||||
}
|
||||
|
||||
d := c.Params("issue")
|
||||
if d == "" {
|
||||
logging.Error(nil, "Issue number is empty")
|
||||
return c.SendStatus(fiber.StatusNotFound)
|
||||
}
|
||||
|
||||
issue, err := viewmodels.IssueView(y, d, kgpz.Library)
|
||||
|
||||
if err != nil {
|
||||
logging.Error(err, "Issue could not be found")
|
||||
return c.SendStatus(fiber.StatusNotFound)
|
||||
}
|
||||
|
||||
return c.Render("/issue/", fiber.Map{"model": issue})
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,8 @@ package controllers
|
||||
|
||||
import (
|
||||
"github.com/Theodor-Springmann-Stiftung/kgpz_web/app"
|
||||
"github.com/Theodor-Springmann-Stiftung/kgpz_web/helpers/logging"
|
||||
"github.com/Theodor-Springmann-Stiftung/kgpz_web/viewmodels"
|
||||
"github.com/gofiber/fiber/v2"
|
||||
)
|
||||
|
||||
@@ -16,8 +18,9 @@ func GetYear(kgpz *app.KGPZ) fiber.Handler {
|
||||
return c.SendStatus(fiber.StatusBadRequest)
|
||||
}
|
||||
|
||||
issues := kgpz.Library.Issues.GetYear(y)
|
||||
if len(issues.Issues) == 0 {
|
||||
issues, err := viewmodels.YearView(y, kgpz.Library)
|
||||
if err != nil {
|
||||
logging.Error(err, "Keine Ausgaben für das Jahr "+y)
|
||||
return c.SendStatus(fiber.StatusNotFound)
|
||||
}
|
||||
|
||||
305
lobid_example.json
Normal file
305
lobid_example.json
Normal file
@@ -0,0 +1,305 @@
|
||||
> curl --header "Accept: application/json" https://lobid.org/gnd/11854523X > lobid_example.json
|
||||
{
|
||||
"gender" : [ {
|
||||
"id" : "https://d-nb.info/standards/vocab/gnd/gender#male",
|
||||
"label" : "Männlich"
|
||||
} ],
|
||||
"dateOfDeath" : [ "1788-06-21" ],
|
||||
"placeOfDeath" : [ {
|
||||
"id" : "https://d-nb.info/gnd/4040608-8",
|
||||
"label" : "Münster (Westf)"
|
||||
} ],
|
||||
"familialRelationship" : [ {
|
||||
"id" : "https://d-nb.info/gnd/124138004",
|
||||
"label" : "Hamann, Johann Georg"
|
||||
} ],
|
||||
"type" : [ "Person", "AuthorityResource", "DifferentiatedPerson" ],
|
||||
"gndSubjectCategory" : [ {
|
||||
"id" : "https://d-nb.info/standards/vocab/gnd/gnd-sc#4.7p",
|
||||
"label" : "Personen zu Philosophie"
|
||||
}, {
|
||||
"id" : "https://d-nb.info/standards/vocab/gnd/gnd-sc#3.6p",
|
||||
"label" : "Personen zu Kirchengeschichte, Systematischer und Praktischer Theologie, Kirche und Konfession"
|
||||
}, {
|
||||
"id" : "https://d-nb.info/standards/vocab/gnd/gnd-sc#12.2p",
|
||||
"label" : "Personen zu Literaturgeschichte (Schriftsteller)"
|
||||
} ],
|
||||
"oldAuthorityNumber" : [ "(DE-588a)11854523X", "(DE-588c)4023109-4", "(DE-588a)126364664" ],
|
||||
"geographicAreaCode" : [ {
|
||||
"id" : "https://d-nb.info/standards/vocab/gnd/geographic-area-code#XA-RU",
|
||||
"label" : "Russland"
|
||||
}, {
|
||||
"id" : "https://d-nb.info/standards/vocab/gnd/geographic-area-code#XA-DE",
|
||||
"label" : "Deutschland"
|
||||
} ],
|
||||
"biographicalOrHistoricalInformation" : [ "Lutherischer Theologe und aufklärungskritischer Philosoph nach einem Erweckungserlebnis" ],
|
||||
"hasAuntUncle" : [ {
|
||||
"id" : "https://d-nb.info/gnd/124138004",
|
||||
"label" : "Hamann, Johann Georg"
|
||||
} ],
|
||||
"publication" : [ "Hamann, Johann G.: Golgatha und Scheblimini", "Rink, Friedrich T.: [Mancherlei zur Geschichte der metakritischen Invasion]", "Hamann, Johann G.: Kreuzzüge der Philologen", "Hamann, Johann G.: Beobachtungen über die heilige Schrift", "Hamann, Johann G.: Versuch einer Sibylle über die Ehe", "Weisheits-Sprüche und Witzreden aus J. Georg Hamanns und Imanuel Kants Schriften", "Hamann, Johann G.: Sibyllinische Blätter des Magus im Norden" ],
|
||||
"describedBy" : {
|
||||
"id" : "https://d-nb.info/gnd/11854523X/about",
|
||||
"license" : {
|
||||
"id" : "http://creativecommons.org/publicdomain/zero/1.0/",
|
||||
"label" : "http://creativecommons.org/publicdomain/zero/1.0/"
|
||||
},
|
||||
"dateModified" : "2024-01-08T10:50:15.000",
|
||||
"descriptionLevel" : {
|
||||
"id" : "https://d-nb.info/standards/vocab/gnd/description-level#1",
|
||||
"label" : "Allgemeines, Interdisziplinäre Allgemeinwörter"
|
||||
}
|
||||
},
|
||||
"gndIdentifier" : "11854523X",
|
||||
"id" : "https://d-nb.info/gnd/11854523X",
|
||||
"preferredName" : "Hamann, Johann Georg",
|
||||
"wikipedia" : [ {
|
||||
"id" : "https://de.wikipedia.org/wiki/Johann_Georg_Hamann",
|
||||
"label" : "https://de.wikipedia.org/wiki/Johann_Georg_Hamann"
|
||||
} ],
|
||||
"preferredNameEntityForThePerson" : {
|
||||
"forename" : [ "Johann Georg" ],
|
||||
"surname" : [ "Hamann" ]
|
||||
},
|
||||
"depiction" : [ {
|
||||
"id" : "https://commons.wikimedia.org/wiki/Special:FilePath/Johann%20Georg%20Hamann%20%281730%E2%80%931788%29.jpg",
|
||||
"url" : "https://commons.wikimedia.org/wiki/File:Johann%20Georg%20Hamann%20%281730%E2%80%931788%29.jpg?uselang=de",
|
||||
"thumbnail" : "https://commons.wikimedia.org/wiki/Special:FilePath/Johann%20Georg%20Hamann%20%281730%E2%80%931788%29.jpg?width=270"
|
||||
} ],
|
||||
"professionOrOccupation" : [ {
|
||||
"id" : "https://d-nb.info/gnd/4045790-4",
|
||||
"label" : "Philosoph"
|
||||
}, {
|
||||
"id" : "https://d-nb.info/gnd/4053309-8",
|
||||
"label" : "Schriftsteller"
|
||||
}, {
|
||||
"id" : "https://d-nb.info/gnd/1041366884",
|
||||
"label" : "Lutherischer Theologe"
|
||||
}, {
|
||||
"id" : "https://d-nb.info/gnd/4128272-3",
|
||||
"label" : "Kaufmann"
|
||||
}, {
|
||||
"id" : "https://d-nb.info/gnd/4061414-1",
|
||||
"label" : "Übersetzer"
|
||||
}, {
|
||||
"id" : "https://d-nb.info/gnd/7719046-4",
|
||||
"label" : "Selbstverleger"
|
||||
} ],
|
||||
"placeOfBirth" : [ {
|
||||
"id" : "https://d-nb.info/gnd/4031541-1",
|
||||
"label" : "Königsberg"
|
||||
} ],
|
||||
"dateOfBirth" : [ "1730-08-27" ],
|
||||
"variantNameEntityForThePerson" : [ {
|
||||
"forename" : [ "Vettius" ],
|
||||
"surname" : [ "Epagathus" ]
|
||||
}, {
|
||||
"forename" : [ "Iogann Georg" ],
|
||||
"surname" : [ "Gaman" ]
|
||||
}, {
|
||||
"forename" : [ "J. G." ],
|
||||
"surname" : [ "Hamann" ]
|
||||
}, {
|
||||
"personalName" : [ "Hamann" ]
|
||||
}, {
|
||||
"forename" : [ "Abälardus" ],
|
||||
"surname" : [ "Virbius" ]
|
||||
}, {
|
||||
"forename" : [ "Yohan Geʼorg" ],
|
||||
"surname" : [ "Haman" ]
|
||||
}, {
|
||||
"nameAddition" : [ "Magus des Nordens" ],
|
||||
"personalName" : [ "Hamann" ]
|
||||
}, {
|
||||
"personalName" : [ "Magus des Nordens" ]
|
||||
}, {
|
||||
"forename" : [ "Johann George" ],
|
||||
"surname" : [ "Hamann" ]
|
||||
}, {
|
||||
"forename" : [ "Johann G." ],
|
||||
"surname" : [ "Haman" ]
|
||||
}, {
|
||||
"forename" : [ "Christian Z." ],
|
||||
"surname" : [ "Telonarcha" ]
|
||||
}, {
|
||||
"forename" : [ "Georg" ],
|
||||
"surname" : [ "Hamann" ]
|
||||
}, {
|
||||
"forename" : [ "I. G." ],
|
||||
"surname" : [ "Gaman" ]
|
||||
}, {
|
||||
"forename" : [ "Johann Georg" ],
|
||||
"surname" : [ "Haman" ]
|
||||
}, {
|
||||
"forename" : [ "Johann Georg" ],
|
||||
"nameAddition" : [ "der Jüngere" ],
|
||||
"surname" : [ "Hamann" ]
|
||||
}, {
|
||||
"forename" : [ "Johann G." ],
|
||||
"surname" : [ "Hamann" ]
|
||||
}, {
|
||||
"personalName" : [ "Aristobulus" ]
|
||||
}, {
|
||||
"forename" : [ "Vetius" ],
|
||||
"surname" : [ "Epagathus" ]
|
||||
} ],
|
||||
"languageCode" : [ {
|
||||
"id" : "http://id.loc.gov/vocabulary/iso639-2/ger",
|
||||
"label" : "http://id.loc.gov/vocabulary/iso639-2/ger"
|
||||
} ],
|
||||
"@context" : "https://lobid.org/gnd/context.jsonld",
|
||||
"professionalRelationship" : [ {
|
||||
"id" : "https://d-nb.info/gnd/118549553",
|
||||
"label" : "Herder, Johann Gottfried von"
|
||||
} ],
|
||||
"relatedSubjectHeading" : [ {
|
||||
"id" : "https://d-nb.info/gnd/4165591-6",
|
||||
"label" : "Kreis von Münster"
|
||||
} ],
|
||||
"variantName" : [ "Hamann, J. G.", "Magus des Nordens", "Haman, Johann G.", "Virbius, Abälardus", "Hamann", "Gaman, Iogann Georg", "Hamann, Johann Georg, der Jüngere", "Hamann, Johann G.", "Aristobulus", "Hamann, Johann George", "Haman, Johann Georg", "Hamann, Magus des Nordens", "Epagathus, Vettius", "Haman, Yohan Geʼorg", "Gaman, I. G.", "Epagathus, Vetius", "Telonarcha, Christian Z.", "Hamann, Georg" ],
|
||||
"sameAs" : [ {
|
||||
"collection" : {
|
||||
"abbr" : "BNF",
|
||||
"name" : "Bibliothèque nationale de France",
|
||||
"publisher" : "Bibliothèque nationale de France",
|
||||
"icon" : "https://www.bnf.fr/themes/custom/bnfsi/favicon.ico",
|
||||
"id" : "http://www.wikidata.org/entity/Q19938912"
|
||||
},
|
||||
"id" : "http://catalogue.bnf.fr/ark:/12148/cb12359677d"
|
||||
}, {
|
||||
"id" : "http://id.loc.gov/rwo/agents/n78093468",
|
||||
"collection" : {
|
||||
"id" : "http://www.wikidata.org/entity/Q13219454",
|
||||
"abbr" : "LC",
|
||||
"publisher" : "Library of Congress",
|
||||
"icon" : "http://www.loc.gov/favicon.ico",
|
||||
"name" : "NACO Authority File"
|
||||
}
|
||||
}, {
|
||||
"collection" : {
|
||||
"abbr" : "OSTDEBIB",
|
||||
"name" : "Ostdeutsche Biographie",
|
||||
"publisher" : "Kulturportal West-Ost",
|
||||
"id" : "http://www.wikidata.org/entity/Q52617553"
|
||||
},
|
||||
"id" : "http://kulturportal-west-ost.eu/persons/hamann-johann-georg/"
|
||||
}, {
|
||||
"id" : "http://viaf.org/viaf/69006033",
|
||||
"collection" : {
|
||||
"id" : "http://www.wikidata.org/entity/Q54919",
|
||||
"abbr" : "VIAF",
|
||||
"publisher" : "OCLC",
|
||||
"icon" : "http://viaf.org/viaf/images/viaf.ico",
|
||||
"name" : "Virtual International Authority File (VIAF)"
|
||||
}
|
||||
}, {
|
||||
"id" : "http://www.wikidata.org/entity/Q76499",
|
||||
"collection" : {
|
||||
"id" : "http://www.wikidata.org/entity/Q2013",
|
||||
"abbr" : "WIKIDATA",
|
||||
"publisher" : "Wikimedia Foundation Inc.",
|
||||
"icon" : "https://www.wikidata.org/static/favicon/wikidata.ico",
|
||||
"name" : "Wikidata"
|
||||
}
|
||||
}, {
|
||||
"collection" : {
|
||||
"abbr" : "DNB",
|
||||
"name" : "Gemeinsame Normdatei (GND) im Katalog der Deutschen Nationalbibliothek",
|
||||
"publisher" : "Deutsche Nationalbibliothek",
|
||||
"icon" : "https://www.dnb.de/SiteGlobals/Frontend/DNBWeb/Images/favicon.png?__blob=normal&v=4",
|
||||
"id" : "http://www.wikidata.org/entity/Q36578"
|
||||
},
|
||||
"id" : "https://d-nb.info/gnd/11854523X/about"
|
||||
}, {
|
||||
"id" : "https://dbpedia.org/resource/Johann_Georg_Hamann",
|
||||
"collection" : {
|
||||
"id" : "https://dbpedia.org"
|
||||
}
|
||||
}, {
|
||||
"collection" : {
|
||||
"abbr" : "dewiki",
|
||||
"name" : "Wikipedia (Deutsch)",
|
||||
"publisher" : "Wikimedia Foundation Inc.",
|
||||
"icon" : "https://de.wikipedia.org/static/favicon/wikipedia.ico",
|
||||
"id" : "http://www.wikidata.org/entity/Q48183"
|
||||
},
|
||||
"id" : "https://de.wikipedia.org/wiki/Johann_Georg_Hamann"
|
||||
}, {
|
||||
"collection" : {
|
||||
"abbr" : "WIKISOURCE",
|
||||
"name" : "Wikisource",
|
||||
"publisher" : "Wikimedia Foundation Inc.",
|
||||
"icon" : "https://wikisource.org/static/favicon/wikisource.ico",
|
||||
"id" : "http://www.wikidata.org/entity/Q263"
|
||||
},
|
||||
"id" : "https://de.wikisource.org/wiki/Johann_Georg_Hamann"
|
||||
}, {
|
||||
"collection" : {
|
||||
"abbr" : "enwiki",
|
||||
"name" : "Wikipedia (English)",
|
||||
"publisher" : "Wikimedia Foundation Inc.",
|
||||
"icon" : "https://en.wikipedia.org/static/favicon/wikipedia.ico",
|
||||
"id" : "http://www.wikidata.org/entity/Q328"
|
||||
},
|
||||
"id" : "https://en.wikipedia.org/wiki/Johann_Georg_Hamann"
|
||||
}, {
|
||||
"id" : "https://isni.org/isni/0000000121021204",
|
||||
"collection" : {
|
||||
"id" : "https://isni.org"
|
||||
}
|
||||
}, {
|
||||
"collection" : {
|
||||
"abbr" : "DE-611",
|
||||
"name" : "Kalliope Verbundkatalog",
|
||||
"publisher" : "Staatsbibliothek zu Berlin - Preußischer Kulturbesitz",
|
||||
"icon" : "https://kalliope-verbund.info/img/favicon.ico",
|
||||
"id" : "https://kalliope-verbund.info"
|
||||
},
|
||||
"id" : "https://kalliope-verbund.info/gnd/11854523X"
|
||||
}, {
|
||||
"collection" : {
|
||||
"abbr" : "ARCHIV-D",
|
||||
"name" : "Archivportal-D",
|
||||
"publisher" : "Deutsche Digitale Bibliothek",
|
||||
"icon" : "https://www.archivportal-d.de/favicon.ico",
|
||||
"id" : "https://www.archivportal-d.de"
|
||||
},
|
||||
"id" : "https://www.archivportal-d.de/person/gnd/11854523X"
|
||||
}, {
|
||||
"collection" : {
|
||||
"abbr" : "ADB",
|
||||
"name" : "Allgemeine Deutsche Biographie (ADB)",
|
||||
"publisher" : "Historische Kommission bei der Bayerischen Akademie der Wissenschaften und Bayerische Staatsbibliothek",
|
||||
"icon" : "https://www.deutsche-biographie.de/favicon.ico",
|
||||
"id" : "https://www.deutsche-biographie.de"
|
||||
},
|
||||
"id" : "https://www.deutsche-biographie.de/pnd11854523X.html#adbcontent"
|
||||
}, {
|
||||
"collection" : {
|
||||
"abbr" : "NDB",
|
||||
"name" : "Neue Deutsche Biographie (NDB)",
|
||||
"publisher" : "Historische Kommission bei der Bayerischen Akademie der Wissenschaften und Bayerische Staatsbibliothek",
|
||||
"icon" : "https://www.deutsche-biographie.de/favicon.ico",
|
||||
"id" : "https://www.deutsche-biographie.de"
|
||||
},
|
||||
"id" : "https://www.deutsche-biographie.de/pnd11854523X.html#ndbcontent"
|
||||
}, {
|
||||
"collection" : {
|
||||
"abbr" : "DDB",
|
||||
"name" : "Deutsche Digitale Bibliothek",
|
||||
"publisher" : "Deutsche Digitale Bibliothek",
|
||||
"icon" : "https://www.deutsche-digitale-bibliothek.de/favicon.ico",
|
||||
"id" : "http://www.wikidata.org/entity/Q621630"
|
||||
},
|
||||
"id" : "https://www.deutsche-digitale-bibliothek.de/person/gnd/11854523X"
|
||||
}, {
|
||||
"collection" : {
|
||||
"abbr" : "Portraitindex",
|
||||
"name" : "Digitaler Portraitindex der druckgraphischen Bildnisse der Frühen Neuzeit",
|
||||
"publisher" : "Deutsches Dokumentationszentrum für Kunstgeschichte - Bildarchiv Foto Marburg",
|
||||
"icon" : "https://www.portraitindex.de/favicon.ico",
|
||||
"id" : "https://www.portraitindex.de"
|
||||
},
|
||||
"id" : "https://www.portraitindex.de/dokumente/pnd/11854523X"
|
||||
} ]
|
||||
}
|
||||
4
providers/gnd/model.go
Normal file
4
providers/gnd/model.go
Normal file
@@ -0,0 +1,4 @@
|
||||
package gnd
|
||||
|
||||
type Person struct {
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package providers
|
||||
package xmlprovider
|
||||
|
||||
import (
|
||||
"encoding/xml"
|
||||
@@ -1,4 +1,4 @@
|
||||
package providers
|
||||
package xmlprovider
|
||||
|
||||
import (
|
||||
"encoding/xml"
|
||||
@@ -1,4 +1,4 @@
|
||||
package providers
|
||||
package xmlprovider
|
||||
|
||||
import (
|
||||
"encoding/xml"
|
||||
@@ -14,44 +14,19 @@ type Issues struct {
|
||||
Issues []Issue `xml:"stueck"`
|
||||
}
|
||||
|
||||
func (i *IssueProvider) GetYear(year string) YearViewModel {
|
||||
res := YearViewModel{Year: year}
|
||||
last := ""
|
||||
for _, issue := range i.Items.Issues {
|
||||
if len(issue.Datum.When) < 4 {
|
||||
continue
|
||||
}
|
||||
|
||||
date := issue.Datum.When[0:4]
|
||||
if date != last {
|
||||
res.PushAvailable(date)
|
||||
last = date
|
||||
}
|
||||
|
||||
if date == year {
|
||||
res.PushIssue(issue)
|
||||
}
|
||||
}
|
||||
|
||||
res.SortAvailableYears()
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
type Issue struct {
|
||||
XMLName xml.Name `xml:"stueck"`
|
||||
Number IssueNumber `xml:"nummer"`
|
||||
Number Nummer `xml:"nummer"`
|
||||
Datum KGPZDate `xml:"datum"`
|
||||
Von string `xml:"von"`
|
||||
Bis string `xml:"bis"`
|
||||
Von int `xml:"von"`
|
||||
Bis int `xml:"bis"`
|
||||
Additionals []Additional `xml:"beilage"`
|
||||
Identifier
|
||||
AnnotationNote
|
||||
}
|
||||
|
||||
type IssueNumber struct {
|
||||
XMLName xml.Name `xml:"nummer"`
|
||||
Value
|
||||
type Nummer struct {
|
||||
No int `xml:",chardata"`
|
||||
Corrected string `xml:"korrigiert,attr"`
|
||||
}
|
||||
|
||||
@@ -76,8 +51,8 @@ func (i Issues) String() 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 (i Issue) String() string {
|
||||
return fmt.Sprintf("Number: %v, Datum: %v, Von: %d, Bis: %d, Additionals: %v, Identifier: %v, AnnotationNote: %v\n", i.Number, i.Datum, i.Von, i.Bis, i.Additionals, i.Identifier, i.AnnotationNote)
|
||||
}
|
||||
|
||||
func NewIssueProvider(paths []string) *IssueProvider {
|
||||
@@ -1,4 +1,4 @@
|
||||
package providers
|
||||
package xmlprovider
|
||||
|
||||
import (
|
||||
"encoding/xml"
|
||||
@@ -44,7 +44,7 @@ func (p Pieces) String() string {
|
||||
return fmt.Sprintf("Pieces: %v", res)
|
||||
}
|
||||
|
||||
func (p *Piece) String() string {
|
||||
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)
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package providers
|
||||
package xmlprovider
|
||||
|
||||
import (
|
||||
"encoding/xml"
|
||||
@@ -1,4 +1,4 @@
|
||||
package providers
|
||||
package xmlprovider
|
||||
|
||||
import (
|
||||
"encoding/xml"
|
||||
@@ -15,14 +15,23 @@ type Works struct {
|
||||
}
|
||||
|
||||
type Work struct {
|
||||
XMLName xml.Name `xml:"werk"`
|
||||
URLs []URL `xml:"url"`
|
||||
Citation []string `xml:"zitation"`
|
||||
Akteur []AgentRef `xml:"akteur"`
|
||||
XMLName xml.Name `xml:"werk"`
|
||||
URLs []URL `xml:"url"`
|
||||
Citation Citation `xml:"zitation"`
|
||||
PreferredTitle string `xml:"preferred"`
|
||||
Akteur []AgentRef `xml:"akteur"`
|
||||
Identifier
|
||||
AnnotationNote
|
||||
}
|
||||
|
||||
type Citation struct {
|
||||
XMLName xml.Name `xml:"zitation"`
|
||||
Title string `xml:"title"`
|
||||
Year []string `xml:"year"`
|
||||
Value
|
||||
Inner
|
||||
}
|
||||
|
||||
func (w Works) Append(data Works) Works {
|
||||
w.Work = append(w.Work, data.Work...)
|
||||
return w
|
||||
@@ -38,7 +47,7 @@ func (w Works) String() string {
|
||||
}
|
||||
|
||||
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)
|
||||
return fmt.Sprintf("URLs: %v, Citation: %v, PreferredTitle: %s, Akteur: %v, Identifier: %v, AnnotationNote: %v\n", w.URLs, w.Citation, w.PreferredTitle, w.Akteur, w.Identifier, w.AnnotationNote)
|
||||
}
|
||||
|
||||
func NewWorkProvider(paths []string) *WorkProvider {
|
||||
55
providers/xmlprovider/xmlcommon.go
Normal file
55
providers/xmlprovider/xmlcommon.go
Normal file
@@ -0,0 +1,55 @@
|
||||
package xmlprovider
|
||||
|
||||
import "encoding/xml"
|
||||
|
||||
type KGPZDate struct {
|
||||
XMLName xml.Name `xml:"datum"`
|
||||
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"`
|
||||
Value
|
||||
}
|
||||
|
||||
type URL struct {
|
||||
XMLName xml.Name `xml:"url"`
|
||||
Address string `xml:"address,attr"`
|
||||
Value
|
||||
}
|
||||
|
||||
type AnnotationNote struct {
|
||||
Annotations []Annotation `xml:"anmerkung"`
|
||||
Notes []Note `xml:"vermerk"`
|
||||
}
|
||||
|
||||
type Annotation struct {
|
||||
XMLName xml.Name `xml:"anmerkung"`
|
||||
Value
|
||||
Inner
|
||||
}
|
||||
|
||||
type Note struct {
|
||||
XMLName xml.Name `xml:"vermerk"`
|
||||
Value
|
||||
Inner
|
||||
}
|
||||
|
||||
type Identifier struct {
|
||||
ID string `xml:"id,attr"`
|
||||
}
|
||||
|
||||
type Reference struct {
|
||||
Ref string `xml:"ref,attr"`
|
||||
Category string `xml:"kat,attr"`
|
||||
Unsicher bool `xml:"unsicher,attr"`
|
||||
Value
|
||||
}
|
||||
|
||||
type Value struct {
|
||||
Chardata string `xml:",chardata"`
|
||||
}
|
||||
|
||||
type Inner struct {
|
||||
InnerXML string `xml:",innerxml"`
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package providers
|
||||
package xmlprovider
|
||||
|
||||
import (
|
||||
"encoding/xml"
|
||||
@@ -50,7 +50,6 @@ func (l *Library) Serialize() {
|
||||
err := l.Agents.Serialize()
|
||||
if err != nil {
|
||||
l.Agents = nil
|
||||
|
||||
}
|
||||
}()
|
||||
|
||||
@@ -59,7 +58,6 @@ func (l *Library) Serialize() {
|
||||
err := l.Places.Serialize()
|
||||
if err != nil {
|
||||
l.Places = nil
|
||||
|
||||
}
|
||||
}()
|
||||
|
||||
@@ -68,7 +66,6 @@ func (l *Library) Serialize() {
|
||||
err := l.Works.Serialize()
|
||||
if err != nil {
|
||||
l.Works = nil
|
||||
|
||||
}
|
||||
}()
|
||||
|
||||
@@ -77,7 +74,6 @@ func (l *Library) Serialize() {
|
||||
err := l.Categories.Serialize()
|
||||
if err != nil {
|
||||
l.Categories = nil
|
||||
|
||||
}
|
||||
}()
|
||||
|
||||
@@ -86,7 +82,6 @@ func (l *Library) Serialize() {
|
||||
err := l.Issues.Serialize()
|
||||
if err != nil {
|
||||
l.Issues = nil
|
||||
|
||||
}
|
||||
}()
|
||||
|
||||
@@ -95,7 +90,6 @@ func (l *Library) Serialize() {
|
||||
err := l.Pieces.Serialize()
|
||||
if err != nil {
|
||||
l.Pieces = nil
|
||||
|
||||
}
|
||||
}()
|
||||
|
||||
@@ -111,7 +105,6 @@ func (p *XMLProvider[T]) Serialize() error {
|
||||
defer wg.Done()
|
||||
var data T
|
||||
if err := UnmarshalFile(path, &data); err != nil {
|
||||
|
||||
return
|
||||
}
|
||||
p.mu.Lock()
|
||||
@@ -121,6 +114,7 @@ func (p *XMLProvider[T]) Serialize() error {
|
||||
}
|
||||
wg.Wait()
|
||||
|
||||
fmt.Println(p.Items)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -133,10 +127,11 @@ func (a *XMLProvider[T]) String() string {
|
||||
func UnmarshalFile[T any](filename string, data *T) error {
|
||||
xmlFile, err := os.Open(filename)
|
||||
if err != nil {
|
||||
logging.Error(err, "Could not deserialize file: "+filename)
|
||||
return err
|
||||
}
|
||||
defer xmlFile.Close()
|
||||
logging.Info("Opened " + filename)
|
||||
logging.Info("Deserialization: " + filename)
|
||||
byteValue, _ := io.ReadAll(xmlFile)
|
||||
xml.Unmarshal(byteValue, data)
|
||||
|
||||
@@ -1,28 +1,12 @@
|
||||
package providers
|
||||
package xmlprovider
|
||||
|
||||
import "encoding/xml"
|
||||
|
||||
type KGPZDate struct {
|
||||
XMLName xml.Name `xml:"datum"`
|
||||
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"`
|
||||
Value
|
||||
}
|
||||
|
||||
type AgentRef struct {
|
||||
XMLName xml.Name `xml:"akteur"`
|
||||
Reference
|
||||
}
|
||||
|
||||
type URL struct {
|
||||
XMLName xml.Name `xml:"url"`
|
||||
Address string `xml:"address,attr"`
|
||||
Value
|
||||
}
|
||||
|
||||
type AdditionalRef struct {
|
||||
XMLName xml.Name `xml:"beilage"`
|
||||
Reference
|
||||
@@ -63,23 +47,3 @@ type PieceRef struct {
|
||||
Page string `xml:"s,attr"`
|
||||
Reference
|
||||
}
|
||||
|
||||
type AnnotationNote struct {
|
||||
Annotations []string `xml:"anmerkung"`
|
||||
Notes []string `xml:"vermerk"`
|
||||
}
|
||||
|
||||
type Identifier struct {
|
||||
ID string `xml:"id,attr"`
|
||||
}
|
||||
|
||||
type Reference struct {
|
||||
Ref string `xml:"ref,attr"`
|
||||
Category string `xml:"kat,attr"`
|
||||
Unsicher bool `xml:"unsicher,attr"`
|
||||
Value
|
||||
}
|
||||
|
||||
type Value struct {
|
||||
Chardata string `xml:",chardata"`
|
||||
}
|
||||
@@ -1,84 +0,0 @@
|
||||
package providers
|
||||
|
||||
import (
|
||||
"slices"
|
||||
"strconv"
|
||||
"time"
|
||||
)
|
||||
|
||||
const TLAYOUT = "2006-01-02"
|
||||
|
||||
var TRANSLM = map[string][]string{
|
||||
"January": {"Januar", "Jan"},
|
||||
"February": {"Februar", "Feb"},
|
||||
"March": {"März", "Mär"},
|
||||
"April": {"April", "Apr"},
|
||||
"May": {"Mai", "Mai"},
|
||||
"June": {"Juni", "Jun"},
|
||||
"July": {"Juli", "Jul"},
|
||||
"August": {"August", "Aug"},
|
||||
"September": {"September", "Sep"},
|
||||
"October": {"Oktober", "Okt"},
|
||||
"November": {"November", "Nov"},
|
||||
"December": {"Dezember", "Dez"},
|
||||
}
|
||||
|
||||
var TRANSLD = map[string][]string{
|
||||
"Monday": {"Montag", "Mo"},
|
||||
"Tuesday": {"Dienstag", "Di"},
|
||||
"Wednesday": {"Mittwoch", "Mi"},
|
||||
"Thursday": {"Donnerstag", "Do"},
|
||||
"Friday": {"Freitag", "Fr"},
|
||||
"Saturday": {"Samstag", "Sa"},
|
||||
"Sunday": {"Sonntag", "So"},
|
||||
}
|
||||
|
||||
type IssueViewModel struct {
|
||||
Issue
|
||||
Weekday []string
|
||||
Day int
|
||||
Month []string
|
||||
}
|
||||
|
||||
func NewIssueView(i Issue) (IssueViewModel, error) {
|
||||
t, err := time.Parse(TLAYOUT, i.Datum.When)
|
||||
if err != nil {
|
||||
return IssueViewModel{}, err
|
||||
}
|
||||
|
||||
return IssueViewModel{
|
||||
Issue: i,
|
||||
Weekday: append(TRANSLD[t.Weekday().String()], t.Weekday().String()),
|
||||
Day: t.Day(),
|
||||
Month: append(TRANSLM[t.Month().String()], i.Datum.When[5:7]),
|
||||
}, nil
|
||||
}
|
||||
|
||||
type YearViewModel struct {
|
||||
Year string
|
||||
AvailableYears []int
|
||||
Issues []IssueViewModel
|
||||
}
|
||||
|
||||
func (y *YearViewModel) PushIssue(i Issue) {
|
||||
iv, err := NewIssueView(i)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
y.Issues = append(y.Issues, iv)
|
||||
}
|
||||
|
||||
func (y *YearViewModel) PushAvailable(s string) {
|
||||
i, err := strconv.Atoi(s)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if !slices.Contains(y.AvailableYears, i) {
|
||||
y.AvailableYears = append(y.AvailableYears, i)
|
||||
}
|
||||
}
|
||||
|
||||
func (y *YearViewModel) SortAvailableYears() {
|
||||
slices.Sort(y.AvailableYears)
|
||||
}
|
||||
@@ -142,7 +142,8 @@ func (s *Server) Start() {
|
||||
} else {
|
||||
srv.Use(cache.New(cache.Config{
|
||||
Next: func(c *fiber.Ctx) bool {
|
||||
return c.Query("noCache") == "true"
|
||||
// We do not cache error responses
|
||||
return c.Query("noCache") == "true" || c.Response().StatusCode() != fiber.StatusOK
|
||||
},
|
||||
Expiration: 30 * time.Minute,
|
||||
CacheControl: true,
|
||||
@@ -153,6 +154,8 @@ func (s *Server) Start() {
|
||||
srv.Use(STATIC_PREFIX, static(&views.StaticFS))
|
||||
|
||||
srv.Get("/:year?", controllers.GetYear(s.kgpz))
|
||||
srv.Get("/:year/:issue/:page?", controllers.GetIssue(s.kgpz))
|
||||
srv.Get("/:year/:issue/beilage/:subpage?", controllers.GetIssue(s.kgpz))
|
||||
|
||||
s.runner(srv)
|
||||
|
||||
|
||||
@@ -1 +1 @@
|
||||
exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1
|
||||
exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1
|
||||
78
viewmodels/issue.go
Normal file
78
viewmodels/issue.go
Normal file
@@ -0,0 +1,78 @@
|
||||
package viewmodels
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/Theodor-Springmann-Stiftung/kgpz_web/providers/xmlprovider"
|
||||
)
|
||||
|
||||
const TLAYOUT = "2006-01-02"
|
||||
|
||||
var TRANSLM = map[string][]string{
|
||||
"January": {"Januar", "Jan", "1"},
|
||||
"February": {"Februar", "Feb", "2"},
|
||||
"March": {"März", "Mär", "3"},
|
||||
"April": {"April", "Apr", "4"},
|
||||
"May": {"Mai", "Mai", "5"},
|
||||
"June": {"Juni", "Jun", "6"},
|
||||
"July": {"Juli", "Jul", "7"},
|
||||
"August": {"August", "Aug", "8"},
|
||||
"September": {"September", "Sep", "9"},
|
||||
"October": {"Oktober", "Okt", "10"},
|
||||
"November": {"November", "Nov", "11"},
|
||||
"December": {"Dezember", "Dez", "12"},
|
||||
}
|
||||
|
||||
var TRANSLD = map[string][]string{
|
||||
"Monday": {"Montag", "Mo"},
|
||||
"Tuesday": {"Dienstag", "Di"},
|
||||
"Wednesday": {"Mittwoch", "Mi"},
|
||||
"Thursday": {"Donnerstag", "Do"},
|
||||
"Friday": {"Freitag", "Fr"},
|
||||
"Saturday": {"Samstag", "Sa"},
|
||||
"Sunday": {"Sonntag", "So"},
|
||||
}
|
||||
|
||||
type IssueViewModel struct {
|
||||
xmlprovider.Issue
|
||||
Weekday []string
|
||||
Day int
|
||||
Month []string
|
||||
}
|
||||
|
||||
func IssueView(y string, No string, lib *xmlprovider.Library) (*IssueViewModel, error) {
|
||||
n, err := strconv.Atoi(No)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, i := range lib.Issues.Items.Issues {
|
||||
if len(i.Datum.When) < 4 {
|
||||
continue
|
||||
}
|
||||
|
||||
d := i.Datum.When[:4]
|
||||
if d == y && i.Number.No == n {
|
||||
return FromIssue(i)
|
||||
}
|
||||
}
|
||||
|
||||
return nil, errors.New("Issue not found")
|
||||
}
|
||||
|
||||
func FromIssue(i xmlprovider.Issue) (*IssueViewModel, error) {
|
||||
t, err := time.Parse(TLAYOUT, i.Datum.When)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ivm := IssueViewModel{
|
||||
Issue: i,
|
||||
Weekday: append(TRANSLD[t.Weekday().String()], t.Weekday().String()),
|
||||
Day: t.Day(),
|
||||
Month: TRANSLM[t.Month().String()]}
|
||||
|
||||
return &ivm, nil
|
||||
}
|
||||
11
viewmodels/piece.go
Normal file
11
viewmodels/piece.go
Normal file
@@ -0,0 +1,11 @@
|
||||
package viewmodels
|
||||
|
||||
import "github.com/Theodor-Springmann-Stiftung/kgpz_web/providers/xmlprovider"
|
||||
|
||||
type PieceViewModel struct {
|
||||
xmlprovider.Piece
|
||||
}
|
||||
|
||||
func NewPieceView(p xmlprovider.Piece) (PieceViewModel, error) {
|
||||
return PieceViewModel{Piece: p}, nil
|
||||
}
|
||||
51
viewmodels/singleissue.go
Normal file
51
viewmodels/singleissue.go
Normal file
@@ -0,0 +1,51 @@
|
||||
package viewmodels
|
||||
|
||||
import (
|
||||
"github.com/Theodor-Springmann-Stiftung/kgpz_web/helpers/logging"
|
||||
"github.com/Theodor-Springmann-Stiftung/kgpz_web/providers/xmlprovider"
|
||||
)
|
||||
|
||||
type SingleIssueViewModel struct {
|
||||
IssueViewModel
|
||||
No string
|
||||
Year string
|
||||
Additionals []PieceViewModel
|
||||
Pieces []PieceViewModel
|
||||
Next IssueViewModel
|
||||
Prev IssueViewModel
|
||||
}
|
||||
|
||||
func NewSingleIssueView(y string, No string, lib *xmlprovider.Library) (*SingleIssueViewModel, error) {
|
||||
ivm, err := IssueView(y, No, lib)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
sivm := SingleIssueViewModel{IssueViewModel: *ivm}
|
||||
|
||||
for _, a := range lib.Pieces.Items.Piece {
|
||||
for _, r := range a.IssueRefs {
|
||||
if r.Datum == y && r.Nr == No {
|
||||
p, err := NewPieceView(a)
|
||||
if err != nil {
|
||||
logging.ObjErr(&a, err)
|
||||
continue
|
||||
}
|
||||
sivm.Pieces = append(sivm.Pieces, p)
|
||||
}
|
||||
}
|
||||
|
||||
for _, r := range a.AdditionalRef {
|
||||
if r.Datum == y && r.Nr == No {
|
||||
p, err := NewPieceView(a)
|
||||
if err != nil {
|
||||
logging.ObjErr(&a, err)
|
||||
continue
|
||||
}
|
||||
sivm.Additionals = append(sivm.Additionals, p)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return &sivm, nil
|
||||
}
|
||||
87
viewmodels/year.go
Normal file
87
viewmodels/year.go
Normal file
@@ -0,0 +1,87 @@
|
||||
package viewmodels
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"slices"
|
||||
"sort"
|
||||
"strconv"
|
||||
|
||||
"github.com/Theodor-Springmann-Stiftung/kgpz_web/helpers/logging"
|
||||
"github.com/Theodor-Springmann-Stiftung/kgpz_web/providers/xmlprovider"
|
||||
)
|
||||
|
||||
type IssuesByMonth map[int][]IssueViewModel
|
||||
|
||||
type YearViewModel struct {
|
||||
Year string
|
||||
AvailableYears []string
|
||||
Issues IssuesByMonth
|
||||
}
|
||||
|
||||
func (y *YearViewModel) PushIssue(i xmlprovider.Issue) {
|
||||
iv, err := FromIssue(i)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
month, _ := strconv.Atoi(iv.Month[2])
|
||||
|
||||
list, ok := y.Issues[month]
|
||||
if !ok {
|
||||
list = []IssueViewModel{}
|
||||
}
|
||||
|
||||
y.Issues[month] = append(list, *iv)
|
||||
}
|
||||
|
||||
func (y *YearViewModel) PushAvailable(s string) {
|
||||
|
||||
if !slices.Contains(y.AvailableYears, s) {
|
||||
y.AvailableYears = append(y.AvailableYears, s)
|
||||
}
|
||||
}
|
||||
|
||||
func (y *YearViewModel) SortAvailableYears() {
|
||||
sort.Slice(y.AvailableYears, func(i, j int) bool {
|
||||
iint, err := strconv.Atoi(y.AvailableYears[i])
|
||||
if err != nil {
|
||||
return true
|
||||
}
|
||||
jint, err := strconv.Atoi(y.AvailableYears[j])
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
return iint < jint
|
||||
})
|
||||
}
|
||||
|
||||
func YearView(year string, lib *xmlprovider.Library) (*YearViewModel, error) {
|
||||
res := YearViewModel{Year: year}
|
||||
res.Issues = make(IssuesByMonth, 12)
|
||||
last := ""
|
||||
for _, issue := range lib.Issues.Items.Issues {
|
||||
|
||||
logging.ObjDebug(&issue, "Issue")
|
||||
if len(issue.Datum.When) < 4 {
|
||||
continue
|
||||
}
|
||||
|
||||
date := issue.Datum.When[0:4]
|
||||
if date != last {
|
||||
res.PushAvailable(date)
|
||||
last = date
|
||||
}
|
||||
|
||||
if date == year {
|
||||
res.PushIssue(issue)
|
||||
}
|
||||
}
|
||||
|
||||
if len(res.Issues) == 0 {
|
||||
return nil, errors.New("No issues found")
|
||||
}
|
||||
|
||||
res.SortAvailableYears()
|
||||
|
||||
return &res, nil
|
||||
}
|
||||
@@ -1,19 +1,26 @@
|
||||
{{ define "body" }}
|
||||
{{ $y := .model.Year }}
|
||||
|
||||
{{ range $year := .model.AvailableYears }}
|
||||
<a href="/{{ $year }}">{{ $year }}</a>
|
||||
<a href="/{{ $year }}" aria-active="{{ eq $year $y }}">{{ $year }}</a>
|
||||
{{ end }}
|
||||
{{ range $issue := .model.Issues }}
|
||||
<div>
|
||||
<div>
|
||||
{{ $issue.Number.Chardata }}
|
||||
</div>
|
||||
<div>
|
||||
{{ index $issue.Month 1 }}
|
||||
</div>
|
||||
<div>
|
||||
{{ index $issue.Weekday 1 }}
|
||||
</div>
|
||||
<div>{{ $issue.Day }}.{{ index $issue.Month 2 }}.</div>
|
||||
</div>
|
||||
{{ range $index, $month := .model.Issues }}
|
||||
|
||||
<!-- Month Header -->
|
||||
{{ $first := index $month 0 }}
|
||||
<h2>{{ index $first.Month 1 }}</h2>
|
||||
|
||||
<!-- Issues -->
|
||||
{{ range $issue := $month }}
|
||||
<a href="/{{ $y }}/{{ $issue.Number.Chardata }}">
|
||||
<div>
|
||||
{{ $issue.Number.Chardata }}
|
||||
</div>
|
||||
<div>
|
||||
{{ index $issue.Weekday 1 }}
|
||||
</div>
|
||||
<div>{{ $issue.Day }}.{{ index $issue.Month 2 }}.</div>
|
||||
</a>
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
|
||||
1
views/routes/issue/body.tmpl
Normal file
1
views/routes/issue/body.tmpl
Normal file
@@ -0,0 +1 @@
|
||||
Hello from an issue!
|
||||
Reference in New Issue
Block a user