before and after save hooks

pull/144/head
Henrique Dias 2016-12-18 12:34:31 +00:00
parent 205f9a22b6
commit aae318028b
3 changed files with 83 additions and 1 deletions

61
config/commands.go Normal file
View File

@ -0,0 +1,61 @@
package config
import (
"log"
"net/http"
"os"
"os/exec"
"path/filepath"
"strings"
"github.com/mholt/caddy"
)
type commandRunner func(r *http.Request, c *Config, u *User) error
// CommandRunner ...
func CommandRunner(c *caddy.Controller) (commandRunner, error) {
fn := func(r *http.Request, c *Config, u *User) error { return nil }
args := c.RemainingArgs()
if len(args) == 0 {
return fn, c.ArgErr()
}
nonblock := false
if len(args) > 1 && args[len(args)-1] == "&" {
// Run command in background; non-blocking
nonblock = true
args = args[:len(args)-1]
}
command, args, err := caddy.SplitCommandAndArgs(strings.Join(args, " "))
if err != nil {
return fn, c.Err(err.Error())
}
fn = func(r *http.Request, c *Config, u *User) error {
path := strings.Replace(r.URL.Path, c.BaseURL+c.WebDavURL, "", 1)
path = u.Scope + "/" + path
path = filepath.Clean(path)
for i := range args {
args[i] = strings.Replace(args[i], "{path}", path, -1)
}
cmd := exec.Command(command, args...)
cmd.Stdin = os.Stdin
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
if nonblock {
log.Printf("[INFO] Nonblocking Command:\"%s %s\"", command, strings.Join(args, " "))
return cmd.Start()
}
log.Printf("[INFO] Blocking Command:\"%s %s\"", command, strings.Join(args, " "))
return cmd.Run()
}
return fn, nil
}

View File

@ -3,6 +3,7 @@ package config
import (
"fmt"
"io/ioutil"
"net/http"
"regexp"
"strconv"
"strings"
@ -23,9 +24,11 @@ type Config struct {
HugoEnabled bool // Enables the Hugo plugin for File Manager
Users map[string]*User
WebDavURL string
CurrentUser *User
BeforeSave commandRunner
AfterSave commandRunner
}
// AbsoluteURL ...
func (c Config) AbsoluteURL() string {
return c.PrefixURL + c.BaseURL
}
@ -70,6 +73,8 @@ func Parse(c *caddy.Controller) ([]Config, error) {
cfg.AllowEdit = true
cfg.AllowNew = true
cfg.Commands = []string{"git", "svn", "hg"}
cfg.BeforeSave = func(r *http.Request, c *Config, u *User) error { return nil }
cfg.AfterSave = func(r *http.Request, c *Config, u *User) error { return nil }
cfg.Rules = []*Rule{{
Regex: true,
Allow: false,
@ -106,6 +111,14 @@ func Parse(c *caddy.Controller) ([]Config, error) {
if user.FrontMatter != "yaml" && user.FrontMatter != "json" && user.FrontMatter != "toml" {
return configs, c.Err("frontmatter type not supported")
}
case "before_save":
if cfg.BeforeSave, err = CommandRunner(c); err != nil {
return configs, err
}
case "after_save":
if cfg.AfterSave, err = CommandRunner(c); err != nil {
return configs, err
}
case "webdav":
if !c.NextArg() {
return configs, c.ArgErr()

View File

@ -83,12 +83,20 @@ func (f FileManager) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, err
// Preprocess the PUT request if it's the case
if r.Method == http.MethodPut {
if err = c.BeforeSave(r, c, user); err != nil {
return http.StatusInternalServerError, err
}
if handlers.PreProccessPUT(w, r, c, user) != nil {
return http.StatusInternalServerError, err
}
}
c.Handler.ServeHTTP(w, r)
if err = c.AfterSave(r, c, user); err != nil {
return http.StatusInternalServerError, err
}
return 0, nil
}