Skip to content
Snippets Groups Projects
Commit 5b309499 authored by moon2's avatar moon2 :speech_balloon:
Browse files

Merge branch 'patches' into 'main'

include repo:tags.json in public:apps.json

See merge request !8
parents bbed915e 30d1c101
No related branches found
No related tags found
1 merge request!8include repo:tags.json in public:apps.json
...@@ -18,6 +18,7 @@ import ( ...@@ -18,6 +18,7 @@ import (
"strings" "strings"
"strconv" "strconv"
"time" "time"
"math"
"github.com/go-git/go-git/v5" "github.com/go-git/go-git/v5"
"github.com/go-git/go-git/v5/config" "github.com/go-git/go-git/v5/config"
...@@ -27,6 +28,18 @@ import ( ...@@ -27,6 +28,18 @@ import (
"github.com/pelletier/go-toml/v2" "github.com/pelletier/go-toml/v2"
) )
type appPatch struct{
repository string
zip []byte
targz []byte
}
type appStatus struct{
tested_version int
broken bool
patch *appPatch
}
type appRegistry struct { type appRegistry struct {
shame []*appShame shame []*appShame
apps []*appDescriptor apps []*appDescriptor
...@@ -58,6 +71,8 @@ type appInfo struct { ...@@ -58,6 +71,8 @@ type appInfo struct {
targz []byte targz []byte
firstErr error firstErr error
tags []string
status *appStatus
} }
type GLProject struct { type GLProject struct {
...@@ -95,7 +110,7 @@ func (s *server) getStars(ctx context.Context, repo string) (int, error) { ...@@ -95,7 +110,7 @@ func (s *server) getStars(ctx context.Context, repo string) (int, error) {
return project.StarCount, nil return project.StarCount, nil
} }
func (s *server) zipApp(ctx context.Context, name, pathInRepo, repo string, obj *object.Commit) ([]byte, error) { func (s *server) zipApp(ctx context.Context, name, pathInRepo, repo string, patch_source *string, obj *object.Commit) ([]byte, error) {
fi, err := obj.Files() fi, err := obj.Files()
if err != nil { if err != nil {
return nil, fmt.Errorf("listing files: %w", err) return nil, fmt.Errorf("listing files: %w", err)
...@@ -134,6 +149,9 @@ func (s *server) zipApp(ctx context.Context, name, pathInRepo, repo string, obj ...@@ -134,6 +149,9 @@ func (s *server) zipApp(ctx context.Context, name, pathInRepo, repo string, obj
if err != nil { if err != nil {
return nil, fmt.Errorf("Blob.Reader: %w", err) return nil, fmt.Errorf("Blob.Reader: %w", err)
} }
if f.Name == "flow3r.toml" && patch_source != nil{
fo.Write([]byte(fmt.Sprintf("patch_source = \"%s\"\n\n", *patch_source)))
}
_, err = io.Copy(fo, rdr) _, err = io.Copy(fo, rdr)
rdr.Close() rdr.Close()
if err != nil { if err != nil {
...@@ -146,7 +164,7 @@ func (s *server) zipApp(ctx context.Context, name, pathInRepo, repo string, obj ...@@ -146,7 +164,7 @@ func (s *server) zipApp(ctx context.Context, name, pathInRepo, repo string, obj
return buf.Bytes(), nil return buf.Bytes(), nil
} }
func (s *server) targzApp(ctx context.Context, name, pathInRepo, repo string, obj *object.Commit) ([]byte, error) { func (s *server) targzApp(ctx context.Context, name, pathInRepo, repo string, patch_source * string, obj *object.Commit) ([]byte, error) {
fi, err := obj.Files() fi, err := obj.Files()
if err != nil { if err != nil {
return nil, fmt.Errorf("listing files: %w", err) return nil, fmt.Errorf("listing files: %w", err)
...@@ -210,10 +228,14 @@ func (s *server) targzApp(ctx context.Context, name, pathInRepo, repo string, ob ...@@ -210,10 +228,14 @@ func (s *server) targzApp(ctx context.Context, name, pathInRepo, repo string, ob
} }
} }
} }
patch_bytes := []byte("")
if f.Name == "flow3r.toml" && patch_source != nil{
patch_bytes = []byte(fmt.Sprintf("patch_source = \"%s\"\n\n", *patch_source))
}
err = t.WriteHeader(&tar.Header{ err = t.WriteHeader(&tar.Header{
Name: outPath, Name: outPath,
Typeflag: tar.TypeReg, Typeflag: tar.TypeReg,
Size: f.Size, Size: f.Size + int64(len(patch_bytes)),
Mode: 0644, Mode: 0644,
}) })
if err != nil { if err != nil {
...@@ -226,6 +248,12 @@ func (s *server) targzApp(ctx context.Context, name, pathInRepo, repo string, ob ...@@ -226,6 +248,12 @@ func (s *server) targzApp(ctx context.Context, name, pathInRepo, repo string, ob
if err != nil { if err != nil {
return nil, fmt.Errorf("Blob.Reader: %w", err) return nil, fmt.Errorf("Blob.Reader: %w", err)
} }
if len(patch_bytes) != 0{
t.Write(patch_bytes)
}
if err != nil {
return nil, fmt.Errorf("patch_source: %w", err)
}
_, err = io.Copy(t, rdr) _, err = io.Copy(t, rdr)
rdr.Close() rdr.Close()
if err != nil { if err != nil {
...@@ -286,9 +314,10 @@ func (s *server) parseAppToml(ctx context.Context, pathInRepo string, obj *objec ...@@ -286,9 +314,10 @@ func (s *server) parseAppToml(ctx context.Context, pathInRepo string, obj *objec
"Music": true, "Music": true,
"Media": true, "Media": true,
"Games": true, "Games": true,
"Demos": true,
} }
if !sections[data.App.Category] { if !sections[data.App.Category] {
return nil, fmt.Errorf("app category invalid (must be one of 'Badge', 'Apps', 'Music', 'Media', 'Games')") return nil, fmt.Errorf("app category invalid (must be one of 'Badge', 'Apps', 'Music', 'Media', 'Games', 'Demos')")
} }
if data.Entry.Class == "" { if data.Entry.Class == "" {
return nil, fmt.Errorf("no entry class") return nil, fmt.Errorf("no entry class")
...@@ -311,7 +340,7 @@ func (s *server) parseAppToml(ctx context.Context, pathInRepo string, obj *objec ...@@ -311,7 +340,7 @@ func (s *server) parseAppToml(ctx context.Context, pathInRepo string, obj *objec
}, nil }, nil
} }
func (s *server) getAppInfo(ctx context.Context, pathInRepo, repo string) (*appInfo, error) { func (s *server) getAppInfo(ctx context.Context, pathInRepo, repo string, slug *string) (*appInfo, error) {
url := "https://git.flow3r.garden/" + repo url := "https://git.flow3r.garden/" + repo
g, err := git.Clone(memory.NewStorage(), nil, &git.CloneOptions{ g, err := git.Clone(memory.NewStorage(), nil, &git.CloneOptions{
URL: url, URL: url,
...@@ -389,14 +418,21 @@ func (s *server) getAppInfo(ctx context.Context, pathInRepo, repo string) (*appI ...@@ -389,14 +418,21 @@ func (s *server) getAppInfo(ctx context.Context, pathInRepo, repo string) (*appI
if err != nil { if err != nil {
return nil, fmt.Errorf("getting gitlab stars failed: %w", err) return nil, fmt.Errorf("getting gitlab stars failed: %w", err)
} }
var patch_source *string = nil
slug_str := repo
if slug != nil{
slug_str = *slug
psrc := fmt.Sprintf("https://git.flow3r.garden/%s", repo)
patch_source = &psrc
}
app := firstTime[highestVer] app := firstTime[highestVer]
app.stars = stars app.stars = stars
zbytes, err := s.zipApp(ctx, app.name, pathInRepo, repo, app.commitObj) zbytes, err := s.zipApp(ctx, app.name, pathInRepo, slug_str, patch_source, app.commitObj)
if err != nil { if err != nil {
return nil, fmt.Errorf("zipping failed: %w", err) return nil, fmt.Errorf("zipping failed: %w", err)
} }
app.zip = zbytes app.zip = zbytes
tbytes, err := s.targzApp(ctx, app.name, pathInRepo, repo, app.commitObj) tbytes, err := s.targzApp(ctx, app.name, pathInRepo, slug_str, patch_source, app.commitObj)
if err != nil { if err != nil {
return nil, fmt.Errorf("targzing failed: %w", err) return nil, fmt.Errorf("targzing failed: %w", err)
} }
...@@ -413,6 +449,7 @@ func (s *server) getAppInfo(ctx context.Context, pathInRepo, repo string) (*appI ...@@ -413,6 +449,7 @@ func (s *server) getAppInfo(ctx context.Context, pathInRepo, repo string) (*appI
app.firstErr = firstErr app.firstErr = firstErr
app.tags = make([]string, 0)
return app, nil return app, nil
} }
...@@ -446,6 +483,26 @@ func (s *server) getAppRegistry(ctx context.Context) (*appRegistry, error) { ...@@ -446,6 +483,26 @@ func (s *server) getAppRegistry(ctx context.Context) (*appRegistry, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
flags, err := obj.File("tags.json")
if err != nil {
return nil, err
}
flagreader, err := flags.Reader()
if err != nil {
return nil, err
}
flagbytes, err := io.ReadAll(flagreader)
if err != nil {
return nil, err
}
var flagmap map[string]interface{}
err = json.Unmarshal([]byte(flagbytes), &flagmap)
if err != nil {
return nil, err
}
iter, err := obj.Files() iter, err := obj.Files()
if err != nil { if err != nil {
return nil, err return nil, err
...@@ -508,7 +565,7 @@ func (s *server) getAppRegistry(ctx context.Context) (*appRegistry, error) { ...@@ -508,7 +565,7 @@ func (s *server) getAppRegistry(ctx context.Context) (*appRegistry, error) {
} }
for _, app := range registry.apps { for _, app := range registry.apps {
info, err := s.getAppInfo(ctx, app.pathInRepo, app.repository) info, err := s.getAppInfo(ctx, app.pathInRepo, app.repository, nil)
if err != nil { if err != nil {
log.Printf("App %q: %v", app.repository, err) log.Printf("App %q: %v", app.repository, err)
registry.shame = append(registry.shame, &appShame{ registry.shame = append(registry.shame, &appShame{
...@@ -522,6 +579,41 @@ func (s *server) getAppRegistry(ctx context.Context) (*appRegistry, error) { ...@@ -522,6 +579,41 @@ func (s *server) getAppRegistry(ctx context.Context) (*appRegistry, error) {
repository: app.repository, repository: app.repository,
errorMsg: fmt.Sprintf("%v", info.firstErr), errorMsg: fmt.Sprintf("%v", info.firstErr),
}) })
} else if app_flags, ok := flagmap[app.repository].(map[string]interface{}); ok {
info.status = new(appStatus)
printed := false
if tags, ok := app_flags["tags"].([]interface{}); ok {
for _, tag := range tags{
if tagtxt, ok := tag.(string); ok {
info.tags = append(info.tags, tagtxt)
}
}
}
if status, ok := app_flags["status"].(map[string]interface{}); ok {
if tested, ok := status["tested_version"].(float64); ok {
info.status.tested_version = int(math.Round(tested))
}
if broken, ok := status["broken"].(bool); ok {
info.status.broken = broken
}
if patch, ok := status["patch"].(string); ok {
printed = true
patch_info, err := s.getAppInfo(ctx, "", patch, &app.repository)
if err != nil {
log.Printf("App %q: couldn't get patch at %q: %v", app.repository, patch, err)
} else {
log.Printf("App: %q: okay, patch found", app.repository)
info.status.patch = &appPatch{
repository: patch,
zip: patch_info.zip,
targz: patch_info.targz,
}
}
}
}
if !printed{
log.Printf("App: %q: okay", app.repository)
}
} else { } else {
log.Printf("App: %q: okay", app.repository) log.Printf("App: %q: okay", app.repository)
} }
...@@ -533,6 +625,18 @@ func (s *server) getAppRegistry(ctx context.Context) (*appRegistry, error) { ...@@ -533,6 +625,18 @@ func (s *server) getAppRegistry(ctx context.Context) (*appRegistry, error) {
return &registry, nil return &registry, nil
} }
type jsonAppPatch struct{
RepoURL string `json:"repoUrl"`
DownloadURL string `json:"downloadUrl"`
TarDownloadURL string `json:"tarDownloadUrl"`
}
type jsonAppStatus struct{
TestedVersion int `json:"tested_version"`
Broken bool `json:"broken"`
Patch jsonAppPatch `json:"patch"`
}
type jsonApp struct { type jsonApp struct {
RepoURL string `json:"repoUrl"` RepoURL string `json:"repoUrl"`
Commit string `json:"commit"` Commit string `json:"commit"`
...@@ -543,13 +647,15 @@ type jsonApp struct { ...@@ -543,13 +647,15 @@ type jsonApp struct {
Author string `json:"author"` Author string `json:"author"`
Description string `json:"description"` Description string `json:"description"`
Version int `json:"version"` Version int `json:"version"`
Timestamp time.Time `json:"timestamp"`
Stars int `json:"stars"` Stars int `json:"stars"`
Tags []string `json:"tags"`
Timestamp time.Time `json:"timestamp"`
Flow3rSeed string `json:"flow3rSeed"` Flow3rSeed string `json:"flow3rSeed"`
Status *jsonAppStatus `json:"status"`
} }
func makeJsonApp(a *appDescriptor) jsonApp { func makeJsonApp(a *appDescriptor) jsonApp {
return jsonApp{ ret := jsonApp{
RepoURL: "https://git.flow3r.garden/" + a.repository, RepoURL: "https://git.flow3r.garden/" + a.repository,
Commit: a.appInfo.commit, Commit: a.appInfo.commit,
DownloadURL: fmt.Sprintf("%sapps/zip/%s.zip", flagBaseURL, a.repository), DownloadURL: fmt.Sprintf("%sapps/zip/%s.zip", flagBaseURL, a.repository),
...@@ -562,8 +668,24 @@ func makeJsonApp(a *appDescriptor) jsonApp { ...@@ -562,8 +668,24 @@ func makeJsonApp(a *appDescriptor) jsonApp {
Timestamp: a.appInfo.commitObj.Committer.When.UTC(), Timestamp: a.appInfo.commitObj.Committer.When.UTC(),
Stars: a.appInfo.stars, Stars: a.appInfo.stars,
Flow3rSeed: a.appInfo.flow3rSeed, Flow3rSeed: a.appInfo.flow3rSeed,
Tags: a.appInfo.tags,
}
if a.appInfo.status != nil{
ret.Status = &jsonAppStatus{
Broken: a.appInfo.status.broken,
TestedVersion: a.appInfo.status.tested_version,
}
if a.appInfo.status.patch != nil{
pa := a.appInfo.status.patch.repository
ret.Status.Patch = jsonAppPatch{
RepoURL: "https://git.flow3r.garden/" + pa,
DownloadURL: fmt.Sprintf("%sapps/zip/%s.zip", flagBaseURL, pa),
TarDownloadURL: fmt.Sprintf("%sapps/tar/%s.tar.gz", flagBaseURL, pa),
}
} }
} }
return ret
}
func (s *server) handleApps(w http.ResponseWriter, r *http.Request) { func (s *server) handleApps(w http.ResponseWriter, r *http.Request) {
ctx := r.Context() ctx := r.Context()
...@@ -682,12 +804,22 @@ func (s *server) handleAppZip(w http.ResponseWriter, r *http.Request) { ...@@ -682,12 +804,22 @@ func (s *server) handleAppZip(w http.ResponseWriter, r *http.Request) {
return return
} }
repository := fmt.Sprintf("%s/%s", orga, repo)
for _, app := range apps { for _, app := range apps {
if app.repository == fmt.Sprintf("%s/%s", orga, repo) { if app.repository == repository {
w.Header().Add("Content-Type", "application/zip") w.Header().Add("Content-Type", "application/zip")
w.Write(app.appInfo.zip) w.Write(app.appInfo.zip)
return return
} }
if app.appInfo == nil || app.appInfo.status == nil || app.appInfo.status.patch == nil {
continue
}
if app.appInfo.status.patch.repository == repository {
w.Header().Add("Content-Type", "application/zip")
w.Write(app.appInfo.status.patch.zip)
return
}
} }
http.NotFound(w, r) http.NotFound(w, r)
...@@ -703,6 +835,7 @@ func (s *server) handleAppTargz(w http.ResponseWriter, r *http.Request) { ...@@ -703,6 +835,7 @@ func (s *server) handleAppTargz(w http.ResponseWriter, r *http.Request) {
} }
orga := matches[1] orga := matches[1]
repo := matches[2] repo := matches[2]
repository := fmt.Sprintf("%s/%s", orga, repo)
apps, err := s.getApps(ctx) apps, err := s.getApps(ctx)
if err != nil { if err != nil {
...@@ -710,12 +843,21 @@ func (s *server) handleAppTargz(w http.ResponseWriter, r *http.Request) { ...@@ -710,12 +843,21 @@ func (s *server) handleAppTargz(w http.ResponseWriter, r *http.Request) {
} }
for _, app := range apps { for _, app := range apps {
if app.repository == fmt.Sprintf("%s/%s", orga, repo) { if app.repository == repository {
w.Header().Add("Content-Type", "application/x-gzip") w.Header().Add("Content-Type", "application/x-gzip")
w.Header().Add("Content-Length", strconv.Itoa(len(app.appInfo.targz))) w.Header().Add("Content-Length", strconv.Itoa(len(app.appInfo.targz)))
w.Write(app.appInfo.targz) w.Write(app.appInfo.targz)
return return
} }
if app.appInfo == nil || app.appInfo.status == nil || app.appInfo.status.patch == nil {
continue
}
if app.appInfo.status.patch.repository == repository {
w.Header().Add("Content-Type", "application/x-gzip")
w.Header().Add("Content-Length", strconv.Itoa(len(app.appInfo.status.patch.targz)))
w.Write(app.appInfo.status.patch.targz)
return
}
} }
http.NotFound(w, r) http.NotFound(w, r)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment