diff options
-rw-r--r-- | Makefile | 6 | ||||
-rw-r--r-- | config/config.go | 15 | ||||
-rw-r--r-- | main.go | 63 | ||||
-rw-r--r-- | web/web.go | 40 |
4 files changed, 55 insertions, 69 deletions
@@ -8,10 +8,6 @@ default: $(BINARIES) $(BINARIES): $(SOURCES) go build - go build cmd/nekoweb.go - go build cmd/nekocrawl.go - go build cmd/nekoimport.go - .PHONY: deps run @@ -19,4 +15,4 @@ $(BINARIES): $(SOURCES) deps: go get $(DEPS) run: - ./nekoweb config.json + ./neko -update -serve diff --git a/config/config.go b/config/config.go index 59baa2b..bcd1d27 100644 --- a/config/config.go +++ b/config/config.go @@ -7,11 +7,11 @@ import ( ) type Settings struct { - DBServer string - WebServer string - Username string - Realm string - DigestPassword string + DBServer string `json:"db"` + WebServer string `json:"web"` + Username string `json:"username"` + DigestPassword string `json:"password"` + StaticDir string `json:"static_dir"` } var Config Settings @@ -19,11 +19,10 @@ var Config Settings func Read(filename string) { file, e := ioutil.ReadFile(filename) if e != nil { - log.Fatal("Can not read config file", e) + log.Fatal("Can not read config file\n", e) } - e = json.Unmarshal(file, &Config) if e != nil { - log.Fatal("Config read error", e) + log.Fatal("Config read error\n", e) } } @@ -1,57 +1,42 @@ package main import ( - "fmt" + "flag" "adammathes.com/neko/config" - "adammathes.com/neko/crawler" - "adammathes.com/neko/importer" + "adammathes.com/neko/crawler" "adammathes.com/neko/models" "adammathes.com/neko/models/feed" "adammathes.com/neko/web" "log" - "os" ) func main() { - // TODO: change this - config.Read("./config.json") + var serve, update bool + var configFile, newFeed string + + flag.StringVar(&configFile, "c", "config.json", "`configuration` file") + flag.BoolVar(&update, "update", false, "update items by fetching feeds") + flag.BoolVar(&serve, "serve", false, "run http server") + flag.StringVar(&newFeed, "add", "", "add feed `http://example.com/rss.xml`") + flag.Parse() + + if !update && !serve { + flag.Usage() + return + } + + config.Read(configFile) models.InitDB(config.Config.DBServer) - if len(os.Args) < 2 { - fmt.Printf("usage: neko [web|addfeed|crawl]\n") - fmt.Printf("addfeed <url> -- add a new feed from <url>\n") - return + + if newFeed != "" { + feed.NewFeed(newFeed) } - cmd := os.Args[1] - switch cmd { - case "web": + if serve { log.Printf("starting web server at %s", config.Config.WebServer) web.Serve() - case "addfeed": - addFeed() - case "crawl": - crawl() - case "import": - importLegacy() - default: - panic("not a valid command") } -} - -func addFeed() { - if len(os.Args) < 2 { - log.Fatal("need a valid url") - } - url := os.Args[2] - feed.NewFeed(url) -} - -func importLegacy() { - json_file := os.Args[2] - log.Printf("importing json file from: %s", json_file) - importer.ImportJSON(json_file) -} - -func crawl() { - crawler.Crawl() + if update { + crawler.Crawl() + } } @@ -1,19 +1,20 @@ package web import ( - "encoding/json" - "fmt" - "log" "adammathes.com/neko/config" "adammathes.com/neko/models/feed" "adammathes.com/neko/models/item" + "encoding/json" + "fmt" + "golang.org/x/crypto/bcrypt" + "log" "net/http" + "path" "strconv" - "golang.org/x/crypto/bcrypt" ) func indexHandler(w http.ResponseWriter, r *http.Request) { - http.ServeFile(w, r, "static/ui.html") + http.ServeFile(w, r, staticFilePath("ui.html")) } func streamHandler(w http.ResponseWriter, r *http.Request) { @@ -40,7 +41,7 @@ func streamHandler(w http.ResponseWriter, r *http.Request) { if r.FormValue("starred") != "" { starred_only = true } - + var items []*item.Item items, err := item.Filter(int64(max_id), feed_id, unread_only, starred_only) if err != nil { @@ -101,39 +102,39 @@ func feedHandler(w http.ResponseWriter, r *http.Request) { } var AuthCookie = "auth" -var SecondsInAYear = 60*60*24*365 +var SecondsInAYear = 60 * 60 * 24 * 365 func loginHandler(w http.ResponseWriter, r *http.Request) { switch r.Method { case "GET": - http.ServeFile(w, r, "static/login.html") + http.ServeFile(w, r, staticFilePath("login.html")) case "POST": - password := r.FormValue("password") + password := r.FormValue("password") if password == config.Config.DigestPassword { - v,_ := bcrypt.GenerateFromPassword([]byte(password), 0) - c := http.Cookie{ Name: AuthCookie, Value: string(v), Path: "/", MaxAge: SecondsInAYear, HttpOnly:false } + v, _ := bcrypt.GenerateFromPassword([]byte(password), 0) + c := http.Cookie{Name: AuthCookie, Value: string(v), Path: "/", MaxAge: SecondsInAYear, HttpOnly: false} http.SetCookie(w, &c) http.Redirect(w, r, "/", 307) } else { http.Error(w, "bad login", 401) - } + } default: http.Error(w, "nope", 500) } } func logoutHandler(w http.ResponseWriter, r *http.Request) { - c := http.Cookie{ Name: AuthCookie, MaxAge: 0, Path: "/", HttpOnly:false } + c := http.Cookie{Name: AuthCookie, MaxAge: 0, Path: "/", HttpOnly: false} http.SetCookie(w, &c) fmt.Fprintf(w, "you are logged out") } func Authenticated(r *http.Request) bool { - pc,err := r.Cookie("auth") + pc, err := r.Cookie("auth") if err != nil { return false } - err = bcrypt.CompareHashAndPassword( []byte(pc.Value), []byte(config.Config.DigestPassword) ) + err = bcrypt.CompareHashAndPassword([]byte(pc.Value), []byte(config.Config.DigestPassword)) if err == nil { return true } @@ -151,7 +152,7 @@ func AuthWrap(wrapped http.HandlerFunc) http.HandlerFunc { } func Serve() { - fs := http.FileServer(http.Dir("static")) + fs := http.FileServer(http.Dir(config.Config.StaticDir)) http.Handle("/static/", http.StripPrefix("/static/", fs)) http.HandleFunc("/stream/", AuthWrap(streamHandler)) @@ -163,6 +164,11 @@ func Serve() { http.HandleFunc("/", AuthWrap(indexHandler)) - http.ListenAndServe(config.Config.WebServer, nil) } + +// given a path, prepend config.Config.StaticDir +// TODO: compile these into the binary to remove dependency on the files +func staticFilePath(p string) string { + return path.Join(config.Config.StaticDir, p) +} |