package main import ( "fmt" "log" "net/http" "os" "os/signal" "strconv" "strings" "syscall" "time" "github.com/gorilla/handlers" "github.com/gorilla/mux" "github.com/gorilla/sessions" "github.com/justinas/alice" ) const AppName = "ribbit" const DbName = AppName + ".db" var sessionStore *sessions.CookieStore var r *mux.Router var m *model var scheduler *JobScheduler func main() { var err error if m, err = NewModel(); err != nil { errorExit("Unable to initialize Model: " + err.Error()) } if len(os.Args) > 2 { key, val := os.Args[1], os.Args[2] switch key { case "--add-user-sub": if len(os.Args) < 3 { errorExit("Usage: --add-user-sub \nFor a list of slugs, use --list-comics") } slug := os.Args[3] var u *User if u, err = m.GetUserByName(val); err != nil { errorExit("Couldn't find a user with the username " + val) } pts := strings.Split(slug, ";") if len(pts) != 2 { errorExit("Invalid slug given: " + slug) } _, err := m.GetComic(pts[0], pts[1]) if err != nil { errorExit("Couldn't find comic with slug: " + slug) } fmt.Println(u.SubSlugs) fmt.Println(slug) u.SubSlugs = append(u.SubSlugs, slug) fmt.Println(u.SubSlugs) m.SaveUser(u) done() default: errorExit("Unknown argument") } } else if len(os.Args) > 1 { switch os.Args[1] { case "--test": fmt.Println(buildRssFeed("30f14e57-6500-443c-8c77-f352788eacb0")) done() case "--list-comics": comics := m.GetAllComics() for _, c := range comics { fmt.Printf("[ %s;%s ] %s\n", c.Source, c.Slug, c.Name) } done() case "--update-feeds": fmt.Println("Updating User Feeds...") m.UpdateAllUserFeeds() fmt.Println("Done.") done() case "--update-comics": fmt.Println("Updating the Comics List...") comics := downloadComicsList() for _, c := range comics { fmt.Printf("Updating [ %s - %s, %s ]\n", c.Slug, c.Name, c.Artist) m.SaveComic(&c) } m.saveChanges() fmt.Println("Done.") default: errorExit("Unknown argument") } } r = mux.NewRouter() r.StrictSlash(true) //r.PathPrefix("/assets/").Handler(http.FileServer()) pub := r.PathPrefix("/").Subrouter() pub.HandleFunc("/", handleRequest) pub.HandleFunc("/api", handleApiCall) pub.HandleFunc("/api/users", handleApiUsersCall) pub.HandleFunc("/api/users/{uid}", handleApiUsersCall) pub.HandleFunc("/api/users/{uid}/{function}", handleApiUsersCall) pub.HandleFunc("/api/users/{uid}/{function}/{slug}", handleApiUsersCall) pub.HandleFunc("/api/comics", handleApiComicsCall) pub.HandleFunc("/api/comics/{cid}", handleApiComicsCall) pub.HandleFunc("/api/comics/{cid}/{function}", handleApiComicsCall) pub.HandleFunc("/{function}", handleRequest) pub.HandleFunc("/{function}/{uid}", handleRequest) pub.HandleFunc("/{function}/{uid}/{subfunc}", handleRequest) pub.HandleFunc("/{function}/{uid}/{subfunc}/{slug}", handleRequest) http.Handle("/", r) chain := alice.New(loggingHandler).Then(r) // Refresh the DB at 2 AM go func() { for { if m.Site.LastSave.IsZero() || (time.Now().Day() != m.Site.LastSave.Day() && time.Now().Hour() == 2) { fmt.Println("Updating GoComics List...") comics := downloadComicsList() for _, c := range comics { fmt.Printf("Updating [ %s - %s, %s ]\n", c.Slug, c.Name, c.Artist) m.SaveComic(&c) } fmt.Println("Updating User Feeds...") m.UpdateAllUserFeeds() m.saveChanges() fmt.Println("Done.") } time.Sleep(time.Minute) } }() // Set up a channel to intercept Ctrl+C for graceful shutdowns c := make(chan os.Signal, 1) signal.Notify(c, os.Interrupt, syscall.SIGTERM) go func() { <-c // Save the changes when the app quits fmt.Println("\nFinishing up...") m.saveChanges() os.Exit(0) }() fmt.Printf("Listening on port %d\n", m.Site.Port) log.Fatal(http.ListenAndServe("127.0.0.1:"+strconv.Itoa(m.Site.Port), chain)) } func loggingHandler(h http.Handler) http.Handler { return handlers.LoggingHandler(os.Stdout, h) } func done() { os.Exit(0) } func errorExit(msg string) { fmt.Println(msg) os.Exit(1) } func assertError(err error) { if err != nil { panic(err) } }