You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
website/storia/storia.go

154 lines
3.3 KiB
Go

package storia
import (
"bytes"
"math"
"os"
"sort"
"strconv"
"strings"
"git.phc.dm.unipi.it/phc/website/articles"
"git.phc.dm.unipi.it/phc/website/util"
"gopkg.in/yaml.v3"
)
type StoriaService interface {
GetStoria() ([]*GenericEvent, error)
}
type GenericEvent struct {
// Campi principali
Type string `yaml:"type"`
Date string `yaml:"date"`
// Altri campi utilizzati ogni tanto
Title string `yaml:"title"`
Description string `yaml:"description"`
// Se il tipo di evento è riferito ad un utente usiamo anche questo campo apposta
Uid string `yaml:"uid"`
FullName string `yaml:"fullName"`
// Se il tipo è "spacer" questa è la sua dimensione
Size int `yaml:"size"`
// Icona opzionale per il tipo "simple"
Icon string `yaml:"icon"`
}
type Macchinista struct {
Uid string `yaml:"uid"`
FullName string `yaml:"fullName"`
EntryDate string `yaml:"entryDate"`
ExitDate string `yaml:"exitDate"`
}
type storiaDB struct {
Macchinisti []*Macchinista `yaml:"macchinisti"`
GenericEvent []*GenericEvent `yaml:"eventi"`
}
type JsonFileStoria struct {
Path string
}
type byEventDateDescending []*GenericEvent
func (m byEventDateDescending) Len() int {
return len(m)
}
func (m byEventDateDescending) Swap(i, j int) {
m[i], m[j] = m[j], m[i]
}
func (m byEventDateDescending) Less(i, j int) bool {
return m[i].Date > m[j].Date
}
func (db *JsonFileStoria) GetStoria() ([]*GenericEvent, error) {
history, err := db.GetRawStoria()
if err != nil {
return nil, err
}
events := history.GenericEvent[:]
for _, m := range history.Macchinisti {
if m.ExitDate != "" {
events = append(events, &GenericEvent{
Type: "exit-macchinista",
Uid: m.Uid,
FullName: m.FullName,
Date: m.ExitDate,
})
}
if m.EntryDate != "" {
events = append(events, &GenericEvent{
Type: "entry-macchinista",
Uid: m.Uid,
FullName: m.FullName,
Date: m.EntryDate,
})
}
}
sort.Sort(byEventDateDescending(events))
// render descriptions to markdown
for _, event := range events {
var buf bytes.Buffer
if err := articles.Markdown.Convert([]byte(event.Description), &buf); err != nil {
return nil, err
}
event.Description = buf.String()
}
return withSpacers(events), nil
}
func (db *JsonFileStoria) GetRawStoria() (*storiaDB, error) {
var rawHistory storiaDB
f, err := os.Open(db.Path)
if err != nil {
return nil, err
}
if err := yaml.NewDecoder(f).Decode(&rawHistory); err != nil {
return nil, err
}
return &rawHistory, nil
}
func withSpacers(events []*GenericEvent) []*GenericEvent {
// crea un nuovo slice con capacità già almeno "len(events)"
newEvents := make([]*GenericEvent, 0, len(events))
for i := 0; i < len(events)-1; i++ {
newEvents = append(newEvents, events[i])
delta := util.Abs(getDateYear(events[i+1].Date) - getDateYear(events[i].Date))
if delta > 1 {
logDelta := int(math.Log(float64(delta)))
newEvents = append(newEvents, &GenericEvent{
Type: "spacer",
Size: logDelta,
})
}
}
newEvents = append(newEvents, events[len(events)-1])
return newEvents
}
func getDateYear(date string) int {
year, err := strconv.Atoi(strings.Split(date, "/")[0])
if err != nil {
panic(err) // Tanto nel caso si nota in fase di sviluppo visto che "_content/storia.json" è statico
}
return year
}