From 36dab8b5182215d53512525991cc23523bdf23dc Mon Sep 17 00:00:00 2001 From: Frédéric Guillot Date: Sat, 9 Jun 2018 19:13:41 -0700 Subject: Add more filters for API call /entries New filters: - before (unix timestamp) - before_entry_id - after - after_entry_id - starred (boolean) --- Gopkg.lock | 2 +- api/entry.go | 30 ++++++++++++++++++++++ fever/fever.go | 10 ++++---- http/request/request.go | 19 ++++++++++---- integration_test.go | 20 ++++++++++++++- vendor/github.com/miniflux/miniflux-go/client.go | 20 +++++++++++++++ vendor/github.com/miniflux/miniflux-go/miniflux.go | 15 +++++++---- 7 files changed, 99 insertions(+), 17 deletions(-) diff --git a/Gopkg.lock b/Gopkg.lock index 398956e..ca51c39 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -45,7 +45,7 @@ branch = "master" name = "github.com/miniflux/miniflux-go" packages = ["."] - revision = "8863d558cbf1f20beeb640328829205971f1a632" + revision = "ec30672607d4dd72470f4c156bd36ba07d9a9a2a" [[projects]] name = "github.com/tdewolff/minify" diff --git a/api/entry.go b/api/entry.go index 390f9ec..6d1167b 100644 --- a/api/entry.go +++ b/api/entry.go @@ -7,11 +7,13 @@ package api import ( "errors" "net/http" + "time" "github.com/miniflux/miniflux/http/context" "github.com/miniflux/miniflux/http/request" "github.com/miniflux/miniflux/http/response/json" "github.com/miniflux/miniflux/model" + "github.com/miniflux/miniflux/storage" ) // GetFeedEntry is the API handler to get a single feed entry. @@ -116,6 +118,7 @@ func (c *Controller) GetFeedEntries(w http.ResponseWriter, r *http.Request) { builder.WithDirection(direction) builder.WithOffset(offset) builder.WithLimit(limit) + configureFilters(builder, r) entries, err := builder.GetEntries() if err != nil { @@ -167,6 +170,7 @@ func (c *Controller) GetEntries(w http.ResponseWriter, r *http.Request) { builder.WithDirection(direction) builder.WithOffset(offset) builder.WithLimit(limit) + configureFilters(builder, r) entries, err := builder.GetEntries() if err != nil { @@ -219,3 +223,29 @@ func (c *Controller) ToggleBookmark(w http.ResponseWriter, r *http.Request) { json.NoContent(w) } + +func configureFilters(builder *storage.EntryQueryBuilder, r *http.Request) { + beforeEntryID := request.QueryInt64Param(r, "before_entry_id", 0) + if beforeEntryID != 0 { + builder.BeforeEntryID(beforeEntryID) + } + + afterEntryID := request.QueryInt64Param(r, "after_entry_id", 0) + if afterEntryID != 0 { + builder.AfterEntryID(afterEntryID) + } + + beforeTimestamp := request.QueryInt64Param(r, "before", 0) + if beforeTimestamp != 0 { + builder.BeforeDate(time.Unix(beforeTimestamp, 0)) + } + + afterTimestamp := request.QueryInt64Param(r, "after", 0) + if afterTimestamp != 0 { + builder.AfterDate(time.Unix(afterTimestamp, 0)) + } + + if request.HasQueryParam(r, "starred") { + builder.WithStarred() + } +} diff --git a/fever/fever.go b/fever/fever.go index 6986353..9fb6bdb 100644 --- a/fever/fever.go +++ b/fever/fever.go @@ -490,7 +490,7 @@ func (c *Controller) handleWriteItems(w http.ResponseWriter, r *http.Request) { userID := ctx.UserID() logger.Debug("[Fever] Receiving mark=item call for userID=%d", userID) - entryID := request.FormIntValue(r, "id") + entryID := request.FormInt64Value(r, "id") if entryID <= 0 { return } @@ -548,7 +548,7 @@ func (c *Controller) handleWriteFeeds(w http.ResponseWriter, r *http.Request) { userID := ctx.UserID() logger.Debug("[Fever] Receiving mark=feed call for userID=%d", userID) - feedID := request.FormIntValue(r, "id") + feedID := request.FormInt64Value(r, "id") if feedID <= 0 { return } @@ -557,7 +557,7 @@ func (c *Controller) handleWriteFeeds(w http.ResponseWriter, r *http.Request) { builder.WithStatus(model.EntryStatusUnread) builder.WithFeedID(feedID) - before := request.FormIntValue(r, "before") + before := request.FormInt64Value(r, "before") if before > 0 { t := time.Unix(before, 0) builder.BeforeDate(t) @@ -589,7 +589,7 @@ func (c *Controller) handleWriteGroups(w http.ResponseWriter, r *http.Request) { userID := ctx.UserID() logger.Debug("[Fever] Receiving mark=group call for userID=%d", userID) - groupID := request.FormIntValue(r, "id") + groupID := request.FormInt64Value(r, "id") if groupID < 0 { return } @@ -598,7 +598,7 @@ func (c *Controller) handleWriteGroups(w http.ResponseWriter, r *http.Request) { builder.WithStatus(model.EntryStatusUnread) builder.WithCategoryID(groupID) - before := request.FormIntValue(r, "before") + before := request.FormInt64Value(r, "before") if before > 0 { t := time.Unix(before, 0) builder.BeforeDate(t) diff --git a/http/request/request.go b/http/request/request.go index 1de6f73..cc5a4dd 100644 --- a/http/request/request.go +++ b/http/request/request.go @@ -24,11 +24,15 @@ func Cookie(r *http.Request, name string) string { return cookie.Value } -// FormIntValue returns a form value as integer. -func FormIntValue(r *http.Request, param string) int64 { +// FormInt64Value returns a form value as integer. +func FormInt64Value(r *http.Request, param string) int64 { value := r.FormValue(param) - integer, _ := strconv.Atoi(value) - return int64(integer) + integer, err := strconv.ParseInt(value, 10, 64) + if err != nil { + return 0 + } + + return integer } // IntParam returns an URL route parameter as integer. @@ -67,12 +71,17 @@ func QueryParam(r *http.Request, param, defaultValue string) string { // QueryIntParam returns a querystring parameter as integer. func QueryIntParam(r *http.Request, param string, defaultValue int) int { + return int(QueryInt64Param(r, param, int64(defaultValue))) +} + +// QueryInt64Param returns a querystring parameter as int64. +func QueryInt64Param(r *http.Request, param string, defaultValue int64) int64 { value := r.URL.Query().Get(param) if value == "" { return defaultValue } - val, err := strconv.Atoi(value) + val, err := strconv.ParseInt(value, 10, 64) if err != nil { return defaultValue } diff --git a/integration_test.go b/integration_test.go index a26fe57..40505ee 100644 --- a/integration_test.go +++ b/integration_test.go @@ -986,7 +986,16 @@ func TestGetAllFeedEntries(t *testing.T) { } if allResults.Entries[0].ID == filteredResults.Entries[0].ID { - t.Fatal(`Filtered entries should be different than previous result`) + t.Fatal(`Filtered entries should be different than previous results`) + } + + filteredResultsByEntryID, err := client.FeedEntries(feedID, &miniflux.Filter{BeforeEntryID: allResults.Entries[0].ID}) + if err != nil { + t.Fatal(err) + } + + if filteredResultsByEntryID.Entries[0].ID == allResults.Entries[0].ID { + t.Fatal(`The first entry should filtered out`) } } @@ -1035,6 +1044,15 @@ func TestGetAllEntries(t *testing.T) { if resultWithDifferentSorting.Entries[0].Title == resultWithoutSorting.Entries[0].Title { t.Fatalf(`The items should be sorted differently "%v" vs "%v"`, resultWithDifferentSorting.Entries[0].Title, resultWithoutSorting.Entries[0].Title) } + + resultWithStarredEntries, err := client.Entries(&miniflux.Filter{Starred: true}) + if err != nil { + t.Fatal(err) + } + + if resultWithStarredEntries.Total != 0 { + t.Fatalf(`We are not supposed to have starred entries yet`) + } } func TestInvalidFilters(t *testing.T) { diff --git a/vendor/github.com/miniflux/miniflux-go/client.go b/vendor/github.com/miniflux/miniflux-go/client.go index 5f5155d..efc2a03 100644 --- a/vendor/github.com/miniflux/miniflux-go/client.go +++ b/vendor/github.com/miniflux/miniflux-go/client.go @@ -477,6 +477,26 @@ func buildFilterQueryString(path string, filter *Filter) string { values.Set("offset", strconv.Itoa(filter.Offset)) } + if filter.After > 0 { + values.Set("after", strconv.FormatInt(filter.After, 10)) + } + + if filter.AfterEntryID > 0 { + values.Set("after_entry_id", strconv.FormatInt(filter.AfterEntryID, 10)) + } + + if filter.Before > 0 { + values.Set("before", strconv.FormatInt(filter.Before, 10)) + } + + if filter.BeforeEntryID > 0 { + values.Set("before_entry_id", strconv.FormatInt(filter.BeforeEntryID, 10)) + } + + if filter.Starred { + values.Set("starred", "1") + } + path = fmt.Sprintf("%s?%s", path, values.Encode()) } diff --git a/vendor/github.com/miniflux/miniflux-go/miniflux.go b/vendor/github.com/miniflux/miniflux-go/miniflux.go index 08db2f9..9d08a65 100644 --- a/vendor/github.com/miniflux/miniflux-go/miniflux.go +++ b/vendor/github.com/miniflux/miniflux-go/miniflux.go @@ -127,11 +127,16 @@ type Enclosures []*Enclosure // Filter is used to filter entries. type Filter struct { - Status string - Offset int - Limit int - Order string - Direction string + Status string + Offset int + Limit int + Order string + Direction string + Starred bool + Before int64 + After int64 + BeforeEntryID int64 + AfterEntryID int64 } // EntryResultSet represents the response when fetching entries. -- cgit v1.2.3