123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117 |
- package feed
- import (
- "fmt"
- "log/slog"
- "net/http"
- "time"
- )
- type githubReleaseResponseJson struct {
- TagName string `json:"tag_name"`
- PublishedAt string `json:"published_at"`
- HtmlUrl string `json:"html_url"`
- Draft bool `json:"draft"`
- PreRelease bool `json:"prerelease"`
- Reactions struct {
- Downvotes int `json:"-1"`
- } `json:"reactions"`
- }
- func parseGithubTime(t string) time.Time {
- parsedTime, err := time.Parse("2006-01-02T15:04:05Z", t)
- if err != nil {
- return time.Now()
- }
- return parsedTime
- }
- func FetchLatestReleasesFromGithub(repositories []string, token string) (AppReleases, error) {
- appReleases := make(AppReleases, 0, len(repositories))
- if len(repositories) == 0 {
- return appReleases, nil
- }
- requests := make([]*http.Request, len(repositories))
- for i, repository := range repositories {
- request, _ := http.NewRequest("GET", fmt.Sprintf("https://api.github.com/repos/%s/releases?per_page=10", repository), nil)
- if token != "" {
- request.Header.Add("Authorization", fmt.Sprintf("Bearer %s", token))
- }
- requests[i] = request
- }
- task := decodeJsonFromRequestTask[[]githubReleaseResponseJson](defaultClient)
- job := newJob(task, requests).withWorkers(15)
- responses, errs, err := workerPoolDo(job)
- if err != nil {
- return nil, err
- }
- var failed int
- for i := range responses {
- if errs[i] != nil {
- failed++
- slog.Error("Failed to fetch or parse github release", "error", errs[i], "url", requests[i].URL)
- continue
- }
- releases := responses[i]
- if len(releases) < 1 {
- failed++
- slog.Error("No releases found", "repository", repositories[i], "url", requests[i].URL)
- continue
- }
- var liveRelease *githubReleaseResponseJson
- for i := range releases {
- release := &releases[i]
- if !release.Draft && !release.PreRelease {
- liveRelease = release
- break
- }
- }
- if liveRelease == nil {
- slog.Error("No live release found", "repository", repositories[i], "url", requests[i].URL)
- continue
- }
- version := liveRelease.TagName
- if version[0] != 'v' {
- version = "v" + version
- }
- appReleases = append(appReleases, AppRelease{
- Name: repositories[i],
- Version: version,
- NotesUrl: liveRelease.HtmlUrl,
- TimeReleased: parseGithubTime(liveRelease.PublishedAt),
- Downvotes: liveRelease.Reactions.Downvotes,
- })
- }
- if len(appReleases) == 0 {
- return nil, ErrNoContent
- }
- appReleases.SortByNewest()
- if failed > 0 {
- return appReleases, fmt.Errorf("%w: could not get %d releases", ErrPartialContent, failed)
- }
- return appReleases, nil
- }
|