225 lines
6.0 KiB
Go
225 lines
6.0 KiB
Go
package api
|
|
|
|
import (
|
|
"fmt"
|
|
"net/http"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
|
|
"git.nemunai.re/nemunaire/hathoris/config"
|
|
"git.nemunai.re/nemunaire/hathoris/inputs"
|
|
)
|
|
|
|
type InputState struct {
|
|
Name string `json:"name"`
|
|
Active bool `json:"active"`
|
|
Controlable bool `json:"controlable"`
|
|
HasPlaylist bool `json:"hasplaylist"`
|
|
Streams map[string]string `json:"streams,omitempty"`
|
|
Mixable bool `json:"mixable"`
|
|
Mixer map[string]*inputs.InputMixer `json:"mixer,omitempty"`
|
|
}
|
|
|
|
func declareInputsRoutes(cfg *config.Config, router *gin.RouterGroup) {
|
|
router.GET("/inputs", func(c *gin.Context) {
|
|
ret := map[string]*InputState{}
|
|
|
|
for k, inp := range inputs.SoundInputs {
|
|
var mixer map[string]*inputs.InputMixer
|
|
|
|
_, controlable := inp.(inputs.ControlableInput)
|
|
im, mixable := inp.(inputs.MixableInput)
|
|
if mixable {
|
|
mixer, _ = im.GetMixers()
|
|
}
|
|
|
|
var hasPlaylist bool
|
|
if p, withPlaylist := inp.(inputs.PlaylistInput); withPlaylist {
|
|
hasPlaylist = p.HasPlaylist()
|
|
}
|
|
|
|
ret[k] = &InputState{
|
|
Name: inp.GetName(),
|
|
Active: inp.IsActive(),
|
|
Controlable: controlable,
|
|
HasPlaylist: hasPlaylist,
|
|
Streams: inp.CurrentlyPlaying(),
|
|
Mixable: mixable,
|
|
Mixer: mixer,
|
|
}
|
|
}
|
|
|
|
c.JSON(http.StatusOK, ret)
|
|
})
|
|
|
|
inputsRoutes := router.Group("/inputs/:input")
|
|
inputsRoutes.Use(InputHandler)
|
|
|
|
inputsRoutes.GET("", func(c *gin.Context) {
|
|
inp := c.MustGet("input").(inputs.SoundInput)
|
|
|
|
var mixer map[string]*inputs.InputMixer
|
|
_, controlable := inp.(inputs.ControlableInput)
|
|
im, mixable := inp.(inputs.MixableInput)
|
|
if mixable {
|
|
mixer, _ = im.GetMixers()
|
|
}
|
|
var hasPlaylist bool
|
|
if p, withPlaylist := inp.(inputs.PlaylistInput); withPlaylist {
|
|
hasPlaylist = p.HasPlaylist()
|
|
}
|
|
|
|
c.JSON(http.StatusOK, &InputState{
|
|
Name: inp.GetName(),
|
|
Active: inp.IsActive(),
|
|
Controlable: controlable,
|
|
HasPlaylist: hasPlaylist,
|
|
Streams: inp.CurrentlyPlaying(),
|
|
Mixable: mixable,
|
|
Mixer: mixer,
|
|
})
|
|
})
|
|
inputsRoutes.GET("/settings", func(c *gin.Context) {
|
|
c.JSON(http.StatusOK, c.MustGet("input"))
|
|
})
|
|
inputsRoutes.GET("/streams", func(c *gin.Context) {
|
|
inp := c.MustGet("input").(inputs.SoundInput)
|
|
|
|
if !inp.IsActive() {
|
|
c.AbortWithStatusJSON(http.StatusNotAcceptable, gin.H{"errmsg": "Input not active"})
|
|
return
|
|
}
|
|
|
|
c.JSON(http.StatusOK, inp.CurrentlyPlaying())
|
|
})
|
|
|
|
streamRoutes := inputsRoutes.Group("/streams/:stream")
|
|
streamRoutes.Use(StreamHandler)
|
|
|
|
// ControlableInput
|
|
streamRoutes.POST("/pause", func(c *gin.Context) {
|
|
input, ok := c.MustGet("input").(inputs.ControlableInput)
|
|
if !ok {
|
|
c.AbortWithStatusJSON(http.StatusMethodNotAllowed, gin.H{"errmsg": "The source doesn't support that"})
|
|
return
|
|
}
|
|
|
|
err := input.TogglePause(c.MustGet("streamid").(string))
|
|
if err != nil {
|
|
c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"errmsg": fmt.Sprintf("Unable to pause the input: %s", err.Error())})
|
|
return
|
|
}
|
|
|
|
c.JSON(http.StatusOK, true)
|
|
})
|
|
|
|
// MixableInput
|
|
streamRoutes.POST("/volume", func(c *gin.Context) {
|
|
input, ok := c.MustGet("input").(inputs.MixableInput)
|
|
if !ok {
|
|
c.AbortWithStatusJSON(http.StatusMethodNotAllowed, gin.H{"errmsg": "The source doesn't support that"})
|
|
return
|
|
}
|
|
|
|
var mixer inputs.InputMixer
|
|
err := c.BindJSON(&mixer)
|
|
if err != nil {
|
|
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"errmsg": err.Error()})
|
|
return
|
|
}
|
|
|
|
err = input.SetMixer(c.MustGet("streamid").(string), &mixer)
|
|
if err != nil {
|
|
c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"errmsg": fmt.Sprintf("Unable to pause the input: %s", err.Error())})
|
|
return
|
|
}
|
|
|
|
c.JSON(http.StatusOK, true)
|
|
})
|
|
|
|
// PlaylistInput
|
|
streamRoutes.POST("/has_playlist", func(c *gin.Context) {
|
|
input, ok := c.MustGet("input").(inputs.PlaylistInput)
|
|
if !ok {
|
|
c.AbortWithStatusJSON(http.StatusMethodNotAllowed, gin.H{"errmsg": "The source doesn't support that"})
|
|
return
|
|
}
|
|
|
|
c.JSON(http.StatusOK, input.HasPlaylist())
|
|
})
|
|
streamRoutes.POST("/next_track", func(c *gin.Context) {
|
|
input, ok := c.MustGet("input").(inputs.PlaylistInput)
|
|
if !ok {
|
|
c.AbortWithStatusJSON(http.StatusMethodNotAllowed, gin.H{"errmsg": "The source doesn't support that"})
|
|
return
|
|
}
|
|
|
|
err := input.NextTrack()
|
|
if err != nil {
|
|
c.AbortWithStatusJSON(http.StatusMethodNotAllowed, gin.H{"errmsg": err.Error()})
|
|
return
|
|
}
|
|
|
|
c.JSON(http.StatusOK, true)
|
|
})
|
|
streamRoutes.POST("/next_random_track", func(c *gin.Context) {
|
|
input, ok := c.MustGet("input").(inputs.PlaylistInput)
|
|
if !ok {
|
|
c.AbortWithStatusJSON(http.StatusMethodNotAllowed, gin.H{"errmsg": "The source doesn't support that"})
|
|
return
|
|
}
|
|
|
|
err := input.NextRandomTrack()
|
|
if err != nil {
|
|
c.AbortWithStatusJSON(http.StatusMethodNotAllowed, gin.H{"errmsg": err.Error()})
|
|
return
|
|
}
|
|
|
|
c.JSON(http.StatusOK, true)
|
|
})
|
|
streamRoutes.POST("/prev_track", func(c *gin.Context) {
|
|
input, ok := c.MustGet("input").(inputs.PlaylistInput)
|
|
if !ok {
|
|
c.AbortWithStatusJSON(http.StatusMethodNotAllowed, gin.H{"errmsg": "The source doesn't support that"})
|
|
return
|
|
}
|
|
|
|
err := input.PreviousTrack()
|
|
if err != nil {
|
|
c.AbortWithStatusJSON(http.StatusMethodNotAllowed, gin.H{"errmsg": err.Error()})
|
|
return
|
|
}
|
|
|
|
c.JSON(http.StatusOK, true)
|
|
})
|
|
}
|
|
|
|
func InputHandler(c *gin.Context) {
|
|
inp, ok := inputs.SoundInputs[c.Param("input")]
|
|
if !ok {
|
|
c.AbortWithStatusJSON(http.StatusNotFound, gin.H{"errmsg": fmt.Sprintf("Input not found: %s", c.Param("input"))})
|
|
return
|
|
}
|
|
|
|
c.Set("input", inp)
|
|
|
|
c.Next()
|
|
}
|
|
|
|
func StreamHandler(c *gin.Context) {
|
|
input := c.MustGet("input").(inputs.SoundInput)
|
|
|
|
streams := input.CurrentlyPlaying()
|
|
|
|
stream, ok := streams[c.Param("stream")]
|
|
if !ok {
|
|
c.AbortWithStatusJSON(http.StatusNotFound, gin.H{"errmsg": fmt.Sprintf("Stream not found: %s", c.Param("stream"))})
|
|
return
|
|
}
|
|
|
|
c.Set("streamid", c.Param("stream"))
|
|
c.Set("stream", stream)
|
|
|
|
c.Next()
|
|
}
|