diff options
Diffstat (limited to 'system/api')
-rw-r--r-- | system/api/analytics/batch.go | 47 | ||||
-rw-r--r-- | system/api/analytics/init.go | 12 | ||||
-rw-r--r-- | system/api/handlers.go | 48 | ||||
-rw-r--r-- | system/api/server.go | 12 |
4 files changed, 76 insertions, 43 deletions
diff --git a/system/api/analytics/batch.go b/system/api/analytics/batch.go new file mode 100644 index 0000000..1fee247 --- /dev/null +++ b/system/api/analytics/batch.go @@ -0,0 +1,47 @@ +package analytics + +import ( + "encoding/json" + "strconv" + + "github.com/boltdb/bolt" +) + +// batchInsert is effectively a specialized version of SetContentMulti from the +// db package, iterating over a []apiRequest instead of []url.Values +func batchInsert(batch []apiRequest) error { + err := store.Update(func(tx *bolt.Tx) error { + b, err := tx.CreateBucketIfNotExists([]byte("requests")) + if err != nil { + return err + } + + for _, apiReq := range batch { + // get the next available ID and convert to string + // also set effectedID to int of ID + id, err := b.NextSequence() + if err != nil { + return err + } + cid := strconv.FormatUint(id, 10) + + j, err := json.Marshal(apiReq) + if err != nil { + return err + } + + err = b.Put([]byte(cid), j) + if err != nil { + return err + } + } + + return nil + + }) + if err != nil { + return err + } + + return nil +} diff --git a/system/api/analytics/init.go b/system/api/analytics/init.go index c351bed..3af1407 100644 --- a/system/api/analytics/init.go +++ b/system/api/analytics/init.go @@ -15,6 +15,7 @@ import ( type apiRequest struct { URL string `json:"url"` Method string `json:"http_method"` + Origin string `json:"origin"` RemoteAddr string `json:"ip_address"` Timestamp int64 `json:"timestamp"` External bool `json:"external"` @@ -32,6 +33,7 @@ func Record(req *http.Request) { r := apiRequest{ URL: req.URL.String(), Method: req.Method, + Origin: req.Header.Get("Origin"), RemoteAddr: req.RemoteAddr, Timestamp: time.Now().Unix() * 1000, External: external, @@ -39,7 +41,6 @@ func Record(req *http.Request) { // put r on buffered recordChan to take advantage of batch insertion in DB recordChan <- r - } // Close exports the abillity to close our db file. Should be called with defer @@ -64,10 +65,6 @@ func Init() { go serve() - err = store.Update(func(tx *bolt.Tx) error { - - return nil - }) if err != nil { log.Fatalln(err) } @@ -93,6 +90,11 @@ func serve() { reqs = append(reqs, <-recordChan) } + err := batchInsert(reqs) + if err != nil { + log.Println(err) + } + case <-pruneDBTimer.C: default: diff --git a/system/api/handlers.go b/system/api/handlers.go index 8356683..d1758f0 100644 --- a/system/api/handlers.go +++ b/system/api/handlers.go @@ -36,6 +36,11 @@ func postsHandler(res http.ResponseWriter, req *http.Request) { return } + if _, ok := content.Types[t]; !ok { + res.WriteHeader(http.StatusNotFound) + return + } + count, err := strconv.Atoi(q.Get("count")) // int: determines number of posts to return (10 default, -1 is all) if err != nil { if q.Get("count") == "" { @@ -57,46 +62,23 @@ func postsHandler(res http.ResponseWriter, req *http.Request) { } order := strings.ToLower(q.Get("order")) // string: sort order of posts by timestamp ASC / DESC (DESC default) - if order != "asc" || order == "" { + if order != "asc" { order = "desc" } - // TODO: time-based ?after=time.Time, ?before=time.Time between=time.Time|time.Time - - posts := db.ContentAll(t + "_sorted") - var all = []json.RawMessage{} - for _, post := range posts { - all = append(all, post) + opts := db.QueryOptions{ + Count: count, + Offset: offset, + Order: order, } - var start, end int - switch count { - case -1: - start = 0 - end = len(posts) - - default: - start = count * offset - end = start + count - } - - // bounds check on posts given the start & end count - if start > len(posts) { - start = len(posts) - count - } - if end > len(posts) { - end = len(posts) - } - - // reverse the sorted order if ASC - if order == "asc" { - all = []json.RawMessage{} - for i := len(posts) - 1; i >= 0; i-- { - all = append(all, posts[i]) - } + bb := db.Query(t+"_sorted", opts) + var result = []json.RawMessage{} + for i := range bb { + result = append(result, bb[i]) } - j, err := fmtJSON(all[start:end]...) + j, err := fmtJSON(result...) if err != nil { res.WriteHeader(http.StatusInternalServerError) return diff --git a/system/api/server.go b/system/api/server.go index 816bc21..4468394 100644 --- a/system/api/server.go +++ b/system/api/server.go @@ -1,14 +1,16 @@ package api -import "net/http" +import ( + "net/http" +) // Run adds Handlers to default http listener for API func Run() { - http.HandleFunc("/api/types", CORS(typesHandler)) + http.HandleFunc("/api/types", CORS(Record(typesHandler))) - http.HandleFunc("/api/posts", CORS(postsHandler)) + http.HandleFunc("/api/posts", CORS(Record(postsHandler))) - http.HandleFunc("/api/post", CORS(postHandler)) + http.HandleFunc("/api/post", CORS(Record(postHandler))) - http.HandleFunc("/api/external/posts", CORS(externalPostsHandler)) + http.HandleFunc("/api/external/posts", CORS(Record(externalPostsHandler))) } |