alhp-web/api.go

192 lines
5.0 KiB
Go

package main
import (
"github.com/c2h5oh/datasize"
"github.com/go-chi/render"
log "github.com/sirupsen/logrus"
"net/http"
"somegit.dev/ALHP/ALHP.GO/ent"
"somegit.dev/ALHP/ALHP.GO/ent/dbpackage"
"somegit.dev/ALHP/ALHP.GO/ent/predicate"
"strconv"
"strings"
"time"
)
type StatsResponse struct {
Failed int `json:"failed"`
Skipped int `json:"skipped"`
Latest int `json:"latest"`
Queued int `json:"queued"`
LTO *struct {
Enabled int `json:"enabled"`
Disabled int `json:"disabled"`
Unknown int `json:"unknown"`
} `json:"lto"`
}
type ThinPackage struct {
Pkgbase string `json:"pkgbase"`
Repo string `json:"repo"`
SplitPackages []string `json:"split_packages"`
Status dbpackage.Status `json:"status"`
SkipReason *string `json:"skip_reason,omitempty"`
LTO dbpackage.Lto `json:"lto"`
DebugSymbols dbpackage.DebugSymbols `json:"debug_symbols"`
ArchVersion string `json:"arch_version"`
RepoVersion string `json:"repo_version"`
BuildDate *string `json:"build_date,omitempty"`
PeakMem *string `json:"peak_mem,omitempty"`
}
type PackageResponse struct {
Packages []*ThinPackage `json:"packages"`
Total int `json:"total"`
Offset int `json:"offset"`
Limit int `json:"limit"`
}
func GetStats(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
var v []struct {
Status dbpackage.Status `json:"status"`
Count int `json:"count"`
}
db.DBPackage.Query().GroupBy(dbpackage.FieldStatus).Aggregate(ent.Count()).ScanX(ctx, &v)
resp := new(StatsResponse)
resp.LTO = new(struct {
Enabled int `json:"enabled"`
Disabled int `json:"disabled"`
Unknown int `json:"unknown"`
})
for _, c := range v {
switch c.Status {
case dbpackage.StatusFailed:
resp.Failed = c.Count
case dbpackage.StatusSkipped:
resp.Skipped = c.Count
case dbpackage.StatusLatest:
resp.Latest = c.Count
case dbpackage.StatusQueued:
resp.Queued = c.Count
}
}
var v2 []struct {
Status dbpackage.Lto `json:"lto"`
Count int `json:"count"`
}
db.DBPackage.Query().Where(dbpackage.StatusNEQ(dbpackage.StatusSkipped)).
GroupBy(dbpackage.FieldLto).Aggregate(ent.Count()).ScanX(ctx, &v2)
for _, c := range v2 {
switch c.Status {
case dbpackage.LtoUnknown:
resp.LTO.Unknown = c.Count
case dbpackage.LtoDisabled, dbpackage.LtoAutoDisabled:
resp.LTO.Disabled += c.Count
case dbpackage.LtoEnabled:
resp.LTO.Enabled = c.Count
}
}
render.Status(r, http.StatusOK)
render.JSON(w, r, resp)
}
func GetPackages(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
pkgbase := r.URL.Query().Get("pkgbase")
status := r.URL.Query().Get("status")
repo := r.URL.Query().Get("repo")
offset, err := strconv.Atoi(r.URL.Query().Get("offset"))
if err != nil {
log.Debugf("error parsing page: %v", err)
w.WriteHeader(http.StatusBadRequest)
return
}
limit, err := strconv.Atoi(r.URL.Query().Get("limit"))
if err != nil {
log.Debugf("error parsing page: %v", err)
w.WriteHeader(http.StatusBadRequest)
return
}
var constraints []predicate.DBPackage
if pkgbase != "" {
constraints = append(constraints, dbpackage.PkgbaseContains(pkgbase))
}
if status != "" {
constraints = append(constraints, dbpackage.StatusEQ(dbpackage.Status(status)))
}
if repo != "" {
before, after, found := strings.Cut(repo, "-")
if found {
constraints = append(constraints, dbpackage.And(dbpackage.MarchEQ(after), dbpackage.RepositoryEQ(dbpackage.Repository(before))))
}
}
nPkgs, err := db.DBPackage.Query().Where(constraints...).Count(ctx)
if err != nil {
log.Warningf("error getting package count from db: %v", err)
render.Status(r, http.StatusInternalServerError)
return
}
if nPkgs == 0 {
w.WriteHeader(http.StatusNotFound)
return
}
rPackages, err := db.DBPackage.Query().Where(constraints...).Limit(limit).Offset(offset).All(ctx)
if err != nil {
log.Warningf("error getting packages from db: %v", err)
render.Status(r, http.StatusInternalServerError)
return
}
resp := new(PackageResponse)
for _, mPkg := range rPackages {
nPkg := &ThinPackage{
Pkgbase: mPkg.Pkgbase,
Repo: mPkg.Repository.String() + "-" + mPkg.March,
SplitPackages: mPkg.Packages,
Status: mPkg.Status,
LTO: mPkg.Lto,
DebugSymbols: mPkg.DebugSymbols,
ArchVersion: mPkg.Version,
RepoVersion: mPkg.RepoVersion,
}
if mPkg.SkipReason != "" {
nPkg.SkipReason = &mPkg.SkipReason
}
if !mPkg.BuildTimeStart.IsZero() {
formattedBuildDate := mPkg.BuildTimeStart.UTC().Format(time.RFC1123)
nPkg.BuildDate = &formattedBuildDate
}
if mPkg.MaxRss != nil {
hrSize := (datasize.ByteSize(*mPkg.MaxRss) * datasize.KB).HumanReadable()
nPkg.PeakMem = &hrSize
}
resp.Packages = append(resp.Packages, nPkg)
}
resp.Offset = offset
resp.Limit = limit
resp.Total = nPkgs
render.Status(r, http.StatusOK)
render.JSON(w, r, resp)
}