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 }