mirror of https://github.com/status-im/fathom.git
add sscreen-resolutions and countries endpoint
This commit is contained in:
parent
516660b211
commit
a2a54482ff
2
ana.go
2
ana.go
|
@ -34,6 +34,8 @@ func main() {
|
||||||
r.Handle("/api/pageviews/count/day", api.Authorize(api.GetPageviewsDayCountHandler)).Methods("GET")
|
r.Handle("/api/pageviews/count/day", api.Authorize(api.GetPageviewsDayCountHandler)).Methods("GET")
|
||||||
r.Handle("/api/pageviews", api.Authorize(api.GetPageviewsHandler)).Methods("GET")
|
r.Handle("/api/pageviews", api.Authorize(api.GetPageviewsHandler)).Methods("GET")
|
||||||
r.Handle("/api/languages", api.Authorize(api.GetLanguagesHandler)).Methods("GET")
|
r.Handle("/api/languages", api.Authorize(api.GetLanguagesHandler)).Methods("GET")
|
||||||
|
r.Handle("/api/screen-resolutions", api.Authorize(api.GetScreenResolutionsHandler)).Methods("GET")
|
||||||
|
r.Handle("/api/countries", api.Authorize(api.GetCountriesHandler)).Methods("GET")
|
||||||
|
|
||||||
r.PathPrefix("/static/").Handler(http.StripPrefix("/static/", http.FileServer(http.Dir("./static/"))))
|
r.PathPrefix("/static/").Handler(http.StripPrefix("/static/", http.FileServer(http.Dir("./static/"))))
|
||||||
r.Handle("/", http.FileServer(http.Dir("./views/")))
|
r.Handle("/", http.FileServer(http.Dir("./views/")))
|
||||||
|
|
11
api/api.go
11
api/api.go
|
@ -3,11 +3,14 @@ package api
|
||||||
import (
|
import (
|
||||||
"log"
|
"log"
|
||||||
"time"
|
"time"
|
||||||
|
"strconv"
|
||||||
|
"net/http"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Datapoint struct {
|
type Datapoint struct {
|
||||||
Count int
|
Count int
|
||||||
Label string
|
Label string
|
||||||
|
Percentage float32 `json:",omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
var defaultPeriod = 7
|
var defaultPeriod = 7
|
||||||
|
@ -42,3 +45,11 @@ func fillDatapoints(days int, points []Datapoint) []Datapoint {
|
||||||
|
|
||||||
return newPoints
|
return newPoints
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getRequestedPeriod(r *http.Request) int {
|
||||||
|
period, err := strconv.Atoi(r.URL.Query().Get("period"))
|
||||||
|
if err != nil || period == 0 {
|
||||||
|
period = defaultPeriod
|
||||||
|
}
|
||||||
|
return period
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,51 @@
|
||||||
|
package api
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
"github.com/dannyvankooten/ana/core"
|
||||||
|
"encoding/json"
|
||||||
|
)
|
||||||
|
|
||||||
|
// URL: /api/countries
|
||||||
|
var GetCountriesHandler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
period := getRequestedPeriod(r)
|
||||||
|
|
||||||
|
// get total
|
||||||
|
stmt, err := core.DB.Prepare(`
|
||||||
|
SELECT
|
||||||
|
COUNT(DISTINCT(ip_address))
|
||||||
|
FROM visits
|
||||||
|
WHERE timestamp >= DATE_SUB(CURRENT_TIMESTAMP, INTERVAL ? DAY)`)
|
||||||
|
checkError(err)
|
||||||
|
defer stmt.Close()
|
||||||
|
var total float32
|
||||||
|
stmt.QueryRow(period).Scan(&total)
|
||||||
|
|
||||||
|
// get rows
|
||||||
|
stmt, err = core.DB.Prepare(`
|
||||||
|
SELECT
|
||||||
|
country,
|
||||||
|
COUNT(DISTINCT(ip_address)) AS count
|
||||||
|
FROM visits
|
||||||
|
WHERE timestamp >= DATE_SUB(CURRENT_TIMESTAMP, INTERVAL ? DAY) AND country IS NOT NULL
|
||||||
|
GROUP BY country
|
||||||
|
ORDER BY count DESC`)
|
||||||
|
checkError(err)
|
||||||
|
defer stmt.Close()
|
||||||
|
rows, err := stmt.Query(period)
|
||||||
|
checkError(err)
|
||||||
|
defer rows.Close()
|
||||||
|
|
||||||
|
results := make([]Datapoint, 0)
|
||||||
|
for rows.Next() {
|
||||||
|
var d Datapoint
|
||||||
|
err = rows.Scan(&d.Label, &d.Count);
|
||||||
|
checkError(err)
|
||||||
|
|
||||||
|
d.Percentage = float32(d.Count) / total * 100
|
||||||
|
results = append(results, d)
|
||||||
|
}
|
||||||
|
|
||||||
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
json.NewEncoder(w).Encode(results)
|
||||||
|
})
|
|
@ -4,12 +4,23 @@ import (
|
||||||
"net/http"
|
"net/http"
|
||||||
"github.com/dannyvankooten/ana/core"
|
"github.com/dannyvankooten/ana/core"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"strconv"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// URL: /api/languages
|
// URL: /api/languages
|
||||||
var GetLanguagesHandler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
var GetLanguagesHandler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
period := getRequestedPeriod(r)
|
||||||
|
|
||||||
stmt, err := core.DB.Prepare(`
|
stmt, err := core.DB.Prepare(`
|
||||||
|
SELECT
|
||||||
|
COUNT(DISTINCT(ip_address))
|
||||||
|
FROM visits
|
||||||
|
WHERE timestamp >= DATE_SUB(CURRENT_TIMESTAMP, INTERVAL ? DAY)`)
|
||||||
|
checkError(err)
|
||||||
|
defer stmt.Close()
|
||||||
|
var total float32
|
||||||
|
stmt.QueryRow(period).Scan(&total)
|
||||||
|
|
||||||
|
stmt, err = core.DB.Prepare(`
|
||||||
SELECT
|
SELECT
|
||||||
browser_language,
|
browser_language,
|
||||||
COUNT(DISTINCT(ip_address)) AS count
|
COUNT(DISTINCT(ip_address)) AS count
|
||||||
|
@ -20,46 +31,21 @@ var GetLanguagesHandler = http.HandlerFunc(func(w http.ResponseWriter, r *http.R
|
||||||
checkError(err)
|
checkError(err)
|
||||||
defer stmt.Close()
|
defer stmt.Close()
|
||||||
|
|
||||||
|
|
||||||
stmt2, err := core.DB.Prepare(`
|
|
||||||
SELECT
|
|
||||||
COUNT(DISTINCT(ip_address))
|
|
||||||
FROM visits
|
|
||||||
WHERE timestamp >= DATE_SUB(CURRENT_TIMESTAMP, INTERVAL ? DAY)`)
|
|
||||||
checkError(err)
|
|
||||||
defer stmt2.Close()
|
|
||||||
|
|
||||||
period, err := strconv.Atoi(r.URL.Query().Get("period"))
|
|
||||||
if err != nil || period == 0 {
|
|
||||||
period = defaultPeriod
|
|
||||||
}
|
|
||||||
|
|
||||||
var total float32
|
|
||||||
stmt2.QueryRow(period).Scan(&total)
|
|
||||||
|
|
||||||
rows, err := stmt.Query(period)
|
rows, err := stmt.Query(period)
|
||||||
checkError(err)
|
checkError(err)
|
||||||
|
|
||||||
type LanguageData struct {
|
|
||||||
Count int
|
|
||||||
Language string
|
|
||||||
Percentage float32
|
|
||||||
}
|
|
||||||
|
|
||||||
results := make([]LanguageData, 0)
|
|
||||||
defer rows.Close()
|
defer rows.Close()
|
||||||
|
|
||||||
|
results := make([]Datapoint, 0)
|
||||||
|
|
||||||
for rows.Next() {
|
for rows.Next() {
|
||||||
var l LanguageData
|
var d Datapoint
|
||||||
err = rows.Scan(&l.Language, &l.Count);
|
err = rows.Scan(&d.Label, &d.Count);
|
||||||
checkError(err)
|
checkError(err)
|
||||||
|
|
||||||
l.Percentage = float32(l.Count) / total * 100
|
d.Percentage = float32(d.Count) / total * 100
|
||||||
results = append(results, l)
|
results = append(results, d)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = rows.Err();
|
|
||||||
checkError(err)
|
|
||||||
|
|
||||||
w.Header().Set("Content-Type", "application/json")
|
w.Header().Set("Content-Type", "application/json")
|
||||||
json.NewEncoder(w).Encode(results)
|
json.NewEncoder(w).Encode(results)
|
||||||
})
|
})
|
||||||
|
|
|
@ -5,11 +5,12 @@ import (
|
||||||
"github.com/dannyvankooten/ana/models"
|
"github.com/dannyvankooten/ana/models"
|
||||||
"github.com/dannyvankooten/ana/core"
|
"github.com/dannyvankooten/ana/core"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"strconv"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// URL: /api/pageviews
|
// URL: /api/pageviews
|
||||||
var GetPageviewsHandler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
var GetPageviewsHandler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
period := getRequestedPeriod(r)
|
||||||
|
|
||||||
stmt, err := core.DB.Prepare(`SELECT
|
stmt, err := core.DB.Prepare(`SELECT
|
||||||
path,
|
path,
|
||||||
COUNT(ip_address) AS pageviews,
|
COUNT(ip_address) AS pageviews,
|
||||||
|
@ -21,16 +22,11 @@ var GetPageviewsHandler = http.HandlerFunc(func(w http.ResponseWriter, r *http.R
|
||||||
checkError(err)
|
checkError(err)
|
||||||
defer stmt.Close()
|
defer stmt.Close()
|
||||||
|
|
||||||
period, err := strconv.Atoi(r.URL.Query().Get("period"))
|
|
||||||
if err != nil || period == 0 {
|
|
||||||
period = defaultPeriod
|
|
||||||
}
|
|
||||||
|
|
||||||
rows, err := stmt.Query(period)
|
rows, err := stmt.Query(period)
|
||||||
checkError(err)
|
checkError(err)
|
||||||
|
defer rows.Close()
|
||||||
|
|
||||||
results := make([]models.Pageview, 0)
|
results := make([]models.Pageview, 0)
|
||||||
defer rows.Close()
|
|
||||||
for rows.Next() {
|
for rows.Next() {
|
||||||
var p models.Pageview
|
var p models.Pageview
|
||||||
err = rows.Scan(&p.Path, &p.Count, &p.CountUnique);
|
err = rows.Scan(&p.Path, &p.Count, &p.CountUnique);
|
||||||
|
@ -48,6 +44,8 @@ var GetPageviewsHandler = http.HandlerFunc(func(w http.ResponseWriter, r *http.R
|
||||||
|
|
||||||
// URL: /api/pageviews/count/day
|
// URL: /api/pageviews/count/day
|
||||||
var GetPageviewsDayCountHandler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
var GetPageviewsDayCountHandler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
period := getRequestedPeriod(r)
|
||||||
|
|
||||||
stmt, err := core.DB.Prepare(`SELECT
|
stmt, err := core.DB.Prepare(`SELECT
|
||||||
COUNT(*) AS count, DATE_FORMAT(timestamp, '%Y-%m-%d') AS date_group
|
COUNT(*) AS count, DATE_FORMAT(timestamp, '%Y-%m-%d') AS date_group
|
||||||
FROM visits
|
FROM visits
|
||||||
|
@ -56,16 +54,11 @@ var GetPageviewsDayCountHandler = http.HandlerFunc(func(w http.ResponseWriter, r
|
||||||
checkError(err)
|
checkError(err)
|
||||||
defer stmt.Close()
|
defer stmt.Close()
|
||||||
|
|
||||||
period, err := strconv.Atoi(r.URL.Query().Get("period"))
|
|
||||||
if err != nil || period == 0 {
|
|
||||||
period = 7
|
|
||||||
}
|
|
||||||
|
|
||||||
rows, err := stmt.Query(period)
|
rows, err := stmt.Query(period)
|
||||||
checkError(err)
|
checkError(err)
|
||||||
|
defer rows.Close()
|
||||||
|
|
||||||
results := make([]Datapoint, 0)
|
results := make([]Datapoint, 0)
|
||||||
defer rows.Close()
|
|
||||||
for rows.Next() {
|
for rows.Next() {
|
||||||
v := Datapoint{}
|
v := Datapoint{}
|
||||||
err = rows.Scan(&v.Count, &v.Label);
|
err = rows.Scan(&v.Count, &v.Label);
|
||||||
|
@ -75,9 +68,6 @@ var GetPageviewsDayCountHandler = http.HandlerFunc(func(w http.ResponseWriter, r
|
||||||
|
|
||||||
results = fillDatapoints(period, results)
|
results = fillDatapoints(period, results)
|
||||||
|
|
||||||
err = rows.Err();
|
|
||||||
checkError(err)
|
|
||||||
|
|
||||||
w.Header().Set("Content-Type", "application/json")
|
w.Header().Set("Content-Type", "application/json")
|
||||||
json.NewEncoder(w).Encode(results)
|
json.NewEncoder(w).Encode(results)
|
||||||
})
|
})
|
||||||
|
|
|
@ -0,0 +1,51 @@
|
||||||
|
package api
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
"github.com/dannyvankooten/ana/core"
|
||||||
|
"encoding/json"
|
||||||
|
)
|
||||||
|
|
||||||
|
// URL: /api/screen-resolutions
|
||||||
|
var GetScreenResolutionsHandler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
period := getRequestedPeriod(r)
|
||||||
|
|
||||||
|
// get total
|
||||||
|
stmt, err := core.DB.Prepare(`
|
||||||
|
SELECT
|
||||||
|
COUNT(DISTINCT(ip_address))
|
||||||
|
FROM visits
|
||||||
|
WHERE timestamp >= DATE_SUB(CURRENT_TIMESTAMP, INTERVAL ? DAY)`)
|
||||||
|
checkError(err)
|
||||||
|
defer stmt.Close()
|
||||||
|
var total float32
|
||||||
|
stmt.QueryRow(period).Scan(&total)
|
||||||
|
|
||||||
|
// get rows
|
||||||
|
stmt, err = core.DB.Prepare(`
|
||||||
|
SELECT
|
||||||
|
screen_resolution,
|
||||||
|
COUNT(DISTINCT(ip_address)) AS count
|
||||||
|
FROM visits
|
||||||
|
WHERE timestamp >= DATE_SUB(CURRENT_TIMESTAMP, INTERVAL ? DAY)
|
||||||
|
GROUP BY screen_resolution
|
||||||
|
ORDER BY count DESC`)
|
||||||
|
checkError(err)
|
||||||
|
defer stmt.Close()
|
||||||
|
rows, err := stmt.Query(period)
|
||||||
|
checkError(err)
|
||||||
|
defer rows.Close()
|
||||||
|
|
||||||
|
results := make([]Datapoint, 0)
|
||||||
|
for rows.Next() {
|
||||||
|
var d Datapoint
|
||||||
|
err = rows.Scan(&d.Label, &d.Count);
|
||||||
|
checkError(err)
|
||||||
|
|
||||||
|
d.Percentage = float32(d.Count) / total * 100
|
||||||
|
results = append(results, d)
|
||||||
|
}
|
||||||
|
|
||||||
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
json.NewEncoder(w).Encode(results)
|
||||||
|
})
|
Loading…
Reference in New Issue