You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
177 lines
4.5 KiB
Go
177 lines
4.5 KiB
Go
package main
|
|
|
|
import (
|
|
"code.gitea.io/sdk/gitea"
|
|
"fmt"
|
|
"github.com/kpango/glg"
|
|
"github.com/labstack/echo/v4"
|
|
"github.com/labstack/echo/v4/middleware"
|
|
"github.com/rs/zerolog"
|
|
"github.com/rs/zerolog/log"
|
|
"github.com/rs/zerolog/pkgerrors"
|
|
"os"
|
|
"strconv"
|
|
"sync"
|
|
"time"
|
|
)
|
|
|
|
type Channel int
|
|
|
|
const (
|
|
Stable Channel = iota
|
|
Prerelease
|
|
)
|
|
|
|
type Attachement struct {
|
|
User string
|
|
Repo string
|
|
Tag string
|
|
Filename string
|
|
Channel Channel
|
|
}
|
|
|
|
type RegionCounter struct {
|
|
RegionCount map[string]int
|
|
sync.RWMutex
|
|
}
|
|
|
|
var giteaURL string
|
|
|
|
func getAttachementURL(attachement Attachement) (string, error) {
|
|
client, err := gitea.NewClient(giteaURL)
|
|
if err != nil {
|
|
return "", fmt.Errorf("Failed to create gitea client: %v")
|
|
}
|
|
var release *gitea.Release
|
|
if attachement.Tag != "" {
|
|
release, _, err = client.GetReleaseByTag(attachement.User, attachement.Repo, attachement.Tag)
|
|
if err != nil {
|
|
return "", fmt.Errorf("Failed to get release by tag: %v")
|
|
}
|
|
} else {
|
|
isPrerelease := false
|
|
if attachement.Channel == Prerelease {
|
|
isPrerelease = true
|
|
}
|
|
releases, _, err := client.ListReleases(attachement.User, attachement.Repo, gitea.ListReleasesOptions{IsPreRelease: &isPrerelease})
|
|
if err != nil {
|
|
return "", fmt.Errorf("Failed to get releases: %v")
|
|
}
|
|
if len(releases) == 0 {
|
|
return "", fmt.Errorf("no release found")
|
|
}
|
|
release = releases[0]
|
|
}
|
|
for _, a := range release.Attachments {
|
|
if a.Name == attachement.Filename {
|
|
return a.DownloadURL, nil
|
|
}
|
|
}
|
|
return "", fmt.Errorf("no matching attachement found")
|
|
}
|
|
|
|
func (r *RegionCounter) countRegion(region string) {
|
|
log.Debug().Msgf("Region %s", region)
|
|
r.Lock()
|
|
defer r.Unlock()
|
|
if region == "" {
|
|
return
|
|
}
|
|
r.RegionCount[region]++
|
|
}
|
|
|
|
func main() {
|
|
zerolog.TimeFieldFormat = time.RFC1123Z
|
|
consoleWriter := zerolog.ConsoleWriter{Out: os.Stdout, TimeFormat: time.RFC1123Z}
|
|
log.Logger = log.Output(consoleWriter).With().Timestamp().Logger()
|
|
|
|
giteaURL = os.Getenv("GITEA_URL")
|
|
logLevel, err := strconv.Atoi(os.Getenv("LOG_LEVEL"))
|
|
if err != nil {
|
|
logLevel = 1
|
|
}
|
|
log.Logger.Level(zerolog.Level(logLevel))
|
|
|
|
if log.Logger.GetLevel() == zerolog.DebugLevel {
|
|
log.Logger = log.Output(consoleWriter).With().Timestamp().Caller().Logger()
|
|
zerolog.ErrorStackMarshaler = pkgerrors.MarshalStack
|
|
}
|
|
|
|
regionCounter := &RegionCounter{
|
|
RegionCount: make(map[string]int),
|
|
}
|
|
|
|
app := echo.New()
|
|
app.Use(middleware.Recover())
|
|
|
|
app.GET("/:user/:repo/releases/download/latest/:name", func(c echo.Context) error {
|
|
log.Debug().Msgf("%+v", map[string]string{"user": c.Param("user"), "repo": c.Param("repo"), "name": c.Param("name")})
|
|
attachement := Attachement{
|
|
User: c.Param("user"),
|
|
Repo: c.Param("repo"),
|
|
Filename: c.Param("name"),
|
|
Channel: Stable,
|
|
}
|
|
url, err := getAttachementURL(attachement)
|
|
if err != nil {
|
|
glg.Debug(err)
|
|
c.String(404, err.Error())
|
|
return nil
|
|
}
|
|
go regionCounter.countRegion(c.Request().Header.Get("Fly-Region"))
|
|
c.Redirect(307, url)
|
|
return nil
|
|
})
|
|
|
|
app.GET("/:user/:repo/releases/download/latest\\::channel/:name", func(c echo.Context) error {
|
|
log.Debug().Msgf("%+v", map[string]string{"user": c.Param("user"), "repo": c.Param("repo"), "name": c.Param("name"), "channel": c.Param("channel")})
|
|
channel := Stable
|
|
if c.Param("channel") == "prerelease" {
|
|
channel = Prerelease
|
|
}
|
|
attachement := Attachement{
|
|
User: c.Param("user"),
|
|
Repo: c.Param("repo"),
|
|
Filename: c.Param("name"),
|
|
Channel: channel,
|
|
}
|
|
url, err := getAttachementURL(attachement)
|
|
if err != nil {
|
|
glg.Debug(err)
|
|
c.String(404, err.Error())
|
|
return nil
|
|
}
|
|
go regionCounter.countRegion(c.Request().Header.Get("Fly-Region"))
|
|
c.Redirect(307, url)
|
|
return nil
|
|
})
|
|
|
|
app.GET("/:user/:repo/releases/download/tag\\::tag/:name", func(c echo.Context) error {
|
|
log.Debug().Msgf("%+v", map[string]string{"user": c.Param("user"), "repo": c.Param("repo"), "name": c.Param("name"), "tag": c.Param("tag")})
|
|
attachement := Attachement{
|
|
User: c.Param("user"),
|
|
Repo: c.Param("repo"),
|
|
Filename: c.Param("name"),
|
|
Tag: c.Param("tag"),
|
|
}
|
|
url, err := getAttachementURL(attachement)
|
|
if err != nil {
|
|
glg.Debug(err)
|
|
c.String(404, err.Error())
|
|
return nil
|
|
}
|
|
|
|
go regionCounter.countRegion(c.Request().Header.Get("Fly-Region"))
|
|
c.Redirect(307, url)
|
|
return nil
|
|
})
|
|
|
|
app.GET("/regions", func(c echo.Context) error {
|
|
regionCounter.RLock()
|
|
defer regionCounter.RUnlock()
|
|
return c.JSON(200, regionCounter.RegionCount)
|
|
})
|
|
|
|
log.Error().Err(app.Start(":8080"))
|
|
}
|