176 lines
3.4 KiB
Go
176 lines
3.4 KiB
Go
package storage
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"io/ioutil"
|
|
"os"
|
|
"sort"
|
|
"sync"
|
|
"time"
|
|
|
|
"github.com/gorilla/feeds"
|
|
)
|
|
|
|
type (
|
|
EntryList struct {
|
|
Filename string
|
|
ModTime time.Time
|
|
v []*Entry
|
|
mu sync.RWMutex
|
|
}
|
|
)
|
|
|
|
func (list *EntryList) Len() int { return len(list.v) }
|
|
func (list *EntryList) Swap(i, j int) { list.v[i], list.v[j] = list.v[j], list.v[i] }
|
|
func (list *EntryList) Less(i, j int) bool {
|
|
return time.Time(list.v[i].Date).After(time.Time(list.v[j].Date))
|
|
}
|
|
|
|
func (list *EntryList) modified() (mod bool) {
|
|
info, err := os.Stat(list.Filename)
|
|
if err == nil {
|
|
mod = list.ModTime.Before(info.ModTime())
|
|
list.ModTime = info.ModTime()
|
|
} else {
|
|
mod = true
|
|
}
|
|
return
|
|
}
|
|
|
|
func (list *EntryList) write() (err error) {
|
|
data, err := json.MarshalIndent(list.v, "", " ")
|
|
if err == nil {
|
|
err = ioutil.WriteFile(list.Filename, data, 0644)
|
|
}
|
|
if err == nil {
|
|
list.ModTime = time.Now()
|
|
}
|
|
return
|
|
}
|
|
|
|
func (list *EntryList) read() (err error) {
|
|
if list.modified() {
|
|
list.v = make([]*Entry, 0, len(list.v))
|
|
if data, err := ioutil.ReadFile(list.Filename); err == nil {
|
|
err = json.Unmarshal(data, &list.v)
|
|
}
|
|
}
|
|
return
|
|
}
|
|
|
|
func (list *EntryList) GetEntries() (entry []*Entry, err error) {
|
|
list.mu.RLock()
|
|
defer list.mu.RUnlock()
|
|
|
|
err = list.read()
|
|
entry = list.v
|
|
|
|
return
|
|
}
|
|
|
|
func (list *EntryList) AddEntry(entry *Entry) (err error) {
|
|
list.mu.Lock()
|
|
defer list.mu.Unlock()
|
|
|
|
if err = list.read(); err == nil {
|
|
list.v = append(list.v, entry)
|
|
sort.Sort(list)
|
|
err = list.write()
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
func (list *EntryList) ReadSliceList(oval int, nval int) (entries []*Entry, err error) {
|
|
list.mu.RLock()
|
|
defer list.mu.RUnlock()
|
|
|
|
if nval <= 0 {
|
|
nval = list.Len()
|
|
}
|
|
|
|
if oval <= 0 {
|
|
oval = 0
|
|
}
|
|
|
|
err = list.read()
|
|
if err == nil {
|
|
if oval >= list.Len() {
|
|
entries = nil
|
|
} else if oval+nval >= list.Len() {
|
|
entries = list.v[oval:]
|
|
} else {
|
|
entries = list.v[oval : oval+nval]
|
|
}
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
func (list *EntryList) DeleteElement(pos int) (err error) {
|
|
list.mu.Lock()
|
|
defer list.mu.Unlock()
|
|
|
|
if err = list.read(); err == nil {
|
|
if pos >= 0 && pos < list.Len() {
|
|
if pos == 0 {
|
|
list.v = list.v[pos+1:]
|
|
} else if pos == list.Len()-1 {
|
|
list.v = list.v[:pos]
|
|
} else {
|
|
list.v = append(list.v[:pos], list.v[pos+1:]...)
|
|
}
|
|
|
|
err = list.write()
|
|
}
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
// TODO rutas relativas
|
|
func (list *EntryList) GetFeed() (feed *feeds.Feed) {
|
|
list.mu.RLock()
|
|
defer list.mu.RUnlock()
|
|
|
|
err := list.read()
|
|
|
|
if err == nil {
|
|
feed = &feeds.Feed{
|
|
Title: "danoloan.es muse",
|
|
Link: &feeds.Link{Href: "https://danoloan.es/muse"},
|
|
Description: "bitácora musical de danoloan",
|
|
Author: &feeds.Author{Name: "danoloan", Email: "danolo@danoloan.es"},
|
|
}
|
|
|
|
feed.Items = make([]*feeds.Item, 0, list.Len())
|
|
for _, elem := range list.v {
|
|
item := &feeds.Item{
|
|
Created: time.Time(elem.Date),
|
|
}
|
|
|
|
if elem.Track != "" {
|
|
item.Title = elem.Track
|
|
} else if elem.Album != "" {
|
|
item.Title = elem.Album
|
|
}
|
|
|
|
item.Description = fmt.Sprintf("<p>%s - %s</p>\n", item.Title, elem.Artist)
|
|
if elem.Cover != "" {
|
|
item.Description = fmt.Sprintf("%s<img src=\"%s\"/>\n", item.Description, elem.Cover)
|
|
}
|
|
|
|
if elem.Linkto != "" {
|
|
item.Link = &feeds.Link{Href: elem.Linkto}
|
|
} else {
|
|
item.Link = &feeds.Link{Href: "https://danoloan.es/muse"}
|
|
}
|
|
|
|
feed.Items = append(feed.Items, item)
|
|
}
|
|
}
|
|
|
|
return
|
|
}
|