From 5b7b97a4bf0be38e9a2ebcd0008491adfad5e03b Mon Sep 17 00:00:00 2001 From: Adhityaa Date: Sun, 3 Jun 2018 21:35:44 +0530 Subject: [PATCH] api: add statistics endpoint --- api/comment_statistics.go | 36 +++++++++++++++++ api/domain_statistics.go | 83 +++++++++++++++++++++++++++++++++++++++ api/router_api.go | 1 + 3 files changed, 120 insertions(+) create mode 100644 api/comment_statistics.go create mode 100644 api/domain_statistics.go diff --git a/api/comment_statistics.go b/api/comment_statistics.go new file mode 100644 index 0000000..ac6d089 --- /dev/null +++ b/api/comment_statistics.go @@ -0,0 +1,36 @@ +package main + +import() + +func commentStatistics(domain string) ([]int64, error) { + statement := ` + SELECT COUNT(comments.creationDate) + FROM ( + SELECT to_char(date_trunc('day', (current_date - offs)), 'YYYY-MM-DD') AS date + FROM generate_series(0, 30, 1) AS offs + ) gen LEFT OUTER JOIN comments + ON gen.date = to_char(date_trunc('day', comments.creationDate), 'YYYY-MM-DD') AND + comments.domain=$1 + GROUP BY gen.date + ORDER BY gen.date; + ` + rows, err := db.Query(statement, domain) + if err != nil { + logger.Errorf("cannot get daily views: %v", err) + return []int64{}, errorInternal + } + + defer rows.Close() + + last30Days := []int64{} + for rows.Next() { + var count int64 + if err = rows.Scan(&count); err != nil { + logger.Errorf("cannot get daily comments for the last month: %v", err) + return make([]int64, 0), errorInternal + } + last30Days = append(last30Days, count) + } + + return last30Days, nil +} diff --git a/api/domain_statistics.go b/api/domain_statistics.go new file mode 100644 index 0000000..eb6a7b3 --- /dev/null +++ b/api/domain_statistics.go @@ -0,0 +1,83 @@ +package main + +import ( + "net/http" +) + +func domainStatistics(domain string) ([]int64, error) { + statement := ` + SELECT COUNT(views.viewDate) + FROM ( + SELECT to_char(date_trunc('day', (current_date - offs)), 'YYYY-MM-DD') AS date + FROM generate_series(0, 30, 1) AS offs + ) gen LEFT OUTER JOIN views + ON gen.date = to_char(date_trunc('day', views.viewDate), 'YYYY-MM-DD') AND + views.domain=$1 + GROUP BY gen.date + ORDER BY gen.date; + ` + rows, err := db.Query(statement, domain) + if err != nil { + logger.Errorf("cannot get daily views: %v", err) + return []int64{}, errorInternal + } + + defer rows.Close() + + last30Days := []int64{} + for rows.Next() { + var count int64 + if err = rows.Scan(&count); err != nil { + logger.Errorf("cannot get daily views for the last month: %v", err) + return []int64{}, errorInternal + } + last30Days = append(last30Days, count) + } + + return last30Days, nil +} + +func domainStatisticsHandler(w http.ResponseWriter, r *http.Request) { + type request struct { + Session *string `json:"session"` + Domain *string `json:"domain"` + } + + var x request + if err := unmarshalBody(r, &x); err != nil { + writeBody(w, response{"success": false, "message": err.Error()}) + return + } + + o, err := ownerGetBySession(*x.Session) + if err != nil { + writeBody(w, response{"success": false, "message": err.Error()}) + return + } + + domain := stripDomain(*x.Domain) + isOwner, err := domainOwnershipVerify(o.OwnerHex, domain) + if err != nil { + writeBody(w, response{"success": false, "message": err.Error()}) + return + } + + if !isOwner { + writeBody(w, response{"success": false, "message": errorNotAuthorised.Error()}) + return + } + + viewsLast30Days, err := domainStatistics(domain) + if err != nil { + writeBody(w, response{"success": false, "message": err.Error()}) + return + } + + commentsLast30Days, err := commentStatistics(domain) + if err != nil { + writeBody(w, response{"success": false, "message": err.Error()}) + return + } + + writeBody(w, response{"success": true, "viewsLast30Days": viewsLast30Days, "commentsLast30Days": commentsLast30Days}) +} diff --git a/api/router_api.go b/api/router_api.go index 2935390..459bf40 100644 --- a/api/router_api.go +++ b/api/router_api.go @@ -18,6 +18,7 @@ func initAPIRouter(router *mux.Router) error { router.HandleFunc("/api/domain/update", domainUpdateHandler).Methods("POST") router.HandleFunc("/api/domain/moderator/new", domainModeratorNewHandler).Methods("POST") router.HandleFunc("/api/domain/moderator/delete", domainModeratorDeleteHandler).Methods("POST") + router.HandleFunc("/api/domain/statistics", domainStatisticsHandler).Methods("POST") router.HandleFunc("/api/commenter/session/new", commenterSessionNewHandler).Methods("GET") router.HandleFunc("/api/commenter/self", commenterSelfHandler).Methods("POST")