format + bump
This commit is contained in:
parent
4febf49b3e
commit
bd76956b46
9
api.go
9
api.go
@ -12,17 +12,20 @@ import (
|
|||||||
|
|
||||||
type DispatchFunction func(*User, []string, io.ReadCloser) (interface{}, error)
|
type DispatchFunction func(*User, []string, io.ReadCloser) (interface{}, error)
|
||||||
|
|
||||||
var apiRoutes = map[string]*(map[string]struct{AuthFunction;DispatchFunction}){
|
var apiRoutes = map[string]*(map[string]struct {
|
||||||
|
AuthFunction
|
||||||
|
DispatchFunction
|
||||||
|
}){
|
||||||
"images": &ApiImagesRouting,
|
"images": &ApiImagesRouting,
|
||||||
"next": &ApiNextImagesRouting,
|
"next": &ApiNextImagesRouting,
|
||||||
"version": &ApiVersionRouting,
|
"version": &ApiVersionRouting,
|
||||||
}
|
}
|
||||||
|
|
||||||
type apiHandler struct {
|
type apiHandler struct {
|
||||||
Authenticate func(*http.Request) (*User)
|
Authenticate func(*http.Request) *User
|
||||||
}
|
}
|
||||||
|
|
||||||
func ApiHandler(Authenticate func(*http.Request) (*User)) (apiHandler) {
|
func ApiHandler(Authenticate func(*http.Request) *User) apiHandler {
|
||||||
return apiHandler{Authenticate}
|
return apiHandler{Authenticate}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,13 +5,19 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
)
|
)
|
||||||
|
|
||||||
var ApiImagesRouting = map[string]struct{AuthFunction; DispatchFunction}{
|
var ApiImagesRouting = map[string]struct {
|
||||||
|
AuthFunction
|
||||||
|
DispatchFunction
|
||||||
|
}{
|
||||||
"GET": {PublicPage, listImages},
|
"GET": {PublicPage, listImages},
|
||||||
"POST": {PublicPage, addImage},
|
"POST": {PublicPage, addImage},
|
||||||
"DELETE": {PrivatePage, hideImage},
|
"DELETE": {PrivatePage, hideImage},
|
||||||
}
|
}
|
||||||
|
|
||||||
var ApiNextImagesRouting = map[string]struct{AuthFunction; DispatchFunction}{
|
var ApiNextImagesRouting = map[string]struct {
|
||||||
|
AuthFunction
|
||||||
|
DispatchFunction
|
||||||
|
}{
|
||||||
"GET": {PrivatePage, listNextImages},
|
"GET": {PrivatePage, listNextImages},
|
||||||
"POST": {PublicPage, addImage},
|
"POST": {PublicPage, addImage},
|
||||||
"DELETE": {PrivatePage, deleteImage},
|
"DELETE": {PrivatePage, deleteImage},
|
||||||
|
4
auth.go
4
auth.go
@ -52,10 +52,9 @@ func (h Htpasswd) Authenticate(username, password string) *User {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// Request authentication
|
/// Request authentication
|
||||||
|
|
||||||
func Authenticate(htpasswd Htpasswd, r *http.Request) (*User) {
|
func Authenticate(htpasswd Htpasswd, r *http.Request) *User {
|
||||||
// Authenticate the user if any
|
// Authenticate the user if any
|
||||||
if username, password, ok := r.BasicAuth(); ok {
|
if username, password, ok := r.BasicAuth(); ok {
|
||||||
return htpasswd.Authenticate(username, password)
|
return htpasswd.Authenticate(username, password)
|
||||||
@ -64,7 +63,6 @@ func Authenticate(htpasswd Htpasswd, r *http.Request) (*User) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// Page rules
|
/// Page rules
|
||||||
|
|
||||||
type AuthFunction func(*User, []string) bool
|
type AuthFunction func(*User, []string) bool
|
||||||
|
@ -6,14 +6,14 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
type imagesHandler struct{
|
type imagesHandler struct {
|
||||||
name string
|
name string
|
||||||
auth func(*http.Request) (bool)
|
auth func(*http.Request) bool
|
||||||
hndlr http.Handler
|
hndlr http.Handler
|
||||||
getter func(fname string) (Picture, error)
|
getter func(fname string) (Picture, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
func ImagesHandler(name string, auth func(*http.Request) (bool), hndlr http.Handler, getter func(fname string) (Picture, error)) (imagesHandler) {
|
func ImagesHandler(name string, auth func(*http.Request) bool, hndlr http.Handler, getter func(fname string) (Picture, error)) imagesHandler {
|
||||||
return imagesHandler{name, auth, hndlr, getter}
|
return imagesHandler{name, auth, hndlr, getter}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -39,7 +39,7 @@ func (i imagesHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check rights
|
// Check rights
|
||||||
if ! i.auth(r) {
|
if !i.auth(r) {
|
||||||
w.Header().Set("WWW-Authenticate", "Basic realm=\"YouP0m\"")
|
w.Header().Set("WWW-Authenticate", "Basic realm=\"YouP0m\"")
|
||||||
http.Error(w, "You are not allowed to perform this request.", http.StatusUnauthorized)
|
http.Error(w, "You are not allowed to perform this request.", http.StatusUnauthorized)
|
||||||
return
|
return
|
||||||
|
14
main.go
14
main.go
@ -48,7 +48,7 @@ func main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
log.Println("Registering handlers...")
|
log.Println("Registering handlers...")
|
||||||
authFunc := func (r *http.Request) (*User){ return Authenticate(*htpasswd, r) }
|
authFunc := func(r *http.Request) *User { return Authenticate(*htpasswd, r) }
|
||||||
|
|
||||||
staticDir, _ := filepath.Abs("static")
|
staticDir, _ := filepath.Abs("static")
|
||||||
if _, err := os.Stat(staticDir); os.IsNotExist(err) {
|
if _, err := os.Stat(staticDir); os.IsNotExist(err) {
|
||||||
@ -59,7 +59,9 @@ func main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
mux := http.NewServeMux()
|
mux := http.NewServeMux()
|
||||||
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { http.ServeFile(w, r, filepath.Join(staticDir, "index.html")) })
|
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
http.ServeFile(w, r, filepath.Join(staticDir, "index.html"))
|
||||||
|
})
|
||||||
mux.Handle("/css/", http.FileServer(http.Dir(staticDir)))
|
mux.Handle("/css/", http.FileServer(http.Dir(staticDir)))
|
||||||
mux.Handle("/js/", http.FileServer(http.Dir(staticDir)))
|
mux.Handle("/js/", http.FileServer(http.Dir(staticDir)))
|
||||||
|
|
||||||
@ -67,26 +69,26 @@ func main() {
|
|||||||
|
|
||||||
mux.Handle("/images/", http.StripPrefix("/images", ImagesHandler(
|
mux.Handle("/images/", http.StripPrefix("/images", ImagesHandler(
|
||||||
"images",
|
"images",
|
||||||
func (*http.Request) (bool){ return true; },
|
func(*http.Request) bool { return true },
|
||||||
http.FileServer(http.Dir(PublishedImgDir)),
|
http.FileServer(http.Dir(PublishedImgDir)),
|
||||||
GetPublishedImage,
|
GetPublishedImage,
|
||||||
)))
|
)))
|
||||||
mux.Handle("/images/next/", http.StripPrefix("/images/next", ImagesHandler(
|
mux.Handle("/images/next/", http.StripPrefix("/images/next", ImagesHandler(
|
||||||
"next",
|
"next",
|
||||||
func (r *http.Request) (bool){ return authFunc(r) != nil; },
|
func(r *http.Request) bool { return authFunc(r) != nil },
|
||||||
http.FileServer(http.Dir(NextImgDir)),
|
http.FileServer(http.Dir(NextImgDir)),
|
||||||
GetNextImage,
|
GetNextImage,
|
||||||
)))
|
)))
|
||||||
|
|
||||||
mux.Handle("/images/thumbs/", http.StripPrefix("/images/thumbs", ImagesHandler(
|
mux.Handle("/images/thumbs/", http.StripPrefix("/images/thumbs", ImagesHandler(
|
||||||
"thumbs",
|
"thumbs",
|
||||||
func (*http.Request) (bool){ return true; },
|
func(*http.Request) bool { return true },
|
||||||
http.FileServer(http.Dir(ThumbsDir)),
|
http.FileServer(http.Dir(ThumbsDir)),
|
||||||
GetPublishedImage,
|
GetPublishedImage,
|
||||||
)))
|
)))
|
||||||
mux.Handle("/images/next/thumbs/", http.StripPrefix("/images/next/thumbs", ImagesHandler(
|
mux.Handle("/images/next/thumbs/", http.StripPrefix("/images/next/thumbs", ImagesHandler(
|
||||||
"nexthumbs",
|
"nexthumbs",
|
||||||
func (r *http.Request) (bool){ return authFunc(r) != nil; },
|
func(r *http.Request) bool { return authFunc(r) != nil },
|
||||||
http.FileServer(http.Dir(ThumbsDir)),
|
http.FileServer(http.Dir(ThumbsDir)),
|
||||||
GetNextImage,
|
GetNextImage,
|
||||||
)))
|
)))
|
||||||
|
34
picture.go
34
picture.go
@ -2,12 +2,12 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"io"
|
|
||||||
"io/ioutil"
|
|
||||||
"image"
|
"image"
|
||||||
_ "image/gif"
|
_ "image/gif"
|
||||||
"image/jpeg"
|
"image/jpeg"
|
||||||
_ "image/png"
|
_ "image/png"
|
||||||
|
"io"
|
||||||
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"sort"
|
"sort"
|
||||||
@ -26,9 +26,11 @@ type Picture struct {
|
|||||||
|
|
||||||
type ByUploadTime []Picture
|
type ByUploadTime []Picture
|
||||||
|
|
||||||
func (a ByUploadTime) Len() int { return len(a) }
|
func (a ByUploadTime) Len() int { return len(a) }
|
||||||
func (a ByUploadTime) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
|
func (a ByUploadTime) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
|
||||||
func (a ByUploadTime) Less(i, j int) bool { return a[i].UploadTime.Sub(a[j].UploadTime).Nanoseconds() < 0 }
|
func (a ByUploadTime) Less(i, j int) bool {
|
||||||
|
return a[i].UploadTime.Sub(a[j].UploadTime).Nanoseconds() < 0
|
||||||
|
}
|
||||||
|
|
||||||
func getImages(dir string) ([]Picture, error) {
|
func getImages(dir string) ([]Picture, error) {
|
||||||
if files, err := ioutil.ReadDir(dir); err != nil {
|
if files, err := ioutil.ReadDir(dir); err != nil {
|
||||||
@ -40,9 +42,9 @@ func getImages(dir string) ([]Picture, error) {
|
|||||||
filename := file.Name()
|
filename := file.Name()
|
||||||
pictures = append(pictures, Picture{
|
pictures = append(pictures, Picture{
|
||||||
filepath.Join(dir, filename), // Path
|
filepath.Join(dir, filename), // Path
|
||||||
filename, // Basename
|
filename, // Basename
|
||||||
filename[:len(filename) - len(filepath.Ext(filename))], // Sanitized filename
|
filename[:len(filename)-len(filepath.Ext(filename))], // Sanitized filename
|
||||||
file.ModTime(), // UploadTime
|
file.ModTime(), // UploadTime
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -94,7 +96,7 @@ func GetNextImage(fname string) (Picture, error) {
|
|||||||
return getImage(GetNextImages, fname)
|
return getImage(GetNextImages, fname)
|
||||||
}
|
}
|
||||||
|
|
||||||
func UniqueImage(filename string) (bool) {
|
func UniqueImage(filename string) bool {
|
||||||
if pict, _ := GetPublishedImage(filename); pict.path != "" {
|
if pict, _ := GetPublishedImage(filename); pict.path != "" {
|
||||||
return false
|
return false
|
||||||
} else {
|
} else {
|
||||||
@ -106,17 +108,17 @@ func UniqueImage(filename string) (bool) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func AddImage(filename string, blob io.ReadCloser) (error) {
|
func AddImage(filename string, blob io.ReadCloser) error {
|
||||||
// Check the name is not already used
|
// Check the name is not already used
|
||||||
if ok := UniqueImage(filename); !ok {
|
if ok := UniqueImage(filename); !ok {
|
||||||
return errors.New("This filename is already used, please choose another one.")
|
return errors.New("This filename is already used, please choose another one.")
|
||||||
|
|
||||||
// Convert to JPEG
|
// Convert to JPEG
|
||||||
} else if img, _, err := image.Decode(blob); err != nil {
|
} else if img, _, err := image.Decode(blob); err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
||||||
// Save file
|
// Save file
|
||||||
} else if fw, err := os.Create(filepath.Join(NextImgDir, filename + ".jpg")); err != nil {
|
} else if fw, err := os.Create(filepath.Join(NextImgDir, filename+".jpg")); err != nil {
|
||||||
return err
|
return err
|
||||||
} else if err := jpeg.Encode(fw, img, nil); err != nil {
|
} else if err := jpeg.Encode(fw, img, nil); err != nil {
|
||||||
return err
|
return err
|
||||||
@ -126,7 +128,7 @@ func AddImage(filename string, blob io.ReadCloser) (error) {
|
|||||||
thumb := resize.Thumbnail(300, 185, img, resize.Lanczos3)
|
thumb := resize.Thumbnail(300, 185, img, resize.Lanczos3)
|
||||||
|
|
||||||
// Save thumbnail
|
// Save thumbnail
|
||||||
if fw, err := os.Create(filepath.Join(ThumbsDir, filename + ".jpg")); err != nil {
|
if fw, err := os.Create(filepath.Join(ThumbsDir, filename+".jpg")); err != nil {
|
||||||
return err
|
return err
|
||||||
} else if err := jpeg.Encode(fw, thumb, nil); err != nil {
|
} else if err := jpeg.Encode(fw, thumb, nil); err != nil {
|
||||||
return err
|
return err
|
||||||
@ -138,7 +140,7 @@ func AddImage(filename string, blob io.ReadCloser) (error) {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p Picture) Publish() (error) {
|
func (p Picture) Publish() error {
|
||||||
npath := filepath.Join(PublishedImgDir, p.basename)
|
npath := filepath.Join(PublishedImgDir, p.basename)
|
||||||
if err := os.Rename(p.path, npath); err != nil {
|
if err := os.Rename(p.path, npath); err != nil {
|
||||||
return err
|
return err
|
||||||
@ -149,7 +151,7 @@ func (p Picture) Publish() (error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p Picture) Unpublish() (error) {
|
func (p Picture) Unpublish() error {
|
||||||
if err := os.Rename(p.path, filepath.Join(NextImgDir, p.basename)); err != nil {
|
if err := os.Rename(p.path, filepath.Join(NextImgDir, p.basename)); err != nil {
|
||||||
return err
|
return err
|
||||||
} else {
|
} else {
|
||||||
@ -157,7 +159,7 @@ func (p Picture) Unpublish() (error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p Picture) Remove() (error) {
|
func (p Picture) Remove() error {
|
||||||
if err := os.Remove(p.path); err != nil {
|
if err := os.Remove(p.path); err != nil {
|
||||||
return err
|
return err
|
||||||
} else {
|
} else {
|
||||||
|
@ -4,12 +4,15 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
)
|
)
|
||||||
|
|
||||||
var ApiVersionRouting = map[string]struct{AuthFunction; DispatchFunction}{
|
var ApiVersionRouting = map[string]struct {
|
||||||
|
AuthFunction
|
||||||
|
DispatchFunction
|
||||||
|
}{
|
||||||
"GET": {PublicPage, showVersion},
|
"GET": {PublicPage, showVersion},
|
||||||
}
|
}
|
||||||
|
|
||||||
func showVersion(u *User, args []string, body io.ReadCloser) (interface{}, error) {
|
func showVersion(u *User, args []string, body io.ReadCloser) (interface{}, error) {
|
||||||
m := map[string]interface{}{"version": 0.1}
|
m := map[string]interface{}{"version": 0.2}
|
||||||
|
|
||||||
if u != nil {
|
if u != nil {
|
||||||
m["youare"] = *u
|
m["youare"] = *u
|
||||||
|
Loading…
Reference in New Issue
Block a user