Skip to content

Commit a81356b

Browse files
committed
Consolidate fetch and feed into feed package
1 parent ab86250 commit a81356b

14 files changed

Lines changed: 99 additions & 106 deletions

File tree

backend/command/command.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
package command
22

33
import (
4-
"github.com/theandrew168/bloggulus/backend/fetch"
4+
"github.com/theandrew168/bloggulus/backend/feed"
55
"github.com/theandrew168/bloggulus/backend/repository"
66
)
77

88
type Command struct {
99
repo *repository.Repository
10-
feedFetcher fetch.FeedFetcher
10+
feedFetcher feed.FeedFetcher
1111
}
1212

13-
func New(repo *repository.Repository, feedFetcher fetch.FeedFetcher) *Command {
13+
func New(repo *repository.Repository, feedFetcher feed.FeedFetcher) *Command {
1414
cmd := Command{
1515
repo: repo,
1616
feedFetcher: feedFetcher,

backend/command/sync/sync.go

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,13 @@ import (
44
"log/slog"
55

66
"github.com/theandrew168/bloggulus/backend/feed"
7-
"github.com/theandrew168/bloggulus/backend/fetch"
87
"github.com/theandrew168/bloggulus/backend/model"
98
"github.com/theandrew168/bloggulus/backend/repository"
109
"github.com/theandrew168/bloggulus/backend/timeutil"
1110
)
1211

1312
// UpdateCacheHeaders updates the ETag and Last-Modified headers for a blog if they have changed.
14-
func UpdateCacheHeaders(blog *model.Blog, response fetch.FetchFeedResponse) bool {
13+
func UpdateCacheHeaders(blog *model.Blog, response feed.FetchFeedResponse) bool {
1514
headersChanged := false
1615
if response.ETag != "" && response.ETag != blog.ETag() {
1716
headersChanged = true
@@ -96,9 +95,9 @@ func ComparePosts(blog *model.Blog, knownPosts []*model.Post, feedPosts []feed.P
9695
return result, nil
9796
}
9897

99-
func SyncNewBlog(repo *repository.Repository, feedFetcher fetch.FeedFetcher, feedURL string) error {
98+
func SyncNewBlog(repo *repository.Repository, feedFetcher feed.FeedFetcher, feedURL string) error {
10099
// Make an unconditional fetch for the blog's feed.
101-
req := fetch.FetchFeedRequest{
100+
req := feed.FetchFeedRequest{
102101
URL: feedURL,
103102
}
104103
resp, err := feedFetcher.FetchFeed(req)
@@ -108,7 +107,7 @@ func SyncNewBlog(repo *repository.Repository, feedFetcher fetch.FeedFetcher, fee
108107

109108
// No feed data from a new blog is an error.
110109
if resp.Feed == "" {
111-
return fetch.ErrUnreachableFeed
110+
return feed.ErrUnreachableFeed
112111
}
113112

114113
feedBlog, err := feed.Parse(feedURL, resp.Feed)
@@ -142,9 +141,9 @@ func SyncNewBlog(repo *repository.Repository, feedFetcher fetch.FeedFetcher, fee
142141
return nil
143142
}
144143

145-
func SyncExistingBlog(repo *repository.Repository, feedFetcher fetch.FeedFetcher, blog *model.Blog) error {
144+
func SyncExistingBlog(repo *repository.Repository, feedFetcher feed.FeedFetcher, blog *model.Blog) error {
146145
// Make a conditional fetch for the blog's feed.
147-
req := fetch.FetchFeedRequest{
146+
req := feed.FetchFeedRequest{
148147
URL: blog.FeedURL(),
149148
ETag: blog.ETag(),
150149
LastModified: blog.LastModified(),

backend/command/sync/sync_test.go

Lines changed: 19 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,6 @@ import (
88
"github.com/theandrew168/bloggulus/backend/command/sync"
99
"github.com/theandrew168/bloggulus/backend/feed"
1010
feedMock "github.com/theandrew168/bloggulus/backend/feed/mock"
11-
"github.com/theandrew168/bloggulus/backend/fetch"
12-
fetchMock "github.com/theandrew168/bloggulus/backend/fetch/mock"
1311
"github.com/theandrew168/bloggulus/backend/model"
1412
"github.com/theandrew168/bloggulus/backend/test"
1513
)
@@ -18,7 +16,7 @@ func TestUpdateCacheHeaders(t *testing.T) {
1816
t.Parallel()
1917

2018
blog := test.NewBlog(t)
21-
resp := fetch.FetchFeedResponse{
19+
resp := feed.FetchFeedResponse{
2220
ETag: "foo",
2321
LastModified: "bar",
2422
}
@@ -33,7 +31,7 @@ func TestUpdateCacheHeadersDoesNotClear(t *testing.T) {
3331
t.Parallel()
3432

3533
blog := test.NewBlog(t)
36-
resp := fetch.FetchFeedResponse{
34+
resp := feed.FetchFeedResponse{
3735
ETag: "",
3836
LastModified: "",
3937
}
@@ -112,10 +110,10 @@ func TestNewBlog(t *testing.T) {
112110
atomFeed, err := feedMock.GenerateAtomFeed(feedBlog)
113111
test.AssertNilError(t, err)
114112

115-
feeds := map[string]fetch.FetchFeedResponse{
113+
feeds := map[string]feed.FetchFeedResponse{
116114
feedBlog.FeedURL: {Feed: atomFeed},
117115
}
118-
feedFetcher := fetchMock.NewFeedFetcher(feeds)
116+
feedFetcher := feedMock.NewFeedFetcher(feeds)
119117

120118
cmd := command.New(repo, feedFetcher)
121119

@@ -159,10 +157,10 @@ func TestExistingBlog(t *testing.T) {
159157
atomFeed, err := feedMock.GenerateAtomFeed(feedBlog)
160158
test.AssertNilError(t, err)
161159

162-
feeds := map[string]fetch.FetchFeedResponse{
160+
feeds := map[string]feed.FetchFeedResponse{
163161
feedBlog.FeedURL: {Feed: atomFeed},
164162
}
165-
feedFetcher := fetchMock.NewFeedFetcher(feeds)
163+
feedFetcher := feedMock.NewFeedFetcher(feeds)
166164

167165
cmd := command.New(repo, feedFetcher)
168166

@@ -197,7 +195,7 @@ func TestExistingBlog(t *testing.T) {
197195
atomFeed, err = feedMock.GenerateAtomFeed(feedBlog)
198196
test.AssertNilError(t, err)
199197

200-
feeds[feedBlog.FeedURL] = fetch.FetchFeedResponse{Feed: atomFeed}
198+
feeds[feedBlog.FeedURL] = feed.FetchFeedResponse{Feed: atomFeed}
201199

202200
// sync the blog again
203201
err = cmd.SyncBlog(feedBlog.FeedURL)
@@ -223,13 +221,13 @@ func TestUnreachableFeed(t *testing.T) {
223221

224222
feedURL := test.RandomURL(20)
225223

226-
feeds := map[string]fetch.FetchFeedResponse{}
227-
feedFetcher := fetchMock.NewFeedFetcher(feeds)
224+
feeds := map[string]feed.FetchFeedResponse{}
225+
feedFetcher := feedMock.NewFeedFetcher(feeds)
228226

229227
cmd := command.New(repo, feedFetcher)
230228

231229
err := cmd.SyncBlog(feedURL)
232-
test.AssertErrorIs(t, err, fetch.ErrUnreachableFeed)
230+
test.AssertErrorIs(t, err, feed.ErrUnreachableFeed)
233231
}
234232

235233
func TestUpdatePostContent(t *testing.T) {
@@ -253,10 +251,10 @@ func TestUpdatePostContent(t *testing.T) {
253251
atomFeed, err := feedMock.GenerateAtomFeed(feedBlog)
254252
test.AssertNilError(t, err)
255253

256-
feeds := map[string]fetch.FetchFeedResponse{
254+
feeds := map[string]feed.FetchFeedResponse{
257255
feedBlog.FeedURL: {Feed: atomFeed},
258256
}
259-
feedFetcher := fetchMock.NewFeedFetcher(feeds)
257+
feedFetcher := feedMock.NewFeedFetcher(feeds)
260258

261259
cmd := command.New(repo, feedFetcher)
262260

@@ -284,7 +282,7 @@ func TestUpdatePostContent(t *testing.T) {
284282
atomFeed, err = feedMock.GenerateAtomFeed(feedBlog)
285283
test.AssertNilError(t, err)
286284

287-
feeds[feedBlog.FeedURL] = fetch.FetchFeedResponse{Feed: atomFeed}
285+
feeds[feedBlog.FeedURL] = feed.FetchFeedResponse{Feed: atomFeed}
288286

289287
// sync the blog again
290288
err = cmd.SyncBlog(feedBlog.FeedURL)
@@ -316,10 +314,10 @@ func TestCacheHeaderOverwrite(t *testing.T) {
316314
atomFeed, err := feedMock.GenerateAtomFeed(feedBlog)
317315
test.AssertNilError(t, err)
318316

319-
feeds := map[string]fetch.FetchFeedResponse{
317+
feeds := map[string]feed.FetchFeedResponse{
320318
feedBlog.FeedURL: {Feed: atomFeed},
321319
}
322-
feedFetcher := fetchMock.NewFeedFetcher(feeds)
320+
feedFetcher := feedMock.NewFeedFetcher(feeds)
323321

324322
cmd := command.New(repo, feedFetcher)
325323

@@ -365,14 +363,14 @@ func TestCacheHeaderUpdate(t *testing.T) {
365363
atomFeed, err := feedMock.GenerateAtomFeed(feedBlog)
366364
test.AssertNilError(t, err)
367365

368-
feeds := map[string]fetch.FetchFeedResponse{
366+
feeds := map[string]feed.FetchFeedResponse{
369367
feedBlog.FeedURL: {
370368
Feed: atomFeed,
371369
ETag: "etag",
372370
LastModified: "lastModified",
373371
},
374372
}
375-
feedFetcher := fetchMock.NewFeedFetcher(feeds)
373+
feedFetcher := feedMock.NewFeedFetcher(feeds)
376374

377375
cmd := command.New(repo, feedFetcher)
378376

@@ -386,13 +384,13 @@ func TestCacheHeaderUpdate(t *testing.T) {
386384
test.AssertEqual(t, blog.LastModified(), "lastModified")
387385

388386
// Update the feed to return new cache value but no data
389-
feeds = map[string]fetch.FetchFeedResponse{
387+
feeds = map[string]feed.FetchFeedResponse{
390388
feedBlog.FeedURL: {
391389
ETag: "other etag",
392390
LastModified: "other lastModified",
393391
},
394392
}
395-
feedFetcher = fetchMock.NewFeedFetcher(feeds)
393+
feedFetcher = feedMock.NewFeedFetcher(feeds)
396394

397395
cmd = command.New(repo, feedFetcher)
398396

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
package fetch
1+
package feed
22

33
import "errors"
44

55
var (
6-
ErrUnreachableFeed = errors.New("fetch: unreachable feed")
6+
ErrUnreachableFeed = errors.New("feed: unreachable feed")
77
)
88

99
type FetchFeedRequest struct {

backend/feed/mock/fetch.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package mock
2+
3+
import (
4+
"github.com/theandrew168/bloggulus/backend/feed"
5+
)
6+
7+
// ensure FeedFetcher interface is satisfied
8+
var _ feed.FeedFetcher = (*FeedFetcher)(nil)
9+
10+
type FeedFetcher struct {
11+
feeds map[string]feed.FetchFeedResponse
12+
}
13+
14+
func NewFeedFetcher(feeds map[string]feed.FetchFeedResponse) *FeedFetcher {
15+
f := FeedFetcher{feeds: feeds}
16+
return &f
17+
}
18+
19+
func (f *FeedFetcher) FetchFeed(request feed.FetchFeedRequest) (feed.FetchFeedResponse, error) {
20+
feedForURL, ok := f.feeds[request.URL]
21+
if !ok {
22+
return feed.FetchFeedResponse{}, feed.ErrUnreachableFeed
23+
}
24+
25+
return feedForURL, nil
26+
}
Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,13 @@ import (
44
"io"
55
"net/http"
66

7-
"github.com/theandrew168/bloggulus/backend/fetch"
7+
"github.com/theandrew168/bloggulus/backend/feed"
88
)
99

10+
const UserAgent = "Bloggulus/0.5.2 (+https://bloggulus.com)"
11+
1012
// ensure FeedFetcher interface is satisfied
11-
var _ fetch.FeedFetcher = (*FeedFetcher)(nil)
13+
var _ feed.FeedFetcher = (*FeedFetcher)(nil)
1214

1315
type FeedFetcher struct{}
1416

@@ -17,10 +19,10 @@ func NewFeedFetcher() *FeedFetcher {
1719
return &f
1820
}
1921

20-
func (f *FeedFetcher) FetchFeed(request fetch.FetchFeedRequest) (fetch.FetchFeedResponse, error) {
22+
func (f *FeedFetcher) FetchFeed(request feed.FetchFeedRequest) (feed.FetchFeedResponse, error) {
2123
req, err := http.NewRequest("GET", request.URL, nil)
2224
if err != nil {
23-
return fetch.FetchFeedResponse{}, fetch.ErrUnreachableFeed
25+
return feed.FetchFeedResponse{}, feed.ErrUnreachableFeed
2426
}
2527
req.Header.Set("User-Agent", UserAgent)
2628

@@ -33,20 +35,20 @@ func (f *FeedFetcher) FetchFeed(request fetch.FetchFeedRequest) (fetch.FetchFeed
3335

3436
resp, err := http.DefaultClient.Do(req)
3537
if err != nil {
36-
return fetch.FetchFeedResponse{}, fetch.ErrUnreachableFeed
38+
return feed.FetchFeedResponse{}, feed.ErrUnreachableFeed
3739
}
3840
defer resp.Body.Close()
3941

4042
if resp.StatusCode >= 400 {
41-
return fetch.FetchFeedResponse{}, fetch.ErrUnreachableFeed
43+
return feed.FetchFeedResponse{}, feed.ErrUnreachableFeed
4244
}
4345

4446
body, err := io.ReadAll(resp.Body)
4547
if err != nil {
46-
return fetch.FetchFeedResponse{}, fetch.ErrUnreachableFeed
48+
return feed.FetchFeedResponse{}, feed.ErrUnreachableFeed
4749
}
4850

49-
fetchFeedResponse := fetch.FetchFeedResponse{
51+
fetchFeedResponse := feed.FetchFeedResponse{
5052
Feed: string(body),
5153
ETag: resp.Header.Get("ETag"),
5254
LastModified: resp.Header.Get("Last-Modified"),

backend/fetch/mock/feed.go

Lines changed: 0 additions & 26 deletions
This file was deleted.

backend/fetch/web/useragent.go

Lines changed: 0 additions & 3 deletions
This file was deleted.

0 commit comments

Comments
 (0)