2024-07-25 17:38:02 +00:00
|
|
|
package api
|
|
|
|
|
|
|
|
import (
|
2024-07-30 08:59:14 +00:00
|
|
|
"bytes"
|
|
|
|
"fmt"
|
2024-07-25 17:38:02 +00:00
|
|
|
"net/http"
|
|
|
|
"time"
|
|
|
|
|
|
|
|
"github.com/gin-gonic/gin"
|
|
|
|
|
|
|
|
"git.nemunai.re/nemunaire/reveil/config"
|
2024-07-30 08:59:14 +00:00
|
|
|
"git.nemunai.re/nemunaire/reveil/model"
|
2024-07-25 17:38:02 +00:00
|
|
|
"git.nemunai.re/nemunaire/reveil/player"
|
|
|
|
)
|
|
|
|
|
|
|
|
func declareFederationRoutes(cfg *config.Config, router *gin.RouterGroup) {
|
|
|
|
router.POST("/federation/wakeup", func(c *gin.Context) {
|
|
|
|
var s map[string]interface{}
|
|
|
|
c.ShouldBind(s)
|
|
|
|
|
|
|
|
if player.CommonPlayer == nil {
|
|
|
|
var seed int64
|
|
|
|
if tmp, ok := s["seed"].(int64); ok {
|
|
|
|
seed = tmp
|
|
|
|
} else {
|
|
|
|
seed := time.Now().Unix()
|
|
|
|
seed -= seed % 172800
|
|
|
|
}
|
|
|
|
|
|
|
|
err := player.WakeUpFromFederation(cfg, seed, nil)
|
|
|
|
if err != nil {
|
|
|
|
c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"errmsg": err.Error()})
|
|
|
|
return
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"errmsg": "Player already running"})
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
c.JSON(http.StatusOK, true)
|
|
|
|
})
|
|
|
|
router.POST("/federation/wakeok", func(c *gin.Context) {
|
|
|
|
if player.CommonPlayer != nil {
|
|
|
|
err := player.CommonPlayer.Stop()
|
|
|
|
if err != nil {
|
|
|
|
c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"errmsg": err.Error()})
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
c.JSON(http.StatusOK, true)
|
|
|
|
})
|
2024-07-30 08:59:14 +00:00
|
|
|
|
|
|
|
router.GET("/federation", func(c *gin.Context) {
|
|
|
|
settings, err := reveil.ReadSettings(cfg.SettingsFile)
|
|
|
|
if err != nil {
|
|
|
|
c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"errmsg": err.Error()})
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
c.JSON(http.StatusOK, settings.Federation)
|
|
|
|
})
|
|
|
|
|
|
|
|
federationsRoutes := router.Group("/federation/:fid")
|
|
|
|
federationsRoutes.Use(func(c *gin.Context) {
|
|
|
|
settings, err := reveil.ReadSettings(cfg.SettingsFile)
|
|
|
|
if err != nil {
|
|
|
|
c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"errmsg": err.Error()})
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
f, ok := settings.Federation[string(c.Param("fid"))]
|
|
|
|
if !ok {
|
|
|
|
c.AbortWithStatusJSON(http.StatusNotFound, gin.H{"errmsg": "Action not found"})
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
c.Set("federation", &f)
|
|
|
|
c.Next()
|
|
|
|
})
|
|
|
|
federationsRoutes.GET("", func(c *gin.Context) {
|
|
|
|
c.JSON(http.StatusOK, c.MustGet("federation"))
|
|
|
|
})
|
|
|
|
federationsRoutes.POST("sync", func(c *gin.Context) {
|
|
|
|
srv := c.MustGet("federation").(*reveil.FederationServer)
|
|
|
|
|
|
|
|
// Retrieve music list on remote
|
|
|
|
remoteMusics, err := srv.GetMusics()
|
|
|
|
if err != nil {
|
|
|
|
c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"errmsg": fmt.Sprintf("Unable to retrieve remote tracks lists: %s", err.Error())})
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
// Retrieve local music list
|
|
|
|
localMusics, err := reveil.LoadTracks(cfg)
|
|
|
|
if err != nil {
|
|
|
|
c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"errmsg": fmt.Sprintf("Unable to retrieve local tracks: %s", err.Error())})
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
// Compute diff
|
|
|
|
var newMusics []reveil.Track
|
|
|
|
var oldMusics []reveil.Track
|
|
|
|
var musicsToEnable []reveil.Track
|
|
|
|
|
|
|
|
for _, rTrack := range remoteMusics {
|
|
|
|
found := false
|
|
|
|
for _, lTrack := range localMusics {
|
|
|
|
if bytes.Compare(lTrack.Id, rTrack.Id) == 0 || lTrack.Name == rTrack.Name {
|
|
|
|
if lTrack.Enabled != rTrack.Enabled {
|
|
|
|
if lTrack.Enabled {
|
|
|
|
musicsToEnable = append(musicsToEnable, rTrack)
|
|
|
|
} else {
|
|
|
|
oldMusics = append(oldMusics, *lTrack)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
found = true
|
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if !found && rTrack.Enabled {
|
|
|
|
oldMusics = append(oldMusics, rTrack)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, lTrack := range localMusics {
|
|
|
|
found := false
|
|
|
|
for _, rTrack := range remoteMusics {
|
|
|
|
if bytes.Compare(lTrack.Id, rTrack.Id) == 0 || lTrack.Name == rTrack.Name {
|
|
|
|
found = true
|
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if !found && lTrack.Enabled {
|
|
|
|
newMusics = append(newMusics, *lTrack)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Disable unexistant musics on local
|
|
|
|
for _, t := range oldMusics {
|
|
|
|
t.Enabled = false
|
|
|
|
err = srv.UpdateTrack(&t)
|
|
|
|
if err != nil {
|
|
|
|
c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"errmsg": fmt.Sprintf("An error occurs when disabling remote tracks (unexistant on local): %s: %s", t.Id.ToString(), err.Error())})
|
|
|
|
return
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Enable existant musics on remote
|
|
|
|
for _, t := range musicsToEnable {
|
|
|
|
t.Enabled = true
|
|
|
|
err = srv.UpdateTrack(&t)
|
|
|
|
if err != nil {
|
|
|
|
c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"errmsg": err.Error()})
|
|
|
|
return
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Send new musics
|
|
|
|
for _, t := range newMusics {
|
|
|
|
err = srv.SendTrack(&t)
|
|
|
|
if err != nil {
|
|
|
|
c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"errmsg": err.Error()})
|
|
|
|
return
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
c.JSON(http.StatusOK, true)
|
|
|
|
})
|
2024-07-25 17:38:02 +00:00
|
|
|
}
|