mirror of
https://github.com/sablierapp/sablier.git
synced 2025-12-21 13:23:03 +01:00
* refactor: rename providers to Provider * refactor folders * fix build cmd * fix build cmd * fix build cmd * fix cmd start
134 lines
3.8 KiB
Go
134 lines
3.8 KiB
Go
package api
|
|
|
|
import (
|
|
"bufio"
|
|
"bytes"
|
|
"errors"
|
|
"github.com/sablierapp/sablier/pkg/sablier"
|
|
"sort"
|
|
"strconv"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
"github.com/sablierapp/sablier/pkg/theme"
|
|
)
|
|
|
|
type DynamicRequest struct {
|
|
Group string `form:"group"`
|
|
Names []string `form:"names"`
|
|
ShowDetails bool `form:"show_details"`
|
|
DisplayName string `form:"display_name"`
|
|
Theme string `form:"theme"`
|
|
SessionDuration time.Duration `form:"session_duration"`
|
|
RefreshFrequency time.Duration `form:"refresh_frequency"`
|
|
}
|
|
|
|
func StartDynamic(router *gin.RouterGroup, s *ServeStrategy) {
|
|
router.GET("/strategies/dynamic", func(c *gin.Context) {
|
|
request := DynamicRequest{
|
|
Theme: s.StrategyConfig.Dynamic.DefaultTheme,
|
|
ShowDetails: s.StrategyConfig.Dynamic.ShowDetailsByDefault,
|
|
RefreshFrequency: s.StrategyConfig.Dynamic.DefaultRefreshFrequency,
|
|
SessionDuration: s.SessionsConfig.DefaultDuration,
|
|
}
|
|
|
|
if err := c.ShouldBind(&request); err != nil {
|
|
AbortWithProblemDetail(c, ProblemValidation(err))
|
|
return
|
|
}
|
|
|
|
if len(request.Names) == 0 && request.Group == "" {
|
|
AbortWithProblemDetail(c, ProblemValidation(errors.New("'names' or 'group' query parameter must be set")))
|
|
return
|
|
}
|
|
|
|
if len(request.Names) > 0 && request.Group != "" {
|
|
AbortWithProblemDetail(c, ProblemValidation(errors.New("'names' and 'group' query parameters are both set, only one must be set")))
|
|
return
|
|
}
|
|
|
|
var sessionState *sablier.SessionState
|
|
var err error
|
|
if len(request.Names) > 0 {
|
|
sessionState, err = s.Sablier.RequestSession(c, request.Names, request.SessionDuration)
|
|
} else {
|
|
sessionState, err = s.Sablier.RequestSessionGroup(c, request.Group, request.SessionDuration)
|
|
var groupNotFoundError sablier.ErrGroupNotFound
|
|
if errors.As(err, &groupNotFoundError) {
|
|
AbortWithProblemDetail(c, ProblemGroupNotFound(groupNotFoundError))
|
|
return
|
|
}
|
|
}
|
|
|
|
if err != nil {
|
|
AbortWithProblemDetail(c, ProblemError(err))
|
|
return
|
|
}
|
|
|
|
if sessionState == nil {
|
|
AbortWithProblemDetail(c, ProblemError(errors.New("session could not be created, please check logs for more details")))
|
|
return
|
|
}
|
|
|
|
AddSablierHeader(c, sessionState)
|
|
|
|
renderOptions := theme.Options{
|
|
DisplayName: request.DisplayName,
|
|
ShowDetails: request.ShowDetails,
|
|
SessionDuration: request.SessionDuration,
|
|
RefreshFrequency: request.RefreshFrequency,
|
|
InstanceStates: sessionStateToRenderOptionsInstanceState(sessionState),
|
|
}
|
|
|
|
buf := new(bytes.Buffer)
|
|
writer := bufio.NewWriter(buf)
|
|
err = s.Theme.Render(request.Theme, renderOptions, writer)
|
|
var themeNotFound theme.ErrThemeNotFound
|
|
if errors.As(err, &themeNotFound) {
|
|
AbortWithProblemDetail(c, ProblemThemeNotFound(themeNotFound))
|
|
return
|
|
}
|
|
writer.Flush()
|
|
|
|
c.Header("Cache-Control", "no-cache")
|
|
c.Header("Content-Type", "text/html")
|
|
c.Header("Content-Length", strconv.Itoa(buf.Len()))
|
|
c.Writer.Write(buf.Bytes())
|
|
})
|
|
}
|
|
|
|
func sessionStateToRenderOptionsInstanceState(sessionState *sablier.SessionState) (instances []theme.Instance) {
|
|
if sessionState == nil {
|
|
return
|
|
}
|
|
|
|
for _, v := range sessionState.Instances {
|
|
instances = append(instances, instanceStateToRenderOptionsRequestState(v.Instance))
|
|
}
|
|
|
|
sort.SliceStable(instances, func(i, j int) bool {
|
|
return strings.Compare(instances[i].Name, instances[j].Name) == -1
|
|
})
|
|
|
|
return
|
|
}
|
|
|
|
func instanceStateToRenderOptionsRequestState(instanceState sablier.InstanceInfo) theme.Instance {
|
|
|
|
var err error
|
|
if instanceState.Message == "" {
|
|
err = nil
|
|
} else {
|
|
err = errors.New(instanceState.Message)
|
|
}
|
|
|
|
return theme.Instance{
|
|
Name: instanceState.Name,
|
|
Status: string(instanceState.Status),
|
|
CurrentReplicas: instanceState.CurrentReplicas,
|
|
DesiredReplicas: instanceState.DesiredReplicas,
|
|
Error: err,
|
|
}
|
|
}
|