Files
geo/server/internal/tenant/transport/desktop_release_handler.go
T

146 lines
4.1 KiB
Go
Raw Normal View History

2026-05-25 19:23:49 +08:00
package transport
import (
"fmt"
"net/http"
"strings"
"github.com/gin-gonic/gin"
"github.com/geo-platform/tenant-api/internal/bootstrap"
opsapp "github.com/geo-platform/tenant-api/internal/ops/app"
opsrepo "github.com/geo-platform/tenant-api/internal/ops/repository"
"github.com/geo-platform/tenant-api/internal/shared/response"
)
type DesktopReleaseHandler struct {
svc *opsapp.DesktopClientReleaseService
}
func NewDesktopReleaseHandler(a *bootstrap.App) *DesktopReleaseHandler {
return &DesktopReleaseHandler{
svc: opsapp.NewDesktopClientReleaseService(
opsrepo.NewDesktopClientReleaseRepository(a.DB),
a.ObjectStorage,
nil,
),
}
}
func (h *DesktopReleaseHandler) Latest(c *gin.Context) {
client := MustDesktopClient(c.Request.Context())
data, err := h.svc.CheckLatest(c.Request.Context(), opsapp.DesktopClientReleaseCheckInput{
Platform: c.Query("platform"),
Arch: c.Query("arch"),
Channel: defaultDesktopReleaseChannel(c.Query("channel"), client.Channel),
CurrentVersion: c.Query("version"),
})
if err != nil {
response.Error(c, err)
return
}
response.Success(c, data)
}
func (h *DesktopReleaseHandler) DownloadURL(c *gin.Context) {
client := MustDesktopClient(c.Request.Context())
data, err := h.svc.ResolveLatestDownloadURL(c.Request.Context(), opsapp.DesktopClientReleaseCheckInput{
Platform: c.Query("platform"),
Arch: c.Query("arch"),
Channel: defaultDesktopReleaseChannel(c.Query("channel"), client.Channel),
CurrentVersion: c.Query("version"),
})
if err != nil {
response.Error(c, err)
return
}
response.Success(c, data)
}
func (h *DesktopReleaseHandler) LatestPublic(c *gin.Context) {
data, err := h.svc.CheckLatest(c.Request.Context(), opsapp.DesktopClientReleaseCheckInput{
Platform: c.Query("platform"),
Arch: c.Query("arch"),
Channel: c.DefaultQuery("channel", "stable"),
CurrentVersion: c.Query("version"),
})
if err != nil {
response.Error(c, err)
return
}
response.Success(c, data)
}
func (h *DesktopReleaseHandler) DownloadURLPublic(c *gin.Context) {
data, err := h.svc.ResolveLatestDownloadURL(c.Request.Context(), opsapp.DesktopClientReleaseCheckInput{
Platform: c.Query("platform"),
Arch: c.Query("arch"),
Channel: c.DefaultQuery("channel", "stable"),
CurrentVersion: c.Query("version"),
})
if err != nil {
response.Error(c, err)
return
}
response.Success(c, data)
}
func (h *DesktopReleaseHandler) ListDownloadable(c *gin.Context) {
data, err := h.svc.ListDownloadable(c.Request.Context(), c.DefaultQuery("channel", "stable"))
if err != nil {
response.Error(c, err)
return
}
response.Success(c, data)
}
2026-05-25 19:23:49 +08:00
func (h *DesktopReleaseHandler) UpdaterFeedPublic(c *gin.Context) {
feed, err := h.svc.ResolveLatestUpdaterFeed(c.Request.Context(), opsapp.DesktopClientReleaseCheckInput{
Platform: firstNonEmpty(c.Param("platform"), c.Query("platform")),
Arch: firstNonEmpty(c.Param("arch"), c.Query("arch")),
Channel: firstNonEmpty(c.Param("channel"), c.DefaultQuery("channel", "stable")),
CurrentVersion: firstNonEmpty(c.Param("version"), c.Query("version")),
}, c.Param("feed"))
if err != nil {
response.Error(c, err)
return
}
c.Header("Content-Type", "application/x-yaml; charset=utf-8")
c.Header("Cache-Control", "no-store")
c.Header("Content-Disposition", fmt.Sprintf(`inline; filename="%s"`, sanitizeHeaderFileName(feed.FileName)))
c.Data(http.StatusOK, "application/x-yaml; charset=utf-8", feed.Content)
}
func firstNonEmpty(values ...string) string {
for _, value := range values {
if strings.TrimSpace(value) != "" {
return value
}
}
return ""
}
func defaultDesktopReleaseChannel(queryValue string, clientChannel *string) string {
if queryValue != "" {
return queryValue
}
if clientChannel != nil && *clientChannel != "" {
return *clientChannel
}
return "stable"
}
func sanitizeHeaderFileName(value string) string {
value = strings.TrimSpace(value)
if value == "" {
return "latest.yml"
}
return strings.Map(func(r rune) rune {
if r == '"' || r == '\\' || r == '\r' || r == '\n' {
return -1
}
return r
}, value)
}