package controllers import ( "fmt" "mime" "net/http" "path/filepath" "strings" "time" "git.kirsle.net/apps/gophertype/pkg/common" "git.kirsle.net/apps/gophertype/pkg/glue" "git.kirsle.net/apps/gophertype/pkg/models" "git.kirsle.net/apps/gophertype/pkg/responses" "git.kirsle.net/apps/gophertype/pkg/settings" "github.com/gorilla/feeds" ) func init() { glue.Register(glue.Endpoint{ Path: "/blog.rss", Methods: []string{"GET"}, Handler: RSSFeed, }) glue.Register(glue.Endpoint{ Path: "/blog.atom", Methods: []string{"GET"}, Handler: RSSFeed, }) glue.Register(glue.Endpoint{ Path: "/blog.json", Methods: []string{"GET"}, Handler: RSSFeed, }) } // RSSFeed returns the RSS (or Atom) feed for the blog. func RSSFeed(w http.ResponseWriter, r *http.Request) { // Get the first (admin) user for the feed. admin, err := models.Users.FirstAdmin() if err != nil { responses.Error(w, r, http.StatusBadRequest, "Blog isn't ready yet.") return } feed := &feeds.Feed{ Title: settings.Current.Title, Link: &feeds.Link{Href: settings.Current.BaseURL}, Description: settings.Current.Description, Author: &feeds.Author{ Name: admin.Name, Email: admin.Email, }, Created: time.Now(), Items: []*feeds.Item{}, } pp, err := models.Posts.GetIndexPosts(models.Public, 1, settings.Current.PostsPerPage) if err != nil { responses.Error(w, r, http.StatusInternalServerError, err.Error()) return } for _, post := range pp.Posts { // If blog is NSFW, allow feed readers to skip the age gate. var urlSuffix string if settings.Current.NSFW { urlSuffix = "?over18=1" } item := &feeds.Item{ Id: fmt.Sprintf("%d", post.ID), Title: post.Title, Link: &feeds.Link{Href: settings.Current.BaseURL + "/" + post.Fragment + urlSuffix}, // Description is the HTML with relative links made absolute. Description: common.ReplaceRelativeLinksToAbsolute(settings.Current.BaseURL, string(post.HTML())), Created: post.CreatedAt, } // Attach the thumbnail? if post.Thumbnail != "" { item.Enclosure = &feeds.Enclosure{ Url: common.ToAbsoluteURL(post.Thumbnail, settings.Current.BaseURL), Type: mime.TypeByExtension(filepath.Ext(post.Thumbnail)), } } feed.Items = append(feed.Items, item) } // What format to encode it in? if strings.Contains(r.URL.Path, ".atom") { atom, _ := feed.ToAtom() w.Header().Set("Content-Type", "application/atom+xml; encoding=utf-8") w.Write([]byte(atom)) } else if strings.Contains(r.URL.Path, ".json") { jsonData, _ := feed.ToJSON() w.Header().Set("Content-Type", "application/json; encoding=utf-8") w.Write([]byte(jsonData)) } else { rss, _ := feed.ToRss() w.Header().Set("Content-Type", "application/rss+xml; encoding=utf-8") w.Write([]byte(rss)) } }