Pierre-Olivier Mercier
ecda17fc7d
All checks were successful
continuous-integration/drone/push Build is passing
130 lines
3.9 KiB
Go
130 lines
3.9 KiB
Go
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)
|
|
}
|
|
}
|