cloud-backend/main.go

214 lines
5.4 KiB
Go
Raw Permalink Normal View History

2022-11-05 07:13:58 -07:00
package main
import (
"log"
2022-11-05 11:18:12 -07:00
"net/http"
2023-11-20 02:54:35 -08:00
"os"
"strings"
2022-11-05 07:13:58 -07:00
2022-11-06 06:12:45 -08:00
_ "main/migrations"
2022-11-05 11:18:12 -07:00
"github.com/labstack/echo/v5"
2022-11-06 06:12:45 -08:00
"github.com/pocketbase/dbx"
2022-11-05 07:13:58 -07:00
"github.com/pocketbase/pocketbase"
2022-11-05 11:40:58 -07:00
"github.com/pocketbase/pocketbase/apis"
2022-11-05 11:18:12 -07:00
"github.com/pocketbase/pocketbase/core"
2022-11-06 06:12:45 -08:00
"github.com/pocketbase/pocketbase/daos"
2022-11-05 11:18:12 -07:00
"github.com/pocketbase/pocketbase/models"
2023-11-20 02:54:35 -08:00
"github.com/pocketbase/pocketbase/plugins/migratecmd"
2022-11-05 07:13:58 -07:00
)
func main() {
2022-11-06 06:12:45 -08:00
tunesCollectionName := "tunes"
iniFilesCollectionName := "iniFiles"
stargazersCollectionName := "stargazers"
2022-11-05 07:13:58 -07:00
app := pocketbase.New()
2023-11-20 02:54:35 -08:00
// loosely check if it was executed using "go run"
isGoRun := strings.HasPrefix(os.Args[0], os.TempDir())
migratecmd.MustRegister(app, app.RootCmd, migratecmd.Config{
// enable auto creation of migration files when making collection changes in the Admin UI
// (the isGoRun check is to enable it only during development)
Automigrate: isGoRun,
})
2022-11-05 11:18:12 -07:00
app.OnBeforeServe().Add(func(e *core.ServeEvent) error {
e.Router.AddRoute(echo.Route{
Method: http.MethodGet,
Path: "/api/custom/tunes/byTuneId/:tuneId",
Handler: func(c echo.Context) error {
2022-11-06 06:12:45 -08:00
record, _err := app.Dao().FindFirstRecordByData(tunesCollectionName, "tuneId", c.PathParam("tuneId"))
2022-11-05 11:18:12 -07:00
if _err != nil {
2022-11-05 11:40:58 -07:00
return apis.NewNotFoundError("Tune not found", nil)
2022-11-05 11:18:12 -07:00
}
if err := apis.EnrichRecord(c, app.Dao(), record, "author"); err != nil {
return err
}
2022-11-05 11:18:12 -07:00
return c.JSON(http.StatusOK, record)
},
2022-11-07 13:09:34 -08:00
Middlewares: []echo.MiddlewareFunc{
apis.ActivityLogger(app),
},
2022-11-05 11:18:12 -07:00
})
e.Router.AddRoute(echo.Route{
Method: http.MethodGet,
Path: "/api/custom/iniFiles/bySignature/:signature",
Handler: func(c echo.Context) error {
2022-11-06 06:12:45 -08:00
record, _err := app.Dao().FindFirstRecordByData(iniFilesCollectionName, "signature", c.PathParam("signature"))
2022-11-05 11:18:12 -07:00
if _err != nil {
return c.JSON(http.StatusNotFound, _err)
}
return c.JSON(http.StatusOK, record)
},
2022-11-07 13:09:34 -08:00
Middlewares: []echo.MiddlewareFunc{
apis.ActivityLogger(app),
},
2022-11-05 11:18:12 -07:00
})
2022-11-06 06:12:45 -08:00
e.Router.AddRoute(echo.Route{
Method: http.MethodPost,
Path: "/api/custom/stargazers/toggleStar",
Handler: func(c echo.Context) (err error) {
auth := c.Get(apis.ContextAuthRecordKey).(*models.Record)
isStarred := false
type Stargazer struct {
User string
Tune string `json:"tune" form:"tune" query:"tune"`
}
stargazer := new(Stargazer)
if err = c.Bind(stargazer); err != nil {
return c.String(http.StatusBadRequest, "Bad request")
}
stargazer.User = auth.Id
_err := app.Dao().RunInTransaction(func(txDao *daos.Dao) error {
collection, err := app.Dao().FindCollectionByNameOrId(stargazersCollectionName)
if err != nil {
return err
}
stargazerRecord := models.NewRecord(collection)
stargazerRecord.Set("user", stargazer.User)
stargazerRecord.Set("tune", stargazer.Tune)
tune, _err := app.Dao().FindFirstRecordByData(tunesCollectionName, "id", stargazer.Tune)
if _err != nil {
return apis.NewNotFoundError("Tune not found", nil)
}
_err = txDao.SaveRecord(stargazerRecord)
// UNIQUE constraint failed most likely, try to unstar
if _err != nil {
currentStargazerRecords, _err := app.Dao().FindRecordsByExpr(
stargazersCollectionName,
dbx.HashExp{"user": stargazer.User},
dbx.HashExp{"tune": stargazer.Tune},
)
if _err != nil || len(currentStargazerRecords) == 0 {
return _err
}
_err = txDao.DeleteRecord(currentStargazerRecords[0])
if _err != nil {
return _err
}
isStarred = false
tune.Set("stars", tune.Get("stars").(float64)-1)
} else {
isStarred = true
tune.Set("stars", tune.Get("stars").(float64)+1)
}
_err = txDao.SaveRecord(tune)
if _err != nil {
return _err
}
return nil
})
if _err != nil {
return apis.NewNotFoundError("Tune not found or already starred", nil)
}
// fetch again and return current state
tune, _err := app.Dao().FindFirstRecordByData(tunesCollectionName, "id", stargazer.Tune)
if _err != nil {
return apis.NewNotFoundError("Tune not found", nil)
}
2022-11-06 06:12:45 -08:00
return c.JSON(http.StatusOK, map[string]any{
"stars": tune.Get("stars").(float64),
"isStarred": isStarred,
})
},
Middlewares: []echo.MiddlewareFunc{
2022-11-07 13:09:34 -08:00
apis.ActivityLogger(app),
2022-11-06 06:12:45 -08:00
apis.LoadAuthContext(app.App),
apis.RequireAdminOrRecordAuth("users"),
},
})
e.Router.AddRoute(echo.Route{
Method: http.MethodGet,
Path: "/api/custom/stargazers/starredByMe/:tune",
Handler: func(c echo.Context) (err error) {
auth := c.Get(apis.ContextAuthRecordKey).(*models.Record)
isStarred := true
type Stargazer struct {
User string
Tune string
}
stargazer := new(Stargazer)
stargazer.User = auth.Id
stargazer.Tune = c.PathParam("tune")
stargazerRecords, _err := app.Dao().FindRecordsByExpr(
stargazersCollectionName,
dbx.HashExp{"user": stargazer.User},
dbx.HashExp{"tune": stargazer.Tune},
)
if _err != nil || len(stargazerRecords) == 0 {
isStarred = false
}
return c.JSON(http.StatusOK, map[string]any{
"isStarred": isStarred,
})
},
Middlewares: []echo.MiddlewareFunc{
2022-11-07 13:09:34 -08:00
apis.ActivityLogger(app),
2022-11-06 06:12:45 -08:00
apis.LoadAuthContext(app.App),
apis.RequireAdminOrRecordAuth("users"),
},
})
2022-11-05 11:18:12 -07:00
return nil
})
2022-11-05 07:13:58 -07:00
if err := app.Start(); err != nil {
log.Fatal(err)
}
}