|
|
|
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
|
|
|
|
}
|