diff --git a/lib/rss.go b/lib/rss.go
new file mode 100644
index 0000000..28f23d7
--- /dev/null
+++ b/lib/rss.go
@@ -0,0 +1,158 @@
+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
+}
diff --git a/lib/stats.go b/lib/stats.go
index b12bb86..9e663f9 100644
--- a/lib/stats.go
+++ b/lib/stats.go
@@ -35,7 +35,7 @@ func (h handler) load(tmpl string, data interface{}) {
fmt := h.r.FormValue("fmt")
switch fmt {
case "rss":
- err = h.template.rss.ExecuteTemplate(h.w, tmpl+".rss", data)
+ err = loadRss(h.w, tmpl, data)
case "opds":
err = h.template.opds.ExecuteTemplate(h.w, tmpl+".opds", data)
case "json":
diff --git a/lib/template.go b/lib/template.go
index 8b73d3d..2b6fb6f 100644
--- a/lib/template.go
+++ b/lib/template.go
@@ -55,7 +55,6 @@ func GetStatus(h handler) Status {
type Template struct {
html *html_tmpl.Template
- rss *txt_tmpl.Template
opds *txt_tmpl.Template
}
@@ -71,18 +70,6 @@ func InitTemplate(assetsPath string) *Template {
log.Critical("Error loading html templates: ", err)
}
- t.rss, err = txt_tmpl.New("rss").Funcs(txt_tmpl.FuncMap{
- "book_list": func(books, baseURL interface{}) (map[string]interface{}, error) {
- data := make(map[string]interface{}, 2)
- data["Books"] = books
- data["BaseURL"] = baseURL
- return data, nil
- },
- }).ParseGlob(path.Join(templatePath, "*.rss"))
- if err != nil {
- log.Critical("Error loading rss templates: ", err)
- }
-
t.opds, err = txt_tmpl.ParseGlob(path.Join(templatePath, "*.opds"))
if err != nil {
log.Critical("Error loading opds templates: ", err)
diff --git a/templates/book_list.rss b/templates/book_list.rss
deleted file mode 100644
index 89ab859..0000000
--- a/templates/book_list.rss
+++ /dev/null
@@ -1,17 +0,0 @@
-{{$baseURL := .BaseURL}}
-{{range .Books}}
- -
- {{.Title}} - {{index .Authors 0}}
- {{.Description}}
- {{$baseURL}}/book/{{.ID}}
-{{if .Isbn}}
- ISBN: {{.Isbn}}
-{{end}}
-
-{{range .Authors}}
- {{if .}}
- {{.}}
- {{end}}
-{{end}}
-
-{{end}}
diff --git a/templates/list.rss b/templates/list.rss
deleted file mode 100644
index 73a7dab..0000000
--- a/templates/list.rss
+++ /dev/null
@@ -1,14 +0,0 @@
-
-
-
- {{.S.Title}}
- {{range .List.Description}}
- {{.}}
-{{end}}
- {{.S.BaseURL}}/list/{{.List.ListID}}
- {{.List.User.Username}}
-
-{{template "book_list.rss" book_list .List.Books .S.BaseURL}}
-
-
-
diff --git a/templates/news.rss b/templates/news.rss
deleted file mode 100644
index 228c4a9..0000000
--- a/templates/news.rss
+++ /dev/null
@@ -1,20 +0,0 @@
-
-
-
-{{with .S}}
- {{.Title}}
- News of the library
- {{.BaseURL}}/news/
-{{end}}
-
-{{$baseURL := .S.BaseURL}}
-{{range .News}}
- -
- {{.Date}}
- {{.Text}}
- {{$baseURL}}/news/
-
-{{end}}
-
-
-
diff --git a/templates/search.rss b/templates/search.rss
deleted file mode 100644
index bba18d9..0000000
--- a/templates/search.rss
+++ /dev/null
@@ -1,17 +0,0 @@
-
-
-
-{{with .S}}
- {{.Title}}
-{{if .Search}}
- Book search: {{.Search}}
-{{else}}
- Last books added
-{{end}}
- {{.BaseURL}}
-{{end}}
-
-{{template "book_list.rss" book_list .Books .S.BaseURL}}
-
-
-