s1llyw0rdz/web/handler/feed_show.go
2021-12-14 07:41:05 +01:00

131 lines
3 KiB
Go

package handler
import (
"fmt"
"net/http"
"status/model"
"time"
)
import (
"encoding/xml"
)
type Feed struct {
XMLName xml.Name `xml:"http://www.w3.org/2005/Atom feed"`
Title string `xml:"title"`
ID string `xml:"id"`
Link []Link `xml:"link"`
Updated TimeStr `xml:"updated"`
Author *Person `xml:"author"`
Icon string `xml:"icon,omitempty"`
Logo string `xml:"logo,omitempty"`
Subtitle string `xml:"subtitle,omitempty"`
Entry []*Entry `xml:"entry"`
}
type Entry struct {
Title string `xml:"title"`
ID string `xml:"id"`
Link []Link `xml:"link"`
Published TimeStr `xml:"published"`
Updated TimeStr `xml:"updated"`
Author *Person `xml:"author"`
Summary *Text `xml:"summary"`
Content *Text `xml:"content"`
}
type Link struct {
Rel string `xml:"rel,attr,omitempty"`
Href string `xml:"href,attr"`
Type string `xml:"type,attr,omitempty"`
HrefLang string `xml:"hreflang,attr,omitempty"`
Title string `xml:"title,attr,omitempty"`
Length uint `xml:"length,attr,omitempty"`
}
type Person struct {
Name string `xml:"name"`
URI string `xml:"uri,omitempty"`
Email string `xml:"email,omitempty"`
InnerXML string `xml:",innerxml"`
}
type Text struct {
Type string `xml:"type,attr"`
Body string `xml:",chardata"`
}
type TimeStr string
func Time(t time.Time) TimeStr {
return TimeStr(t.Format("2006-01-02T15:04:05-07:00"))
}
func createAtomEntryFromStatus(status model.Status) *Entry {
return &Entry{
Title: fmt.Sprintf("%s %s %s", status.User, status.Face, truncate(status.Content, 50)),
ID: fmt.Sprintf("https://status.cafe/users/%s/%d", status.User, status.Id),
//Link: []Link{
// {
// Rel: "alternate",
// Href: fmt.Sprintf("https://status.cafe/users/%s/%d", status.User, status.Id),
// Type: "text/html",
// },
//},
Updated: Time(status.CreatedAt),
Published: Time(status.CreatedAt),
Author: &Person{
Name: status.User,
URI: fmt.Sprintf("https://status.cafe/users/%s", status.User),
},
Content: &Text{
Type: "text",
Body: status.Content,
},
}
}
func (h *Handler) showFeedView(w http.ResponseWriter, r *http.Request) {
feed := Feed{
Title: "status.cafe",
ID: "https://status.cafe/",
Subtitle: "Your friends' updates",
Icon: "/assets/icon.png",
Author: &Person{
Name: "status.cafe",
URI: "https://status.cafe",
},
Updated: Time(time.Now()),
Link: []Link{
{
Rel: "self",
Href: "https://status.cafe/feed.atom",
},
{
Rel: "alternate",
Type: "text/html",
Href: "https://status.cafe",
},
},
}
statuses, err := h.storage.StatusFeed()
if err != nil {
serverError(w, err)
return
}
for _, status := range statuses {
feed.Entry = append(feed.Entry, createAtomEntryFromStatus(status))
}
w.Header().Set("Access-Control-Allow-Origin", "*")
w.Header().Set("Content-Type", "application/atom+xml")
var data []byte
data, err = xml.MarshalIndent(&feed, "", " ")
if err != nil {
serverError(w, err)
}
w.Write([]byte(xml.Header + string(data)))
}