|
|
@ -6,11 +6,11 @@ import ( |
|
|
|
"io/ioutil" |
|
|
|
"io/ioutil" |
|
|
|
"net/http" |
|
|
|
"net/http" |
|
|
|
"os" |
|
|
|
"os" |
|
|
|
"os/exec" |
|
|
|
|
|
|
|
"path" |
|
|
|
"path" |
|
|
|
"time" |
|
|
|
"sync" |
|
|
|
|
|
|
|
|
|
|
|
"git.stephensearles.com/stephen/acedoc" |
|
|
|
"git.stephensearles.com/stephen/acedoc" |
|
|
|
|
|
|
|
"git.stephensearles.com/stephen/idleshut" |
|
|
|
) |
|
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
type editSession struct { |
|
|
|
type editSession struct { |
|
|
@ -19,6 +19,14 @@ type editSession struct { |
|
|
|
filename string |
|
|
|
filename string |
|
|
|
doc *acedoc.Document |
|
|
|
doc *acedoc.Document |
|
|
|
tmpdir string |
|
|
|
tmpdir string |
|
|
|
|
|
|
|
mtx sync.Mutex |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func (es *editSession) Clients() uint { |
|
|
|
|
|
|
|
es.mtx.Lock() |
|
|
|
|
|
|
|
defer es.mtx.Unlock() |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return es.clients |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func (ch *CaddyHugo) newEditSession(docName string) (*editSession, error) { |
|
|
|
func (ch *CaddyHugo) newEditSession(docName string) (*editSession, error) { |
|
|
@ -54,68 +62,15 @@ func (ch *CaddyHugo) newEditSession(docName string) (*editSession, error) { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func (ch *CaddyHugo) renderDraft(es *editSession) error { |
|
|
|
func (ch *CaddyHugo) renderDraft(es *editSession) error { |
|
|
|
hugoCmd := exec.Command("hugo", "--watch", "-D", "-d", es.tmpdir) |
|
|
|
var proc *idleshut.Process |
|
|
|
hugoCmd.Dir = ch.Dir |
|
|
|
|
|
|
|
err := hugoCmd.Start() |
|
|
|
|
|
|
|
if err != nil { |
|
|
|
|
|
|
|
return fmt.Errorf("error starting hugo: %v", err) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
renderer := HugoCmdRenderer{ |
|
|
|
f := func() { |
|
|
|
TmpDir: es.tmpdir, |
|
|
|
if es.clients != 0 { |
|
|
|
SrcDir: ch.Dir, |
|
|
|
proc.Touch() |
|
|
|
Filename: es.filename, |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
go func() { |
|
|
|
|
|
|
|
ticker := time.NewTicker(WebsocketFileTicker) |
|
|
|
|
|
|
|
idleTicks := 0 |
|
|
|
|
|
|
|
closeTicks := int(IdleWebsocketTimeout / WebsocketFileTicker) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
defer func() { |
|
|
|
|
|
|
|
err = renderer.Stop() |
|
|
|
|
|
|
|
if err != nil { |
|
|
|
|
|
|
|
fmt.Println("error stopping hugo:", err) |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
}() |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for { |
|
|
|
proc = idleshut.New(HugoCmdProcessConfig(ch, es, f)) |
|
|
|
<-ticker.C |
|
|
|
|
|
|
|
ch.mtx.Lock() |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// render if there are connected clients OR if we haven't
|
|
|
|
|
|
|
|
// been idle for very long.
|
|
|
|
|
|
|
|
if es.clients > 0 || idleTicks < 2 { |
|
|
|
|
|
|
|
err := renderer.Render(es.doc.Contents()) |
|
|
|
|
|
|
|
if err != nil { |
|
|
|
|
|
|
|
fmt.Println("error saving document contents:", err) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// count up idle time and possibly close down
|
|
|
|
|
|
|
|
if es.clients == 0 { |
|
|
|
|
|
|
|
idleTicks++ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if idleTicks >= closeTicks { |
|
|
|
|
|
|
|
idleTime := time.Duration(idleTicks) * WebsocketFileTicker |
|
|
|
|
|
|
|
err := ch.Publish() |
|
|
|
|
|
|
|
fmt.Printf("idle for %v, quitting\n", idleTime) |
|
|
|
|
|
|
|
if err != nil { |
|
|
|
|
|
|
|
fmt.Printf(", error publishing: %v\n", err) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
es.doc.Close() |
|
|
|
|
|
|
|
os.RemoveAll(es.tmpdir) |
|
|
|
|
|
|
|
delete(ch.docs, es.filename) |
|
|
|
|
|
|
|
ch.mtx.Unlock() |
|
|
|
|
|
|
|
return |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
idleTicks = 0 |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
ch.mtx.Unlock() |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
}() |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return nil |
|
|
|
return nil |
|
|
|
} |
|
|
|
} |
|
|
|