mirror of
https://github.com/muety/wakapi.git
synced 2023-08-10 21:12:56 +03:00
Initial.
This commit is contained in:
commit
0bd71b7708
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
launch.json
|
||||||
|
.vscode
|
38
handlers.go
Normal file
38
handlers.go
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
_ "github.com/go-sql-driver/mysql"
|
||||||
|
"github.com/n1try/wakapi/models"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Authenticate(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func HeartbeatHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
|
if r.Method != "POST" {
|
||||||
|
w.WriteHeader(415)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
dec := json.NewDecoder(r.Body)
|
||||||
|
var heartbeats []models.Heartbeat
|
||||||
|
err := dec.Decode(&heartbeats)
|
||||||
|
if err != nil {
|
||||||
|
w.WriteHeader(400)
|
||||||
|
w.Write([]byte(err.Error()))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
err = HeartbeatSrvc.InsertMulti(heartbeats)
|
||||||
|
if err != nil {
|
||||||
|
w.WriteHeader(500)
|
||||||
|
os.Stderr.WriteString(err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
w.WriteHeader(201)
|
||||||
|
}
|
56
main.go
Normal file
56
main.go
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"database/sql"
|
||||||
|
"flag"
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"strconv"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
_ "github.com/go-sql-driver/mysql"
|
||||||
|
"github.com/n1try/wakapi/models"
|
||||||
|
"github.com/n1try/wakapi/services"
|
||||||
|
)
|
||||||
|
|
||||||
|
var HeartbeatSrvc services.HeartbeatService
|
||||||
|
|
||||||
|
func getConfig() models.Config {
|
||||||
|
portPtr := flag.Int("port", 8080, "Port for the webserver to listen on")
|
||||||
|
flag.Parse()
|
||||||
|
return models.Config{
|
||||||
|
Port: *portPtr,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
// Read Config
|
||||||
|
config := getConfig()
|
||||||
|
|
||||||
|
// Connect Database
|
||||||
|
db, _ := sql.Open("mysql", "fakatime_user:eB2zyLt2heqWj5Y9@tcp(muetsch.io:3306)/fakatime")
|
||||||
|
defer db.Close()
|
||||||
|
err := db.Ping()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("Could not connect to database.")
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Init Services
|
||||||
|
HeartbeatSrvc = services.HeartbeatService{db}
|
||||||
|
|
||||||
|
// Define Routes
|
||||||
|
http.HandleFunc("/api/heartbeat", HeartbeatHandler)
|
||||||
|
|
||||||
|
// Listen HTTP
|
||||||
|
portString := ":" + strconv.Itoa(config.Port)
|
||||||
|
s := &http.Server{
|
||||||
|
Addr: portString,
|
||||||
|
ReadTimeout: 10 * time.Second,
|
||||||
|
WriteTimeout: 10 * time.Second,
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Printf("Listening on %+s\n", portString)
|
||||||
|
s.ListenAndServe()
|
||||||
|
}
|
5
models/config.go
Normal file
5
models/config.go
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
package models
|
||||||
|
|
||||||
|
type Config struct {
|
||||||
|
Port int
|
||||||
|
}
|
37
models/heartbeat.go
Normal file
37
models/heartbeat.go
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
package models
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
type HeartbeatReqTime time.Time
|
||||||
|
|
||||||
|
type Heartbeat struct {
|
||||||
|
User string `json:"user"`
|
||||||
|
Entity string `json:"entity"`
|
||||||
|
Type string `json:"type"`
|
||||||
|
Category string `json:"category"`
|
||||||
|
Project string `json:"project"`
|
||||||
|
Branch string `json:"branch"`
|
||||||
|
Language string `json:"language"`
|
||||||
|
IsWrite bool `json:"is_write"`
|
||||||
|
Time HeartbeatReqTime `json:"time"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (j *HeartbeatReqTime) UnmarshalJSON(b []byte) error {
|
||||||
|
s := strings.Split(strings.Trim(string(b), "\""), ".")[0]
|
||||||
|
i, err := strconv.ParseInt(s, 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
t := time.Unix(i, 0)
|
||||||
|
*j = HeartbeatReqTime(t)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (j HeartbeatReqTime) String() string {
|
||||||
|
t := time.Time(j)
|
||||||
|
return t.Format("2006-01-02 15:04:05")
|
||||||
|
}
|
40
services/heartbeat.go
Normal file
40
services/heartbeat.go
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
package services
|
||||||
|
|
||||||
|
import (
|
||||||
|
"database/sql"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/n1try/wakapi/models"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
TableName = "heartbeat"
|
||||||
|
)
|
||||||
|
|
||||||
|
type HeartbeatService struct {
|
||||||
|
Db *sql.DB
|
||||||
|
}
|
||||||
|
|
||||||
|
func (srv *HeartbeatService) InsertMulti(heartbeats []models.Heartbeat) error {
|
||||||
|
qTpl := "INSERT INTO %+s (user, time, entity, type, category, is_write, project, branch, language) VALUES %+s;"
|
||||||
|
qFill := ""
|
||||||
|
vals := []interface{}{}
|
||||||
|
|
||||||
|
for _, h := range heartbeats {
|
||||||
|
qFill = "(?, ?, ?, ?, ?, ?, ?, ?, ?),"
|
||||||
|
vals = append(vals, h.User, h.Time.String(), h.Entity, h.Type, h.Category, h.IsWrite, h.Project, h.Branch, h.Language)
|
||||||
|
}
|
||||||
|
|
||||||
|
q := fmt.Sprintf(qTpl, TableName, qFill[0:len(qFill)-1])
|
||||||
|
stmt, _ := srv.Db.Prepare(q)
|
||||||
|
result, err := stmt.Exec(vals...)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
n, err := result.RowsAffected()
|
||||||
|
if err != nil || n != int64(len(heartbeats)) {
|
||||||
|
return errors.New(fmt.Sprintf("Failed to insert %+v rows.", len(heartbeats)))
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user