diff options
author | Steve Manuel <nilslice@gmail.com> | 2017-04-25 13:23:37 -0700 |
---|---|---|
committer | Steve Manuel <nilslice@gmail.com> | 2017-04-25 13:23:37 -0700 |
commit | 099d000119447708d7d0d0482758d352438fa7e5 (patch) | |
tree | f4386ae2ff25a5b6b15c2e6442d4c56705e8271e /system/db/upload.go | |
parent | 7092fb8979869f3c09b364d454d8d8081bb7c0bc (diff) |
adding support for file upload type and API handler to fetch file info
Diffstat (limited to 'system/db/upload.go')
-rw-r--r-- | system/db/upload.go | 142 |
1 files changed, 142 insertions, 0 deletions
diff --git a/system/db/upload.go b/system/db/upload.go new file mode 100644 index 0000000..3157f13 --- /dev/null +++ b/system/db/upload.go @@ -0,0 +1,142 @@ +package db + +import ( + "bytes" + "encoding/json" + "fmt" + "net/url" + "strings" + "time" + + "github.com/ponzu-cms/ponzu/system/item" + + "github.com/boltdb/bolt" + "github.com/gorilla/schema" + uuid "github.com/satori/go.uuid" +) + +// SetUpload stores information about files uploaded to the system +func SetUpload(data url.Values) error { + // set new UUID for upload + data.Set("uuid", uuid.NewV4().String()) + + // create slug based on filename and timestamp/updated fields + slug := data.Get("name") + slug, err := checkSlugForDuplicate(slug) + if err != nil { + return err + } + data.Set("slug", slug) + + ts := fmt.Sprintf("%d", time.Now().Unix()*1000) + data.Set("timestamp", ts) + data.Set("updated", ts) + + // store in database + err = store.Update(func(tx *bolt.Tx) error { + b, err := tx.CreateBucketIfNotExists([]byte("__uploads")) + if err != nil { + return err + } + + // get sequential ID for item + id, err := b.NextSequence() + if err != nil { + return err + } + data.Set("id", fmt.Sprintf("%d", id)) + + file := &item.FileUpload{} + 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(file, data) + if err != nil { + return err + } + + // marshal data to json for storage + j, err := json.Marshal(file) + if err != nil { + return err + } + + err = b.Put([]byte(data.Get("id")), j) + if err != nil { + return err + } + + return nil + }) + if err != nil { + return err + } + + // add slug to __contentIndex for lookup + return store.Update(func(tx *bolt.Tx) error { + b, err := tx.CreateBucketIfNotExists([]byte("__contentIndex")) + if err != nil { + return err + } + + k := []byte(data.Get("slug")) + v := []byte(fmt.Sprintf("%s:%s", "__uploads", data.Get("id"))) + err = b.Put(k, v) + if err != nil { + return err + } + + return nil + }) +} + +// Upload returns the value for an upload by its target (__uploads:{id}) +func Upload(target string) ([]byte, error) { + val := &bytes.Buffer{} + parts := strings.Split(target, ":") + if len(parts) < 2 { + return nil, fmt.Errorf("invalid target for upload: %s", target) + } + + id := []byte(parts[1]) + + err := store.View(func(tx *bolt.Tx) error { + b := tx.Bucket([]byte("__uploads")) + if b == nil { + return bolt.ErrBucketNotFound + } + + j := b.Get(id) + _, err := val.Write(j) + return err + }) + + return val.Bytes(), err +} + +// UploadBySlug returns the value for an upload by its slug +func UploadBySlug(slug string) ([]byte, error) { + val := &bytes.Buffer{} + // get target from __contentIndex or return nil if not exists + err := store.View(func(tx *bolt.Tx) error { + b := tx.Bucket([]byte("__contentIndex")) + if b == nil { + return bolt.ErrBucketNotFound + } + + target := b.Get([]byte(slug)) + if target == nil { + return fmt.Errorf("no value for target in %s", "__contentIndex") + } + j, err := Upload(string(target)) + if err != nil { + return err + } + + _, err = val.Write(j) + + return err + }) + + return val.Bytes(), err +} |