diff options
Diffstat (limited to 'web')
-rw-r--r-- | web/web.go | 131 |
1 files changed, 131 insertions, 0 deletions
diff --git a/web/web.go b/web/web.go new file mode 100644 index 0000000..794a3d7 --- /dev/null +++ b/web/web.go @@ -0,0 +1,131 @@ +package web + +import ( + "encoding/json" + "github.com/abbot/go-http-auth" + "log" + "neko/config" + "neko/models/feed" + "neko/models/item" + "net/http" + "strconv" +) + +func indexHandler(w http.ResponseWriter, r *http.Request) { + http.ServeFile(w, r, "static/ui.html") +} + +func streamHandler(w http.ResponseWriter, r *http.Request) { + + max_id := 0 + if r.FormValue("max_id") != "" { + max_id, _ = strconv.Atoi(r.FormValue("max_id")) + } + + feed_id := int64(0) + if r.FormValue("feed_url") != "" { + feed_url := r.FormValue("feed_url") + var f feed.Feed + f.ByUrl(feed_url) + feed_id = f.Id + } + + unread_only := true + if r.FormValue("read_filter") != "" { + unread_only = false + } + + var items []*item.Item + items, err := item.Filter(int64(max_id), feed_id, unread_only) + if err != nil { + log.Println(err) + } + + w.Header().Set("Content-Type", "application/json") + js, _ := json.Marshal(items) + w.Write(js) +} + +func itemHandler(w http.ResponseWriter, r *http.Request) { + var i item.Item + err := json.NewDecoder(r.Body).Decode(&i) + if err != nil { + log.Println(err) + } else { + i.Save() + } + defer r.Body.Close() +} + +func feedHandler(w http.ResponseWriter, r *http.Request) { + if r.Method == "GET" { + feeds, err := feed.All() + if err != nil { + log.Println(err) + } + + js, err := json.Marshal(feeds) + if err != nil { + log.Println(err) + } + w.Write(js) + return + } + + var f feed.Feed + err := json.NewDecoder(r.Body).Decode(&f) + if err != nil { + log.Println(err) + } + + switch r.Method { + case "POST": + feed.NewFeed(f.Url) + case "PUT": + f.Update() + case "DELETE": + feed_id, err := strconv.Atoi(r.URL.Path[len("/feed/"):]) + if err != nil { + log.Println(err) + return + } + f.Id = int64(feed_id) + f.Delete() + } +} + +func Secret(user, realm string) string { + if user == config.Config.Username { + return config.Config.DigestPassword + } + return "" +} + +func AuthWrap(a *auth.DigestAuth, wrapped http.HandlerFunc) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + if username, authinfo := a.CheckAuth(r); username == "" { + a.RequireAuth(w, r) + } else { + _ = &auth.AuthenticatedRequest{Request: *r, Username: username} + if authinfo != nil { + w.Header().Set(a.Headers.V().AuthInfo, *authinfo) + } + wrapped(w, r) + } + } +} + +func Serve() { + authenticator := auth.NewDigestAuthenticator(config.Config.Realm, Secret) + authenticator.PlainTextSecrets = true + + fs := http.FileServer(http.Dir("static")) + http.Handle("/static/", http.StripPrefix("/static/", fs)) + + http.HandleFunc("/stream/", AuthWrap(authenticator, streamHandler)) + http.HandleFunc("/item/", AuthWrap(authenticator, itemHandler)) + http.HandleFunc("/feed/", AuthWrap(authenticator, feedHandler)) + http.HandleFunc("/", AuthWrap(authenticator, indexHandler)) + + log.Fatal(http.ListenAndServe(config.Config.WebServer, nil)) +} |