summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSteve Manuel <nilslice@gmail.com>2016-10-29 17:36:47 -0700
committerSteve Manuel <nilslice@gmail.com>2016-10-29 17:36:47 -0700
commitb1212fa6f48da1d539a73e1bd5a0bf6894b97d7d (patch)
tree43529519307a01aad1006975e3f04cea9c88c273
parent0be1959e0e19bf77c24ddd49e0ad9ccea0e3b31a (diff)
adding db procedures and updating handler for external submissions / pending content
-rw-r--r--system/admin/handlers.go12
-rw-r--r--system/api/external.go2
-rw-r--r--system/db/content.go83
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>
&nbsp;&vert;&nbsp;
<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>
&nbsp;&vert;&nbsp;
<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
+}