Browse Source

Show count of feeds with permanent errors in header menu

Only for feeds that reach `maxParsingError` are counted (so transient errors do not trigger counter).
Dave Z 7 years ago
parent
commit
9169fbafb2

+ 11 - 0
storage/feed.go

@@ -46,6 +46,17 @@ func (s *Storage) CountFeeds(userID int64) int {
 	return result
 }
 
+// CountErrorFeeds returns the number of feeds with parse errors that belong to the given user.
+func (s *Storage) CountErrorFeeds(userID int64) int {
+	var result int
+	err := s.db.QueryRow(`SELECT count(*) FROM feeds WHERE user_id=$1 AND parsing_error_count>=$2`, userID, maxParsingError).Scan(&result)
+	if err != nil {
+		return 0
+	}
+
+	return result
+}
+
 // Feeds returns all feeds of the given user.
 func (s *Storage) Feeds(userID int64) (model.Feeds, error) {
 	defer timer.ExecutionTime(time.Now(), fmt.Sprintf("[Storage:Feeds] userID=%d", userID))

+ 6 - 2
template/common.go

@@ -134,7 +134,11 @@ var templateCommonMap = map[string]string{
                     <a href="{{ route "history" }}" data-page="history">{{ t "History" }}</a>
                 </li>
                 <li {{ if eq .menu "feeds" }}class="active"{{ end }} title="{{ t "Keyboard Shortcut: %s" "g f" }}">
-                    <a href="{{ route "feeds" }}" data-page="feeds">{{ t "Feeds" }}</a>
+                    <a href="{{ route "feeds" }}" data-page="feeds">{{ t "Feeds" }}
+                      {{ if gt .countErrorFeeds 0 }}
+                          <span class="error-feeds-counter-wrapper">(<span class="error-feeds-counter">{{ .countErrorFeeds }}</span>)</span>
+                      {{ end }}
+                    </a>
                 </li>
                 <li {{ if eq .menu "categories" }}class="active"{{ end }} title="{{ t "Keyboard Shortcut: %s" "g c" }}">
                     <a href="{{ route "categories" }}" data-page="categories">{{ t "Categories" }}</a>
@@ -239,6 +243,6 @@ var templateCommonMap = map[string]string{
 var templateCommonMapChecksums = map[string]string{
 	"entry_pagination": "756ef122f3ebc73754b5fc4304bf05e59da0ab4af030b2509ff4c9b4a74096ce",
 	"item_meta":        "2da78476f6c7fb8742c969ad1bfc20b7b61fddf97d79a77baf3cabda52f6fb49",
-	"layout":           "952632cafa23e02e3ae74c33a6606e127ab7bff0b82a2aa848967da8966475a5",
+	"layout":           "2491695e33a496c9bd902a2cb5bc3a6a540f98ac7c24591d503a77ba0f5f0ebe",
 	"pagination":       "b592d58ea9d6abf2dc0b158621404cbfaeea5413b1c8b8b9818725963096b196",
 }

+ 5 - 1
template/html/common/layout.html

@@ -60,7 +60,11 @@
                     <a href="{{ route "history" }}" data-page="history">{{ t "History" }}</a>
                 </li>
                 <li {{ if eq .menu "feeds" }}class="active"{{ end }} title="{{ t "Keyboard Shortcut: %s" "g f" }}">
-                    <a href="{{ route "feeds" }}" data-page="feeds">{{ t "Feeds" }}</a>
+                    <a href="{{ route "feeds" }}" data-page="feeds">{{ t "Feeds" }}
+                      {{ if gt .countErrorFeeds 0 }}
+                          <span class="error-feeds-counter-wrapper">(<span class="error-feeds-counter">{{ .countErrorFeeds }}</span>)</span>
+                      {{ end }}
+                    </a>
                 </li>
                 <li {{ if eq .menu "categories" }}class="active"{{ end }} title="{{ t "Keyboard Shortcut: %s" "g c" }}">
                     <a href="{{ route "categories" }}" data-page="categories">{{ t "Categories" }}</a>

+ 1 - 0
ui/about.go

@@ -31,6 +31,7 @@ func (c *Controller) About(w http.ResponseWriter, r *http.Request) {
 	view.Set("menu", "settings")
 	view.Set("user", user)
 	view.Set("countUnread", c.store.CountUnreadEntries(user.ID))
+	view.Set("countErrorFeeds", c.store.CountErrorFeeds(user.ID))
 
 	html.OK(w, r, view.Render("about"))
 }

+ 1 - 0
ui/bookmark_entries.go

@@ -56,6 +56,7 @@ func (c *Controller) ShowStarredPage(w http.ResponseWriter, r *http.Request) {
 	view.Set("menu", "starred")
 	view.Set("user", user)
 	view.Set("countUnread", c.store.CountUnreadEntries(user.ID))
+	view.Set("countErrorFeeds", c.store.CountErrorFeeds(user.ID))
 	view.Set("hasSaveEntry", c.store.HasSaveEntry(user.ID))
 
 	html.OK(w, r, view.Render("bookmark_entries"))

+ 1 - 0
ui/category_create.go

@@ -28,6 +28,7 @@ func (c *Controller) CreateCategory(w http.ResponseWriter, r *http.Request) {
 	view.Set("menu", "categories")
 	view.Set("user", user)
 	view.Set("countUnread", c.store.CountUnreadEntries(user.ID))
+	view.Set("countErrorFeeds", c.store.CountErrorFeeds(user.ID))
 
 	html.OK(w, r, view.Render("create_category"))
 }

+ 1 - 0
ui/category_edit.go

@@ -53,6 +53,7 @@ func (c *Controller) EditCategory(w http.ResponseWriter, r *http.Request) {
 	view.Set("menu", "categories")
 	view.Set("user", user)
 	view.Set("countUnread", c.store.CountUnreadEntries(user.ID))
+	view.Set("countErrorFeeds", c.store.CountErrorFeeds(user.ID))
 
 	html.OK(w, r, view.Render("edit_category"))
 }

+ 1 - 0
ui/category_entries.go

@@ -73,6 +73,7 @@ func (c *Controller) CategoryEntries(w http.ResponseWriter, r *http.Request) {
 	view.Set("menu", "categories")
 	view.Set("user", user)
 	view.Set("countUnread", c.store.CountUnreadEntries(user.ID))
+	view.Set("countErrorFeeds", c.store.CountErrorFeeds(user.ID))
 	view.Set("hasSaveEntry", c.store.HasSaveEntry(user.ID))
 
 	html.OK(w, r, view.Render("category_entries"))

+ 1 - 0
ui/category_list.go

@@ -36,6 +36,7 @@ func (c *Controller) CategoryList(w http.ResponseWriter, r *http.Request) {
 	view.Set("menu", "categories")
 	view.Set("user", user)
 	view.Set("countUnread", c.store.CountUnreadEntries(user.ID))
+	view.Set("countErrorFeeds", c.store.CountErrorFeeds(user.ID))
 
 	html.OK(w, r, view.Render("categories"))
 }

+ 1 - 0
ui/category_save.go

@@ -36,6 +36,7 @@ func (c *Controller) SaveCategory(w http.ResponseWriter, r *http.Request) {
 	view.Set("menu", "categories")
 	view.Set("user", user)
 	view.Set("countUnread", c.store.CountUnreadEntries(user.ID))
+	view.Set("countErrorFeeds", c.store.CountErrorFeeds(user.ID))
 
 	if err := categoryForm.Validate(); err != nil {
 		view.Set("errorMessage", err.Error())

+ 1 - 0
ui/category_update.go

@@ -54,6 +54,7 @@ func (c *Controller) UpdateCategory(w http.ResponseWriter, r *http.Request) {
 	view.Set("menu", "categories")
 	view.Set("user", user)
 	view.Set("countUnread", c.store.CountUnreadEntries(user.ID))
+	view.Set("countErrorFeeds", c.store.CountErrorFeeds(user.ID))
 
 	if err := categoryForm.Validate(); err != nil {
 		view.Set("errorMessage", err.Error())

+ 1 - 0
ui/entry_bookmark.go

@@ -86,6 +86,7 @@ func (c *Controller) ShowStarredEntry(w http.ResponseWriter, r *http.Request) {
 	view.Set("menu", "starred")
 	view.Set("user", user)
 	view.Set("countUnread", c.store.CountUnreadEntries(user.ID))
+	view.Set("countErrorFeeds", c.store.CountErrorFeeds(user.ID))
 	view.Set("hasSaveEntry", c.store.HasSaveEntry(user.ID))
 
 	html.OK(w, r, view.Render("entry"))

+ 1 - 0
ui/entry_category.go

@@ -93,6 +93,7 @@ func (c *Controller) ShowCategoryEntry(w http.ResponseWriter, r *http.Request) {
 	view.Set("menu", "categories")
 	view.Set("user", user)
 	view.Set("countUnread", c.store.CountUnreadEntries(user.ID))
+	view.Set("countErrorFeeds", c.store.CountErrorFeeds(user.ID))
 	view.Set("hasSaveEntry", c.store.HasSaveEntry(user.ID))
 
 	html.OK(w, r, view.Render("entry"))

+ 1 - 0
ui/entry_feed.go

@@ -93,6 +93,7 @@ func (c *Controller) ShowFeedEntry(w http.ResponseWriter, r *http.Request) {
 	view.Set("menu", "feeds")
 	view.Set("user", user)
 	view.Set("countUnread", c.store.CountUnreadEntries(user.ID))
+	view.Set("countErrorFeeds", c.store.CountErrorFeeds(user.ID))
 	view.Set("hasSaveEntry", c.store.HasSaveEntry(user.ID))
 
 	html.OK(w, r, view.Render("entry"))

+ 1 - 0
ui/entry_read.go

@@ -76,6 +76,7 @@ func (c *Controller) ShowReadEntry(w http.ResponseWriter, r *http.Request) {
 	view.Set("menu", "history")
 	view.Set("user", user)
 	view.Set("countUnread", c.store.CountUnreadEntries(user.ID))
+	view.Set("countErrorFeeds", c.store.CountErrorFeeds(user.ID))
 	view.Set("hasSaveEntry", c.store.HasSaveEntry(user.ID))
 
 	html.OK(w, r, view.Render("entry"))

+ 1 - 0
ui/entry_search.go

@@ -89,6 +89,7 @@ func (c *Controller) ShowSearchEntry(w http.ResponseWriter, r *http.Request) {
 	view.Set("menu", "search")
 	view.Set("user", user)
 	view.Set("countUnread", c.store.CountUnreadEntries(user.ID))
+	view.Set("countErrorFeeds", c.store.CountErrorFeeds(user.ID))
 	view.Set("hasSaveEntry", c.store.HasSaveEntry(user.ID))
 
 	html.OK(w, r, view.Render("entry"))

+ 1 - 0
ui/entry_unread.go

@@ -95,6 +95,7 @@ func (c *Controller) ShowUnreadEntry(w http.ResponseWriter, r *http.Request) {
 	view.Set("menu", "unread")
 	view.Set("user", user)
 	view.Set("hasSaveEntry", c.store.HasSaveEntry(user.ID))
+	view.Set("countErrorFeeds", c.store.CountErrorFeeds(user.ID))
 
 	// Fetching the counter here avoid to be off by one.
 	view.Set("countUnread", c.store.CountUnreadEntries(user.ID))

+ 1 - 0
ui/feed_edit.go

@@ -68,6 +68,7 @@ func (c *Controller) EditFeed(w http.ResponseWriter, r *http.Request) {
 	view.Set("menu", "feeds")
 	view.Set("user", user)
 	view.Set("countUnread", c.store.CountUnreadEntries(user.ID))
+	view.Set("countErrorFeeds", c.store.CountErrorFeeds(user.ID))
 
 	html.OK(w, r, view.Render("edit_feed"))
 }

+ 1 - 0
ui/feed_entries.go

@@ -73,6 +73,7 @@ func (c *Controller) ShowFeedEntries(w http.ResponseWriter, r *http.Request) {
 	view.Set("menu", "feeds")
 	view.Set("user", user)
 	view.Set("countUnread", c.store.CountUnreadEntries(user.ID))
+	view.Set("countErrorFeeds", c.store.CountErrorFeeds(user.ID))
 	view.Set("hasSaveEntry", c.store.HasSaveEntry(user.ID))
 
 	html.OK(w, r, view.Render("feed_entries"))

+ 1 - 0
ui/feed_list.go

@@ -36,6 +36,7 @@ func (c *Controller) ShowFeedsPage(w http.ResponseWriter, r *http.Request) {
 	view.Set("menu", "feeds")
 	view.Set("user", user)
 	view.Set("countUnread", c.store.CountUnreadEntries(user.ID))
+	view.Set("countErrorFeeds", c.store.CountErrorFeeds(user.ID))
 
 	html.OK(w, r, view.Render("feeds"))
 }

+ 1 - 0
ui/feed_update.go

@@ -61,6 +61,7 @@ func (c *Controller) UpdateFeed(w http.ResponseWriter, r *http.Request) {
 	view.Set("menu", "feeds")
 	view.Set("user", user)
 	view.Set("countUnread", c.store.CountUnreadEntries(user.ID))
+	view.Set("countErrorFeeds", c.store.CountErrorFeeds(user.ID))
 
 	if err := feedForm.ValidateModification(); err != nil {
 		view.Set("errorMessage", err.Error())

+ 1 - 0
ui/history_entries.go

@@ -54,6 +54,7 @@ func (c *Controller) ShowHistoryPage(w http.ResponseWriter, r *http.Request) {
 	view.Set("menu", "history")
 	view.Set("user", user)
 	view.Set("countUnread", c.store.CountUnreadEntries(user.ID))
+	view.Set("countErrorFeeds", c.store.CountErrorFeeds(user.ID))
 	view.Set("hasSaveEntry", c.store.HasSaveEntry(user.ID))
 
 	html.OK(w, r, view.Render("history_entries"))

+ 1 - 0
ui/integration_show.go

@@ -61,6 +61,7 @@ func (c *Controller) ShowIntegrations(w http.ResponseWriter, r *http.Request) {
 	view.Set("menu", "settings")
 	view.Set("user", user)
 	view.Set("countUnread", c.store.CountUnreadEntries(user.ID))
+	view.Set("countErrorFeeds", c.store.CountErrorFeeds(user.ID))
 	view.Set("hasPocketConsumerKeyConfigured", c.cfg.PocketConsumerKey("") != "")
 
 	html.OK(w, r, view.Render("integrations"))

+ 1 - 0
ui/opml_import.go

@@ -28,6 +28,7 @@ func (c *Controller) Import(w http.ResponseWriter, r *http.Request) {
 	view.Set("menu", "feeds")
 	view.Set("user", user)
 	view.Set("countUnread", c.store.CountUnreadEntries(user.ID))
+	view.Set("countErrorFeeds", c.store.CountErrorFeeds(user.ID))
 
 	html.OK(w, r, view.Render("import"))
 }

+ 1 - 0
ui/opml_upload.go

@@ -47,6 +47,7 @@ func (c *Controller) UploadOPML(w http.ResponseWriter, r *http.Request) {
 	view.Set("menu", "feeds")
 	view.Set("user", user)
 	view.Set("countUnread", c.store.CountUnreadEntries(user.ID))
+	view.Set("countErrorFeeds", c.store.CountErrorFeeds(user.ID))
 
 	if fileHeader.Size == 0 {
 		view.Set("errorMessage", "This file is empty")

+ 1 - 0
ui/search_entries.go

@@ -60,6 +60,7 @@ func (c *Controller) ShowSearchEntries(w http.ResponseWriter, r *http.Request) {
 	view.Set("menu", "search")
 	view.Set("user", user)
 	view.Set("countUnread", c.store.CountUnreadEntries(user.ID))
+	view.Set("countErrorFeeds", c.store.CountErrorFeeds(user.ID))
 	view.Set("hasSaveEntry", c.store.HasSaveEntry(user.ID))
 
 	html.OK(w, r, view.Render("search_entries"))

+ 1 - 0
ui/session_list.go

@@ -39,6 +39,7 @@ func (c *Controller) ShowSessions(w http.ResponseWriter, r *http.Request) {
 	view.Set("menu", "settings")
 	view.Set("user", user)
 	view.Set("countUnread", c.store.CountUnreadEntries(user.ID))
+	view.Set("countErrorFeeds", c.store.CountErrorFeeds(user.ID))
 
 	html.OK(w, r, view.Render("sessions"))
 }

+ 1 - 0
ui/settings_show.go

@@ -49,6 +49,7 @@ func (c *Controller) ShowSettings(w http.ResponseWriter, r *http.Request) {
 	view.Set("menu", "settings")
 	view.Set("user", user)
 	view.Set("countUnread", c.store.CountUnreadEntries(user.ID))
+	view.Set("countErrorFeeds", c.store.CountErrorFeeds(user.ID))
 
 	html.OK(w, r, view.Render("settings"))
 }

+ 1 - 0
ui/settings_update.go

@@ -46,6 +46,7 @@ func (c *Controller) UpdateSettings(w http.ResponseWriter, r *http.Request) {
 	view.Set("menu", "settings")
 	view.Set("user", user)
 	view.Set("countUnread", c.store.CountUnreadEntries(user.ID))
+	view.Set("countErrorFeeds", c.store.CountErrorFeeds(user.ID))
 
 	if err := settingsForm.Validate(); err != nil {
 		view.Set("errorMessage", err.Error())

File diff suppressed because it is too large
+ 0 - 0
ui/static/css.go


+ 3 - 2
ui/static/css/black.css

@@ -125,8 +125,9 @@ input[type="text"]:focus {
     color: #9b9b9b;
 }
 
-/* Counter */
-.unread-counter-wrapper {
+/* Counters */
+.unread-counter-wrapper,
+.error-feeds-counter-wrapper {
     color: #bbb;
 }
 

+ 3 - 2
ui/static/css/common.css

@@ -467,8 +467,9 @@ a.button {
     max-width: 280px;
 }
 
-/* Counter */
-.unread-counter-wrapper {
+/* Counters */
+.unread-counter-wrapper,
+.error-feeds-counter-wrapper {
     font-size: 0.9em;
     font-weight: 300;
     color: #666;

+ 1 - 0
ui/subscription_add.go

@@ -35,6 +35,7 @@ func (c *Controller) AddSubscription(w http.ResponseWriter, r *http.Request) {
 	view.Set("menu", "feeds")
 	view.Set("user", user)
 	view.Set("countUnread", c.store.CountUnreadEntries(user.ID))
+	view.Set("countErrorFeeds", c.store.CountErrorFeeds(user.ID))
 
 	html.OK(w, r, view.Render("add_subscription"))
 }

+ 1 - 0
ui/subscription_bookmarklet.go

@@ -40,6 +40,7 @@ func (c *Controller) Bookmarklet(w http.ResponseWriter, r *http.Request) {
 	view.Set("menu", "feeds")
 	view.Set("user", user)
 	view.Set("countUnread", c.store.CountUnreadEntries(user.ID))
+	view.Set("countErrorFeeds", c.store.CountErrorFeeds(user.ID))
 
 	html.OK(w, r, view.Render("add_subscription"))
 }

+ 1 - 0
ui/subscription_choose.go

@@ -38,6 +38,7 @@ func (c *Controller) ChooseSubscription(w http.ResponseWriter, r *http.Request)
 	view.Set("menu", "feeds")
 	view.Set("user", user)
 	view.Set("countUnread", c.store.CountUnreadEntries(user.ID))
+	view.Set("countErrorFeeds", c.store.CountErrorFeeds(user.ID))
 
 	subscriptionForm := form.NewSubscriptionForm(r)
 	if err := subscriptionForm.Validate(); err != nil {

+ 2 - 0
ui/subscription_submit.go

@@ -40,6 +40,7 @@ func (c *Controller) SubmitSubscription(w http.ResponseWriter, r *http.Request)
 	v.Set("menu", "feeds")
 	v.Set("user", user)
 	v.Set("countUnread", c.store.CountUnreadEntries(user.ID))
+	v.Set("countErrorFeeds", c.store.CountErrorFeeds(user.ID))
 
 	subscriptionForm := form.NewSubscriptionForm(r)
 	if err := subscriptionForm.Validate(); err != nil {
@@ -94,6 +95,7 @@ func (c *Controller) SubmitSubscription(w http.ResponseWriter, r *http.Request)
 		v.Set("menu", "feeds")
 		v.Set("user", user)
 		v.Set("countUnread", c.store.CountUnreadEntries(user.ID))
+		v.Set("countErrorFeeds", c.store.CountErrorFeeds(user.ID))
 
 		html.OK(w, r, v.Render("choose_subscription"))
 	}

+ 1 - 0
ui/unread_entries.go

@@ -58,6 +58,7 @@ func (c *Controller) ShowUnreadPage(w http.ResponseWriter, r *http.Request) {
 	view.Set("menu", "unread")
 	view.Set("user", user)
 	view.Set("countUnread", countUnread)
+	view.Set("countErrorFeeds", c.store.CountErrorFeeds(user.ID))
 	view.Set("hasSaveEntry", c.store.HasSaveEntry(user.ID))
 
 	html.OK(w, r, view.Render("unread_entries"))

+ 1 - 0
ui/user_create.go

@@ -35,6 +35,7 @@ func (c *Controller) CreateUser(w http.ResponseWriter, r *http.Request) {
 	view.Set("menu", "settings")
 	view.Set("user", user)
 	view.Set("countUnread", c.store.CountUnreadEntries(user.ID))
+	view.Set("countErrorFeeds", c.store.CountErrorFeeds(user.ID))
 
 	html.OK(w, r, view.Render("create_user"))
 }

+ 1 - 0
ui/user_edit.go

@@ -59,6 +59,7 @@ func (c *Controller) EditUser(w http.ResponseWriter, r *http.Request) {
 	view.Set("menu", "settings")
 	view.Set("user", user)
 	view.Set("countUnread", c.store.CountUnreadEntries(user.ID))
+	view.Set("countErrorFeeds", c.store.CountErrorFeeds(user.ID))
 
 	html.OK(w, r, view.Render("edit_user"))
 }

+ 1 - 0
ui/user_list.go

@@ -42,6 +42,7 @@ func (c *Controller) ShowUsers(w http.ResponseWriter, r *http.Request) {
 	view.Set("menu", "settings")
 	view.Set("user", user)
 	view.Set("countUnread", c.store.CountUnreadEntries(user.ID))
+	view.Set("countErrorFeeds", c.store.CountErrorFeeds(user.ID))
 
 	html.OK(w, r, view.Render("users"))
 }

+ 1 - 0
ui/user_save.go

@@ -39,6 +39,7 @@ func (c *Controller) SaveUser(w http.ResponseWriter, r *http.Request) {
 	view.Set("menu", "settings")
 	view.Set("user", user)
 	view.Set("countUnread", c.store.CountUnreadEntries(user.ID))
+	view.Set("countErrorFeeds", c.store.CountErrorFeeds(user.ID))
 	view.Set("form", userForm)
 
 	if err := userForm.ValidateCreation(); err != nil {

+ 1 - 0
ui/user_update.go

@@ -57,6 +57,7 @@ func (c *Controller) UpdateUser(w http.ResponseWriter, r *http.Request) {
 	view.Set("menu", "settings")
 	view.Set("user", user)
 	view.Set("countUnread", c.store.CountUnreadEntries(user.ID))
+	view.Set("countErrorFeeds", c.store.CountErrorFeeds(user.ID))
 	view.Set("selected_user", selectedUser)
 	view.Set("form", userForm)
 

Some files were not shown because too many files changed in this diff