summaryrefslogblamecommitdiff
path: root/pkg/handler/location.go
blob: 9f4a2c141bc0dd365e2e986dfdf5296d31f52cb7 (plain) (tree)












































































































































                                                                                                        
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"`
}