Something went wrong. Try again.
This repository has no description
Something went wrong. Try again.
4.6 kB · 165 lines
Go
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166package api
import ( "context" "encoding/json" "fmt" "io" "net/http" "regexp" "strings"
"github.com/julienschmidt/httprouter" apierrors "stream.place/streamplace/pkg/errors" "stream.place/streamplace/pkg/log")
var ( re = regexp.MustCompile(`^streamplace(-desktop)?-(v[0-9]+\.[0-9]+\.[0-9]+)(-[0-9a-f]+)?-([0-9a-z]+)-([0-9a-z]+)\.(?:([0-9a-f]+)\.)?(.+)$`) inputRe = regexp.MustCompile(`^streamplace(-desktop)?-([0-9a-z]+)-([0-9a-z]+)\.(.+)$`))
func queryGitlabReal(url string) (io.ReadCloser, error) { req, err := http.Get(url) if err != nil { return nil, err } return req.Body, nil}
var queryGitlab = queryGitlabReal
func (a *StreamplaceAPI) HandleAppDownload(ctx context.Context) httprouter.Handle { return func(w http.ResponseWriter, r *http.Request, params httprouter.Params) { log.Log(ctx, "got here") pathname := r.URL.Path parts := strings.Split(pathname, "/") if len(parts) < 4 { apierrors.WriteHTTPBadRequest(w, "usage: /dl/latest/streamplace-linux-arm64.tar.gz", nil) return }
_, branch, file := parts[1], parts[2], parts[3] if branch == "" || file == "" { apierrors.WriteHTTPBadRequest(w, "usage: /dl/latest/streamplace-linux-arm64.tar.gz", nil) return }
inputPieces := inputRe.FindStringSubmatch(file) if inputPieces == nil { apierrors.WriteHTTPBadRequest(w, fmt.Sprintf("could not parse filename %s", file), nil) return }
inputDesktop, inputPlatform, inputArch, inputExt := inputPieces[1], inputPieces[2], inputPieces[3], inputPieces[4] files, err := a.getGitlabPackage(branch) if err != nil { apierrors.WriteHTTPBadRequest(w, fmt.Sprintf("could not get gitlab package %s", file), err) return }
var foundFile *GitlabFile for _, f := range files { if f.Desktop == inputDesktop && f.Platform == inputPlatform && f.Architecture == inputArch && f.Extension == inputExt { foundFile = &f break } }
if foundFile == nil { apierrors.WriteHTTPNotFound(w, fmt.Sprintf("could not find a file for desktop=%s platform=%s arch=%s ext=%s", inputDesktop, inputPlatform, inputArch, inputExt), nil) return }
http.Redirect(w, r, foundFile.URL(), http.StatusTemporaryRedirect) }}
type GitlabFile struct { GitLabURL string Branch string Filename string Desktop string Version string Hash string Platform string Architecture string SHA1 string Extension string Size int}
func (f GitlabFile) FullVer() string { return f.Version + f.Hash}
func (f GitlabFile) URL() string { return fmt.Sprintf("%s/packages/generic/%s/%s/%s", f.GitLabURL, f.Branch, f.FullVer(), f.Filename)}
func (a *StreamplaceAPI) getGitlabPackage(branch string) ([]GitlabFile, error) { packageURL := fmt.Sprintf("%s/packages?order_by=created_at&sort=desc&package_name=%s", a.CLI.GitLabURL, branch)
packageBody, err := queryGitlab(packageURL) if err != nil { return nil, fmt.Errorf("failed to fetch packages: %w", err) } defer packageBody.Close()
var packages []map[string]any if err := json.NewDecoder(packageBody).Decode(&packages); err != nil { return nil, fmt.Errorf("failed to decode package response: %w", err) } // bs, _ := json.Marshal(packages) // fmt.Println(string(bs))
if len(packages) == 0 { return nil, fmt.Errorf("package for branch %s not found", branch) }
pkg := packages[0] fileURL := fmt.Sprintf("%s/packages/%v/package_files", a.CLI.GitLabURL, pkg["id"])
fileBody, err := queryGitlab(fileURL) if err != nil { return nil, fmt.Errorf("failed to fetch files: %w", err) } defer fileBody.Close()
var files []map[string]any if err := json.NewDecoder(fileBody).Decode(&files); err != nil { return nil, fmt.Errorf("failed to decode file response: %w", err) }
out := []GitlabFile{} for _, f := range files { filename, ok := f["file_name"].(string) if !ok { continue } pieces := re.FindStringSubmatch(filename) if pieces == nil { // log.Log(ctx, "could not parse filename %s", "filename", filename) continue } size, ok := f["size"].(float64) if !ok { continue } desktop, ver, hash, platform, arch, sha1, ext := pieces[1], pieces[2], pieces[3], pieces[4], pieces[5], pieces[6], pieces[7] out = append(out, GitlabFile{ GitLabURL: a.CLI.GitLabURL, Branch: branch, Filename: filename, Desktop: desktop, Version: ver, Hash: hash, Platform: platform, Architecture: arch, SHA1: sha1, Extension: ext, Size: int(size), }) } return out, nil}