package main import ( "flag" "fmt" "log" "net/http" "os" "path" ) var mux = http.NewServeMux() var ( ThumbsDir string backend = "local" ) func main() { bind := flag.String("bind", ":8080", "Bind port/socket") htpasswd_file := flag.String("htpasswd", "", "Admin passwords file, Apache htpasswd format") publishedImgDir := flag.String("publishedimgdir", "published/", "Directory where save published pictures") nextImgDir := flag.String("nextimgdir", "next/", "Directory where save pictures to review") baseDir := flag.String("basedir", "images/", "Local base directory where find published and next dirs") flag.StringVar(&backend, "storage-backend", backend, fmt.Sprintf("Storage backend to use (between: %s)", existing_backends)) flag.StringVar(&ThumbsDir, "thumbsdir", "./images/thumbs/", "Directory where generate thumbs") flag.Parse() htpasswd := &Htpasswd{} if htpasswd_file != nil && *htpasswd_file != "" { log.Println("Reading htpasswd file...") var err error if htpasswd, err = NewHtpasswd(*htpasswd_file); htpasswd == nil { log.Fatal("Unable to parse htpasswd:", err) } } else if *nextImgDir == "next/" { log.Println("Disable admin interface, images will be published without moderation") nextImgDir = publishedImgDir } log.Println("Checking paths...") if _, err := os.Stat(ThumbsDir); os.IsNotExist(err) { if err := os.MkdirAll(ThumbsDir, 0755); err != nil { log.Fatal(err) } } log.Println("Registering handlers...") authFunc := func(r *http.Request) *User { return Authenticate(*htpasswd, r) } if err := sanitizeStaticOptions(); err != nil { log.Fatal(err) } mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { r.URL.Path = "/" http.FileServer(Assets).ServeHTTP(w, r) }) var storage_backend FileBackend if backend == "local" { storage_backend = &LocalFileBackend{*baseDir} if _, err := os.Stat(path.Join(*baseDir, *publishedImgDir)); os.IsNotExist(err) { if err := os.MkdirAll(path.Join(*baseDir, *publishedImgDir), 0755); err != nil { log.Fatal(err) } } if _, err := os.Stat(path.Join(*baseDir, *nextImgDir)); os.IsNotExist(err) { if err := os.MkdirAll(path.Join(*baseDir, *nextImgDir), 0755); err != nil { log.Fatal(err) } } } else if backend == "s3" { storage_backend = &S3FileBackend{s3_endpoint, s3_region, s3_bucket, s3_access_key, s3_secret_key, s3_path_style, *baseDir} } else { log.Fatalf("%q is not a valid storage backend.", backend) } log.Printf("Using %s storage backend", backend) pe := &PictureExplorer{ FileBackend: storage_backend, PublishedImgDir: *publishedImgDir, NextImgDir: *nextImgDir, } mux.Handle("/api/", http.StripPrefix("/api", NewAPIHandler(pe, authFunc))) mux.Handle("/images/", http.StripPrefix("/images", ImagesHandler( "images", func(*http.Request) bool { return true }, pe.ServeFile(), pe.GetPublishedImage, ))) mux.Handle("/images/next/", http.StripPrefix("/images/next", ImagesHandler( "next", func(r *http.Request) bool { return authFunc(r) != nil }, pe.ServeFile(), pe.GetNextImage, ))) mux.Handle("/images/thumbs/", http.StripPrefix("/images/thumbs", ImagesHandler( "thumbs", func(*http.Request) bool { return true }, http.FileServer(http.Dir(ThumbsDir)), pe.GetPublishedImage, ))) mux.Handle("/images/next/thumbs/", http.StripPrefix("/images/next/thumbs", ImagesHandler( "nexthumbs", func(r *http.Request) bool { return authFunc(r) != nil }, http.FileServer(http.Dir(ThumbsDir)), pe.GetNextImage, ))) mux.HandleFunc("/admin/", func(w http.ResponseWriter, r *http.Request) { if authFunc(r) == nil { w.Header().Set("WWW-Authenticate", "Basic realm=\"YouP0m\"") http.Error(w, "You are not allowed to perform this request.", http.StatusUnauthorized) } else { r.URL.Path = "/admin.html" http.FileServer(Assets).ServeHTTP(w, r) } }) log.Println("Ready, listening on", *bind) if err := http.ListenAndServe(*bind, mux); err != nil { log.Fatal("Unable to listen and serve: ", err) } }