diff --git a/server_apps.go b/server_apps.go index 807b8cf679c60167c2fe46132bd6b431fe12c93c..8d9692fbd1b6446bde113b83e7e314844cece804 100644 --- a/server_apps.go +++ b/server_apps.go @@ -7,6 +7,7 @@ import ( "io" "log" "net/http" + "net/url" "path" "regexp" "strings" @@ -33,6 +34,11 @@ type appInfo struct { description string version int commit string + stars int +} + +type GLProject struct { + StarCount int `json:"star_count"` } var ( @@ -40,6 +46,32 @@ var ( reAppRepo = regexp.MustCompile(`^([a-zA-Z\-_\.0-9]+)/([a-zA-Z\-_0-9]+)$`) ) +func (s *server) getStars(ctx context.Context, repo string) (int, error) { + path := fmt.Sprintf("https://%s/api/v4/projects/%s", flagGitlabHost, url.PathEscape(repo)) + + req, err := http.NewRequestWithContext(ctx, "GET", path, nil) + if err != nil { + return 0, fmt.Errorf("when building request: %w", err) + } + res, err := http.DefaultTransport.RoundTrip(req) + if err != nil { + return 0, fmt.Errorf("when performing request: %w", err) + } + defer res.Body.Close() + + if res.StatusCode != 200 { + return 0, fmt.Errorf("invalid response code %d", res.StatusCode) + } + + var project GLProject + j := json.NewDecoder(res.Body) + err = j.Decode(&project) + if err != nil { + return 0, fmt.Errorf("when performing request: %w", err) + } + return project.StarCount, nil +} + func (s *server) parseAppToml(ctx context.Context, pathInRepo string, obj *object.Commit) (*appInfo, error) { p := path.Join(pathInRepo, "flow3r.toml") f, err := obj.File(p) @@ -92,6 +124,7 @@ func (s *server) parseAppToml(ctx context.Context, pathInRepo string, obj *objec if len(data.Metadata.Description) > 140 { return nil, fmt.Errorf("metadata description too long") } + return &appInfo{ name: data.App.Name, author: data.Metadata.Author, @@ -167,6 +200,11 @@ func (s *server) getAppInfo(ctx context.Context, pathInRepo, repo string) (*appI if highsetVerNil { return nil, fmt.Errorf("no version") } + stars, err := s.getStars(ctx, repo) + if err != nil { + return nil, fmt.Errorf("getting stars failed: %w", err) + } + firstTime[highestVer].stars = stars return firstTime[highestVer], nil } @@ -281,6 +319,7 @@ func (s *server) handleApps(w http.ResponseWriter, r *http.Request) { Author string `json:"author"` Description string `json:"description"` Version int `json:"version"` + Stars int `json:"stars"` } type res struct { @@ -308,6 +347,7 @@ func (s *server) handleApps(w http.ResponseWriter, r *http.Request) { Author: a.appInfo.author, Description: a.appInfo.description, Version: a.appInfo.version, + Stars: a.appInfo.stars, }) } w.Header().Add("Access-Control-Allow-Origin", "*")