A social RSS reader built on the AT Protocol. glean.at
glean atproto atmosphere rss feed social app
14
fork

Configure Feed

Select the types of activity you want to include in your feed.

Refactor fetcher to include feed discovery logic

+25 -21
+24
internal/feed/fetcher.go
··· 80 80 return nil, lastErr 81 81 } 82 82 83 + func (f *Fetcher) FetchOrDiscover(ctx context.Context, feedURL string) (*ParseResult, string, error) { 84 + result, err := f.Fetch(ctx, feedURL) 85 + if err != nil && !strings.HasPrefix(feedURL, "at://") { 86 + return f.discover(ctx, feedURL) 87 + } 88 + return result, feedURL, err 89 + } 90 + 91 + func (f *Fetcher) discover(ctx context.Context, feedURL string) (*ParseResult, string, error) { 92 + discovered, err := Discover(ctx, feedURL) 93 + if err != nil || len(discovered.FeedURLs) == 0 { 94 + return nil, feedURL, fmt.Errorf("no feeds found at %s", feedURL) 95 + } 96 + 97 + for _, candidate := range discovered.FeedURLs { 98 + result, fetchErr := f.Fetch(ctx, candidate) 99 + if fetchErr == nil && result != nil { 100 + return result, candidate, nil 101 + } 102 + } 103 + 104 + return nil, feedURL, fmt.Errorf("no feeds found at %s", feedURL) 105 + } 106 + 83 107 func (f *Fetcher) executeRequest(ctx context.Context, feedURL string) (*ParseResult, *http.Response, error) { 84 108 req, err := http.NewRequestWithContext(ctx, http.MethodGet, feedURL, nil) 85 109 if err != nil {
+1 -21
internal/server/feeds_handler.go
··· 4 4 "context" 5 5 "database/sql" 6 6 "errors" 7 - "fmt" 8 7 "net/http" 9 8 "net/url" 10 9 "time" ··· 132 131 } 133 132 } 134 133 135 - result, err := s.fetcher.Fetch(r.Context(), feedURL) 136 - if err != nil && !atproto.IsATProtoFeedURL(feedURL) { 137 - result, feedURL, err = s.discoverFeed(r.Context(), feedURL) 138 - } 134 + result, feedURL, err := s.fetcher.FetchOrDiscover(r.Context(), feedURL) 139 135 if err != nil { 140 136 s.logger.Error("failed to fetch feed", "error", err, "url", feedURL) 141 137 http.Error(w, err.Error(), http.StatusInternalServerError) ··· 471 467 s.render(w, r, "dead-feeds.html", map[string]any{ 472 468 "DeadFeeds": deadFeeds, 473 469 }) 474 - } 475 - 476 - func (s *Server) discoverFeed(ctx context.Context, feedURL string) (*feed.ParseResult, string, error) { 477 - discovered, err := feed.Discover(ctx, feedURL) 478 - if err != nil || len(discovered.FeedURLs) == 0 { 479 - return nil, feedURL, fmt.Errorf("no feeds found at %s", feedURL) 480 - } 481 - 482 - for _, candidate := range discovered.FeedURLs { 483 - result, fetchErr := s.fetcher.Fetch(ctx, candidate) 484 - if fetchErr == nil && result != nil { 485 - return result, candidate, nil 486 - } 487 - } 488 - 489 - return nil, feedURL, fmt.Errorf("no feeds found at %s", feedURL) 490 470 } 491 471 492 472 func nullString(s string) sql.NullString {