diff options
-rw-r--r-- | server/ui/controller/category.go | 8 | ||||
-rw-r--r-- | server/ui/controller/entry.go | 17 | ||||
-rw-r--r-- | server/ui/controller/feed.go | 12 | ||||
-rw-r--r-- | server/ui/controller/unread.go | 1 | ||||
-rw-r--r-- | storage/entry_query_builder.go | 53 |
5 files changed, 62 insertions, 29 deletions
diff --git a/server/ui/controller/category.go b/server/ui/controller/category.go index 48c77c3..a32b83a 100644 --- a/server/ui/controller/category.go +++ b/server/ui/controller/category.go @@ -13,6 +13,7 @@ import ( "github.com/miniflux/miniflux2/server/ui/form" ) +// ShowCategories shows the page with all categories. func (c *Controller) ShowCategories(ctx *core.Context, request *core.Request, response *core.Response) { args, err := c.getCommonTemplateArgs(ctx) if err != nil { @@ -34,6 +35,7 @@ func (c *Controller) ShowCategories(ctx *core.Context, request *core.Request, re })) } +// ShowCategoryEntries shows all entries for the given category. func (c *Controller) ShowCategoryEntries(ctx *core.Context, request *core.Request, response *core.Response) { user := ctx.GetLoggedUser() offset := request.GetQueryIntegerParam("offset", 0) @@ -53,6 +55,7 @@ func (c *Controller) ShowCategoryEntries(ctx *core.Context, request *core.Reques builder.WithCategoryID(category.ID) builder.WithOrder(model.DefaultSortingOrder) builder.WithDirection(model.DefaultSortingDirection) + builder.WithoutStatus(model.EntryStatusRemoved) builder.WithOffset(offset) builder.WithLimit(NbItemsPerPage) @@ -77,6 +80,7 @@ func (c *Controller) ShowCategoryEntries(ctx *core.Context, request *core.Reques })) } +// CreateCategory shows the form to create a new category. func (c *Controller) CreateCategory(ctx *core.Context, request *core.Request, response *core.Response) { args, err := c.getCommonTemplateArgs(ctx) if err != nil { @@ -89,6 +93,7 @@ func (c *Controller) CreateCategory(ctx *core.Context, request *core.Request, re })) } +// SaveCategory validate and save the new category into the database. func (c *Controller) SaveCategory(ctx *core.Context, request *core.Request, response *core.Response) { user := ctx.GetLoggedUser() args, err := c.getCommonTemplateArgs(ctx) @@ -131,6 +136,7 @@ func (c *Controller) SaveCategory(ctx *core.Context, request *core.Request, resp response.Redirect(ctx.GetRoute("categories")) } +// EditCategory shows the form to modify a category. func (c *Controller) EditCategory(ctx *core.Context, request *core.Request, response *core.Response) { user := ctx.GetLoggedUser() @@ -149,6 +155,7 @@ func (c *Controller) EditCategory(ctx *core.Context, request *core.Request, resp response.Html().Render("edit_category", args) } +// UpdateCategory validate and update a category. func (c *Controller) UpdateCategory(ctx *core.Context, request *core.Request, response *core.Response) { user := ctx.GetLoggedUser() @@ -191,6 +198,7 @@ func (c *Controller) UpdateCategory(ctx *core.Context, request *core.Request, re response.Redirect(ctx.GetRoute("categories")) } +// RemoveCategory delete a category from the database. func (c *Controller) RemoveCategory(ctx *core.Context, request *core.Request, response *core.Response) { user := ctx.GetLoggedUser() diff --git a/server/ui/controller/entry.go b/server/ui/controller/entry.go index c4ca587..82a13ad 100644 --- a/server/ui/controller/entry.go +++ b/server/ui/controller/entry.go @@ -33,6 +33,7 @@ func (c *Controller) ShowFeedEntry(ctx *core.Context, request *core.Request, res builder := c.store.GetEntryQueryBuilder(user.ID, user.Timezone) builder.WithFeedID(feedID) builder.WithEntryID(entryID) + builder.WithoutStatus(model.EntryStatusRemoved) entry, err := builder.GetEntry() if err != nil { @@ -52,6 +53,7 @@ func (c *Controller) ShowFeedEntry(ctx *core.Context, request *core.Request, res } builder = c.store.GetEntryQueryBuilder(user.ID, user.Timezone) + builder.WithoutStatus(model.EntryStatusRemoved) builder.WithFeedID(feedID) builder.WithCondition("e.id", "!=", entryID) builder.WithCondition("e.published_at", "<=", entry.Date) @@ -64,6 +66,7 @@ func (c *Controller) ShowFeedEntry(ctx *core.Context, request *core.Request, res } builder = c.store.GetEntryQueryBuilder(user.ID, user.Timezone) + builder.WithoutStatus(model.EntryStatusRemoved) builder.WithFeedID(feedID) builder.WithCondition("e.id", "!=", entryID) builder.WithCondition("e.published_at", ">=", entry.Date) @@ -88,8 +91,7 @@ func (c *Controller) ShowFeedEntry(ctx *core.Context, request *core.Request, res if entry.Status == model.EntryStatusUnread { err = c.store.SetEntriesStatus(user.ID, []int64{entry.ID}, model.EntryStatusRead) if err != nil { - log.Println(err) - response.Html().ServerError(nil) + response.Html().ServerError(err) return } } @@ -124,6 +126,7 @@ func (c *Controller) ShowCategoryEntry(ctx *core.Context, request *core.Request, builder := c.store.GetEntryQueryBuilder(user.ID, user.Timezone) builder.WithCategoryID(categoryID) builder.WithEntryID(entryID) + builder.WithoutStatus(model.EntryStatusRemoved) entry, err := builder.GetEntry() if err != nil { @@ -143,6 +146,7 @@ func (c *Controller) ShowCategoryEntry(ctx *core.Context, request *core.Request, } builder = c.store.GetEntryQueryBuilder(user.ID, user.Timezone) + builder.WithoutStatus(model.EntryStatusRemoved) builder.WithCategoryID(categoryID) builder.WithCondition("e.id", "!=", entryID) builder.WithCondition("e.published_at", "<=", entry.Date) @@ -155,6 +159,7 @@ func (c *Controller) ShowCategoryEntry(ctx *core.Context, request *core.Request, } builder = c.store.GetEntryQueryBuilder(user.ID, user.Timezone) + builder.WithoutStatus(model.EntryStatusRemoved) builder.WithCategoryID(categoryID) builder.WithCondition("e.id", "!=", entryID) builder.WithCondition("e.published_at", ">=", entry.Date) @@ -208,6 +213,7 @@ func (c *Controller) ShowUnreadEntry(ctx *core.Context, request *core.Request, r builder := c.store.GetEntryQueryBuilder(user.ID, user.Timezone) builder.WithEntryID(entryID) + builder.WithoutStatus(model.EntryStatusRemoved) entry, err := builder.GetEntry() if err != nil { @@ -227,6 +233,7 @@ func (c *Controller) ShowUnreadEntry(ctx *core.Context, request *core.Request, r } builder = c.store.GetEntryQueryBuilder(user.ID, user.Timezone) + builder.WithoutStatus(model.EntryStatusRemoved) builder.WithStatus(model.EntryStatusUnread) builder.WithCondition("e.id", "!=", entryID) builder.WithCondition("e.published_at", "<=", entry.Date) @@ -239,6 +246,7 @@ func (c *Controller) ShowUnreadEntry(ctx *core.Context, request *core.Request, r } builder = c.store.GetEntryQueryBuilder(user.ID, user.Timezone) + builder.WithoutStatus(model.EntryStatusRemoved) builder.WithStatus(model.EntryStatusUnread) builder.WithCondition("e.id", "!=", entryID) builder.WithCondition("e.published_at", ">=", entry.Date) @@ -292,6 +300,7 @@ func (c *Controller) ShowReadEntry(ctx *core.Context, request *core.Request, res builder := c.store.GetEntryQueryBuilder(user.ID, user.Timezone) builder.WithEntryID(entryID) + builder.WithoutStatus(model.EntryStatusRemoved) entry, err := builder.GetEntry() if err != nil { @@ -311,6 +320,7 @@ func (c *Controller) ShowReadEntry(ctx *core.Context, request *core.Request, res } builder = c.store.GetEntryQueryBuilder(user.ID, user.Timezone) + builder.WithoutStatus(model.EntryStatusRemoved) builder.WithStatus(model.EntryStatusRead) builder.WithCondition("e.id", "!=", entryID) builder.WithCondition("e.published_at", "<=", entry.Date) @@ -323,6 +333,7 @@ func (c *Controller) ShowReadEntry(ctx *core.Context, request *core.Request, res } builder = c.store.GetEntryQueryBuilder(user.ID, user.Timezone) + builder.WithoutStatus(model.EntryStatusRemoved) builder.WithStatus(model.EntryStatusRead) builder.WithCondition("e.id", "!=", entryID) builder.WithCondition("e.published_at", ">=", entry.Date) @@ -354,7 +365,7 @@ func (c *Controller) ShowReadEntry(ctx *core.Context, request *core.Request, res })) } -// UpdateEntriesStatus handles Ajax request to update a list of entries. +// UpdateEntriesStatus handles Ajax request to update the status for a list of entries. func (c *Controller) UpdateEntriesStatus(ctx *core.Context, request *core.Request, response *core.Response) { user := ctx.GetLoggedUser() diff --git a/server/ui/controller/feed.go b/server/ui/controller/feed.go index 400f81a..1ed3668 100644 --- a/server/ui/controller/feed.go +++ b/server/ui/controller/feed.go @@ -6,12 +6,14 @@ package controller import ( "errors" + "log" + "github.com/miniflux/miniflux2/model" "github.com/miniflux/miniflux2/server/core" "github.com/miniflux/miniflux2/server/ui/form" - "log" ) +// ShowFeedsPage shows the page with all subscriptions. func (c *Controller) ShowFeedsPage(ctx *core.Context, request *core.Request, response *core.Response) { user := ctx.GetLoggedUser() @@ -34,6 +36,7 @@ func (c *Controller) ShowFeedsPage(ctx *core.Context, request *core.Request, res })) } +// ShowFeedEntries shows all entries for the given feed. func (c *Controller) ShowFeedEntries(ctx *core.Context, request *core.Request, response *core.Response) { user := ctx.GetLoggedUser() offset := request.GetQueryIntegerParam("offset", 0) @@ -51,6 +54,7 @@ func (c *Controller) ShowFeedEntries(ctx *core.Context, request *core.Request, r builder := c.store.GetEntryQueryBuilder(user.ID, user.Timezone) builder.WithFeedID(feed.ID) + builder.WithoutStatus(model.EntryStatusRemoved) builder.WithOrder(model.DefaultSortingOrder) builder.WithDirection(model.DefaultSortingDirection) builder.WithOffset(offset) @@ -77,6 +81,7 @@ func (c *Controller) ShowFeedEntries(ctx *core.Context, request *core.Request, r })) } +// EditFeed shows the form to modify a subscription. func (c *Controller) EditFeed(ctx *core.Context, request *core.Request, response *core.Response) { user := ctx.GetLoggedUser() @@ -94,6 +99,7 @@ func (c *Controller) EditFeed(ctx *core.Context, request *core.Request, response response.Html().Render("edit_feed", args) } +// UpdateFeed update a subscription and redirect to the feed entries page. func (c *Controller) UpdateFeed(ctx *core.Context, request *core.Request, response *core.Response) { user := ctx.GetLoggedUser() @@ -125,9 +131,10 @@ func (c *Controller) UpdateFeed(ctx *core.Context, request *core.Request, respon return } - response.Redirect(ctx.GetRoute("feeds")) + response.Redirect(ctx.GetRoute("feedEntries", "feedID", feed.ID)) } +// RemoveFeed delete a subscription from the database and redirect to the list of feeds page. func (c *Controller) RemoveFeed(ctx *core.Context, request *core.Request, response *core.Response) { feedID, err := request.GetIntegerParam("feedID") if err != nil { @@ -144,6 +151,7 @@ func (c *Controller) RemoveFeed(ctx *core.Context, request *core.Request, respon response.Redirect(ctx.GetRoute("feeds")) } +// RefreshFeed refresh a subscription and redirect to the feed entries page. func (c *Controller) RefreshFeed(ctx *core.Context, request *core.Request, response *core.Response) { feedID, err := request.GetIntegerParam("feedID") if err != nil { diff --git a/server/ui/controller/unread.go b/server/ui/controller/unread.go index 63d7db0..16728e8 100644 --- a/server/ui/controller/unread.go +++ b/server/ui/controller/unread.go @@ -9,6 +9,7 @@ import ( "github.com/miniflux/miniflux2/server/core" ) +// ShowUnreadPage render the page with all unread entries. func (c *Controller) ShowUnreadPage(ctx *core.Context, request *core.Request, response *core.Response) { user := ctx.GetLoggedUser() offset := request.GetQueryIntegerParam("offset", 0) diff --git a/storage/entry_query_builder.go b/storage/entry_query_builder.go index 0c210c3..2c2f270 100644 --- a/storage/entry_query_builder.go +++ b/storage/entry_query_builder.go @@ -6,12 +6,14 @@ package storage import ( "fmt" - "github.com/miniflux/miniflux2/helper" - "github.com/miniflux/miniflux2/model" "strings" "time" + + "github.com/miniflux/miniflux2/helper" + "github.com/miniflux/miniflux2/model" ) +// EntryQueryBuilder builds a SQL query to fetch entries. type EntryQueryBuilder struct { store *Storage feedID int64 @@ -19,73 +21,78 @@ type EntryQueryBuilder struct { timezone string categoryID int64 status string + notStatus string order string direction string limit int offset int entryID int64 - gtEntryID int64 - ltEntryID int64 conditions []string args []interface{} } +// WithCondition defines a new condition. func (e *EntryQueryBuilder) WithCondition(column, operator string, value interface{}) *EntryQueryBuilder { e.args = append(e.args, value) e.conditions = append(e.conditions, fmt.Sprintf("%s %s $%d", column, operator, len(e.args)+1)) return e } +// WithEntryID set the entryID. func (e *EntryQueryBuilder) WithEntryID(entryID int64) *EntryQueryBuilder { e.entryID = entryID return e } -func (e *EntryQueryBuilder) WithEntryIDGreaterThan(entryID int64) *EntryQueryBuilder { - e.gtEntryID = entryID - return e -} - -func (e *EntryQueryBuilder) WithEntryIDLowerThan(entryID int64) *EntryQueryBuilder { - e.ltEntryID = entryID - return e -} - +// WithFeedID set the feedID. func (e *EntryQueryBuilder) WithFeedID(feedID int64) *EntryQueryBuilder { e.feedID = feedID return e } +// WithCategoryID set the categoryID. func (e *EntryQueryBuilder) WithCategoryID(categoryID int64) *EntryQueryBuilder { e.categoryID = categoryID return e } +// WithStatus set the entry status. func (e *EntryQueryBuilder) WithStatus(status string) *EntryQueryBuilder { e.status = status return e } +// WithoutStatus set the entry status that should not be returned. +func (e *EntryQueryBuilder) WithoutStatus(status string) *EntryQueryBuilder { + e.notStatus = status + return e +} + +// WithOrder set the sorting order. func (e *EntryQueryBuilder) WithOrder(order string) *EntryQueryBuilder { e.order = order return e } +// WithDirection set the sorting direction. func (e *EntryQueryBuilder) WithDirection(direction string) *EntryQueryBuilder { e.direction = direction return e } +// WithLimit set the limit. func (e *EntryQueryBuilder) WithLimit(limit int) *EntryQueryBuilder { e.limit = limit return e } +// WithOffset set the offset. func (e *EntryQueryBuilder) WithOffset(offset int) *EntryQueryBuilder { e.offset = offset return e } +// CountEntries count the number of entries that match the condition. func (e *EntryQueryBuilder) CountEntries() (count int, err error) { defer helper.ExecutionTime( time.Now(), @@ -102,6 +109,7 @@ func (e *EntryQueryBuilder) CountEntries() (count int, err error) { return count, nil } +// GetEntry returns a single entry that match the condition. func (e *EntryQueryBuilder) GetEntry() (*model.Entry, error) { e.limit = 1 entries, err := e.GetEntries() @@ -121,6 +129,7 @@ func (e *EntryQueryBuilder) GetEntry() (*model.Entry, error) { return entries[0], nil } +// GetEntries returns a list of entries that match the condition. func (e *EntryQueryBuilder) GetEntries() (model.Entries, error) { debugStr := "[EntryQueryBuilder:GetEntries] userID=%d, feedID=%d, categoryID=%d, status=%s, order=%s, direction=%s, offset=%d, limit=%d" defer helper.ExecutionTime(time.Now(), fmt.Sprintf(debugStr, e.userID, e.feedID, e.categoryID, e.status, e.order, e.direction, e.offset, e.limit)) @@ -219,21 +228,16 @@ func (e *EntryQueryBuilder) buildCondition() ([]interface{}, string) { args = append(args, e.entryID) } - if e.gtEntryID != 0 { - conditions = append(conditions, fmt.Sprintf("e.id > $%d", len(args)+1)) - args = append(args, e.gtEntryID) - } - - if e.ltEntryID != 0 { - conditions = append(conditions, fmt.Sprintf("e.id < $%d", len(args)+1)) - args = append(args, e.ltEntryID) - } - if e.status != "" { conditions = append(conditions, fmt.Sprintf("e.status=$%d", len(args)+1)) args = append(args, e.status) } + if e.notStatus != "" { + conditions = append(conditions, fmt.Sprintf("e.status != $%d", len(args)+1)) + args = append(args, e.notStatus) + } + return args, strings.Join(conditions, " AND ") } @@ -259,6 +263,7 @@ func (e *EntryQueryBuilder) buildSorting() string { return strings.Join(queries, " ") } +// NewEntryQueryBuilder returns a new EntryQueryBuilder. func NewEntryQueryBuilder(store *Storage, userID int64, timezone string) *EntryQueryBuilder { return &EntryQueryBuilder{ store: store, |