This repository has been archived on 2025-03-01. You can view files and clone it, but cannot push or open issues or pull requests.
trantor/lib/rss.go

159 lines
3.4 KiB
Go
Raw Normal View History

package trantor
import (
"encoding/xml"
"errors"
"net/http"
"strings"
"gitlab.com/trantor/trantor/lib/database"
)
type rss struct {
XMLName xml.Name `xml:"rss"`
Version string `xml:"version,attr"`
Channel channel `xml:"channel"`
}
type channel struct {
Title string `xml:"title"`
Description string `xml:"description"`
Link string `xml:"link"`
ManagingEditor string `xml:"managingEditor,omitempty"`
Item []item `xml:"item"`
}
type item struct {
Title string `xml:"title"`
Description string `xml:"description"`
Link string `xml:"link"`
GUID *guid `xml:"guid,omitempty"`
Enclosure *enclosure `xml:"enclosure,omitempty"`
Category []string `xml:"category"`
}
type guid struct {
IsPermaLink bool `xml:"isPermaLink,attr"`
Chardata string `xml:",chardata"`
}
type enclosure struct {
URL string `xml:"url,attr"`
Length int `xml:"length,attr"`
Type string `xml:"type,attr"`
}
func loadRss(w http.ResponseWriter, tmpl string, data interface{}) error {
var err error
var res rss
switch tmpl {
case "news":
res, err = newsRss(data)
case "search":
res, err = searchRss(data)
case "list":
res, err = listRss(data)
}
if err != nil {
return err
}
w.Write([]byte(xml.Header))
enc := xml.NewEncoder(w)
enc.Indent("", " ")
return enc.Encode(res)
}
func newsRss(data interface{}) (rss, error) {
news, ok := data.(newsData)
if !ok {
return rss{}, errors.New("Data is not valid")
}
feed := rss{
Version: "2.0",
Channel: channel{
Title: news.S.Title,
Description: "News of the library",
Link: news.S.BaseURL + "/news/",
Item: make([]item, len(news.News)),
},
}
for i, n := range news.News {
feed.Channel.Item[i] = item{
Title: n.Date,
Description: n.Text,
Link: news.S.BaseURL + "/news/",
}
}
return feed, nil
}
func searchRss(data interface{}) (rss, error) {
search, ok := data.(searchData)
if !ok {
return rss{}, errors.New("Data is not valid")
}
description := "Last books added"
link := search.S.BaseURL
if search.S.Search != "" {
description = "Book search: " + search.S.Search
link += "/search/?q=" + search.S.Search
}
feed := rss{
Version: "2.0",
Channel: channel{
Title: search.S.Title,
Description: description,
Link: link,
Item: bookListRss(search.Books, search.S.BaseURL),
},
}
return feed, nil
}
func listRss(data interface{}) (rss, error) {
lb, ok := data.(listData)
if !ok {
return rss{}, errors.New("Data is not valid")
}
feed := rss{
Version: "2.0",
Channel: channel{
Title: lb.S.Title,
Description: strings.Join(lb.List.Description, "\n"),
Link: lb.S.BaseURL + "/list/" + lb.List.ListID,
ManagingEditor: lb.List.User.Username,
Item: bookListRss(lb.List.Books, lb.S.BaseURL),
},
}
return feed, nil
}
func bookListRss(books []database.Book, baseURL string) []item {
items := make([]item, len(books))
for i, b := range books {
items[i] = item{
Title: b.Title,
Description: b.Description,
Link: baseURL + "/download/" + b.ID,
Category: b.Tags,
Enclosure: &enclosure{
URL: baseURL + "/download/" + b.ID + "/" + b.Title + ".epub",
Length: b.FileSize,
Type: "application/epub+zip",
},
}
if b.Isbn != "" {
items[i].GUID = &guid{
IsPermaLink: false,
Chardata: "ISBN: " + b.Isbn,
}
}
}
return items
}