72 lines
1.4 KiB
Go
72 lines
1.4 KiB
Go
package lib
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/json"
|
|
"io"
|
|
"net/http"
|
|
)
|
|
|
|
// Entry represents a single fetched item.
|
|
type Entry struct {
|
|
Title string
|
|
URL string
|
|
}
|
|
|
|
// 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
|
|
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
|
|
}
|
|
defer res.Body.Close()
|
|
|
|
return json.NewDecoder(res.Body).Decode(target)
|
|
}
|