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.

Fix fetch feed when added

+44 -26
+44 -26
internal/server/feeds_handler.go
··· 78 78 } 79 79 80 80 s.render(w, r, "feeds.html", map[string]any{ 81 - "User": user, 82 - "Subscriptions": subs, 83 - "SubscriptionCount": subCount, 84 - "Categories": categories, 85 - "Category": category, 86 - "FeedRecommendations": feedRecs, 87 - "FollowedPeople": followedPeople, 88 - "DiscoverPeople": discoverPeople, 89 - "DeadFeeds": deadFeeds, 90 - "Page": page, 91 - "BaseURL": "/feeds", 92 - "QueryParams": buildQueryParams(map[string]string{"category": category}), 81 + "User": user, 82 + "Subscriptions": subs, 83 + "SubscriptionCount": subCount, 84 + "Categories": categories, 85 + "Category": category, 86 + "FeedRecommendations": feedRecs, 87 + "FollowedPeople": followedPeople, 88 + "DiscoverPeople": discoverPeople, 89 + "DeadFeeds": deadFeeds, 90 + "Page": page, 91 + "BaseURL": "/feeds", 92 + "QueryParams": buildQueryParams(map[string]string{"category": category}), 93 93 }) 94 94 } 95 95 96 + func (s *Server) storeFetchResult(ctx context.Context, feedURL, siteURL string, result *feed.ParseResult) { 97 + if result == nil { 98 + _ = s.dbs.Articles.MarkFeedFetched(ctx, feedURL) 99 + return 100 + } 101 + faviconURL := result.Feed.FaviconURL 102 + if faviconURL == "" { 103 + faviconURL = feed.ResolveFavicon(ctx, feedURL, siteURL) 104 + } 105 + if len(result.Articles) > 0 { 106 + if err := s.dbs.Articles.BatchUpsertArticles(ctx, result.Articles); err != nil { 107 + s.logger.Error("failed to store articles", "error", err, "feed", feedURL) 108 + } 109 + } 110 + _ = s.dbs.Articles.MarkFeedFetched(ctx, feedURL) 111 + if faviconURL != "" { 112 + _ = s.dbs.Articles.UpdateFeedFavicon(ctx, feedURL, faviconURL) 113 + } 114 + } 115 + 96 116 func (s *Server) handleAddFeed(w http.ResponseWriter, r *http.Request) { 97 117 user := currentUser(r) 98 118 feedURL := r.FormValue("feed_url") ··· 113 133 return 114 134 } 115 135 116 - var feedTitle string 117 - var faviconURL string 136 + var feedTitle, faviconURL string 118 137 if result != nil { 119 138 feedTitle = result.Feed.Title 120 139 faviconURL = result.Feed.FaviconURL 121 - if faviconURL == "" { 122 - go func() { 123 - if f := feed.ResolveFavicon(context.Background(), feedURL, result.Feed.SiteURL); f != "" { 124 - _ = s.dbs.Articles.UpdateFeedFavicon(context.Background(), feedURL, f) 125 - } 126 - }() 127 - } 128 140 } 129 141 130 142 f := &db.Feed{ ··· 168 180 http.Error(w, err.Error(), http.StatusInternalServerError) 169 181 return 170 182 } 183 + 184 + go s.storeFetchResult(context.Background(), feedURL, result.Feed.SiteURL, result) 171 185 172 186 if err := s.engine.MarkImpressionActed(r.Context(), user.DID, "feed", feedURL); err != nil { 173 187 s.logger.Warn("failed to mark impression acted", "error", err) ··· 272 286 var added int 273 287 client := s.pdsClientForUser(r) 274 288 275 - var favGoroutines []struct{ feedURL, siteURL string } 289 + var feedsToFetch []struct{ feedURL, siteURL string } 276 290 for _, fu := range feedURLs { 277 291 f := &db.Feed{ 278 292 FeedURL: fu.URL, ··· 285 299 continue 286 300 } 287 301 288 - favGoroutines = append(favGoroutines, struct{ feedURL, siteURL string }{fu.URL, fu.SiteURL}) 302 + feedsToFetch = append(feedsToFetch, struct{ feedURL, siteURL string }{fu.URL, fu.SiteURL}) 289 303 290 304 var subURI, subCID string 291 305 if client != nil { ··· 316 330 go func() { 317 331 g, ctx := errgroup.WithContext(context.Background()) 318 332 g.SetLimit(5) 319 - for _, fav := range favGoroutines { 333 + for _, f := range feedsToFetch { 320 334 g.Go(func() error { 321 - if f := feed.ResolveFavicon(ctx, fav.feedURL, fav.siteURL); f != "" { 322 - _ = s.dbs.Articles.UpdateFeedFavicon(ctx, fav.feedURL, f) 335 + result, err := s.fetcher.Fetch(ctx, f.feedURL) 336 + if err != nil { 337 + s.logger.Error("failed to fetch feed", "error", err, "feed", f.feedURL) 338 + _ = s.dbs.Articles.MarkFeedFetchError(ctx, f.feedURL, err.Error()) 339 + return nil 323 340 } 341 + s.storeFetchResult(ctx, f.feedURL, f.siteURL, result) 324 342 return nil 325 343 }) 326 344 }