package handler
import (
"encoding/json"
"time"
"github.com/alexedwards/scs/v2"
"github.com/labstack/echo/v4"
"gitrepo.ru/neonxp/track/pkg/models"
"go.etcd.io/bbolt"
"go.neonxp.ru/objectid"
)
type Location struct {
db *bbolt.DB
sessions *scs.SessionManager
}
func NewLocation(db *bbolt.DB, sessions *scs.SessionManager) *Location {
return &Location{
db: db,
sessions: sessions,
}
}
func (l *Location) AddPoint(c echo.Context) error {
uu := l.sessions.Get(c.Request().Context(), "user")
if uu == nil {
return echo.ErrForbidden
}
user, ok := uu.(*models.User)
if !ok {
return echo.ErrForbidden
}
req := new(PointArgs)
if err := c.Bind(req); err != nil {
return err
}
point := &models.Point{
ID: objectid.FromTime(req.Time),
UserID: user.ID,
Lat: req.Lat,
Lon: req.Lon,
Time: req.Time,
Speed: req.Speed,
Direction: req.Direction,
Accuracy: req.Accuracy,
}
err := l.db.Update(func(tx *bbolt.Tx) error {
points, err := tx.CreateBucketIfNotExists([]byte("points"))
if err != nil {
return err
}
jp, err := json.Marshal(point)
if err != nil {
return err
}
return points.Put(point.ID, jp)
})
if err != nil {
return err
}
return c.NoContent(201)
}
func (l *Location) GetPoints(c echo.Context) error {
// uu := l.sessions.Get(c.Request().Context(), "user")
// if uu == nil {
// return echo.ErrForbidden
// }
// user, ok := uu.(*models.User)
// if !ok {
// return echo.ErrForbidden
// }
pointsResp := []models.Point{}
err := l.db.View(func(tx *bbolt.Tx) error {
points := tx.Bucket([]byte("points"))
point := new(models.Point)
return points.ForEach(func(k, v []byte) error {
if err := json.Unmarshal(v, point); err != nil {
return err
}
// if slices.Equal(point.UserID, user.ID) {
pointsResp = append(pointsResp, *point)
// }
return nil
})
})
if err != nil {
return err
}
return c.JSON(200, pointsResp)
}
func (l *Location) GetLast(c echo.Context) error {
// uu := l.sessions.Get(c.Request().Context(), "user")
// if uu == nil {
// return echo.ErrForbidden
// }
// user, ok := uu.(*models.User)
// if !ok {
// return echo.ErrForbidden
// }
lastPoint := new(models.Point)
err := l.db.View(func(tx *bbolt.Tx) error {
points := tx.Bucket([]byte("points"))
point := new(models.Point)
return points.ForEach(func(k, v []byte) error {
if err := json.Unmarshal(v, point); err != nil {
return err
}
// if slices.Equal(point.UserID, user.ID) && lastPoint.Time.Before(point.Time) {
if lastPoint.Time.Before(point.Time) {
lastPoint = point
}
return nil
})
})
if err != nil {
return err
}
return c.JSON(200, lastPoint)
}
type PointArgs struct {
Lat float64 `query:"lat"`
Lon float64 `query:"lon"`
Time time.Time `query:"time"`
Speed float64 `query:"spd"`
Direction float64 `query:"dir"`
Accuracy float64 `query:"acc"`
}