No Description
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

client.go 2.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. package caddyhugo
  2. import (
  3. "fmt"
  4. "io/ioutil"
  5. "net/http"
  6. "path"
  7. "sync"
  8. "github.com/spf13/afero"
  9. "git.stephensearles.com/stephen/acedoc"
  10. "git.stephensearles.com/stephen/idleshut"
  11. )
  12. type editSession struct {
  13. clients uint
  14. docname string
  15. filename string
  16. doc *acedoc.Document
  17. tmpfs afero.Fs
  18. mtx sync.Mutex
  19. }
  20. func (es *editSession) Clients() uint {
  21. es.mtx.Lock()
  22. defer es.mtx.Unlock()
  23. return es.clients
  24. }
  25. func (ch *CaddyHugo) newEditSession(docName string) (*editSession, error) {
  26. filename := ch.docFilename(docName)
  27. fmt.Println("opening", filename)
  28. contents, err := ioutil.ReadFile(filename)
  29. if err != nil {
  30. return nil, err
  31. }
  32. tmpfs := afero.NewCopyOnWriteFs(afero.NewOsFs(), afero.NewMemMapFs())
  33. es := &editSession{
  34. docname: docName,
  35. filename: filename,
  36. doc: acedoc.NewString(string(contents)),
  37. tmpfs: tmpfs,
  38. }
  39. err = es.doc.LogToFile(path.Join(ch.Dir, "logs", docName))
  40. if err != nil {
  41. fmt.Println(err)
  42. return nil, err
  43. }
  44. ch.docs[filename] = es
  45. err = ch.renderDraft(es)
  46. if err != nil {
  47. return nil, err
  48. }
  49. return es, nil
  50. }
  51. func (ch *CaddyHugo) renderDraft(es *editSession) error {
  52. var proc *idleshut.Process
  53. f := func() {
  54. if es.clients != 0 {
  55. proc.Touch()
  56. }
  57. }
  58. cfg, err := HugoInternalProcessConfig(ch, es, f)
  59. if err != nil {
  60. return fmt.Errorf("rendering draft: %v", err)
  61. }
  62. proc = idleshut.New(cfg)
  63. return proc.Start()
  64. }
  65. func (ch *CaddyHugo) persistAllEdits() error {
  66. ch.mtx.Lock()
  67. defer ch.mtx.Unlock()
  68. for _, es := range ch.docs {
  69. err := ch.persistEditsForSession(es)
  70. if err != nil {
  71. return err
  72. }
  73. }
  74. return nil
  75. }
  76. func (ch *CaddyHugo) persistEditsForSession(es *editSession) error {
  77. err := afero.WriteFile(afero.NewOsFs(), es.filename, []byte(es.doc.Contents()), 0644)
  78. if err != nil {
  79. return err
  80. }
  81. return nil
  82. }
  83. func (ch *CaddyHugo) hasEditSession(docName string) (*editSession, bool) {
  84. dr, ok := ch.docs[ch.docFilename(docName)]
  85. return dr, ok
  86. }
  87. func (ch *CaddyHugo) editSession(docName string) (*editSession, error) {
  88. ch.mtx.Lock()
  89. defer ch.mtx.Unlock()
  90. var err error
  91. dr, ok := ch.hasEditSession(docName)
  92. if !ok {
  93. dr, err = ch.newEditSession(docName)
  94. }
  95. return dr, err
  96. }
  97. func docNameFromEditRequest(r *http.Request) string {
  98. return r.URL.Path[len("/hugo/edit/"):]
  99. }
  100. func docNameFromCommentRequest(r *http.Request) string {
  101. return r.URL.Path[1 : len(r.URL.Path)-len("/comments")]
  102. }