mirror of https://github.com/miniflux/v2.git
Add support for the `continuation` parameter and result for Google Reader API ID calls
Support the ``continuation parameter and result for Google Reader API ID calls. Allows clients to support paging of results / fetching additional results when the number of entries exceed the limit parameter passed in by the client.
This commit is contained in:
parent
84d5a9a354
commit
74b69a4c7c
|
@ -88,8 +88,10 @@ const (
|
||||||
ParamTitle = "t"
|
ParamTitle = "t"
|
||||||
// ParamQuickAdd - name of the parameter for a URL being quick subscribed to
|
// ParamQuickAdd - name of the parameter for a URL being quick subscribed to
|
||||||
ParamQuickAdd = "quickadd"
|
ParamQuickAdd = "quickadd"
|
||||||
// ParamDestination - name fo the parameter for the new name of a tag
|
// ParamDestination - name of the parameter for the new name of a tag
|
||||||
ParamDestination = "dest"
|
ParamDestination = "dest"
|
||||||
|
// ParamContinuation - name of the parameter for callers to pass to receive the next page of results
|
||||||
|
ParamContinuation = "c"
|
||||||
)
|
)
|
||||||
|
|
||||||
// StreamType represents the possible stream types
|
// StreamType represents the possible stream types
|
||||||
|
@ -130,6 +132,7 @@ type RequestModifiers struct {
|
||||||
FilterTargets []Stream
|
FilterTargets []Stream
|
||||||
Streams []Stream
|
Streams []Stream
|
||||||
Count int
|
Count int
|
||||||
|
Offset int
|
||||||
SortDirection string
|
SortDirection string
|
||||||
StartTime int64
|
StartTime int64
|
||||||
StopTime int64
|
StopTime int64
|
||||||
|
@ -185,6 +188,7 @@ func (r RequestModifiers) String() string {
|
||||||
result += fmt.Sprintf(" %v\n", s)
|
result += fmt.Sprintf(" %v\n", s)
|
||||||
}
|
}
|
||||||
result += fmt.Sprintf("Count: %d\n", r.Count)
|
result += fmt.Sprintf("Count: %d\n", r.Count)
|
||||||
|
result += fmt.Sprintf("Offset: %d\n", r.Offset)
|
||||||
result += fmt.Sprintf("Sort Direction: %s\n", r.SortDirection)
|
result += fmt.Sprintf("Sort Direction: %s\n", r.SortDirection)
|
||||||
result += fmt.Sprintf("Continuation Token: %s\n", r.ContinuationToken)
|
result += fmt.Sprintf("Continuation Token: %s\n", r.ContinuationToken)
|
||||||
result += fmt.Sprintf("Start Time: %d\n", r.StartTime)
|
result += fmt.Sprintf("Start Time: %d\n", r.StartTime)
|
||||||
|
@ -243,8 +247,9 @@ func getStreamFilterModifiers(r *http.Request) (RequestModifiers, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
result.Count = request.QueryIntParam(r, ParamStreamMaxItems, 0)
|
result.Count = request.QueryIntParam(r, ParamStreamMaxItems, 0)
|
||||||
result.StartTime = int64(request.QueryIntParam(r, ParamStreamStartTime, 0))
|
result.Offset = request.QueryIntParam(r, ParamContinuation, 0)
|
||||||
result.StopTime = int64(request.QueryIntParam(r, ParamStreamStopTime, 0))
|
result.StartTime = request.QueryInt64Param(r, ParamStreamStartTime, int64(0))
|
||||||
|
result.StopTime = request.QueryInt64Param(r, ParamStreamStopTime, int64(0))
|
||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1120,7 +1125,9 @@ func (h *handler) handleReadingListStream(w http.ResponseWriter, r *http.Request
|
||||||
logger.Info("[GoogleReader][ReadingListStreamIDs][ClientIP=%s] xt filter type: %#v", clientIP, s)
|
logger.Info("[GoogleReader][ReadingListStreamIDs][ClientIP=%s] xt filter type: %#v", clientIP, s)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
builder.WithoutStatus(model.EntryStatusRemoved)
|
||||||
builder.WithLimit(rm.Count)
|
builder.WithLimit(rm.Count)
|
||||||
|
builder.WithOffset(rm.Offset)
|
||||||
builder.WithOrder(model.DefaultSortingOrder)
|
builder.WithOrder(model.DefaultSortingOrder)
|
||||||
builder.WithDirection(rm.SortDirection)
|
builder.WithDirection(rm.SortDirection)
|
||||||
if rm.StartTime > 0 {
|
if rm.StartTime > 0 {
|
||||||
|
@ -1141,15 +1148,29 @@ func (h *handler) handleReadingListStream(w http.ResponseWriter, r *http.Request
|
||||||
formattedID := strconv.FormatInt(entryID, 10)
|
formattedID := strconv.FormatInt(entryID, 10)
|
||||||
itemRefs = append(itemRefs, itemRef{ID: formattedID})
|
itemRefs = append(itemRefs, itemRef{ID: formattedID})
|
||||||
}
|
}
|
||||||
json.OK(w, r, streamIDResponse{itemRefs})
|
|
||||||
|
totalEntries, err := builder.CountEntries()
|
||||||
|
if err != nil {
|
||||||
|
logger.Error("[GoogleReader][/stream/items/ids#reading-list] [ClientIP=%s] %v", clientIP, err)
|
||||||
|
json.ServerError(w, r, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
continuation := 0
|
||||||
|
if len(itemRefs)+rm.Offset < totalEntries {
|
||||||
|
continuation = len(itemRefs) + rm.Offset
|
||||||
|
}
|
||||||
|
|
||||||
|
json.OK(w, r, streamIDResponse{itemRefs, continuation})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *handler) handleStarredStream(w http.ResponseWriter, r *http.Request, rm RequestModifiers) {
|
func (h *handler) handleStarredStream(w http.ResponseWriter, r *http.Request, rm RequestModifiers) {
|
||||||
clientIP := request.ClientIP(r)
|
clientIP := request.ClientIP(r)
|
||||||
|
|
||||||
builder := h.store.NewEntryQueryBuilder(rm.UserID)
|
builder := h.store.NewEntryQueryBuilder(rm.UserID)
|
||||||
|
builder.WithoutStatus(model.EntryStatusRemoved)
|
||||||
builder.WithStarred(true)
|
builder.WithStarred(true)
|
||||||
builder.WithLimit(rm.Count)
|
builder.WithLimit(rm.Count)
|
||||||
|
builder.WithOffset(rm.Offset)
|
||||||
builder.WithOrder(model.DefaultSortingOrder)
|
builder.WithOrder(model.DefaultSortingOrder)
|
||||||
builder.WithDirection(rm.SortDirection)
|
builder.WithDirection(rm.SortDirection)
|
||||||
if rm.StartTime > 0 {
|
if rm.StartTime > 0 {
|
||||||
|
@ -1170,14 +1191,29 @@ func (h *handler) handleStarredStream(w http.ResponseWriter, r *http.Request, rm
|
||||||
formattedID := strconv.FormatInt(entryID, 10)
|
formattedID := strconv.FormatInt(entryID, 10)
|
||||||
itemRefs = append(itemRefs, itemRef{ID: formattedID})
|
itemRefs = append(itemRefs, itemRef{ID: formattedID})
|
||||||
}
|
}
|
||||||
json.OK(w, r, streamIDResponse{itemRefs})
|
|
||||||
|
totalEntries, err := builder.CountEntries()
|
||||||
|
if err != nil {
|
||||||
|
logger.Error("[GoogleReader][/stream/items/ids#starred] [ClientIP=%s] %v", clientIP, err)
|
||||||
|
json.ServerError(w, r, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
continuation := 0
|
||||||
|
if len(itemRefs)+rm.Offset < totalEntries {
|
||||||
|
continuation = len(itemRefs) + rm.Offset
|
||||||
|
}
|
||||||
|
|
||||||
|
json.OK(w, r, streamIDResponse{itemRefs, continuation})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *handler) handleReadStream(w http.ResponseWriter, r *http.Request, rm RequestModifiers) {
|
func (h *handler) handleReadStream(w http.ResponseWriter, r *http.Request, rm RequestModifiers) {
|
||||||
clientIP := request.ClientIP(r)
|
clientIP := request.ClientIP(r)
|
||||||
|
|
||||||
builder := h.store.NewEntryQueryBuilder(rm.UserID)
|
builder := h.store.NewEntryQueryBuilder(rm.UserID)
|
||||||
|
builder.WithoutStatus(model.EntryStatusRemoved)
|
||||||
builder.WithStatus(model.EntryStatusRead)
|
builder.WithStatus(model.EntryStatusRead)
|
||||||
|
builder.WithLimit(rm.Count)
|
||||||
|
builder.WithOffset(rm.Offset)
|
||||||
builder.WithOrder(model.DefaultSortingOrder)
|
builder.WithOrder(model.DefaultSortingOrder)
|
||||||
builder.WithDirection(rm.SortDirection)
|
builder.WithDirection(rm.SortDirection)
|
||||||
if rm.StartTime > 0 {
|
if rm.StartTime > 0 {
|
||||||
|
@ -1198,7 +1234,19 @@ func (h *handler) handleReadStream(w http.ResponseWriter, r *http.Request, rm Re
|
||||||
formattedID := strconv.FormatInt(entryID, 10)
|
formattedID := strconv.FormatInt(entryID, 10)
|
||||||
itemRefs = append(itemRefs, itemRef{ID: formattedID})
|
itemRefs = append(itemRefs, itemRef{ID: formattedID})
|
||||||
}
|
}
|
||||||
json.OK(w, r, streamIDResponse{itemRefs})
|
|
||||||
|
totalEntries, err := builder.CountEntries()
|
||||||
|
if err != nil {
|
||||||
|
logger.Error("[GoogleReader][/stream/items/ids#read] [ClientIP=%s] %v", clientIP, err)
|
||||||
|
json.ServerError(w, r, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
continuation := 0
|
||||||
|
if len(itemRefs)+rm.Offset < totalEntries {
|
||||||
|
continuation = len(itemRefs) + rm.Offset
|
||||||
|
}
|
||||||
|
|
||||||
|
json.OK(w, r, streamIDResponse{itemRefs, continuation})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *handler) handleFeedStream(w http.ResponseWriter, r *http.Request, rm RequestModifiers) {
|
func (h *handler) handleFeedStream(w http.ResponseWriter, r *http.Request, rm RequestModifiers) {
|
||||||
|
@ -1211,8 +1259,10 @@ func (h *handler) handleFeedStream(w http.ResponseWriter, r *http.Request, rm Re
|
||||||
}
|
}
|
||||||
|
|
||||||
builder := h.store.NewEntryQueryBuilder(rm.UserID)
|
builder := h.store.NewEntryQueryBuilder(rm.UserID)
|
||||||
|
builder.WithoutStatus(model.EntryStatusRemoved)
|
||||||
builder.WithFeedID(feedID)
|
builder.WithFeedID(feedID)
|
||||||
builder.WithLimit(rm.Count)
|
builder.WithLimit(rm.Count)
|
||||||
|
builder.WithOffset(rm.Offset)
|
||||||
builder.WithOrder(model.DefaultSortingOrder)
|
builder.WithOrder(model.DefaultSortingOrder)
|
||||||
builder.WithDirection(rm.SortDirection)
|
builder.WithDirection(rm.SortDirection)
|
||||||
if rm.StartTime > 0 {
|
if rm.StartTime > 0 {
|
||||||
|
@ -1224,7 +1274,7 @@ func (h *handler) handleFeedStream(w http.ResponseWriter, r *http.Request, rm Re
|
||||||
|
|
||||||
rawEntryIDs, err := builder.GetEntryIDs()
|
rawEntryIDs, err := builder.GetEntryIDs()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Error("[GoogleReader][/stream/items/ids#starred] [ClientIP=%s] %v", clientIP, err)
|
logger.Error("[GoogleReader][/stream/items/ids#feed] [ClientIP=%s] %v", clientIP, err)
|
||||||
json.ServerError(w, r, err)
|
json.ServerError(w, r, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -1233,5 +1283,17 @@ func (h *handler) handleFeedStream(w http.ResponseWriter, r *http.Request, rm Re
|
||||||
formattedID := strconv.FormatInt(entryID, 10)
|
formattedID := strconv.FormatInt(entryID, 10)
|
||||||
itemRefs = append(itemRefs, itemRef{ID: formattedID})
|
itemRefs = append(itemRefs, itemRef{ID: formattedID})
|
||||||
}
|
}
|
||||||
json.OK(w, r, streamIDResponse{itemRefs})
|
|
||||||
|
totalEntries, err := builder.CountEntries()
|
||||||
|
if err != nil {
|
||||||
|
logger.Error("[GoogleReader][/stream/items/ids#feed] [ClientIP=%s] %v", clientIP, err)
|
||||||
|
json.ServerError(w, r, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
continuation := 0
|
||||||
|
if len(itemRefs)+rm.Offset < totalEntries {
|
||||||
|
continuation = len(itemRefs) + rm.Offset
|
||||||
|
}
|
||||||
|
|
||||||
|
json.OK(w, r, streamIDResponse{itemRefs, continuation})
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,7 +61,8 @@ type itemRef struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type streamIDResponse struct {
|
type streamIDResponse struct {
|
||||||
ItemRefs []itemRef `json:"itemRefs"`
|
ItemRefs []itemRef `json:"itemRefs"`
|
||||||
|
Continuation int `json:"continuation,omitempty,string"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type tagsResponse struct {
|
type tagsResponse struct {
|
||||||
|
|
Loading…
Reference in New Issue