Simplify Static Generators Code; progresses on #108
Former-commit-id: 7f4552b70980f39204e5a5517a1c1f3602304569 [formerly 0c9cdc2a1e988d378f8a068b9a6b53eb41144f2f] [formerly e221c08add31a6837c8695c413b2c55d31806f16 [formerly 7ee721a9e3
]]
Former-commit-id: de2ff86dbc24a8f77260539d656201daf9dfebe5 [formerly 3d0eb1e810bbce97a7bf430abf0d0c7a3833ce2a]
Former-commit-id: 6f22d477a1105c7b84cbe70dda1afb0d364e47c5
pull/726/head
parent
97f31310c6
commit
25a86a9382
|
@ -121,15 +121,6 @@ type FileManager struct {
|
||||||
Commands map[string][]string
|
Commands map[string][]string
|
||||||
}
|
}
|
||||||
|
|
||||||
type StaticGen interface {
|
|
||||||
SettingsPath() string
|
|
||||||
|
|
||||||
Hook(c *RequestContext, w http.ResponseWriter, r *http.Request) (int, error)
|
|
||||||
Preview(c *RequestContext, w http.ResponseWriter, r *http.Request) (int, error)
|
|
||||||
Publish(c *RequestContext, w http.ResponseWriter, r *http.Request) (int, error)
|
|
||||||
Schedule(c *RequestContext, w http.ResponseWriter, r *http.Request) (int, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Command is a command function.
|
// Command is a command function.
|
||||||
type Command func(r *http.Request, m *FileManager, u *User) error
|
type Command func(r *http.Request, m *FileManager, u *User) error
|
||||||
|
|
||||||
|
@ -357,6 +348,8 @@ func (m *FileManager) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// EnableStaticGen attaches a static generator to the current File Manager
|
||||||
|
// instance.
|
||||||
func (m *FileManager) EnableStaticGen(data StaticGen) error {
|
func (m *FileManager) EnableStaticGen(data StaticGen) error {
|
||||||
if reflect.TypeOf(data).Kind() != reflect.Ptr {
|
if reflect.TypeOf(data).Kind() != reflect.Ptr {
|
||||||
return errors.New("data should be a pointer to interface, not interface")
|
return errors.New("data should be a pointer to interface, not interface")
|
||||||
|
|
42
resource.go
42
resource.go
|
@ -5,13 +5,16 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/hacdias/fileutils"
|
"github.com/hacdias/fileutils"
|
||||||
|
"github.com/robfig/cron"
|
||||||
)
|
)
|
||||||
|
|
||||||
// sanitizeURL sanitizes the URL to prevent path transversal
|
// sanitizeURL sanitizes the URL to prevent path transversal
|
||||||
|
@ -231,10 +234,45 @@ func resourcePublishSchedule(c *RequestContext, w http.ResponseWriter, r *http.R
|
||||||
}
|
}
|
||||||
|
|
||||||
if publish == "true" {
|
if publish == "true" {
|
||||||
return c.StaticGen.Publish(c, w, r)
|
return resourcePublish(c, w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
return c.StaticGen.Schedule(c, w, r)
|
t, err := time.Parse("2006-01-02T15:04", schedule)
|
||||||
|
if err != nil {
|
||||||
|
return http.StatusInternalServerError, err
|
||||||
|
}
|
||||||
|
|
||||||
|
scheduler := cron.New()
|
||||||
|
scheduler.AddFunc(t.Format("05 04 15 02 01 *"), func() {
|
||||||
|
_, err := resourcePublish(c, w, r)
|
||||||
|
if err != nil {
|
||||||
|
log.Print(err)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
scheduler.Start()
|
||||||
|
return http.StatusOK, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourcePublish(c *RequestContext, w http.ResponseWriter, r *http.Request) (int, error) {
|
||||||
|
path := filepath.Join(string(c.User.FileSystem), r.URL.Path)
|
||||||
|
|
||||||
|
// Before save command handler.
|
||||||
|
if err := c.Runner("before_publish", path); err != nil {
|
||||||
|
return http.StatusInternalServerError, err
|
||||||
|
}
|
||||||
|
|
||||||
|
code, err := c.StaticGen.Publish(c, w, r)
|
||||||
|
if err != nil {
|
||||||
|
return code, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Executed the before publish command.
|
||||||
|
if err := c.Runner("before_publish", path); err != nil {
|
||||||
|
return http.StatusInternalServerError, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return code, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// resourcePatchHandler is the entry point for resource handler.
|
// resourcePatchHandler is the entry point for resource handler.
|
||||||
|
|
82
staticgen.go
82
staticgen.go
|
@ -9,17 +9,23 @@ import (
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/hacdias/varutils"
|
"github.com/hacdias/varutils"
|
||||||
"github.com/robfig/cron"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
// ErrUnsupportedFileType ...
|
errUnsupportedFileType = errors.New("The type of the provided file isn't supported for this action")
|
||||||
ErrUnsupportedFileType = errors.New("The type of the provided file isn't supported for this action")
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// StaticGen is a static website generator.
|
||||||
|
type StaticGen interface {
|
||||||
|
SettingsPath() string
|
||||||
|
|
||||||
|
Hook(c *RequestContext, w http.ResponseWriter, r *http.Request) (int, error)
|
||||||
|
Preview(c *RequestContext, w http.ResponseWriter, r *http.Request) (int, error)
|
||||||
|
Publish(c *RequestContext, w http.ResponseWriter, r *http.Request) (int, error)
|
||||||
|
}
|
||||||
|
|
||||||
// Hugo is the Hugo static website generator.
|
// Hugo is the Hugo static website generator.
|
||||||
type Hugo struct {
|
type Hugo struct {
|
||||||
// Website root
|
// Website root
|
||||||
|
@ -89,7 +95,7 @@ func (h Hugo) Hook(c *RequestContext, w http.ResponseWriter, r *http.Request) (i
|
||||||
// If the request isn't for a markdown file, we can't
|
// If the request isn't for a markdown file, we can't
|
||||||
// handle it.
|
// handle it.
|
||||||
if ext != ".markdown" && ext != ".md" {
|
if ext != ".markdown" && ext != ".md" {
|
||||||
return http.StatusBadRequest, ErrUnsupportedFileType
|
return http.StatusBadRequest, errUnsupportedFileType
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tries to create a new file based on this archetype.
|
// Tries to create a new file based on this archetype.
|
||||||
|
@ -107,11 +113,6 @@ func (h Hugo) Hook(c *RequestContext, w http.ResponseWriter, r *http.Request) (i
|
||||||
func (h Hugo) Publish(c *RequestContext, w http.ResponseWriter, r *http.Request) (int, error) {
|
func (h Hugo) Publish(c *RequestContext, w http.ResponseWriter, r *http.Request) (int, error) {
|
||||||
filename := filepath.Join(string(c.User.FileSystem), r.URL.Path)
|
filename := filepath.Join(string(c.User.FileSystem), r.URL.Path)
|
||||||
|
|
||||||
// Before save command handler.
|
|
||||||
if err := c.Runner("before_publish", filename); err != nil {
|
|
||||||
return http.StatusInternalServerError, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// We only run undraft command if it is a file.
|
// We only run undraft command if it is a file.
|
||||||
if strings.HasSuffix(filename, ".md") && strings.HasSuffix(filename, ".markdown") {
|
if strings.HasSuffix(filename, ".md") && strings.HasSuffix(filename, ".markdown") {
|
||||||
if err := h.undraft(filename); err != nil {
|
if err := h.undraft(filename); err != nil {
|
||||||
|
@ -122,37 +123,9 @@ func (h Hugo) Publish(c *RequestContext, w http.ResponseWriter, r *http.Request)
|
||||||
// Regenerates the file
|
// Regenerates the file
|
||||||
h.run(false)
|
h.run(false)
|
||||||
|
|
||||||
// Executed the before publish command.
|
|
||||||
if err := c.Runner("before_publish", filename); err != nil {
|
|
||||||
return http.StatusInternalServerError, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0, nil
|
return 0, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Schedule schedules a post.
|
|
||||||
func (h Hugo) Schedule(c *RequestContext, w http.ResponseWriter, r *http.Request) (int, error) {
|
|
||||||
t, err := time.Parse("2006-01-02T15:04", r.Header.Get("Schedule"))
|
|
||||||
path := filepath.Join(string(c.User.FileSystem), r.URL.Path)
|
|
||||||
path = filepath.Clean(path)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return http.StatusInternalServerError, err
|
|
||||||
}
|
|
||||||
|
|
||||||
scheduler := cron.New()
|
|
||||||
scheduler.AddFunc(t.Format("05 04 15 02 01 *"), func() {
|
|
||||||
if err := h.undraft(path); err != nil {
|
|
||||||
log.Printf(err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
h.run(false)
|
|
||||||
})
|
|
||||||
|
|
||||||
scheduler.Start()
|
|
||||||
return http.StatusOK, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Preview handles the preview path.
|
// Preview handles the preview path.
|
||||||
func (h *Hugo) Preview(c *RequestContext, w http.ResponseWriter, r *http.Request) (int, error) {
|
func (h *Hugo) Preview(c *RequestContext, w http.ResponseWriter, r *http.Request) (int, error) {
|
||||||
// Get a new temporary path if there is none.
|
// Get a new temporary path if there is none.
|
||||||
|
@ -252,11 +225,6 @@ func (j Jekyll) Hook(c *RequestContext, w http.ResponseWriter, r *http.Request)
|
||||||
func (j Jekyll) Publish(c *RequestContext, w http.ResponseWriter, r *http.Request) (int, error) {
|
func (j Jekyll) Publish(c *RequestContext, w http.ResponseWriter, r *http.Request) (int, error) {
|
||||||
filename := filepath.Join(string(c.User.FileSystem), r.URL.Path)
|
filename := filepath.Join(string(c.User.FileSystem), r.URL.Path)
|
||||||
|
|
||||||
// Before save command handler.
|
|
||||||
if err := c.Runner("before_publish", filename); err != nil {
|
|
||||||
return http.StatusInternalServerError, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// We only run undraft command if it is a file.
|
// We only run undraft command if it is a file.
|
||||||
if err := j.undraft(filename); err != nil {
|
if err := j.undraft(filename); err != nil {
|
||||||
return http.StatusInternalServerError, err
|
return http.StatusInternalServerError, err
|
||||||
|
@ -265,37 +233,9 @@ func (j Jekyll) Publish(c *RequestContext, w http.ResponseWriter, r *http.Reques
|
||||||
// Regenerates the file
|
// Regenerates the file
|
||||||
j.run()
|
j.run()
|
||||||
|
|
||||||
// Executed the before publish command.
|
|
||||||
if err := c.Runner("before_publish", filename); err != nil {
|
|
||||||
return http.StatusInternalServerError, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0, nil
|
return 0, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Schedule schedules a post.
|
|
||||||
func (j Jekyll) Schedule(c *RequestContext, w http.ResponseWriter, r *http.Request) (int, error) {
|
|
||||||
t, err := time.Parse("2006-01-02T15:04", r.Header.Get("Schedule"))
|
|
||||||
path := filepath.Join(string(c.User.FileSystem), r.URL.Path)
|
|
||||||
path = filepath.Clean(path)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return http.StatusInternalServerError, err
|
|
||||||
}
|
|
||||||
|
|
||||||
scheduler := cron.New()
|
|
||||||
scheduler.AddFunc(t.Format("05 04 15 02 01 *"), func() {
|
|
||||||
if err := j.undraft(path); err != nil {
|
|
||||||
log.Printf(err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
j.run()
|
|
||||||
})
|
|
||||||
|
|
||||||
scheduler.Start()
|
|
||||||
return http.StatusOK, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Preview handles the preview path.
|
// Preview handles the preview path.
|
||||||
func (j *Jekyll) Preview(c *RequestContext, w http.ResponseWriter, r *http.Request) (int, error) {
|
func (j *Jekyll) Preview(c *RequestContext, w http.ResponseWriter, r *http.Request) (int, error) {
|
||||||
// Get a new temporary path if there is none.
|
// Get a new temporary path if there is none.
|
||||||
|
|
Loading…
Reference in New Issue