mirror of https://github.com/status-im/fathom.git
generate unique visitor key from date + ip + user agent
This commit is contained in:
parent
f6cab7c297
commit
626de69c95
|
@ -1,7 +1,9 @@
|
||||||
package api
|
package api
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"database/sql"
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
@ -42,13 +44,18 @@ func CollectHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
defer stmt.Close()
|
defer stmt.Close()
|
||||||
err := stmt.QueryRow(page.Hostname, page.Path).Scan(&page.ID)
|
err := stmt.QueryRow(page.Hostname, page.Path).Scan(&page.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
if err == sql.ErrNoRows {
|
||||||
page.Save(db.Conn)
|
page.Save(db.Conn)
|
||||||
|
} else {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// find or insert visitor.
|
// find or insert visitor.
|
||||||
// TODO: Mask IP Address
|
now := time.Now()
|
||||||
|
ip := getRequestIp(r)
|
||||||
visitor := models.Visitor{
|
visitor := models.Visitor{
|
||||||
IpAddress: getRequestIp(r),
|
IpAddress: ip,
|
||||||
BrowserLanguage: q.Get("l"),
|
BrowserLanguage: q.Get("l"),
|
||||||
ScreenResolution: q.Get("sr"),
|
ScreenResolution: q.Get("sr"),
|
||||||
DeviceOS: ua.OS(),
|
DeviceOS: ua.OS(),
|
||||||
|
@ -60,21 +67,26 @@ func CollectHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
visitor.BrowserName = parseMajorMinor(visitor.BrowserName)
|
visitor.BrowserName = parseMajorMinor(visitor.BrowserName)
|
||||||
|
|
||||||
// query by unique visitor key
|
// query by unique visitor key
|
||||||
visitor.GenerateKey()
|
visitor.Key = visitor.GenerateKey(now.Format("2006-01-02"), visitor.IpAddress, r.UserAgent())
|
||||||
|
|
||||||
stmt, _ = db.Conn.Prepare("SELECT v.id FROM visitors v WHERE v.visitor_key = ? LIMIT 1")
|
stmt, _ = db.Conn.Prepare("SELECT v.id FROM visitors v WHERE v.visitor_key = ? LIMIT 1")
|
||||||
defer stmt.Close()
|
defer stmt.Close()
|
||||||
err = stmt.QueryRow(visitor.Key).Scan(&visitor.ID)
|
err = stmt.QueryRow(visitor.Key).Scan(&visitor.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
visitor.Save(db.Conn)
|
if err == sql.ErrNoRows {
|
||||||
|
err = visitor.Save(db.Conn)
|
||||||
|
checkError(err)
|
||||||
|
} else {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
now := time.Now().Format("2006-01-02 15:04:05")
|
|
||||||
pageview := models.Pageview{
|
pageview := models.Pageview{
|
||||||
PageID: page.ID,
|
PageID: page.ID,
|
||||||
VisitorID: visitor.ID,
|
VisitorID: visitor.ID,
|
||||||
ReferrerUrl: q.Get("ru"),
|
ReferrerUrl: q.Get("ru"),
|
||||||
ReferrerKeyword: q.Get("rk"),
|
ReferrerKeyword: q.Get("rk"),
|
||||||
Timestamp: now,
|
Timestamp: now.Format("2006-01-02 15:04:05"),
|
||||||
}
|
}
|
||||||
|
|
||||||
// only store referrer URL if not coming from own site
|
// only store referrer URL if not coming from own site
|
||||||
|
|
|
@ -99,6 +99,7 @@ func Seed(n int) {
|
||||||
|
|
||||||
// print a dot as progress indicator
|
// print a dot as progress indicator
|
||||||
fmt.Print(".")
|
fmt.Print(".")
|
||||||
|
date := randomDateBeforeNow()
|
||||||
|
|
||||||
// create or find visitor
|
// create or find visitor
|
||||||
visitor := models.Visitor{
|
visitor := models.Visitor{
|
||||||
|
@ -110,7 +111,8 @@ func Seed(n int) {
|
||||||
ScreenResolution: randSliceElement(screenResolutions),
|
ScreenResolution: randSliceElement(screenResolutions),
|
||||||
Country: randomdata.Country(randomdata.TwoCharCountry),
|
Country: randomdata.Country(randomdata.TwoCharCountry),
|
||||||
}
|
}
|
||||||
visitor.Key = visitor.GenerateKey()
|
dummyUserAgent := visitor.BrowserName + visitor.BrowserVersion + visitor.DeviceOS
|
||||||
|
visitor.Key = visitor.GenerateKey(date.Format("2006-01-02"), visitor.IpAddress, dummyUserAgent)
|
||||||
|
|
||||||
err := stmtVisitor.QueryRow(visitor.Key).Scan(&visitor.ID)
|
err := stmtVisitor.QueryRow(visitor.Key).Scan(&visitor.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -118,7 +120,6 @@ func Seed(n int) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// generate random timestamp
|
// generate random timestamp
|
||||||
date := randomDateBeforeNow()
|
|
||||||
timestamp := fmt.Sprintf("%s %d:%d:%d", date.Format("2006-01-02"), randInt(10, 24), randInt(10, 60), randInt(10, 60))
|
timestamp := fmt.Sprintf("%s %d:%d:%d", date.Format("2006-01-02"), randInt(10, 24), randInt(10, 60), randInt(10, 60))
|
||||||
|
|
||||||
pv := models.Pageview{
|
pv := models.Pageview{
|
||||||
|
@ -144,7 +145,7 @@ func Seed(n int) {
|
||||||
func randomDate() time.Time {
|
func randomDate() time.Time {
|
||||||
now := time.Now()
|
now := time.Now()
|
||||||
month := months[randInt(0, len(months))]
|
month := months[randInt(0, len(months))]
|
||||||
t := time.Date(now.Year(), month, randInt(1, 31), randInt(0, 23), randInt(0, 59), randInt(0, 59), 0, time.UTC)
|
t := time.Date(randInt(now.Year()-1, now.Year()), month, randInt(1, 31), randInt(0, 23), randInt(0, 59), randInt(0, 59), 0, time.UTC)
|
||||||
return t
|
return t
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -34,7 +34,6 @@ func (v *Visitor) Save(conn *sql.DB) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
defer stmt.Close()
|
defer stmt.Close()
|
||||||
|
|
||||||
result, err := stmt.Exec(
|
result, err := stmt.Exec(
|
||||||
v.Key,
|
v.Key,
|
||||||
v.IpAddress,
|
v.IpAddress,
|
||||||
|
@ -53,8 +52,8 @@ func (v *Visitor) Save(conn *sql.DB) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// GenerateKey generates the "unique" visitor key
|
// GenerateKey generates the "unique" visitor key from date, user agent + screen resolution
|
||||||
func (v *Visitor) GenerateKey() string {
|
func (v *Visitor) GenerateKey(date string, ipAddress string, userAgent string) string {
|
||||||
byteKey := md5.Sum([]byte(v.IpAddress + v.DeviceOS + v.BrowserName + v.ScreenResolution))
|
byteKey := md5.Sum([]byte(date + ipAddress + userAgent))
|
||||||
return hex.EncodeToString(byteKey[:])
|
return hex.EncodeToString(byteKey[:])
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue