mirror of
https://github.com/status-im/fathom.git
synced 2025-03-01 03:20:27 +00:00
remove 'period' query parameter in favor of before & after
This commit is contained in:
parent
ab770c6c21
commit
fded071f7a
46
api/api.go
46
api/api.go
@ -23,25 +23,34 @@ func checkError(err error) {
|
||||
}
|
||||
}
|
||||
|
||||
func fillDatapoints(days int, points []Datapoint) []Datapoint {
|
||||
func fillDatapoints(start int64, end int64, points []Datapoint) []Datapoint {
|
||||
// be smart about received timestamps
|
||||
if start > end {
|
||||
tmp := end
|
||||
end = start
|
||||
start = tmp
|
||||
}
|
||||
|
||||
now := time.Now().AddDate(0, 0, 1)
|
||||
start := now.AddDate(0, 0, -days)
|
||||
newPoints := make([]Datapoint, days)
|
||||
startTime := time.Unix(start, 0)
|
||||
endTime := time.Unix(end, 0)
|
||||
newPoints := make([]Datapoint, 0)
|
||||
|
||||
for i := 0; i < days; i++ {
|
||||
newPoints[i] = Datapoint{
|
||||
for startTime.Before(endTime) {
|
||||
point := Datapoint{
|
||||
Count: 0,
|
||||
Label: start.AddDate(0, 0, i).Format("2006-01-02"),
|
||||
Label: startTime.Format("2006-01-02"),
|
||||
}
|
||||
|
||||
for j, p := range points {
|
||||
if p.Label == newPoints[i].Label {
|
||||
newPoints[i].Count = p.Count
|
||||
if p.Label == point.Label {
|
||||
point.Count = p.Count
|
||||
points[j] = points[len(points)-1]
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
newPoints = append(newPoints, point)
|
||||
startTime = startTime.AddDate(0, 0, 1)
|
||||
}
|
||||
|
||||
return newPoints
|
||||
@ -56,10 +65,19 @@ func getRequestedLimit(r *http.Request) int {
|
||||
return limit
|
||||
}
|
||||
|
||||
func getRequestedPeriod(r *http.Request) int {
|
||||
period, err := strconv.Atoi(r.URL.Query().Get("period"))
|
||||
if err != nil || period == 0 {
|
||||
period = defaultPeriod
|
||||
func getRequestedPeriods(r *http.Request) (int64, int64) {
|
||||
var before, after int64
|
||||
var err error
|
||||
|
||||
before, err = strconv.ParseInt(r.URL.Query().Get("before"), 10, 64)
|
||||
if err != nil || before == 0 {
|
||||
before = time.Now().Unix()
|
||||
}
|
||||
return period
|
||||
|
||||
after, err = strconv.ParseInt(r.URL.Query().Get("after"), 10, 64)
|
||||
if err != nil || before == 0 {
|
||||
after = time.Now().AddDate(0, 0, -7).Unix()
|
||||
}
|
||||
|
||||
return before, after
|
||||
}
|
||||
|
@ -8,18 +8,19 @@ import (
|
||||
|
||||
// URL: /api/browsers
|
||||
var GetBrowsersHandler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
period := getRequestedPeriod(r)
|
||||
before, after := getRequestedPeriods(r)
|
||||
|
||||
// get total
|
||||
stmt, err := core.DB.Prepare(`
|
||||
SELECT
|
||||
COUNT(DISTINCT(ip_address))
|
||||
FROM visits
|
||||
WHERE timestamp >= DATE_SUB(CURRENT_TIMESTAMP, INTERVAL ? DAY)`)
|
||||
WHERE UNIX_TIMESTAMP(timestamp) <= ? AND UNIX_TIMESTAMP(timestamp) >= ?
|
||||
`)
|
||||
checkError(err)
|
||||
defer stmt.Close()
|
||||
var total float32
|
||||
stmt.QueryRow(period).Scan(&total)
|
||||
stmt.QueryRow(before, after).Scan(&total)
|
||||
|
||||
// get rows
|
||||
stmt, err = core.DB.Prepare(`
|
||||
@ -27,13 +28,13 @@ var GetBrowsersHandler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Re
|
||||
browser_name,
|
||||
COUNT(DISTINCT(ip_address)) AS count
|
||||
FROM visits
|
||||
WHERE timestamp >= DATE_SUB(CURRENT_TIMESTAMP, INTERVAL ? DAY) AND browser_name IS NOT NULL
|
||||
WHERE UNIX_TIMESTAMP(timestamp) <= ? AND UNIX_TIMESTAMP(timestamp) >= ? AND browser_name IS NOT NULL
|
||||
GROUP BY browser_name
|
||||
ORDER BY count DESC
|
||||
LIMIT ?`)
|
||||
checkError(err)
|
||||
defer stmt.Close()
|
||||
rows, err := stmt.Query(period, defaultLimit)
|
||||
rows, err := stmt.Query(before, after, defaultLimit)
|
||||
checkError(err)
|
||||
defer rows.Close()
|
||||
|
||||
|
@ -8,18 +8,19 @@ import (
|
||||
|
||||
// URL: /api/countries
|
||||
var GetCountriesHandler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
period := getRequestedPeriod(r)
|
||||
before, after := getRequestedPeriods(r)
|
||||
|
||||
// get total
|
||||
stmt, err := core.DB.Prepare(`
|
||||
SELECT
|
||||
COUNT(DISTINCT(ip_address))
|
||||
FROM visits
|
||||
WHERE timestamp >= DATE_SUB(CURRENT_TIMESTAMP, INTERVAL ? DAY)`)
|
||||
WHERE UNIX_TIMESTAMP(timestamp) <= ? AND UNIX_TIMESTAMP(timestamp) >= ?
|
||||
`)
|
||||
checkError(err)
|
||||
defer stmt.Close()
|
||||
var total float32
|
||||
stmt.QueryRow(period).Scan(&total)
|
||||
stmt.QueryRow(before, after).Scan(&total)
|
||||
|
||||
// get rows
|
||||
stmt, err = core.DB.Prepare(`
|
||||
@ -27,13 +28,13 @@ var GetCountriesHandler = http.HandlerFunc(func(w http.ResponseWriter, r *http.R
|
||||
country,
|
||||
COUNT(DISTINCT(ip_address)) AS count
|
||||
FROM visits
|
||||
WHERE timestamp >= DATE_SUB(CURRENT_TIMESTAMP, INTERVAL ? DAY) AND country IS NOT NULL
|
||||
WHERE UNIX_TIMESTAMP(timestamp) <= ? AND UNIX_TIMESTAMP(timestamp) >= ? AND country IS NOT NULL
|
||||
GROUP BY country
|
||||
ORDER BY count DESC
|
||||
LIMIT ?`)
|
||||
checkError(err)
|
||||
defer stmt.Close()
|
||||
rows, err := stmt.Query(period, defaultLimit)
|
||||
rows, err := stmt.Query(before, after, defaultLimit)
|
||||
checkError(err)
|
||||
defer rows.Close()
|
||||
|
||||
|
@ -8,31 +8,32 @@ import (
|
||||
|
||||
// URL: /api/languages
|
||||
var GetLanguagesHandler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
period := getRequestedPeriod(r)
|
||||
before, after := getRequestedPeriods(r)
|
||||
|
||||
stmt, err := core.DB.Prepare(`
|
||||
SELECT
|
||||
COUNT(DISTINCT(ip_address))
|
||||
FROM visits
|
||||
WHERE timestamp >= DATE_SUB(CURRENT_TIMESTAMP, INTERVAL ? DAY)`)
|
||||
WHERE UNIX_TIMESTAMP(timestamp) <= ? AND UNIX_TIMESTAMP(timestamp) >= ?
|
||||
`)
|
||||
checkError(err)
|
||||
defer stmt.Close()
|
||||
var total float32
|
||||
stmt.QueryRow(period).Scan(&total)
|
||||
stmt.QueryRow(before, after).Scan(&total)
|
||||
|
||||
stmt, err = core.DB.Prepare(`
|
||||
SELECT
|
||||
browser_language,
|
||||
COUNT(DISTINCT(ip_address)) AS count
|
||||
FROM visits
|
||||
WHERE timestamp >= DATE_SUB(CURRENT_TIMESTAMP, INTERVAL ? DAY)
|
||||
WHERE UNIX_TIMESTAMP(timestamp) <= ? AND UNIX_TIMESTAMP(timestamp) >= ?
|
||||
GROUP BY browser_language
|
||||
ORDER BY count DESC
|
||||
LIMIT ?`)
|
||||
checkError(err)
|
||||
defer stmt.Close()
|
||||
|
||||
rows, err := stmt.Query(period, defaultLimit)
|
||||
rows, err := stmt.Query(before, after, defaultLimit)
|
||||
checkError(err)
|
||||
defer rows.Close()
|
||||
|
||||
|
@ -9,21 +9,20 @@ import (
|
||||
|
||||
// URL: /api/pageviews
|
||||
var GetPageviewsHandler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
period := getRequestedPeriod(r)
|
||||
|
||||
before, after := getRequestedPeriods(r)
|
||||
stmt, err := core.DB.Prepare(`SELECT
|
||||
path,
|
||||
COUNT(ip_address) AS pageviews,
|
||||
COUNT(DISTINCT(ip_address)) AS pageviews_unique
|
||||
FROM visits
|
||||
WHERE timestamp >= DATE_SUB(CURRENT_TIMESTAMP, INTERVAL ? DAY)
|
||||
WHERE UNIX_TIMESTAMP(timestamp) <= ? AND UNIX_TIMESTAMP(timestamp) >= ?
|
||||
GROUP BY path
|
||||
ORDER BY pageviews DESC
|
||||
ORDER BY pageviews DESC
|
||||
LIMIT ?`)
|
||||
checkError(err)
|
||||
defer stmt.Close()
|
||||
|
||||
rows, err := stmt.Query(period, defaultLimit)
|
||||
rows, err := stmt.Query(before, after, defaultLimit)
|
||||
checkError(err)
|
||||
defer rows.Close()
|
||||
|
||||
@ -45,14 +44,13 @@ var GetPageviewsHandler = http.HandlerFunc(func(w http.ResponseWriter, r *http.R
|
||||
|
||||
// URL: /api/pageviews/count
|
||||
var GetPageviewsCountHandler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
period := getRequestedPeriod(r)
|
||||
stmt, err := core.DB.Prepare(`SELECT COUNT(*) FROM visits WHERE timestamp >= DATE_SUB(CURRENT_TIMESTAMP, INTERVAL ? day) AND timestamp <= CURRENT_TIMESTAMP`)
|
||||
|
||||
before, after := getRequestedPeriods(r)
|
||||
stmt, err := core.DB.Prepare(`SELECT COUNT(*) FROM visits WHERE UNIX_TIMESTAMP(timestamp) <= ? AND UNIX_TIMESTAMP(timestamp) >= ?`)
|
||||
checkError(err)
|
||||
defer stmt.Close()
|
||||
|
||||
var result int
|
||||
stmt.QueryRow(period).Scan(&result)
|
||||
stmt.QueryRow(before, after).Scan(&result)
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
json.NewEncoder(w).Encode(result)
|
||||
@ -60,17 +58,16 @@ var GetPageviewsCountHandler = http.HandlerFunc(func(w http.ResponseWriter, r *h
|
||||
|
||||
// URL: /api/pageviews/count/day
|
||||
var GetPageviewsDayCountHandler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
period := getRequestedPeriod(r)
|
||||
|
||||
before, after := getRequestedPeriods(r)
|
||||
stmt, err := core.DB.Prepare(`SELECT
|
||||
COUNT(*) AS count, DATE_FORMAT(timestamp, '%Y-%m-%d') AS date_group
|
||||
FROM visits
|
||||
WHERE timestamp >= DATE_SUB(CURRENT_TIMESTAMP, INTERVAL ? DAY)
|
||||
WHERE UNIX_TIMESTAMP(timestamp) <= ? AND UNIX_TIMESTAMP(timestamp) >= ?
|
||||
GROUP BY date_group`)
|
||||
checkError(err)
|
||||
defer stmt.Close()
|
||||
|
||||
rows, err := stmt.Query(period)
|
||||
rows, err := stmt.Query(before, after)
|
||||
checkError(err)
|
||||
defer rows.Close()
|
||||
|
||||
@ -82,7 +79,7 @@ var GetPageviewsDayCountHandler = http.HandlerFunc(func(w http.ResponseWriter, r
|
||||
results = append(results, v)
|
||||
}
|
||||
|
||||
results = fillDatapoints(period, results)
|
||||
results = fillDatapoints(before, after, results)
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
json.NewEncoder(w).Encode(results)
|
||||
|
@ -8,18 +8,18 @@ import (
|
||||
|
||||
// URL: /api/screen-resolutions
|
||||
var GetScreenResolutionsHandler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
period := getRequestedPeriod(r)
|
||||
before, after := getRequestedPeriods(r)
|
||||
|
||||
// get total
|
||||
stmt, err := core.DB.Prepare(`
|
||||
SELECT
|
||||
COUNT(DISTINCT(ip_address))
|
||||
FROM visits
|
||||
WHERE timestamp >= DATE_SUB(CURRENT_TIMESTAMP, INTERVAL ? DAY)`)
|
||||
WHERE UNIX_TIMESTAMP(timestamp) <= ? AND UNIX_TIMESTAMP(timestamp) >= ?`)
|
||||
checkError(err)
|
||||
defer stmt.Close()
|
||||
var total float32
|
||||
stmt.QueryRow(period).Scan(&total)
|
||||
stmt.QueryRow(before, after).Scan(&total)
|
||||
|
||||
// get rows
|
||||
stmt, err = core.DB.Prepare(`
|
||||
@ -27,13 +27,13 @@ var GetScreenResolutionsHandler = http.HandlerFunc(func(w http.ResponseWriter, r
|
||||
screen_resolution,
|
||||
COUNT(DISTINCT(ip_address)) AS count
|
||||
FROM visits
|
||||
WHERE timestamp >= DATE_SUB(CURRENT_TIMESTAMP, INTERVAL ? DAY)
|
||||
WHERE UNIX_TIMESTAMP(timestamp) <= ? AND UNIX_TIMESTAMP(timestamp) >= ?
|
||||
GROUP BY screen_resolution
|
||||
ORDER BY count DESC
|
||||
LIMIT ?`)
|
||||
checkError(err)
|
||||
defer stmt.Close()
|
||||
rows, err := stmt.Query(period, defaultLimit)
|
||||
rows, err := stmt.Query(before, after, defaultLimit)
|
||||
checkError(err)
|
||||
defer rows.Close()
|
||||
|
||||
|
@ -47,14 +47,14 @@ var GetVisitsHandler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Requ
|
||||
|
||||
// URL: /api/visits/count
|
||||
var GetVisitsCountHandler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
period := getRequestedPeriod(r)
|
||||
stmt, err := core.DB.Prepare(`SELECT COUNT(DISTINCT(ip_address)) FROM visits WHERE timestamp >= DATE_SUB(CURRENT_TIMESTAMP, INTERVAL ? day) AND timestamp <= CURRENT_TIMESTAMP`)
|
||||
before, after := getRequestedPeriods(r)
|
||||
stmt, err := core.DB.Prepare(`SELECT COUNT(DISTINCT(ip_address)) FROM visits WHERE UNIX_TIMESTAMP(timestamp) <= ? AND UNIX_TIMESTAMP(timestamp) >= ?`)
|
||||
|
||||
checkError(err)
|
||||
defer stmt.Close()
|
||||
|
||||
var result int
|
||||
stmt.QueryRow(period).Scan(&result)
|
||||
stmt.QueryRow(before, after).Scan(&result)
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
json.NewEncoder(w).Encode(result)
|
||||
@ -74,13 +74,13 @@ var GetVisitsDayCountHandler = http.HandlerFunc(func(w http.ResponseWriter, r *h
|
||||
stmt, err := core.DB.Prepare(`SELECT
|
||||
COUNT(DISTINCT(ip_address)) AS count, DATE_FORMAT(timestamp, '%Y-%m-%d') AS date_group
|
||||
FROM visits
|
||||
WHERE timestamp >= DATE_SUB(CURRENT_TIMESTAMP, INTERVAL ? DAY)
|
||||
WHERE UNIX_TIMESTAMP(timestamp) <= ? AND UNIX_TIMESTAMP(timestamp) >= ?
|
||||
GROUP BY date_group`)
|
||||
checkError(err)
|
||||
defer stmt.Close()
|
||||
|
||||
period := getRequestedPeriod(r)
|
||||
rows, err := stmt.Query(period)
|
||||
before, after := getRequestedPeriods(r)
|
||||
rows, err := stmt.Query(before, after)
|
||||
checkError(err)
|
||||
|
||||
results := make([]Datapoint, 0)
|
||||
@ -92,8 +92,7 @@ var GetVisitsDayCountHandler = http.HandlerFunc(func(w http.ResponseWriter, r *h
|
||||
results = append(results, v)
|
||||
}
|
||||
|
||||
results = fillDatapoints(period, results)
|
||||
|
||||
results = fillDatapoints(before, after, results)
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
json.NewEncoder(w).Encode(results)
|
||||
})
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
import { h, render, Component } from 'preact';
|
||||
import Chart from 'chart.js'
|
||||
const dayInSeconds = 60 * 60 * 24;
|
||||
|
||||
Chart.defaults.global.tooltips.xPadding = 10;
|
||||
Chart.defaults.global.tooltips.yPadding = 10;
|
||||
@ -60,8 +61,11 @@ class Graph extends Component {
|
||||
}
|
||||
|
||||
fetchData(period) {
|
||||
const before = Math.round((+new Date() ) / 1000);
|
||||
const after = before - ( period * dayInSeconds );
|
||||
|
||||
// fetch visitor data
|
||||
fetch('/api/visits/count/day?period=' + period, {
|
||||
fetch(`/api/visits/count/day?before=${before}&after=${after}`, {
|
||||
credentials: 'include'
|
||||
}).then((r) => {
|
||||
if( r.ok ) {
|
||||
@ -74,7 +78,7 @@ class Graph extends Component {
|
||||
});
|
||||
|
||||
// fetch pageview data
|
||||
fetch('/api/pageviews/count/day?period=' + period, {
|
||||
fetch(`/api/pageviews/count/day?before=${before}&after=${after}`, {
|
||||
credentials: 'include'
|
||||
}).then((r) => {
|
||||
if( r.ok ) {
|
||||
|
@ -1,6 +1,7 @@
|
||||
'use strict';
|
||||
|
||||
import { h, render, Component } from 'preact';
|
||||
const dayInSeconds = 60 * 60 * 24;
|
||||
|
||||
class Pageviews extends Component {
|
||||
|
||||
@ -21,7 +22,10 @@ class Pageviews extends Component {
|
||||
}
|
||||
|
||||
fetchRecords(period) {
|
||||
return fetch('/api/pageviews?period=' + period, {
|
||||
const before = Math.round((+new Date() ) / 1000);
|
||||
const after = before - ( period * dayInSeconds );
|
||||
|
||||
return fetch(`/api/pageviews?before=${before}&after=${after}`, {
|
||||
credentials: 'include'
|
||||
}).then((r) => {
|
||||
if( r.ok ) {
|
||||
@ -31,8 +35,6 @@ class Pageviews extends Component {
|
||||
throw new Error();
|
||||
}).then((data) => {
|
||||
this.setState({ records: data })
|
||||
}).catch((e) => {
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
'use strict';
|
||||
|
||||
import { h, render, Component } from 'preact';
|
||||
const dayInSeconds = 60 * 60 * 24;
|
||||
|
||||
class Table extends Component {
|
||||
|
||||
@ -33,7 +34,10 @@ class Table extends Component {
|
||||
}
|
||||
|
||||
fetchRecords(period) {
|
||||
return fetch('/api/'+this.props.endpoint+'?period=' + period, {
|
||||
const before = Math.round((+new Date() ) / 1000);
|
||||
const after = before - ( period * dayInSeconds );
|
||||
|
||||
return fetch(`/api/${this.props.endpoint}?before=${before}&after=${after}`, {
|
||||
credentials: 'include'
|
||||
}).then((r) => {
|
||||
if( r.ok ) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user