mirror of
https://github.com/miniflux/v2.git
synced 2025-06-27 16:36:00 +00:00
refactor(googlereader): move constants to separate files
This commit is contained in:
parent
6cc8d8abf1
commit
653e80be8e
5 changed files with 282 additions and 256 deletions
|
@ -9,7 +9,6 @@ import (
|
||||||
"log/slog"
|
"log/slog"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"miniflux.app/v2/internal/config"
|
"miniflux.app/v2/internal/config"
|
||||||
|
@ -35,184 +34,12 @@ type handler struct {
|
||||||
router *mux.Router
|
router *mux.Router
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
|
||||||
// StreamPrefix is the prefix for astreams (read/starred/reading list and so on)
|
|
||||||
StreamPrefix = "user/-/state/com.google/"
|
|
||||||
// UserStreamPrefix is the user specific prefix for streams (read/starred/reading list and so on)
|
|
||||||
UserStreamPrefix = "user/%d/state/com.google/"
|
|
||||||
// LabelPrefix is the prefix for a label stream
|
|
||||||
LabelPrefix = "user/-/label/"
|
|
||||||
// UserLabelPrefix is the user specific prefix prefix for a label stream
|
|
||||||
UserLabelPrefix = "user/%d/label/"
|
|
||||||
// FeedPrefix is the prefix for a feed stream
|
|
||||||
FeedPrefix = "feed/"
|
|
||||||
// Read is the suffix for read stream
|
|
||||||
Read = "read"
|
|
||||||
// Starred is the suffix for starred stream
|
|
||||||
Starred = "starred"
|
|
||||||
// ReadingList is the suffix for reading list stream
|
|
||||||
ReadingList = "reading-list"
|
|
||||||
// KeptUnread is the suffix for kept unread stream
|
|
||||||
KeptUnread = "kept-unread"
|
|
||||||
// Broadcast is the suffix for broadcast stream
|
|
||||||
Broadcast = "broadcast"
|
|
||||||
// BroadcastFriends is the suffix for broadcast friends stream
|
|
||||||
BroadcastFriends = "broadcast-friends"
|
|
||||||
// Like is the suffix for like stream
|
|
||||||
Like = "like"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
// ParamItemIDs - name of the parameter with the item ids
|
|
||||||
ParamItemIDs = "i"
|
|
||||||
// ParamStreamID - name of the parameter containing the stream to be included
|
|
||||||
ParamStreamID = "s"
|
|
||||||
// ParamStreamExcludes - name of the parameter containing streams to be excluded
|
|
||||||
ParamStreamExcludes = "xt"
|
|
||||||
// ParamStreamFilters - name of the parameter containing streams to be included
|
|
||||||
ParamStreamFilters = "it"
|
|
||||||
// ParamStreamMaxItems - name of the parameter containing number of items per page/max items returned
|
|
||||||
ParamStreamMaxItems = "n"
|
|
||||||
// ParamStreamOrder - name of the parameter containing the sort criteria
|
|
||||||
ParamStreamOrder = "r"
|
|
||||||
// ParamStreamStartTime - name of the parameter containing epoch timestamp, filtering items older than
|
|
||||||
ParamStreamStartTime = "ot"
|
|
||||||
// ParamStreamStopTime - name of the parameter containing epoch timestamp, filtering items newer than
|
|
||||||
ParamStreamStopTime = "nt"
|
|
||||||
// ParamTagsRemove - name of the parameter containing tags (streams) to be removed
|
|
||||||
ParamTagsRemove = "r"
|
|
||||||
// ParamTagsAdd - name of the parameter containing tags (streams) to be added
|
|
||||||
ParamTagsAdd = "a"
|
|
||||||
// ParamSubscribeAction - name of the parameter indicating the action to take for subscription/edit
|
|
||||||
ParamSubscribeAction = "ac"
|
|
||||||
// ParamTitle - name of the parameter for the title of the subscription
|
|
||||||
ParamTitle = "t"
|
|
||||||
// ParamQuickAdd - name of the parameter for a URL being quick subscribed to
|
|
||||||
ParamQuickAdd = "quickadd"
|
|
||||||
// ParamDestination - name of the parameter for the new name of a tag
|
|
||||||
ParamDestination = "dest"
|
|
||||||
// ParamContinuation - name of the parameter for callers to pass to receive the next page of results
|
|
||||||
ParamContinuation = "c"
|
|
||||||
// ParamStreamType - name of the parameter for unix timestamp
|
|
||||||
ParamTimestamp = "ts"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
var (
|
||||||
errEmptyFeedTitle = errors.New("googlereader: empty feed title")
|
errEmptyFeedTitle = errors.New("googlereader: empty feed title")
|
||||||
errFeedNotFound = errors.New("googlereader: feed not found")
|
errFeedNotFound = errors.New("googlereader: feed not found")
|
||||||
errCategoryNotFound = errors.New("googlereader: category not found")
|
errCategoryNotFound = errors.New("googlereader: category not found")
|
||||||
)
|
)
|
||||||
|
|
||||||
// StreamType represents the possible stream types
|
|
||||||
type StreamType int
|
|
||||||
|
|
||||||
const (
|
|
||||||
// NoStream - no stream type
|
|
||||||
NoStream StreamType = iota
|
|
||||||
// ReadStream - read stream type
|
|
||||||
ReadStream
|
|
||||||
// StarredStream - starred stream type
|
|
||||||
StarredStream
|
|
||||||
// ReadingListStream - reading list stream type
|
|
||||||
ReadingListStream
|
|
||||||
// KeptUnreadStream - kept unread stream type
|
|
||||||
KeptUnreadStream
|
|
||||||
// BroadcastStream - broadcast stream type
|
|
||||||
BroadcastStream
|
|
||||||
// BroadcastFriendsStream - broadcast friends stream type
|
|
||||||
BroadcastFriendsStream
|
|
||||||
// LabelStream - label stream type
|
|
||||||
LabelStream
|
|
||||||
// FeedStream - feed stream type
|
|
||||||
FeedStream
|
|
||||||
// LikeStream - like stream type
|
|
||||||
LikeStream
|
|
||||||
)
|
|
||||||
|
|
||||||
// Stream defines a stream type and its ID.
|
|
||||||
type Stream struct {
|
|
||||||
Type StreamType
|
|
||||||
ID string
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s Stream) String() string {
|
|
||||||
return fmt.Sprintf("%v - '%s'", s.Type, s.ID)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (st StreamType) String() string {
|
|
||||||
switch st {
|
|
||||||
case NoStream:
|
|
||||||
return "NoStream"
|
|
||||||
case ReadStream:
|
|
||||||
return "ReadStream"
|
|
||||||
case StarredStream:
|
|
||||||
return "StarredStream"
|
|
||||||
case ReadingListStream:
|
|
||||||
return "ReadingListStream"
|
|
||||||
case KeptUnreadStream:
|
|
||||||
return "KeptUnreadStream"
|
|
||||||
case BroadcastStream:
|
|
||||||
return "BroadcastStream"
|
|
||||||
case BroadcastFriendsStream:
|
|
||||||
return "BroadcastFriendsStream"
|
|
||||||
case LabelStream:
|
|
||||||
return "LabelStream"
|
|
||||||
case FeedStream:
|
|
||||||
return "FeedStream"
|
|
||||||
case LikeStream:
|
|
||||||
return "LikeStream"
|
|
||||||
default:
|
|
||||||
return st.String()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// RequestModifiers are the parsed request parameters.
|
|
||||||
type RequestModifiers struct {
|
|
||||||
ExcludeTargets []Stream
|
|
||||||
FilterTargets []Stream
|
|
||||||
Streams []Stream
|
|
||||||
Count int
|
|
||||||
Offset int
|
|
||||||
SortDirection string
|
|
||||||
StartTime int64
|
|
||||||
StopTime int64
|
|
||||||
ContinuationToken string
|
|
||||||
UserID int64
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r RequestModifiers) String() string {
|
|
||||||
var results []string
|
|
||||||
|
|
||||||
results = append(results, fmt.Sprintf("UserID: %d", r.UserID))
|
|
||||||
|
|
||||||
var streamStr []string
|
|
||||||
for _, s := range r.Streams {
|
|
||||||
streamStr = append(streamStr, s.String())
|
|
||||||
}
|
|
||||||
results = append(results, fmt.Sprintf("Streams: [%s]", strings.Join(streamStr, ", ")))
|
|
||||||
|
|
||||||
var exclusions []string
|
|
||||||
for _, s := range r.ExcludeTargets {
|
|
||||||
exclusions = append(exclusions, s.String())
|
|
||||||
}
|
|
||||||
results = append(results, fmt.Sprintf("Exclusions: [%s]", strings.Join(exclusions, ", ")))
|
|
||||||
|
|
||||||
var filters []string
|
|
||||||
for _, s := range r.FilterTargets {
|
|
||||||
filters = append(filters, s.String())
|
|
||||||
}
|
|
||||||
results = append(results, fmt.Sprintf("Filters: [%s]", strings.Join(filters, ", ")))
|
|
||||||
|
|
||||||
results = append(results, fmt.Sprintf("Count: %d", r.Count))
|
|
||||||
results = append(results, fmt.Sprintf("Offset: %d", r.Offset))
|
|
||||||
results = append(results, fmt.Sprintf("Sort Direction: %s", r.SortDirection))
|
|
||||||
results = append(results, fmt.Sprintf("Continuation Token: %s", r.ContinuationToken))
|
|
||||||
results = append(results, fmt.Sprintf("Start Time: %d", r.StartTime))
|
|
||||||
results = append(results, fmt.Sprintf("Stop Time: %d", r.StopTime))
|
|
||||||
|
|
||||||
return strings.Join(results, "; ")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Serve handles Google Reader API calls.
|
// Serve handles Google Reader API calls.
|
||||||
func Serve(router *mux.Router, store *storage.Storage) {
|
func Serve(router *mux.Router, store *storage.Storage) {
|
||||||
handler := &handler{store, router}
|
handler := &handler{store, router}
|
||||||
|
@ -238,87 +65,6 @@ func Serve(router *mux.Router, store *storage.Storage) {
|
||||||
sr.PathPrefix("/").HandlerFunc(handler.serveHandler).Methods(http.MethodPost, http.MethodGet).Name("GoogleReaderApiEndpoint")
|
sr.PathPrefix("/").HandlerFunc(handler.serveHandler).Methods(http.MethodPost, http.MethodGet).Name("GoogleReaderApiEndpoint")
|
||||||
}
|
}
|
||||||
|
|
||||||
func getStreamFilterModifiers(r *http.Request) (RequestModifiers, error) {
|
|
||||||
userID := request.UserID(r)
|
|
||||||
|
|
||||||
result := RequestModifiers{
|
|
||||||
SortDirection: "desc",
|
|
||||||
UserID: userID,
|
|
||||||
}
|
|
||||||
streamOrder := request.QueryStringParam(r, ParamStreamOrder, "d")
|
|
||||||
if streamOrder == "o" {
|
|
||||||
result.SortDirection = "asc"
|
|
||||||
}
|
|
||||||
var err error
|
|
||||||
result.Streams, err = getStreams(request.QueryStringParamList(r, ParamStreamID), userID)
|
|
||||||
if err != nil {
|
|
||||||
return RequestModifiers{}, err
|
|
||||||
}
|
|
||||||
result.ExcludeTargets, err = getStreams(request.QueryStringParamList(r, ParamStreamExcludes), userID)
|
|
||||||
if err != nil {
|
|
||||||
return RequestModifiers{}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
result.FilterTargets, err = getStreams(request.QueryStringParamList(r, ParamStreamFilters), userID)
|
|
||||||
if err != nil {
|
|
||||||
return RequestModifiers{}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
result.Count = request.QueryIntParam(r, ParamStreamMaxItems, 0)
|
|
||||||
result.Offset = request.QueryIntParam(r, ParamContinuation, 0)
|
|
||||||
result.StartTime = request.QueryInt64Param(r, ParamStreamStartTime, int64(0))
|
|
||||||
result.StopTime = request.QueryInt64Param(r, ParamStreamStopTime, int64(0))
|
|
||||||
return result, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func getStream(streamID string, userID int64) (Stream, error) {
|
|
||||||
switch {
|
|
||||||
case strings.HasPrefix(streamID, FeedPrefix):
|
|
||||||
return Stream{Type: FeedStream, ID: strings.TrimPrefix(streamID, FeedPrefix)}, nil
|
|
||||||
case strings.HasPrefix(streamID, fmt.Sprintf(UserStreamPrefix, userID)) || strings.HasPrefix(streamID, StreamPrefix):
|
|
||||||
id := strings.TrimPrefix(streamID, fmt.Sprintf(UserStreamPrefix, userID))
|
|
||||||
id = strings.TrimPrefix(id, StreamPrefix)
|
|
||||||
switch id {
|
|
||||||
case Read:
|
|
||||||
return Stream{ReadStream, ""}, nil
|
|
||||||
case Starred:
|
|
||||||
return Stream{StarredStream, ""}, nil
|
|
||||||
case ReadingList:
|
|
||||||
return Stream{ReadingListStream, ""}, nil
|
|
||||||
case KeptUnread:
|
|
||||||
return Stream{KeptUnreadStream, ""}, nil
|
|
||||||
case Broadcast:
|
|
||||||
return Stream{BroadcastStream, ""}, nil
|
|
||||||
case BroadcastFriends:
|
|
||||||
return Stream{BroadcastFriendsStream, ""}, nil
|
|
||||||
case Like:
|
|
||||||
return Stream{LikeStream, ""}, nil
|
|
||||||
default:
|
|
||||||
return Stream{NoStream, ""}, fmt.Errorf("googlereader: unknown stream with id: %s", id)
|
|
||||||
}
|
|
||||||
case strings.HasPrefix(streamID, fmt.Sprintf(UserLabelPrefix, userID)) || strings.HasPrefix(streamID, LabelPrefix):
|
|
||||||
id := strings.TrimPrefix(streamID, fmt.Sprintf(UserLabelPrefix, userID))
|
|
||||||
id = strings.TrimPrefix(id, LabelPrefix)
|
|
||||||
return Stream{LabelStream, id}, nil
|
|
||||||
case streamID == "":
|
|
||||||
return Stream{NoStream, ""}, nil
|
|
||||||
default:
|
|
||||||
return Stream{NoStream, ""}, fmt.Errorf("googlereader: unknown stream type: %s", streamID)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func getStreams(streamIDs []string, userID int64) ([]Stream, error) {
|
|
||||||
streams := make([]Stream, 0)
|
|
||||||
for _, streamID := range streamIDs {
|
|
||||||
stream, err := getStream(streamID, userID)
|
|
||||||
if err != nil {
|
|
||||||
return []Stream{}, err
|
|
||||||
}
|
|
||||||
streams = append(streams, stream)
|
|
||||||
}
|
|
||||||
return streams, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func checkAndSimplifyTags(addTags []Stream, removeTags []Stream) (map[StreamType]bool, error) {
|
func checkAndSimplifyTags(addTags []Stream, removeTags []Stream) (map[StreamType]bool, error) {
|
||||||
tags := make(map[StreamType]bool)
|
tags := make(map[StreamType]bool)
|
||||||
for _, s := range addTags {
|
for _, s := range addTags {
|
||||||
|
@ -951,7 +697,7 @@ func (h *handler) streamItemContentsHandler(w http.ResponseWriter, r *http.Reque
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
requestModifiers, err := getStreamFilterModifiers(r)
|
requestModifiers, err := parseStreamFilterFromRequest(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
json.ServerError(w, r, err)
|
json.ServerError(w, r, err)
|
||||||
return
|
return
|
||||||
|
@ -1303,7 +1049,7 @@ func (h *handler) streamItemIDsHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
rm, err := getStreamFilterModifiers(r)
|
rm, err := parseStreamFilterFromRequest(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
json.ServerError(w, r, err)
|
json.ServerError(w, r, err)
|
||||||
return
|
return
|
||||||
|
|
39
internal/googlereader/parameters.go
Normal file
39
internal/googlereader/parameters.go
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
// SPDX-FileCopyrightText: Copyright The Miniflux Authors. All rights reserved.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
package googlereader // import "miniflux.app/v2/internal/googlereader"
|
||||||
|
|
||||||
|
const (
|
||||||
|
// ParamItemIDs - name of the parameter with the item ids
|
||||||
|
ParamItemIDs = "i"
|
||||||
|
// ParamStreamID - name of the parameter containing the stream to be included
|
||||||
|
ParamStreamID = "s"
|
||||||
|
// ParamStreamExcludes - name of the parameter containing streams to be excluded
|
||||||
|
ParamStreamExcludes = "xt"
|
||||||
|
// ParamStreamFilters - name of the parameter containing streams to be included
|
||||||
|
ParamStreamFilters = "it"
|
||||||
|
// ParamStreamMaxItems - name of the parameter containing number of items per page/max items returned
|
||||||
|
ParamStreamMaxItems = "n"
|
||||||
|
// ParamStreamOrder - name of the parameter containing the sort criteria
|
||||||
|
ParamStreamOrder = "r"
|
||||||
|
// ParamStreamStartTime - name of the parameter containing epoch timestamp, filtering items older than
|
||||||
|
ParamStreamStartTime = "ot"
|
||||||
|
// ParamStreamStopTime - name of the parameter containing epoch timestamp, filtering items newer than
|
||||||
|
ParamStreamStopTime = "nt"
|
||||||
|
// ParamTagsRemove - name of the parameter containing tags (streams) to be removed
|
||||||
|
ParamTagsRemove = "r"
|
||||||
|
// ParamTagsAdd - name of the parameter containing tags (streams) to be added
|
||||||
|
ParamTagsAdd = "a"
|
||||||
|
// ParamSubscribeAction - name of the parameter indicating the action to take for subscription/edit
|
||||||
|
ParamSubscribeAction = "ac"
|
||||||
|
// ParamTitle - name of the parameter for the title of the subscription
|
||||||
|
ParamTitle = "t"
|
||||||
|
// ParamQuickAdd - name of the parameter for a URL being quick subscribed to
|
||||||
|
ParamQuickAdd = "quickadd"
|
||||||
|
// ParamDestination - name of the parameter for the new name of a tag
|
||||||
|
ParamDestination = "dest"
|
||||||
|
// ParamContinuation - name of the parameter for callers to pass to receive the next page of results
|
||||||
|
ParamContinuation = "c"
|
||||||
|
// ParamStreamType - name of the parameter for unix timestamp
|
||||||
|
ParamTimestamp = "ts"
|
||||||
|
)
|
31
internal/googlereader/prefix_suffix.go
Normal file
31
internal/googlereader/prefix_suffix.go
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
// SPDX-FileCopyrightText: Copyright The Miniflux Authors. All rights reserved.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
package googlereader // import "miniflux.app/v2/internal/googlereader"
|
||||||
|
|
||||||
|
const (
|
||||||
|
// StreamPrefix is the prefix for astreams (read/starred/reading list and so on)
|
||||||
|
StreamPrefix = "user/-/state/com.google/"
|
||||||
|
// UserStreamPrefix is the user specific prefix for streams (read/starred/reading list and so on)
|
||||||
|
UserStreamPrefix = "user/%d/state/com.google/"
|
||||||
|
// LabelPrefix is the prefix for a label stream
|
||||||
|
LabelPrefix = "user/-/label/"
|
||||||
|
// UserLabelPrefix is the user specific prefix prefix for a label stream
|
||||||
|
UserLabelPrefix = "user/%d/label/"
|
||||||
|
// FeedPrefix is the prefix for a feed stream
|
||||||
|
FeedPrefix = "feed/"
|
||||||
|
// Read is the suffix for read stream
|
||||||
|
Read = "read"
|
||||||
|
// Starred is the suffix for starred stream
|
||||||
|
Starred = "starred"
|
||||||
|
// ReadingList is the suffix for reading list stream
|
||||||
|
ReadingList = "reading-list"
|
||||||
|
// KeptUnread is the suffix for kept unread stream
|
||||||
|
KeptUnread = "kept-unread"
|
||||||
|
// Broadcast is the suffix for broadcast stream
|
||||||
|
Broadcast = "broadcast"
|
||||||
|
// BroadcastFriends is the suffix for broadcast friends stream
|
||||||
|
BroadcastFriends = "broadcast-friends"
|
||||||
|
// Like is the suffix for like stream
|
||||||
|
Like = "like"
|
||||||
|
)
|
91
internal/googlereader/request_modifier.go
Normal file
91
internal/googlereader/request_modifier.go
Normal file
|
@ -0,0 +1,91 @@
|
||||||
|
// SPDX-FileCopyrightText: Copyright The Miniflux Authors. All rights reserved.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
package googlereader // import "miniflux.app/v2/internal/googlereader"
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"miniflux.app/v2/internal/http/request"
|
||||||
|
)
|
||||||
|
|
||||||
|
type RequestModifiers struct {
|
||||||
|
ExcludeTargets []Stream
|
||||||
|
FilterTargets []Stream
|
||||||
|
Streams []Stream
|
||||||
|
Count int
|
||||||
|
Offset int
|
||||||
|
SortDirection string
|
||||||
|
StartTime int64
|
||||||
|
StopTime int64
|
||||||
|
ContinuationToken string
|
||||||
|
UserID int64
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r RequestModifiers) String() string {
|
||||||
|
var results []string
|
||||||
|
|
||||||
|
results = append(results, fmt.Sprintf("UserID: %d", r.UserID))
|
||||||
|
|
||||||
|
var streamStr []string
|
||||||
|
for _, s := range r.Streams {
|
||||||
|
streamStr = append(streamStr, s.String())
|
||||||
|
}
|
||||||
|
results = append(results, fmt.Sprintf("Streams: [%s]", strings.Join(streamStr, ", ")))
|
||||||
|
|
||||||
|
var exclusions []string
|
||||||
|
for _, s := range r.ExcludeTargets {
|
||||||
|
exclusions = append(exclusions, s.String())
|
||||||
|
}
|
||||||
|
results = append(results, fmt.Sprintf("Exclusions: [%s]", strings.Join(exclusions, ", ")))
|
||||||
|
|
||||||
|
var filters []string
|
||||||
|
for _, s := range r.FilterTargets {
|
||||||
|
filters = append(filters, s.String())
|
||||||
|
}
|
||||||
|
results = append(results, fmt.Sprintf("Filters: [%s]", strings.Join(filters, ", ")))
|
||||||
|
|
||||||
|
results = append(results, fmt.Sprintf("Count: %d", r.Count))
|
||||||
|
results = append(results, fmt.Sprintf("Offset: %d", r.Offset))
|
||||||
|
results = append(results, fmt.Sprintf("Sort Direction: %s", r.SortDirection))
|
||||||
|
results = append(results, fmt.Sprintf("Continuation Token: %s", r.ContinuationToken))
|
||||||
|
results = append(results, fmt.Sprintf("Start Time: %d", r.StartTime))
|
||||||
|
results = append(results, fmt.Sprintf("Stop Time: %d", r.StopTime))
|
||||||
|
|
||||||
|
return strings.Join(results, "; ")
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseStreamFilterFromRequest(r *http.Request) (RequestModifiers, error) {
|
||||||
|
userID := request.UserID(r)
|
||||||
|
result := RequestModifiers{
|
||||||
|
SortDirection: "desc",
|
||||||
|
UserID: userID,
|
||||||
|
}
|
||||||
|
|
||||||
|
streamOrder := request.QueryStringParam(r, ParamStreamOrder, "d")
|
||||||
|
if streamOrder == "o" {
|
||||||
|
result.SortDirection = "asc"
|
||||||
|
}
|
||||||
|
var err error
|
||||||
|
result.Streams, err = getStreams(request.QueryStringParamList(r, ParamStreamID), userID)
|
||||||
|
if err != nil {
|
||||||
|
return RequestModifiers{}, err
|
||||||
|
}
|
||||||
|
result.ExcludeTargets, err = getStreams(request.QueryStringParamList(r, ParamStreamExcludes), userID)
|
||||||
|
if err != nil {
|
||||||
|
return RequestModifiers{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
result.FilterTargets, err = getStreams(request.QueryStringParamList(r, ParamStreamFilters), userID)
|
||||||
|
if err != nil {
|
||||||
|
return RequestModifiers{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
result.Count = request.QueryIntParam(r, ParamStreamMaxItems, 0)
|
||||||
|
result.Offset = request.QueryIntParam(r, ParamContinuation, 0)
|
||||||
|
result.StartTime = request.QueryInt64Param(r, ParamStreamStartTime, int64(0))
|
||||||
|
result.StopTime = request.QueryInt64Param(r, ParamStreamStopTime, int64(0))
|
||||||
|
return result, nil
|
||||||
|
}
|
119
internal/googlereader/stream.go
Normal file
119
internal/googlereader/stream.go
Normal file
|
@ -0,0 +1,119 @@
|
||||||
|
// SPDX-FileCopyrightText: Copyright The Miniflux Authors. All rights reserved.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
package googlereader // import "miniflux.app/v2/internal/googlereader"
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
type StreamType int
|
||||||
|
|
||||||
|
const (
|
||||||
|
// NoStream - no stream type
|
||||||
|
NoStream StreamType = iota
|
||||||
|
// ReadStream - read stream type
|
||||||
|
ReadStream
|
||||||
|
// StarredStream - starred stream type
|
||||||
|
StarredStream
|
||||||
|
// ReadingListStream - reading list stream type
|
||||||
|
ReadingListStream
|
||||||
|
// KeptUnreadStream - kept unread stream type
|
||||||
|
KeptUnreadStream
|
||||||
|
// BroadcastStream - broadcast stream type
|
||||||
|
BroadcastStream
|
||||||
|
// BroadcastFriendsStream - broadcast friends stream type
|
||||||
|
BroadcastFriendsStream
|
||||||
|
// LabelStream - label stream type
|
||||||
|
LabelStream
|
||||||
|
// FeedStream - feed stream type
|
||||||
|
FeedStream
|
||||||
|
// LikeStream - like stream type
|
||||||
|
LikeStream
|
||||||
|
)
|
||||||
|
|
||||||
|
// Stream defines a stream type and its ID.
|
||||||
|
type Stream struct {
|
||||||
|
Type StreamType
|
||||||
|
ID string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s Stream) String() string {
|
||||||
|
return fmt.Sprintf("%v - '%s'", s.Type, s.ID)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (st StreamType) String() string {
|
||||||
|
switch st {
|
||||||
|
case NoStream:
|
||||||
|
return "NoStream"
|
||||||
|
case ReadStream:
|
||||||
|
return "ReadStream"
|
||||||
|
case StarredStream:
|
||||||
|
return "StarredStream"
|
||||||
|
case ReadingListStream:
|
||||||
|
return "ReadingListStream"
|
||||||
|
case KeptUnreadStream:
|
||||||
|
return "KeptUnreadStream"
|
||||||
|
case BroadcastStream:
|
||||||
|
return "BroadcastStream"
|
||||||
|
case BroadcastFriendsStream:
|
||||||
|
return "BroadcastFriendsStream"
|
||||||
|
case LabelStream:
|
||||||
|
return "LabelStream"
|
||||||
|
case FeedStream:
|
||||||
|
return "FeedStream"
|
||||||
|
case LikeStream:
|
||||||
|
return "LikeStream"
|
||||||
|
default:
|
||||||
|
return st.String()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func getStream(streamID string, userID int64) (Stream, error) {
|
||||||
|
switch {
|
||||||
|
case strings.HasPrefix(streamID, FeedPrefix):
|
||||||
|
return Stream{Type: FeedStream, ID: strings.TrimPrefix(streamID, FeedPrefix)}, nil
|
||||||
|
case strings.HasPrefix(streamID, fmt.Sprintf(UserStreamPrefix, userID)) || strings.HasPrefix(streamID, StreamPrefix):
|
||||||
|
id := strings.TrimPrefix(streamID, fmt.Sprintf(UserStreamPrefix, userID))
|
||||||
|
id = strings.TrimPrefix(id, StreamPrefix)
|
||||||
|
switch id {
|
||||||
|
case Read:
|
||||||
|
return Stream{ReadStream, ""}, nil
|
||||||
|
case Starred:
|
||||||
|
return Stream{StarredStream, ""}, nil
|
||||||
|
case ReadingList:
|
||||||
|
return Stream{ReadingListStream, ""}, nil
|
||||||
|
case KeptUnread:
|
||||||
|
return Stream{KeptUnreadStream, ""}, nil
|
||||||
|
case Broadcast:
|
||||||
|
return Stream{BroadcastStream, ""}, nil
|
||||||
|
case BroadcastFriends:
|
||||||
|
return Stream{BroadcastFriendsStream, ""}, nil
|
||||||
|
case Like:
|
||||||
|
return Stream{LikeStream, ""}, nil
|
||||||
|
default:
|
||||||
|
return Stream{NoStream, ""}, fmt.Errorf("googlereader: unknown stream with id: %s", id)
|
||||||
|
}
|
||||||
|
case strings.HasPrefix(streamID, fmt.Sprintf(UserLabelPrefix, userID)) || strings.HasPrefix(streamID, LabelPrefix):
|
||||||
|
id := strings.TrimPrefix(streamID, fmt.Sprintf(UserLabelPrefix, userID))
|
||||||
|
id = strings.TrimPrefix(id, LabelPrefix)
|
||||||
|
return Stream{LabelStream, id}, nil
|
||||||
|
case streamID == "":
|
||||||
|
return Stream{NoStream, ""}, nil
|
||||||
|
default:
|
||||||
|
return Stream{NoStream, ""}, fmt.Errorf("googlereader: unknown stream type: %s", streamID)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func getStreams(streamIDs []string, userID int64) ([]Stream, error) {
|
||||||
|
streams := make([]Stream, 0)
|
||||||
|
for _, streamID := range streamIDs {
|
||||||
|
stream, err := getStream(streamID, userID)
|
||||||
|
if err != nil {
|
||||||
|
return []Stream{}, err
|
||||||
|
}
|
||||||
|
streams = append(streams, stream)
|
||||||
|
}
|
||||||
|
return streams, nil
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue