From 6be44be9bfa28014b9bf8a375e1e168f67962e37 Mon Sep 17 00:00:00 2001 From: Zsolt Tasnadi Date: Tue, 20 Jan 2026 08:31:59 +0100 Subject: [PATCH] FetcherRequest --- lib/fetcher.gitea.go | 21 ++++++++++++++++----- lib/fetcher.go | 30 +++++++++++++++++++++++++++++- lib/fetcher.redmine.go | 13 +++++++++---- lib/fetcher.wikijs.go | 18 ++++++++++++------ 4 files changed, 66 insertions(+), 16 deletions(-) diff --git a/lib/fetcher.gitea.go b/lib/fetcher.gitea.go index b8d1b91..710ca09 100644 --- a/lib/fetcher.gitea.go +++ b/lib/fetcher.gitea.go @@ -29,15 +29,25 @@ func (f GiteaFetcher) Fetch() []Entry { if repo == "" { continue } - giteaURL := fmt.Sprintf("%s/api/v1/repos/%s/commits", f.BaseURL, strings.TrimSpace(repo)) - req, _ := http.NewRequest("GET", giteaURL, nil) + + repo = strings.TrimSpace(repo) + path := fmt.Sprintf("/api/v1/repos/%s/commits", repo) + + headers := map[string]string{} if f.Token != "" { - req.Header.Set("Authorization", "token "+f.Token) + headers["Authorization"] = "token " + f.Token + } + + req := FetcherRequest{ + BaseURL: f.BaseURL, + Path: path, + Method: http.MethodGet, + Headers: headers, } var r GiteaResponse - if err := getJSON(req, &r); err != nil { + if err := req.Run(&r); err != nil { continue } @@ -46,8 +56,9 @@ func (f GiteaFetcher) Fetch() []Entry { } commit := r[0] + cacheKey := "gitea_" + url.QueryEscape(f.BaseURL+path) - if f.Cache.TryUpdate("gitea_"+url.QueryEscape(giteaURL), commit.Sha) { + if f.Cache.TryUpdate(cacheKey, commit.Sha) { messages = append(messages, Entry{ Title: fmt.Sprintf("📝 [Gitea] - (%s) %s", repo, commit.Commit.Message), URL: commit.HTMLURL, diff --git a/lib/fetcher.go b/lib/fetcher.go index 7587030..70f64d7 100644 --- a/lib/fetcher.go +++ b/lib/fetcher.go @@ -1,7 +1,9 @@ package lib import ( + "bytes" "encoding/json" + "io" "net/http" ) @@ -16,7 +18,33 @@ type Fetcher interface { Fetch() []Entry } -func getJSON(req *http.Request, target interface{}) error { +// FetcherRequest represents a common HTTP request configuration. +type FetcherRequest struct { + BaseURL string + Path string + Method string + Headers map[string]string + Body []byte +} + +// Run executes the HTTP request and decodes the JSON response into target. +func (r FetcherRequest) Run(target interface{}) error { + url := r.BaseURL + r.Path + + var body io.Reader + if r.Body != nil { + body = bytes.NewBuffer(r.Body) + } + + req, err := http.NewRequest(r.Method, url, body) + if err != nil { + return err + } + + for key, value := range r.Headers { + req.Header.Set(key, value) + } + res, err := http.DefaultClient.Do(req) if err != nil { return err diff --git a/lib/fetcher.redmine.go b/lib/fetcher.redmine.go index 849f556..c8cb187 100644 --- a/lib/fetcher.redmine.go +++ b/lib/fetcher.redmine.go @@ -20,13 +20,18 @@ type RedmineFetcher struct { } func (f RedmineFetcher) Fetch() []Entry { - redmineURL := fmt.Sprintf("%s/issues.json", f.BaseURL) - req, _ := http.NewRequest("GET", redmineURL, nil) - req.Header.Set("X-Redmine-API-Key", f.Key) + 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, + }, + } var r RedmineResponse - if err := getJSON(req, &r); err != nil { + if err := req.Run(&r); err != nil { return []Entry{} } diff --git a/lib/fetcher.wikijs.go b/lib/fetcher.wikijs.go index fba5be5..e3a5470 100644 --- a/lib/fetcher.wikijs.go +++ b/lib/fetcher.wikijs.go @@ -1,7 +1,6 @@ package lib import ( - "bytes" "fmt" "net/http" ) @@ -26,14 +25,21 @@ type WikiFetcher struct { func (f WikiFetcher) Fetch() []Entry { q := `{"query":"{ pages { list(orderBy: UPDATED, orderByDirection: DESC, limit: 1){ path, updatedAt, title }}}"}` - wikiURL := fmt.Sprintf("%s/graphql", f.BaseURL) - req, _ := http.NewRequest("POST", wikiURL, bytes.NewBuffer([]byte(q))) - req.Header.Set("Authorization", "Bearer "+f.Token) - req.Header.Set("Content-Type", "application/json") + + req := FetcherRequest{ + BaseURL: f.BaseURL, + Path: "/graphql", + Method: http.MethodPost, + Headers: map[string]string{ + "Authorization": "Bearer " + f.Token, + "Content-Type": "application/json", + }, + Body: []byte(q), + } var r WikiResponse - if err := getJSON(req, &r); err != nil { + if err := req.Run(&r); err != nil { return []Entry{} }