mirror of https://github.com/glanceapp/glance.git
Update releases widget
parent
3076593021
commit
0ce706e02e
@ -1,73 +0,0 @@
|
|||||||
package feed
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"log/slog"
|
|
||||||
)
|
|
||||||
|
|
||||||
type ReleaseSource string
|
|
||||||
|
|
||||||
const (
|
|
||||||
ReleaseSourceCodeberg ReleaseSource = "codeberg"
|
|
||||||
ReleaseSourceGithub ReleaseSource = "github"
|
|
||||||
ReleaseSourceGitlab ReleaseSource = "gitlab"
|
|
||||||
ReleaseSourceDockerHub ReleaseSource = "dockerhub"
|
|
||||||
)
|
|
||||||
|
|
||||||
type ReleaseRequest struct {
|
|
||||||
Source ReleaseSource
|
|
||||||
Repository string
|
|
||||||
Token *string
|
|
||||||
IncludeGithubPreReleases bool
|
|
||||||
}
|
|
||||||
|
|
||||||
func FetchLatestReleases(requests []*ReleaseRequest) (AppReleases, error) {
|
|
||||||
job := newJob(fetchLatestReleaseTask, requests).withWorkers(20)
|
|
||||||
results, errs, err := workerPoolDo(job)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var failed int
|
|
||||||
|
|
||||||
releases := make(AppReleases, 0, len(requests))
|
|
||||||
|
|
||||||
for i := range results {
|
|
||||||
if errs[i] != nil {
|
|
||||||
failed++
|
|
||||||
slog.Error("Failed to fetch release", "source", requests[i].Source, "repository", requests[i].Repository, "error", errs[i])
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
releases = append(releases, *results[i])
|
|
||||||
}
|
|
||||||
|
|
||||||
if failed == len(requests) {
|
|
||||||
return nil, ErrNoContent
|
|
||||||
}
|
|
||||||
|
|
||||||
releases.SortByNewest()
|
|
||||||
|
|
||||||
if failed > 0 {
|
|
||||||
return releases, fmt.Errorf("%w: could not get %d releases", ErrPartialContent, failed)
|
|
||||||
}
|
|
||||||
|
|
||||||
return releases, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func fetchLatestReleaseTask(request *ReleaseRequest) (*AppRelease, error) {
|
|
||||||
switch request.Source {
|
|
||||||
case ReleaseSourceCodeberg:
|
|
||||||
return fetchLatestCodebergRelease(request)
|
|
||||||
case ReleaseSourceGithub:
|
|
||||||
return fetchLatestGithubRelease(request)
|
|
||||||
case ReleaseSourceGitlab:
|
|
||||||
return fetchLatestGitLabRelease(request)
|
|
||||||
case ReleaseSourceDockerHub:
|
|
||||||
return fetchLatestDockerHubRelease(request)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil, errors.New("unsupported source")
|
|
||||||
}
|
|
||||||
@ -1,105 +0,0 @@
|
|||||||
package widget
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"errors"
|
|
||||||
"html/template"
|
|
||||||
"strings"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/glanceapp/glance/internal/assets"
|
|
||||||
"github.com/glanceapp/glance/internal/feed"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Releases struct {
|
|
||||||
widgetBase `yaml:",inline"`
|
|
||||||
Releases feed.AppReleases `yaml:"-"`
|
|
||||||
releaseRequests []*feed.ReleaseRequest `yaml:"-"`
|
|
||||||
Repositories []string `yaml:"repositories"`
|
|
||||||
Token OptionalEnvString `yaml:"token"`
|
|
||||||
GitLabToken OptionalEnvString `yaml:"gitlab-token"`
|
|
||||||
Limit int `yaml:"limit"`
|
|
||||||
CollapseAfter int `yaml:"collapse-after"`
|
|
||||||
ShowSourceIcon bool `yaml:"show-source-icon"`
|
|
||||||
IncludeGithubPreReleases bool `yaml:"include-github-prereleases"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (widget *Releases) Initialize() error {
|
|
||||||
widget.withTitle("Releases").withCacheDuration(2 * time.Hour)
|
|
||||||
|
|
||||||
if widget.Limit <= 0 {
|
|
||||||
widget.Limit = 10
|
|
||||||
}
|
|
||||||
|
|
||||||
if widget.CollapseAfter == 0 || widget.CollapseAfter < -1 {
|
|
||||||
widget.CollapseAfter = 5
|
|
||||||
}
|
|
||||||
|
|
||||||
var tokenAsString = widget.Token.String()
|
|
||||||
var gitLabTokenAsString = widget.GitLabToken.String()
|
|
||||||
|
|
||||||
for _, repository := range widget.Repositories {
|
|
||||||
parts := strings.SplitN(repository, ":", 2)
|
|
||||||
var request *feed.ReleaseRequest
|
|
||||||
if len(parts) == 1 {
|
|
||||||
request = &feed.ReleaseRequest{
|
|
||||||
Source: feed.ReleaseSourceGithub,
|
|
||||||
Repository: repository,
|
|
||||||
IncludeGithubPreReleases: widget.IncludeGithubPreReleases,
|
|
||||||
}
|
|
||||||
|
|
||||||
if widget.Token != "" {
|
|
||||||
request.Token = &tokenAsString
|
|
||||||
}
|
|
||||||
} else if len(parts) == 2 {
|
|
||||||
if parts[0] == string(feed.ReleaseSourceGitlab) {
|
|
||||||
request = &feed.ReleaseRequest{
|
|
||||||
Source: feed.ReleaseSourceGitlab,
|
|
||||||
Repository: parts[1],
|
|
||||||
}
|
|
||||||
|
|
||||||
if widget.GitLabToken != "" {
|
|
||||||
request.Token = &gitLabTokenAsString
|
|
||||||
}
|
|
||||||
} else if parts[0] == string(feed.ReleaseSourceDockerHub) {
|
|
||||||
request = &feed.ReleaseRequest{
|
|
||||||
Source: feed.ReleaseSourceDockerHub,
|
|
||||||
Repository: parts[1],
|
|
||||||
}
|
|
||||||
} else if parts[0] == string(feed.ReleaseSourceCodeberg) {
|
|
||||||
request = &feed.ReleaseRequest{
|
|
||||||
Source: feed.ReleaseSourceCodeberg,
|
|
||||||
Repository: parts[1],
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return errors.New("invalid repository source " + parts[0])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
widget.releaseRequests = append(widget.releaseRequests, request)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (widget *Releases) Update(ctx context.Context) {
|
|
||||||
releases, err := feed.FetchLatestReleases(widget.releaseRequests)
|
|
||||||
|
|
||||||
if !widget.canContinueUpdateAfterHandlingErr(err) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(releases) > widget.Limit {
|
|
||||||
releases = releases[:widget.Limit]
|
|
||||||
}
|
|
||||||
|
|
||||||
for i := range releases {
|
|
||||||
releases[i].SourceIconURL = widget.Providers.AssetResolver("icons/" + string(releases[i].Source) + ".svg")
|
|
||||||
}
|
|
||||||
|
|
||||||
widget.Releases = releases
|
|
||||||
}
|
|
||||||
|
|
||||||
func (widget *Releases) Render() template.HTML {
|
|
||||||
return widget.render(widget, assets.ReleasesTemplate)
|
|
||||||
}
|
|
||||||
Loading…
Reference in New Issue