summaryrefslogtreecommitdiff
path: root/system/api
diff options
context:
space:
mode:
Diffstat (limited to 'system/api')
-rw-r--r--system/api/analytics/batch.go47
-rw-r--r--system/api/analytics/init.go12
-rw-r--r--system/api/handlers.go48
-rw-r--r--system/api/server.go12
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)))
}