aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--server/ui/controller/category.go8
-rw-r--r--server/ui/controller/entry.go17
-rw-r--r--server/ui/controller/feed.go12
-rw-r--r--server/ui/controller/unread.go1
-rw-r--r--storage/entry_query_builder.go53
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,