package storia import ( "encoding/json" "math" "os" "sort" "strconv" "strings" "git.phc.dm.unipi.it/phc/website/util" ) type StoriaService interface { GetStoria() ([]*GenericEvent, error) } type GenericEvent struct { // Campi principali Type string `json:"type"` Date string `json:"date"` // Altri campi utilizzati ogni tanto Title string `json:"title"` Description string `json:"description"` // Se il tipo di evento è riferito ad un utente usiamo anche questo campo apposta Uid string `json:"uid"` FullName string `json:"fullName"` // Se il tipo è "spacer" questa è la sua dimensione Size int `json:"size"` // Icona opzionale per il tipo "simple" Icon string `json:"icon"` } type Macchinista struct { Uid string `json:"uid"` FullName string `json:"fullName"` EntryDate string `json:"entryDate"` ExitDate string `json:"exitDate"` } type storiaDB struct { Macchinisti []*Macchinista `json:"macchinisti"` GenericEvent []*GenericEvent `json:"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)) return withSpacers(events), nil } func (db *JsonFileStoria) GetRawStoria() (*storiaDB, error) { var rawHistory storiaDB historyDB, err := os.ReadFile(db.Path) if err != nil { return nil, err } if err := json.Unmarshal(historyDB, &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 "storia.json" è statico } return year }