From 4f168197b881bff7472bf6d23ed28ba818002eec Mon Sep 17 00:00:00 2001 From: Zsolt Tasnadi Date: Tue, 20 Jan 2026 08:39:02 +0100 Subject: [PATCH] fetcher refact --- lib/fetcher.gitea.go | 44 +++++++++++++++++++++++------------------ lib/fetcher.go | 16 +++++++++++++++ lib/fetcher.redmine.go | 42 +++++++++++++++++++++------------------ lib/fetcher.wikijs.go | 45 +++++++++++++++++++++++------------------- lib/runner.go | 45 ++++++++++++++++++++++-------------------- 5 files changed, 113 insertions(+), 79 deletions(-) diff --git a/lib/fetcher.gitea.go b/lib/fetcher.gitea.go index 710ca09..383048a 100644 --- a/lib/fetcher.gitea.go +++ b/lib/fetcher.gitea.go @@ -16,22 +16,24 @@ type GiteaResponse []struct { } type GiteaFetcher struct { - BaseURL string - Token string - Repos []string - Cache *Cache + BaseFetcher + Repos []string } -func (f GiteaFetcher) Fetch() []Entry { - var messages []Entry +func (f *GiteaFetcher) Name() string { + return "Gitea" +} + +func (f *GiteaFetcher) Fetch() []Entry { + var entries []Entry for _, repo := range f.Repos { + repo = strings.TrimSpace(repo) if repo == "" { continue } - repo = strings.TrimSpace(repo) - path := fmt.Sprintf("/api/v1/repos/%s/commits", repo) + path := fmt.Sprintf("/api/v1/repos/%s/commits?limit=1", repo) headers := map[string]string{} if f.Token != "" { @@ -45,25 +47,29 @@ func (f GiteaFetcher) Fetch() []Entry { Headers: headers, } - var r GiteaResponse - - if err := req.Run(&r); err != nil { + var resp GiteaResponse + if err := req.Run(&resp); err != nil { continue } - if len(r) == 0 { + if len(resp) == 0 { continue } - commit := r[0] + commit := resp[0] cacheKey := "gitea_" + url.QueryEscape(f.BaseURL+path) - if f.Cache.TryUpdate(cacheKey, commit.Sha) { - messages = append(messages, Entry{ - Title: fmt.Sprintf("📝 [Gitea] - (%s) %s", repo, commit.Commit.Message), - URL: commit.HTMLURL, - }) + entry := f.TryCreateEntry( + cacheKey, + commit.Sha, + fmt.Sprintf("📝 [%s] - (%s) %s", f.Name(), repo, commit.Commit.Message), + commit.HTMLURL, + ) + + if entry != nil { + entries = append(entries, *entry) } } - return messages + + return entries } diff --git a/lib/fetcher.go b/lib/fetcher.go index 70f64d7..c55d3c9 100644 --- a/lib/fetcher.go +++ b/lib/fetcher.go @@ -15,9 +15,25 @@ type Entry struct { // Fetcher is the interface for a fetcher. type Fetcher interface { + Name() string Fetch() []Entry } +// BaseFetcher contains common fields for all fetchers. +type BaseFetcher struct { + BaseURL string + Token string + Cache *Cache +} + +// TryCreateEntry checks the cache and creates an Entry if the value has changed. +func (b *BaseFetcher) TryCreateEntry(cacheKey, cacheValue, title, url string) *Entry { + if b.Cache.TryUpdate(cacheKey, cacheValue) { + return &Entry{Title: title, URL: url} + } + return nil +} + // FetcherRequest represents a common HTTP request configuration. type FetcherRequest struct { BaseURL string diff --git a/lib/fetcher.redmine.go b/lib/fetcher.redmine.go index c8cb187..cfc287c 100644 --- a/lib/fetcher.redmine.go +++ b/lib/fetcher.redmine.go @@ -14,38 +14,42 @@ type RedmineResponse struct { } type RedmineFetcher struct { - BaseURL string - Key string - Cache *Cache + BaseFetcher } -func (f RedmineFetcher) Fetch() []Entry { +func (f *RedmineFetcher) Name() string { + return "Redmine" +} + +func (f *RedmineFetcher) Fetch() []Entry { req := FetcherRequest{ BaseURL: f.BaseURL, Path: "/issues.json?limit=1&sort=updated_on:desc", Method: http.MethodGet, Headers: map[string]string{ - "X-Redmine-API-Key": f.Key, + "X-Redmine-API-Key": f.Token, }, } - var r RedmineResponse - - if err := req.Run(&r); err != nil { - return []Entry{} + var resp RedmineResponse + if err := req.Run(&resp); err != nil { + return nil } - if len(r.Issues) == 0 { - return []Entry{} + if len(resp.Issues) == 0 { + return nil } - i := r.Issues[0] - if f.Cache.TryUpdate("redmine", i.UpdatedOn) { - url := fmt.Sprintf("%s/issues/%d", f.BaseURL, i.ID) - return []Entry{{ - Title: fmt.Sprintf("🎫 [Redmine] - #%d %s", i.ID, i.Subject), - URL: url, - }} + issue := resp.Issues[0] + entry := f.TryCreateEntry( + "redmine", + issue.UpdatedOn, + fmt.Sprintf("🎫 [%s] - #%d %s", f.Name(), issue.ID, issue.Subject), + fmt.Sprintf("%s/issues/%d", f.BaseURL, issue.ID), + ) + + if entry != nil { + return []Entry{*entry} } - return []Entry{} + return nil } diff --git a/lib/fetcher.wikijs.go b/lib/fetcher.wikijs.go index e3a5470..ee6fe2a 100644 --- a/lib/fetcher.wikijs.go +++ b/lib/fetcher.wikijs.go @@ -18,13 +18,15 @@ type WikiResponse struct { } type WikiFetcher struct { - BaseURL string - Token string - Cache *Cache + BaseFetcher } -func (f WikiFetcher) Fetch() []Entry { - q := `{"query":"{ pages { list(orderBy: UPDATED, orderByDirection: DESC, limit: 1){ path, updatedAt, title }}}"}` +func (f *WikiFetcher) Name() string { + return "WikiJS" +} + +func (f *WikiFetcher) Fetch() []Entry { + query := `{"query":"{ pages { list(orderBy: UPDATED, orderByDirection: DESC, limit: 1){ path, updatedAt, title }}}"}` req := FetcherRequest{ BaseURL: f.BaseURL, @@ -34,25 +36,28 @@ func (f WikiFetcher) Fetch() []Entry { "Authorization": "Bearer " + f.Token, "Content-Type": "application/json", }, - Body: []byte(q), + Body: []byte(query), } - var r WikiResponse - - if err := req.Run(&r); err != nil { - return []Entry{} + var resp WikiResponse + if err := req.Run(&resp); err != nil { + return nil } - if len(r.Data.Pages.List) == 0 { - return []Entry{} + if len(resp.Data.Pages.List) == 0 { + return nil } - u := r.Data.Pages.List[0] - if f.Cache.TryUpdate("wiki", u.UpdatedAt) { - url := fmt.Sprintf("%s/%s", f.BaseURL, u.Path) - return []Entry{{ - Title: fmt.Sprintf("📖 [WikiJS] - %s", u.Title), - URL: url, - }} + + page := resp.Data.Pages.List[0] + entry := f.TryCreateEntry( + "wiki", + page.UpdatedAt, + fmt.Sprintf("📖 [%s] - %s", f.Name(), page.Title), + fmt.Sprintf("%s/%s", f.BaseURL, page.Path), + ) + + if entry != nil { + return []Entry{*entry} } - return []Entry{} + return nil } diff --git a/lib/runner.go b/lib/runner.go index 02940df..98f132a 100644 --- a/lib/runner.go +++ b/lib/runner.go @@ -32,27 +32,30 @@ func getConfig() Config { } func getFetchers(config *Config, cache *Cache) []Fetcher { - var fetchers []Fetcher - - fetchers = append(fetchers, &GiteaFetcher{ - BaseURL: config.GiteaBaseURL, - Token: config.GiteaToken, - Repos: config.GiteaRepos, - Cache: cache, - }) - - fetchers = append(fetchers, &WikiFetcher{ - BaseURL: config.WikiBaseURL, - Token: config.WikiToken, - Cache: cache, - }) - fetchers = append(fetchers, &RedmineFetcher{ - BaseURL: config.RedmineBaseURL, - Key: config.RedmineKey, - Cache: cache, - }) - - return fetchers + return []Fetcher{ + &GiteaFetcher{ + BaseFetcher: BaseFetcher{ + BaseURL: config.GiteaBaseURL, + Token: config.GiteaToken, + Cache: cache, + }, + Repos: config.GiteaRepos, + }, + &WikiFetcher{ + BaseFetcher: BaseFetcher{ + BaseURL: config.WikiBaseURL, + Token: config.WikiToken, + Cache: cache, + }, + }, + &RedmineFetcher{ + BaseFetcher: BaseFetcher{ + BaseURL: config.RedmineBaseURL, + Token: config.RedmineKey, + Cache: cache, + }, + }, + } } func getCache() Cache {