generate unique visitor key from date + ip + user agent

This commit is contained in:
Danny van Kooten 2017-01-13 16:45:17 +01:00
parent f6cab7c297
commit 626de69c95
3 changed files with 26 additions and 14 deletions

View File

@ -1,7 +1,9 @@
package api
import (
"database/sql"
"encoding/base64"
"log"
"net/http"
"strings"
"time"
@ -42,13 +44,18 @@ func CollectHandler(w http.ResponseWriter, r *http.Request) {
defer stmt.Close()
err := stmt.QueryRow(page.Hostname, page.Path).Scan(&page.ID)
if err != nil {
page.Save(db.Conn)
if err == sql.ErrNoRows {
page.Save(db.Conn)
} else {
log.Fatal(err)
}
}
// find or insert visitor.
// TODO: Mask IP Address
now := time.Now()
ip := getRequestIp(r)
visitor := models.Visitor{
IpAddress: getRequestIp(r),
IpAddress: ip,
BrowserLanguage: q.Get("l"),
ScreenResolution: q.Get("sr"),
DeviceOS: ua.OS(),
@ -60,21 +67,26 @@ func CollectHandler(w http.ResponseWriter, r *http.Request) {
visitor.BrowserName = parseMajorMinor(visitor.BrowserName)
// 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")
defer stmt.Close()
err = stmt.QueryRow(visitor.Key).Scan(&visitor.ID)
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{
PageID: page.ID,
VisitorID: visitor.ID,
ReferrerUrl: q.Get("ru"),
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

View File

@ -99,6 +99,7 @@ func Seed(n int) {
// print a dot as progress indicator
fmt.Print(".")
date := randomDateBeforeNow()
// create or find visitor
visitor := models.Visitor{
@ -110,7 +111,8 @@ func Seed(n int) {
ScreenResolution: randSliceElement(screenResolutions),
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)
if err != nil {
@ -118,7 +120,6 @@ func Seed(n int) {
}
// 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))
pv := models.Pageview{
@ -144,7 +145,7 @@ func Seed(n int) {
func randomDate() time.Time {
now := time.Now()
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
}

View File

@ -34,7 +34,6 @@ func (v *Visitor) Save(conn *sql.DB) error {
return err
}
defer stmt.Close()
result, err := stmt.Exec(
v.Key,
v.IpAddress,
@ -53,8 +52,8 @@ func (v *Visitor) Save(conn *sql.DB) error {
return err
}
// GenerateKey generates the "unique" visitor key
func (v *Visitor) GenerateKey() string {
byteKey := md5.Sum([]byte(v.IpAddress + v.DeviceOS + v.BrowserName + v.ScreenResolution))
// GenerateKey generates the "unique" visitor key from date, user agent + screen resolution
func (v *Visitor) GenerateKey(date string, ipAddress string, userAgent string) string {
byteKey := md5.Sum([]byte(date + ipAddress + userAgent))
return hex.EncodeToString(byteKey[:])
}