From 6917c4259e758f9cb29abfd9ddfb0cb354ed3059 Mon Sep 17 00:00:00 2001 From: Aleksey Lobanov Date: Sat, 26 Mar 2016 19:16:03 +0300 Subject: [PATCH] Changed interface of StatForTime and added functions for DB. Added AddStatTimeToDb that save one StatForTime in DB. Added Init() for StatForTime that initialize time with current Unix time and keys with empty map. Application now ssae keys to DB. --- src/main.go | 70 +++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 63 insertions(+), 7 deletions(-) diff --git a/src/main.go b/src/main.go index 0f2b0fe..23cf5bd 100644 --- a/src/main.go +++ b/src/main.go @@ -4,10 +4,10 @@ package main import ( "database/sql" "flag" - "fmt" "log" "os/exec" "regexp" + "sort" "strconv" "strings" "time" @@ -19,14 +19,19 @@ const ( SLEEP_TIME = 3 * time.Second KEYBOARD_BUFER_SIZE = 10000 DATABASE_NAME = "./gokeystat.db" - CAPTURE_TIME = 5 * time.Second // time between capturing keyboard to db + CAPTURE_TIME = 5 // time in seconds between capturing keyboard to db ) type StatForTime struct { - time int + time int64 keys map[uint8]int } +func (stat *StatForTime) Init() { + stat.time = time.Now().Unix() + stat.keys = make(map[uint8]int) +} + // Return map from key numbers to key names like "F1", "Tab", "d" func GetKeymap() map[uint8]string { return GetKeymapFromOutput(GetKeymapOutput()) @@ -76,11 +81,17 @@ func GetKeyNumsFromOutput(buf []byte) []uint8 { return keyNums } -func InitDb(db *sql.DB, keyMap map[uint8]string) { - keyNums := make([]int, 0, len(keyMap)) +func GetKeyNumsFromKeyMap(keyMap map[uint8]string) []int { + res := make([]int, 0, len(keyMap)) for keyNum := range keyMap { - keyNums = append(keyNums, int(keyNum)) + res = append(res, int(keyNum)) } + sort.Ints(res) + return res +} + +func InitDb(db *sql.DB, keyMap map[uint8]string) { + keyNums := GetKeyNumsFromKeyMap(keyMap) sqlInit := `CREATE TABLE IF NOT EXISTS keylog ( time INTEGER primary key` @@ -104,6 +115,19 @@ func InitDb(db *sql.DB, keyMap map[uint8]string) { if err != nil { log.Fatalf("%q: %s\n", err, sqlInit) } + rows, err := db.Query("select COUNT(*) from keymap") + if err != nil { + log.Fatal(err) + } + defer rows.Close() + + var rowsCount int + rows.Next() + rows.Scan(&rowsCount) + if rowsCount > 0 { + // already inserted keymap + return + } tx, err := db.Begin() if err != nil { @@ -124,6 +148,25 @@ func InitDb(db *sql.DB, keyMap map[uint8]string) { tx.Commit() } +func AddStatTimeToDb(db *sql.DB, statTime StatForTime, keyMap map[uint8]string) { + keyNums := GetKeyNumsFromKeyMap(keyMap) + sqlStmt := "insert into keylog(time" + for keyNum := range keyNums { + sqlStmt += ",\n" + "KEY" + strconv.Itoa(keyNum) + } + sqlStmt += ") values " + sqlStmt += "(" + strconv.FormatInt(statTime.time, 10) + for keyNum := range keyNums { + keyNumber, _ := statTime.keys[uint8(keyNum)] + sqlStmt += ",\n" + strconv.Itoa(keyNumber) + } + sqlStmt += ")" + _, err := db.Exec(sqlStmt) + if err != nil { + log.Printf("%q: %s\n", err, sqlStmt) + } +} + func main() { keyboardId := flag.Int("id", -1, "Your keyboard id") @@ -144,6 +187,7 @@ func main() { keyMap := GetKeymap() InitDb(db, keyMap) + cmd := exec.Command("xinput", "test", strconv.Itoa(*keyboardId)) stdout, err := cmd.StdoutPipe() @@ -155,13 +199,25 @@ func main() { } buf := make([]byte, KEYBOARD_BUFER_SIZE) + var curStat StatForTime + curStat.Init() for { n, err := stdout.Read(buf) if err != nil { log.Fatal(err) } // processing buf here - fmt.Println(n) + for _, keyNum := range GetKeyNumsFromOutput(buf[:n]) { + oldKeyCount, _ := curStat.keys[keyNum] + curStat.keys[keyNum] = oldKeyCount + 1 + } + + // Every CAPTURE_TIME seconds save to BD + if time.Now().Unix()-curStat.time > CAPTURE_TIME { + AddStatTimeToDb(db, curStat, keyMap) + curStat.Init() + } + time.Sleep(SLEEP_TIME) } case *outputPath != "":