1
0
mirror of https://github.com/muety/wakapi.git synced 2023-08-10 21:12:56 +03:00

refactor: significant changes related to routing and general code cleanup

This commit is contained in:
Ferdinand Mütsch
2021-02-03 21:28:02 +01:00
parent 4838300086
commit a2368ff76a
16 changed files with 171 additions and 152 deletions

33
routes/api/health.go Normal file
View File

@ -0,0 +1,33 @@
package api
import (
"fmt"
"github.com/gorilla/mux"
"gorm.io/gorm"
"net/http"
)
type HealthApiHandler struct {
db *gorm.DB
}
func NewHealthApiHandler(db *gorm.DB) *HealthApiHandler {
return &HealthApiHandler{db: db}
}
func (h *HealthApiHandler) RegisterRoutes(router *mux.Router) {
r := router.PathPrefix("/health").Subrouter()
r.Methods(http.MethodGet).HandlerFunc(h.Get)
}
func (h *HealthApiHandler) Get(w http.ResponseWriter, r *http.Request) {
var dbStatus int
if sqlDb, err := h.db.DB(); err == nil {
if err := sqlDb.Ping(); err == nil {
dbStatus = 1
}
}
w.Header().Set("Content-Type", "text/plain")
w.Write([]byte(fmt.Sprintf("app=1\ndb=%d", dbStatus)))
}

96
routes/api/heartbeat.go Normal file
View File

@ -0,0 +1,96 @@
package api
import (
"encoding/json"
"github.com/emvi/logbuch"
"github.com/gorilla/mux"
conf "github.com/muety/wakapi/config"
customMiddleware "github.com/muety/wakapi/middlewares/custom"
"github.com/muety/wakapi/services"
"github.com/muety/wakapi/utils"
"net/http"
"github.com/muety/wakapi/models"
)
type HeartbeatApiHandler struct {
config *conf.Config
heartbeatSrvc services.IHeartbeatService
languageMappingSrvc services.ILanguageMappingService
}
func NewHeartbeatApiHandler(heartbeatService services.IHeartbeatService, languageMappingService services.ILanguageMappingService) *HeartbeatApiHandler {
return &HeartbeatApiHandler{
config: conf.Get(),
heartbeatSrvc: heartbeatService,
languageMappingSrvc: languageMappingService,
}
}
type heartbeatResponseVm struct {
Responses [][]interface{} `json:"responses"`
}
func (h *HeartbeatApiHandler) RegisterRoutes(router *mux.Router) {
r := router.PathPrefix("/heartbeat").Subrouter()
r.Use(
customMiddleware.NewWakatimeRelayMiddleware().Handler,
)
router.Methods(http.MethodPost).HandlerFunc(h.Post)
}
func (h *HeartbeatApiHandler) Post(w http.ResponseWriter, r *http.Request) {
var heartbeats []*models.Heartbeat
user := r.Context().Value(models.UserKey).(*models.User)
opSys, editor, _ := utils.ParseUserAgent(r.Header.Get("User-Agent"))
machineName := r.Header.Get("X-Machine-Name")
dec := json.NewDecoder(r.Body)
if err := dec.Decode(&heartbeats); err != nil {
w.WriteHeader(http.StatusBadRequest)
w.Write([]byte(err.Error()))
return
}
for _, hb := range heartbeats {
hb.OperatingSystem = opSys
hb.Editor = editor
hb.Machine = machineName
hb.User = user
hb.UserID = user.ID
if !hb.Valid() {
w.WriteHeader(http.StatusBadRequest)
w.Write([]byte("Invalid heartbeat object."))
return
}
hb.Hashed()
}
if err := h.heartbeatSrvc.InsertBatch(heartbeats); err != nil {
w.WriteHeader(http.StatusInternalServerError)
logbuch.Error(err.Error())
return
}
utils.RespondJSON(w, http.StatusCreated, constructSuccessResponse(len(heartbeats)))
}
// construct weird response format (see https://github.com/wakatime/wakatime/blob/2e636d389bf5da4e998e05d5285a96ce2c181e3d/wakatime/api.py#L288)
// to make the cli consider all heartbeats to having been successfully saved
// response looks like: { "responses": [ [ { "data": {...} }, 201 ], ... ] }
func constructSuccessResponse(n int) *heartbeatResponseVm {
responses := make([][]interface{}, n)
for i := 0; i < n; i++ {
r := make([]interface{}, 2)
r[0] = nil
r[1] = http.StatusCreated
responses[i] = r
}
return &heartbeatResponseVm{
Responses: responses,
}
}

37
routes/api/summary.go Normal file
View File

@ -0,0 +1,37 @@
package api
import (
"github.com/gorilla/mux"
conf "github.com/muety/wakapi/config"
su "github.com/muety/wakapi/routes/utils"
"github.com/muety/wakapi/services"
"github.com/muety/wakapi/utils"
"net/http"
)
type SummaryApiHandler struct {
config *conf.Config
summarySrvc services.ISummaryService
}
func NewSummaryApiHandler(summaryService services.ISummaryService) *SummaryApiHandler {
return &SummaryApiHandler{
summarySrvc: summaryService,
config: conf.Get(),
}
}
func (h *SummaryApiHandler) RegisterRoutes(router *mux.Router) {
router.Methods(http.MethodGet).HandlerFunc(h.Get)
}
func (h *SummaryApiHandler) Get(w http.ResponseWriter, r *http.Request) {
summary, err, status := su.LoadUserSummary(h.summarySrvc, r)
if err != nil {
w.WriteHeader(status)
w.Write([]byte(err.Error()))
return
}
utils.RespondJSON(w, http.StatusOK, summary)
}