package postctl import ( "fmt" "net/http" "regexp" "strings" "time" "github.com/gorilla/feeds" "github.com/kirsle/blog/models/posts" "github.com/kirsle/blog/models/settings" "github.com/kirsle/blog/models/users" "github.com/kirsle/blog/src/markdown" "github.com/kirsle/blog/src/responses" "github.com/kirsle/blog/src/types" ) // Feed configuration. TODO make configurable. var ( FeedPostsPerPage = 20 reRelativeLink = regexp.MustCompile(` (src|href|poster)=(['"])/([^'"]+)['"]`) ) func feedHandler(w http.ResponseWriter, r *http.Request) { config, _ := settings.Load() admin, err := users.Load(1) if err != nil { responses.Error(w, r, "Blog isn't ready yet.") return } feed := &feeds.Feed{ Title: config.Site.Title, Link: &feeds.Link{Href: config.Site.URL}, Description: config.Site.Description, Author: &feeds.Author{ Name: admin.Name, Email: admin.Email, }, Created: time.Now(), } feed.Items = []*feeds.Item{} for i, p := range RecentPosts(r, "", "") { post, _ := posts.Load(p.ID) // Render the post to HTML. var rendered string if post.ContentType == string(types.MARKDOWN) { rendered = markdown.RenderTrustedMarkdown(post.Body) } else { rendered = post.Body } // Make relative links absolute. matches := reRelativeLink.FindAllStringSubmatch(rendered, -1) for _, match := range matches { var ( attr = match[1] quote = match[2] uri = match[3] absURI = config.Site.URL + "/" + uri new = fmt.Sprintf(" %s%s%s%s", attr, quote, absURI, quote, ) ) rendered = strings.Replace(rendered, match[0], new, 1) } feed.Items = append(feed.Items, &feeds.Item{ Id: fmt.Sprintf("%d", p.ID), Title: p.Title, Link: &feeds.Link{Href: config.Site.URL + "/" + p.Fragment}, Description: rendered, Created: p.Created, }) if i == FeedPostsPerPage-1 { break } } // 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)) } }