2022-02-12 10:29:56 +01:00
|
|
|
package storage
|
|
|
|
|
|
|
|
import (
|
|
|
|
"encoding/json"
|
|
|
|
"fmt"
|
|
|
|
"io/ioutil"
|
|
|
|
"os"
|
|
|
|
"sort"
|
|
|
|
"sync"
|
|
|
|
"time"
|
|
|
|
|
|
|
|
"github.com/gorilla/feeds"
|
|
|
|
)
|
|
|
|
|
|
|
|
type (
|
|
|
|
EntryMap struct {
|
|
|
|
Filename string
|
|
|
|
modtime time.Time
|
|
|
|
mapped map[string]*Entry
|
|
|
|
sorted []*Entry
|
|
|
|
mu sync.RWMutex
|
|
|
|
}
|
|
|
|
entryList []*Entry
|
|
|
|
)
|
|
|
|
|
2022-02-16 23:59:19 +01:00
|
|
|
// entryList
|
|
|
|
|
|
|
|
func (list entryList) Len() int { return len(list) }
|
|
|
|
func (list entryList) Swap(i, j int) { list[i], list[j] = list[j], list[i] }
|
|
|
|
func (list entryList) Less(i, j int) bool {
|
|
|
|
return time.Time(list[i].Date).After(time.Time(list[j].Date))
|
|
|
|
}
|
2022-02-12 10:29:56 +01:00
|
|
|
|
|
|
|
func (list *EntryMap) 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 *EntryMap) write() (err error) {
|
|
|
|
data, err := json.MarshalIndent(list.mapped, "", " ")
|
|
|
|
if err == nil {
|
|
|
|
err = ioutil.WriteFile(list.Filename, data, 0644)
|
|
|
|
}
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
func (list *EntryMap) read() (err error) {
|
|
|
|
if list.modified() {
|
|
|
|
if data, err := ioutil.ReadFile(list.Filename); err == nil {
|
|
|
|
|
|
|
|
// read map
|
|
|
|
list.mapped = make(map[string]*Entry)
|
|
|
|
err = json.Unmarshal(data, &list.mapped)
|
|
|
|
|
|
|
|
// sort list
|
|
|
|
list.sorted = make([]*Entry, 0, len(list.mapped))
|
|
|
|
for _, entry := range list.mapped {
|
|
|
|
list.sorted = append(list.sorted, entry)
|
|
|
|
}
|
|
|
|
sort.Sort(entryList(list.sorted))
|
|
|
|
|
|
|
|
// assign prev/next
|
|
|
|
for index, value := range list.sorted {
|
|
|
|
if index-1 >= 0 {
|
|
|
|
value.Next = list.sorted[index-1]
|
|
|
|
}
|
|
|
|
if index+1 < len(list.sorted) {
|
|
|
|
value.Prev = list.sorted[index+1]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2022-02-16 23:59:19 +01:00
|
|
|
func (list *EntryMap) GetEntry(uuid string) (result Entry, err error) {
|
2022-02-12 10:29:56 +01:00
|
|
|
list.mu.Lock()
|
|
|
|
defer list.mu.Unlock()
|
|
|
|
|
2022-02-16 23:59:19 +01:00
|
|
|
if err = list.read(); err == nil {
|
|
|
|
result = *list.mapped[uuid]
|
2022-02-12 10:29:56 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2022-02-16 23:59:19 +01:00
|
|
|
func (list *EntryMap) GetEntries() (result []Entry, err error) {
|
|
|
|
list.mu.RLock()
|
|
|
|
defer list.mu.RUnlock()
|
2022-02-12 10:29:56 +01:00
|
|
|
|
2022-02-16 23:59:19 +01:00
|
|
|
err = list.read()
|
|
|
|
|
|
|
|
if err == nil {
|
|
|
|
result = make([]Entry, len(list.sorted))
|
|
|
|
for index, elem := range list.sorted {
|
|
|
|
result[index] = *elem
|
|
|
|
}
|
2022-02-12 10:29:56 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2022-02-16 23:59:19 +01:00
|
|
|
func (list *EntryMap) GetFeed() (feed *feeds.Feed) {
|
2022-02-12 10:29:56 +01:00
|
|
|
feed = &feeds.Feed{
|
|
|
|
Title: "danoloan.es igar",
|
|
|
|
Link: &feeds.Link{Href: "https://danoloan.es/igar/"},
|
|
|
|
Description: "bitácora fotográfica de danoloan",
|
|
|
|
Author: &feeds.Author{Name: "danoloan", Email: "danolo@danoloan.es"},
|
|
|
|
}
|
|
|
|
|
|
|
|
feed.Items = make([]*feeds.Item, 0, list.Len())
|
|
|
|
|
|
|
|
elements, err := list.GetEntries()
|
|
|
|
if err != nil {
|
|
|
|
for _, elem := range elements {
|
|
|
|
item := &feeds.Item{
|
|
|
|
Title: elem.Description,
|
|
|
|
Link: &feeds.Link{Href: fmt.Sprintf("https://danoloan.es/igar/view?uuid=%s", elem.Post)},
|
|
|
|
Description: fmt.Sprintf("<p>%s</p>\n<div>\n", elem.Description),
|
|
|
|
Created: time.Time(elem.Date),
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, media := range elem.Media {
|
|
|
|
if media.Type == "GraphImage" {
|
|
|
|
// TODO ruta relativa al proxy
|
|
|
|
item.Description = fmt.Sprintf("%s\n\t<img src=/igar/img/%s/%s>", item.Description, elem.Post, media.File)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
item.Description = fmt.Sprintf("%s\n</div>", item.Description)
|
|
|
|
|
|
|
|
feed.Items = append(feed.Items, item)
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2022-02-16 23:59:19 +01:00
|
|
|
func (list *EntryMap) Len() int { return len(list.mapped) }
|
2022-02-12 10:29:56 +01:00
|
|
|
|
2022-02-16 23:59:19 +01:00
|
|
|
func (list *EntryMap) AddEntry(entry *Entry) (err error) {
|
|
|
|
list.mu.Lock()
|
|
|
|
defer list.mu.Unlock()
|
|
|
|
|
|
|
|
list.read()
|
|
|
|
|
|
|
|
if entry != nil {
|
|
|
|
list.mapped[entry.Post] = entry
|
|
|
|
err = list.write()
|
|
|
|
}
|
|
|
|
|
|
|
|
return
|
2022-02-12 10:29:56 +01:00
|
|
|
}
|
|
|
|
|
2022-02-16 23:59:19 +01:00
|
|
|
func (list *EntryMap) RemoveEntry(uuid string) (entry *Entry) {
|
|
|
|
list.mu.Lock()
|
|
|
|
defer list.mu.Unlock()
|
|
|
|
|
|
|
|
list.read()
|
|
|
|
|
|
|
|
entry, ok := list.mapped[uuid]
|
|
|
|
if ok {
|
|
|
|
delete(list.mapped, uuid)
|
2022-02-12 10:29:56 +01:00
|
|
|
}
|
2022-02-16 23:59:19 +01:00
|
|
|
|
|
|
|
list.write()
|
|
|
|
|
|
|
|
return
|
2022-02-12 10:29:56 +01:00
|
|
|
}
|