diff options
author | Steve Manuel <nilslice@gmail.com> | 2016-10-29 17:36:47 -0700 |
---|---|---|
committer | Steve Manuel <nilslice@gmail.com> | 2016-10-29 17:36:47 -0700 |
commit | b1212fa6f48da1d539a73e1bd5a0bf6894b97d7d (patch) | |
tree | 43529519307a01aad1006975e3f04cea9c88c273 | |
parent | 0be1959e0e19bf77c24ddd49e0ad9ccea0e3b31a (diff) |
adding db procedures and updating handler for external submissions / pending content
-rw-r--r-- | system/admin/handlers.go | 12 | ||||
-rw-r--r-- | system/api/external.go | 2 | ||||
-rw-r--r-- | system/db/content.go | 83 |
3 files changed, 65 insertions, 32 deletions
diff --git a/system/admin/handlers.go b/system/admin/handlers.go index 9414fba..181478a 100644 --- a/system/admin/handlers.go +++ b/system/admin/handlers.go @@ -642,7 +642,7 @@ func postsHandler(res http.ResponseWriter, req *http.Request) { case "public", "": html += `<div class="row externalable"> - Status: + <span class="description">Status:</span> <span class="active">Public</span> | <a href="` + pendingURL + `">Pending</a> @@ -650,17 +650,21 @@ func postsHandler(res http.ResponseWriter, req *http.Request) { case "pending": html += `<div class="row externalable"> - Status: + <span class="description">Status:</span> <a href="` + publicURL + `">Public</a> | <span class="active">Pending</span> </div>` } + // get _pending posts of type t from the db + posts = db.ContentAll(t + "_pending") + } html += `<ul class="posts row">` - if order == "desc" || order == "" { + switch order { + case "desc", "": // keep natural order of posts slice, as returned from sorted bucket for i := range posts { err := json.Unmarshal(posts[i], &p) @@ -676,7 +680,7 @@ func postsHandler(res http.ResponseWriter, req *http.Request) { b.Write(post) } - } else if order == "asc" { + case "asc": // reverse the order of posts slice for i := len(posts) - 1; i >= 0; i-- { err := json.Unmarshal(posts[i], &p) diff --git a/system/api/external.go b/system/api/external.go index a65618b..f9f2538 100644 --- a/system/api/external.go +++ b/system/api/external.go @@ -59,7 +59,7 @@ func externalPostsHandler(res http.ResponseWriter, req *http.Request) { } if ext.Accepts() { - _, err := db.SetContent(t+"_external"+":-1", req.Form) + err := db.SetPendingContent(t+"_pending", req.Form) if err != nil { log.Println("[External] error:", err) res.WriteHeader(http.StatusInternalServerError) diff --git a/system/db/content.go b/system/db/content.go index 616d75f..0b486ba 100644 --- a/system/db/content.go +++ b/system/db/content.go @@ -3,12 +3,14 @@ package db import ( "bytes" "encoding/json" + "errors" "fmt" "log" "net/url" "sort" "strconv" "strings" + "time" "github.com/bosssauce/ponzu/content" "github.com/bosssauce/ponzu/management/editor" @@ -108,44 +110,39 @@ func insert(ns string, data url.Values) (int, error) { return 0, err } - // since sorting can be expensive, limit sort to non-externally created posts - if !strings.Contains(ns, "_external") { - go SortContent(ns) - } + go SortContent(ns) return effectedID, nil } -func postToJSON(ns string, data url.Values) ([]byte, error) { - // find the content type and decode values into it - ns = strings.TrimSuffix(ns, "_external") - t, ok := content.Types[ns] - if !ok { - return nil, fmt.Errorf(content.ErrTypeNotRegistered, ns) +// SetPendingContent inserts submitted content for pending approval +func SetPendingContent(target string, data url.Values) error { + if !strings.Contains(target, "_pending") { + return errors.New("Only set items into _pending bucket using SetPendingContent. Namespace should be <Type>_pending") } - post := t() - dec := schema.NewDecoder() - dec.SetAliasTag("json") // allows simpler struct tagging when creating a content type - dec.IgnoreUnknownKeys(true) // will skip over form values submitted, but not in struct - err := dec.Decode(post, data) - if err != nil { - return nil, err - } + ns := strings.Split(target, "_")[0] - slug, err := manager.Slug(post.(editor.Editable)) - if err != nil { - return nil, err - } - post.(editor.Editable).SetSlug(slug) + err := store.Update(func(tx *bolt.Tx) error { + b, err := tx.CreateBucketIfNotExists([]byte(target)) + if err != nil { + return err + } - // marshall content struct to json for db storage - j, err := json.Marshal(post) + key := fmt.Sprintf("%d", time.Now().UTC().Unix()) + j, err := postToJSON(ns, data) + if err != nil { + return err + } + b.Put([]byte(key), j) + + return nil + }) if err != nil { - return nil, err + return err } - return j, nil + return nil } // DeleteContent removes an item from the database. Deleting a non-existent item @@ -283,3 +280,35 @@ func (s sortablePosts) Less(i, j int) bool { func (s sortablePosts) Swap(i, j int) { s[i], s[j] = s[j], s[i] } + +func postToJSON(ns string, data url.Values) ([]byte, error) { + // find the content type and decode values into it + ns = strings.TrimSuffix(ns, "_external") + t, ok := content.Types[ns] + if !ok { + return nil, fmt.Errorf(content.ErrTypeNotRegistered, ns) + } + post := t() + + dec := schema.NewDecoder() + dec.SetAliasTag("json") // allows simpler struct tagging when creating a content type + dec.IgnoreUnknownKeys(true) // will skip over form values submitted, but not in struct + err := dec.Decode(post, data) + if err != nil { + return nil, err + } + + slug, err := manager.Slug(post.(editor.Editable)) + if err != nil { + return nil, err + } + post.(editor.Editable).SetSlug(slug) + + // marshall content struct to json for db storage + j, err := json.Marshal(post) + if err != nil { + return nil, err + } + + return j, nil +} |