s1llyw0rdz/web/handler/feed_show.go

132 lines
3 KiB
Go
Raw Permalink Normal View History

2021-12-10 17:48:24 +00:00
package handler
import (
"fmt"
"net/http"
2021-12-14 06:41:05 +00:00
"status/model"
2021-12-10 17:48:24 +00:00
"time"
)
2021-12-14 06:41:05 +00:00
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),
2022-02-20 06:49:50 +00:00
Link: []Link{
{
Rel: "alternate",
2022-02-20 07:08:16 +00:00
Href: fmt.Sprintf("https://status.cafe/statuses/%d", status.Id),
2022-02-20 06:49:50 +00:00
Type: "text/html",
},
},
2021-12-14 06:41:05 +00:00
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{
2022-02-20 06:49:50 +00:00
Type: "html",
Body: status.ContentDisplay(),
2021-12-14 06:41:05 +00:00
},
}
}
2021-12-10 17:48:24 +00:00
func (h *Handler) showFeedView(w http.ResponseWriter, r *http.Request) {
2021-12-14 06:41:05 +00:00
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",
},
},
2021-12-10 17:48:24 +00:00
}
statuses, err := h.storage.StatusFeed()
if err != nil {
serverError(w, err)
return
}
for _, status := range statuses {
2021-12-14 06:41:05 +00:00
feed.Entry = append(feed.Entry, createAtomEntryFromStatus(status))
2021-12-10 17:48:24 +00:00
}
w.Header().Set("Access-Control-Allow-Origin", "*")
w.Header().Set("Content-Type", "application/atom+xml")
2021-12-14 06:41:05 +00:00
var data []byte
data, err = xml.MarshalIndent(&feed, "", " ")
if err != nil {
serverError(w, err)
}
w.Write([]byte(xml.Header + string(data)))
2021-12-10 17:48:24 +00:00
}