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