adoc support #22

Merged
cws merged 1 commits from 7_support_doc_conversion into master 2020-07-23 16:15:00 +00:00
4 changed files with 81 additions and 60 deletions

View File

@ -49,7 +49,7 @@ func makeKey() (string, error) {
} }
func New(db *db.Database, name, password string) (*User, error) { func New(db *db.Database, name, password string) (*User, error) {
q := `insert into users values (null, ?, ?, ?, ?)` q := `insert or replace into users values (null, ?, ?, ?, ?)`
key, err := makeKey() key, err := makeKey()
if err != nil { if err != nil {

View File

@ -2,6 +2,8 @@ package entry
import ( import (
"fmt" "fmt"
"io"
"os/exec"
"regexp" "regexp"
"strings" "strings"
"time" "time"
@ -53,7 +55,7 @@ func PrepareTable(tx *sqlx.Tx) error {
return nil return nil
} }
func NewFromMd(db *db.Database, body string) *Entry { func NewFromAdoc(db *db.Database, body string) *Entry {
e := New(db) e := New(db)
e.Content = body e.Content = body
e.Title = e.GenerateTitle() e.Title = e.GenerateTitle()
@ -61,6 +63,33 @@ func NewFromMd(db *db.Database, body string) *Entry {
return e return e
} }
func pandocMdToAdoc(body string) string {
log.Debug().Str("input", body).Msgf("converting md->adoc")
cmd := exec.Command("pandoc", "-f", "commonmark", "-t", "asciidoctor")
stdin, err := cmd.StdinPipe()
if err != nil {
log.Error().Err(err).Msgf("could not get stdin")
}
go func() {
defer stdin.Close()
io.WriteString(stdin, body)
}()
out, err := cmd.CombinedOutput()
if err != nil {
log.Error().Err(err).Msgf("could not get stdout")
}
log.Debug().Msgf("md->adoc: %s", out)
return string(out)
}
func NewFromMd(db *db.Database, body string) *Entry {
body = pandocMdToAdoc(body)
return NewFromAdoc(db, body)
}
func New(db *db.Database) *Entry { func New(db *db.Database) *Entry {
e := Entry{ e := Entry{
db: db, db: db,

View File

@ -13,6 +13,18 @@ import (
"github.com/gorilla/mux" "github.com/gorilla/mux"
) )
func (web *Web) writeJSON(w http.ResponseWriter, code int, data interface{}) error {
w.Header().Set("content-type", "application/json")
resp, err := json.Marshal(data)
if err != nil {
w.WriteHeader(500)
return err
}
w.WriteHeader(code)
w.Write(resp)
return nil
}
func (web *Web) editEntry(w http.ResponseWriter, r *http.Request) { func (web *Web) editEntry(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r) vars := mux.Vars(r)
slug := vars["slug"] slug := vars["slug"]
@ -43,70 +55,67 @@ func (web *Web) editEntry(w http.ResponseWriter, r *http.Request) {
err = oldEntry.Update() err = oldEntry.Update()
if err != nil { if err != nil {
w.WriteHeader(500) web.writeJSON(w, 500, err)
fmt.Fprint(w, err)
return return
} }
resp, err := json.Marshal(oldEntry) web.writeJSON(w, 200, oldEntry)
}
func (web *Web) newAdocEntry(w http.ResponseWriter, r *http.Request) {
body, err := ioutil.ReadAll(r.Body)
if err != nil { if err != nil {
w.WriteHeader(500) web.writeJSON(w, 500, err)
fmt.Fprint(w, err) return
}
newEntry := entry.NewFromAdoc(web.db, string(body))
err = newEntry.Create()
if err != nil {
web.writeJSON(w, 500, err)
return return
} }
w.Header().Set("content-type", "application/json") web.writeJSON(w, 200, newEntry)
fmt.Fprint(w, string(resp))
} }
func (web *Web) newMarkdownEntry(w http.ResponseWriter, r *http.Request) { func (web *Web) newMarkdownEntry(w http.ResponseWriter, r *http.Request) {
body, err := ioutil.ReadAll(r.Body) body, err := ioutil.ReadAll(r.Body)
if err != nil { if err != nil {
w.WriteHeader(500) log.Error().Err(err).Msgf("could not read message body")
fmt.Fprint(w, err) web.writeJSON(w, 500, err)
return return
} }
newEntry := entry.NewFromMd(web.db, string(body)) newEntry := entry.NewFromMd(web.db, string(body))
err = newEntry.Create() err = newEntry.Create()
if err != nil { if err != nil {
w.WriteHeader(500) log.Error().Err(err).Msgf("could not create entry")
fmt.Fprint(w, err) web.writeJSON(w, 500, err)
return return
} }
resp, err := json.Marshal(newEntry) web.writeJSON(w, 200, newEntry)
if err != nil {
w.WriteHeader(500)
fmt.Fprint(w, err)
return
}
w.Header().Set("content-type", "application/json")
fmt.Fprint(w, string(resp))
} }
func (web *Web) newEntry(w http.ResponseWriter, r *http.Request) { func (web *Web) newEntry(w http.ResponseWriter, r *http.Request) {
log.Debug().
Str("content-type", r.Header.Get("Content-Type")).
Msgf("newEntry")
dec := json.NewDecoder(r.Body) dec := json.NewDecoder(r.Body)
newEntry := entry.New(web.db) newEntry := entry.New(web.db)
err := dec.Decode(&newEntry) err := dec.Decode(&newEntry)
if err != nil { if err != nil {
w.WriteHeader(500) log.Error().Err(err).Msgf("could not decode entry")
fmt.Fprint(w, err) web.writeJSON(w, 500, err)
return return
} }
err = newEntry.Create() err = newEntry.Create()
if err != nil { if err != nil {
w.WriteHeader(500) log.Error().Err(err).Msgf("could not create raw entry")
fmt.Fprint(w, err) web.writeJSON(w, 500, err)
return return
} }
resp, err := json.Marshal(newEntry)
if err != nil { web.writeJSON(w, 200, newEntry)
w.WriteHeader(500)
fmt.Fprint(w, err)
return
}
w.Header().Set("content-type", "application/json")
fmt.Fprint(w, string(resp))
} }
func (web *Web) allEntries(w http.ResponseWriter, r *http.Request) { func (web *Web) allEntries(w http.ResponseWriter, r *http.Request) {
@ -122,19 +131,11 @@ func (web *Web) allEntries(w http.ResponseWriter, r *http.Request) {
entries, err := entry.SearchByTag(web.db, query, tags) entries, err := entry.SearchByTag(web.db, query, tags)
if err != nil { if err != nil {
log.Error().Msgf("Error querying: %w", err) log.Error().Msgf("Error querying: %w", err)
w.WriteHeader(500) web.writeJSON(w, 500, err)
fmt.Fprint(w, err)
return return
} }
resp, err := json.Marshal(entries) web.writeJSON(w, 200, entries)
if err != nil {
w.WriteHeader(500)
fmt.Fprint(w, err)
return
}
w.Header().Set("content-type", "application/json")
fmt.Fprint(w, string(resp))
} }
func (web *Web) getEntry(w http.ResponseWriter, r *http.Request) { func (web *Web) getEntry(w http.ResponseWriter, r *http.Request) {
@ -143,25 +144,16 @@ func (web *Web) getEntry(w http.ResponseWriter, r *http.Request) {
entry, err := entry.GetBySlug(web.db, slug) entry, err := entry.GetBySlug(web.db, slug)
if err != nil { if err != nil {
w.WriteHeader(500) web.writeJSON(w, 500, err)
fmt.Fprint(w, err)
return return
} }
if !web.AuthCheck(r) && !entry.HasTag("public") { if !web.AuthCheck(r) && !entry.HasTag("public") {
w.WriteHeader(401) web.writeJSON(w, 401, "not authorized")
fmt.Fprint(w, "not allowed")
return return
} }
resp, err := json.Marshal(entry) web.writeJSON(w, 200, entry)
if err != nil {
w.WriteHeader(500)
fmt.Fprint(w, err)
return
}
w.Header().Set("content-type", "application/json")
fmt.Fprint(w, string(resp))
} }
func (web *Web) removeEntry(w http.ResponseWriter, r *http.Request) { func (web *Web) removeEntry(w http.ResponseWriter, r *http.Request) {
@ -171,9 +163,8 @@ func (web *Web) removeEntry(w http.ResponseWriter, r *http.Request) {
err := entry.RemoveBySlug(web.db, slug) err := entry.RemoveBySlug(web.db, slug)
if err != nil { if err != nil {
log.Error().Msgf("Error deleting: %s", err) log.Error().Msgf("Error deleting: %s", err)
w.WriteHeader(500) web.writeJSON(w, 500, err)
fmt.Fprint(w, err)
return return
} }
w.WriteHeader(200) web.writeJSON(w, 200, "success")
} }

View File

@ -88,11 +88,12 @@ func (web *Web) routeSetup() http.Handler {
// curl 'http://127.0.0.1:8080/v1/test' -X POST -H 'Accept: application/json, text/plain, */*' --compressed -H 'Content-Type: application/json;charset=utf-8' --data '{ "test": 1 }' // curl 'http://127.0.0.1:8080/v1/test' -X POST -H 'Accept: application/json, text/plain, */*' --compressed -H 'Content-Type: application/json;charset=utf-8' --data '{ "test": 1 }'
authedApi.HandleFunc("/entries", web.newEntry).Methods(http.MethodPost)
authedApi.HandleFunc("/entries", web.newEntry).Methods(http.MethodPost). authedApi.HandleFunc("/entries", web.newEntry).Methods(http.MethodPost).
HeadersRegexp("Content-Type", "application/(text|json).*") HeadersRegexp("Content-Type", "application/(text|json).*")
authedApi.HandleFunc("/entries", web.newMarkdownEntry).Methods(http.MethodPost). authedApi.HandleFunc("/entries", web.newMarkdownEntry).Methods(http.MethodPost).
HeadersRegexp("Content-Type", "application/markdown.*") HeadersRegexp("Content-Type", "application/markdown")
authedApi.HandleFunc("/entries", web.newAdocEntry).Methods(http.MethodPost).
HeadersRegexp("Content-Type", "application/asciidoc")
authedApi.HandleFunc("/entries/{slug}", web.removeEntry).Methods(http.MethodDelete) authedApi.HandleFunc("/entries/{slug}", web.removeEntry).Methods(http.MethodDelete)
authedApi.HandleFunc("/entries/{slug}", web.editEntry).Methods(http.MethodPut) authedApi.HandleFunc("/entries/{slug}", web.editEntry).Methods(http.MethodPut)