package main import ( "encoding/json" "fmt" "net/http" "net/url" "text/template" "time" ) var SharedCache *Datastore type Link struct { Url string `json:"url"` PublishedDate string `json:"publishedDate"` Title string `json:"title"` } // Healthcheck route // // Confirms that the app is alive without guarantees // about it being fully-functional. func healthcheck(w http.ResponseWriter, r *http.Request) { w.WriteHeader(200) } // About page // // Static content for the about page. func about(w http.ResponseWriter, r *http.Request) { tmpl, _ := template.New("about.html.tmpl").ParseFiles("templates/about.html.tmpl") tmpl.Execute(w, nil) } // Feeds list // // Lists all feed elements in store. func listContent(w http.ResponseWriter, r *http.Request) { links := []Link{} for _, feed := range SharedCache.List("feeds") { var formattedItems []Link json.Unmarshal([]byte(feed), &formattedItems) links = append(links, formattedItems...) } tmpl, _ := template.New("index.html.tmpl").ParseFiles("templates/index.html.tmpl") tmpl.Execute(w, links) } // Manage content // // Interface to add new feed subscriptions and get a list // of current subs. func manageContent(w http.ResponseWriter, r *http.Request) { if r.Method == "POST" { r.ParseForm() urlValue := r.PostFormValue("url") if _, err := url.Parse(urlValue); err != nil { w.WriteHeader(400) return } cacheKey := fmt.Sprintf("feedurl:%s", urlValue) SharedCache.Set(cacheKey, urlValue) go fetchFeed(urlValue) w.WriteHeader(201) } allFeeds := SharedCache.List("feedurl") type ManageTmplData struct { Feeds map[string]string } tmpl, _ := template.New("manage.html.tmpl").ParseFiles("templates/manage.html.tmpl") tmpl.Execute(w, ManageTmplData{Feeds: allFeeds}) } var routeMap = map[string]http.HandlerFunc{ "/": listContent, "/about": about, "/manage": manageContent, "/ping": healthcheck, } func main() { SharedCache = &Datastore{ Data: map[string]string{}, } if existingStore := FromFile("datastore.json"); existingStore != nil { SharedCache = existingStore } api := API{StaticRoot: "./static"} for route, handler := range routeMap { api.AddRoute(route, handler) } go func() { for { refreshFeeds() time.Sleep(10 * time.Minute) } }() api.Start(":9000") }