Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow specifying for different time ranges for follow feed #460

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 13 additions & 5 deletions routes/exchange.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import (
"net/http"
"reflect"
"sort"
"time"

"github.com/deso-protocol/core/lib"

Expand Down Expand Up @@ -1585,8 +1584,18 @@ func (fes *APIServer) GetProfilesByCoinValue(
return profilesByPublicKey, postsByPublicKey, postEntryReaderStates, nil
}

func (fes *APIServer) GetPostsForFollowFeedForPublicKey(bav *lib.UtxoView, startAfterPostHash *lib.BlockHash, publicKey []byte, numToFetch int, skipHidden bool, mediaRequired bool, onlyNFTs bool, onlyPosts bool) (
_postEntries []*lib.PostEntry, _err error) {
func (fes *APIServer) GetPostsForFollowFeedForPublicKey(
bav *lib.UtxoView,
startAfterPostHash *lib.BlockHash,
publicKey []byte,
minTimestampNanos uint64,
maxTimestampNanos uint64,
numToFetch int,
skipHidden bool,
mediaRequired bool,
onlyNFTs bool,
onlyPosts bool,
) (_postEntries []*lib.PostEntry, _err error) {
// Get the people who follow publicKey
// Note: GetFollowEntriesForPublicKey also loads them into the view
if onlyNFTs && onlyPosts {
Expand Down Expand Up @@ -1621,12 +1630,11 @@ func (fes *APIServer) GetPostsForFollowFeedForPublicKey(bav *lib.UtxoView, start
return nil, errors.Wrapf(err, "GetPostsForFollowFeedForPublicKey: Problem filtering out restricted public keys: ")
}

minTimestampNanos := uint64(time.Now().UTC().AddDate(0, 0, -2).UnixNano()) // two days ago
// For each of these pub keys, get their posts, and load them into the view too
for _, followedPubKey := range filteredPubKeysMap {

_, dbPostAndCommentHashes, _, err := lib.DBGetAllPostsAndCommentsForPublicKeyOrderedByTimestamp(
bav.Handle, fes.blockchain.Snapshot(), followedPubKey, false /*fetchEntries*/, minTimestampNanos, 0, /*maxTimestampNanos*/
bav.Handle, fes.blockchain.Snapshot(), followedPubKey, false /*fetchEntries*/, minTimestampNanos, maxTimestampNanos,
)
if err != nil {
return nil, errors.Wrapf(err, "GetPostsForFollowFeedForPublicKey: Problem fetching PostEntry's from db: ")
Expand Down
55 changes: 51 additions & 4 deletions routes/post.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,21 @@ import (
"github.com/pkg/errors"
)

// ------------
// Constants
// ------------

// NanosInSecond is a helper constant to convert seconds into nanos
const NanosInSecond = uint64(1_000_000_000)

// MaxTstampSecsInterval is the max difference allowed between
// GetPostsStatelessRequest.StartTstampSecs and GetPostsStatelessRequest.EndTstampSecs
const MaxTstampSecsInterval = uint64(2 * 24 * 60 * 60)

// ------------
// Types
// ------------

// GetPostsStatelessRequest ...
type GetPostsStatelessRequest struct {
// This is the PostHashHex of the post we want to start our paginated lookup at. We
Expand All @@ -25,6 +40,7 @@ type GetPostsStatelessRequest struct {
ReaderPublicKeyBase58Check string `safeForLogging:"true"`
OrderBy string `safeForLogging:"true"`
StartTstampSecs uint64 `safeForLogging:"true"`
EndTstampSecs uint64 `safeForLogging:"true"`
PostContent string `safeForLogging:"true"`
NumToFetch int `safeForLogging:"true"`

Expand Down Expand Up @@ -334,7 +350,9 @@ func (fes *APIServer) GetAllPostEntries(readerPK []byte) (
}

func (fes *APIServer) GetPostEntriesForFollowFeed(
startAfterPostHash *lib.BlockHash, readerPK []byte, numToFetch int, utxoView *lib.UtxoView, mediaRequired bool, onlyNFTs bool, onlyPosts bool) (
startAfterPostHash *lib.BlockHash, readerPK []byte, minTimestampNanos uint64, maxTimestampNanos uint64,
numToFetch int, utxoView *lib.UtxoView, mediaRequired bool, onlyNFTs bool, onlyPosts bool,
) (
_postEntries []*lib.PostEntry,
_profilesByPublicKey map[lib.PkMapKey]*lib.ProfileEntry,
_postEntryReaderStates map[lib.BlockHash]*lib.PostEntryReaderState, err error) {
Expand All @@ -343,7 +361,7 @@ func (fes *APIServer) GetPostEntriesForFollowFeed(
return nil, nil, nil, fmt.Errorf("GetPostEntriesForFollowFeed: OnlyNFTS and OnlyPosts can not be enabled both")
}

postEntries, err := fes.GetPostsForFollowFeedForPublicKey(utxoView, startAfterPostHash, readerPK, numToFetch, true /* skip hidden */, mediaRequired, onlyNFTs, onlyPosts)
postEntries, err := fes.GetPostsForFollowFeedForPublicKey(utxoView, startAfterPostHash, readerPK, minTimestampNanos, maxTimestampNanos, numToFetch, true /* skip hidden */, mediaRequired, onlyNFTs, onlyPosts)
if err != nil {
return nil, nil, nil, fmt.Errorf("GetPostEntriesForFollowFeed: Error fetching posts from view: %v", err)
}
Expand Down Expand Up @@ -894,11 +912,40 @@ func (fes *APIServer) GetPostsStateless(ww http.ResponseWriter, req *http.Reques
var profileEntryMap map[lib.PkMapKey]*lib.ProfileEntry
var readerStateMap map[lib.BlockHash]*lib.PostEntryReaderState
if requestData.GetPostsForFollowFeed {
utcTimeNow := time.Now().UTC()

var minTimestampNanos, maxTimestampNanos uint64
if requestData.StartTstampSecs > 0 {
minTimestampNanos = requestData.StartTstampSecs * NanosInSecond
} else {
// two days ago
minTimestampNanos = uint64(utcTimeNow.AddDate(0, 0, -2).UnixNano())
}

if requestData.EndTstampSecs > 0 {
maxTimestampNanos = requestData.EndTstampSecs * NanosInSecond
} else {
// now
minTimestampNanos = uint64(utcTimeNow.UnixNano())
}

// min should not be greater than max
if minTimestampNanos > maxTimestampNanos {
_AddBadRequestError(ww, fmt.Sprintf("GetPostsStateless: minTimestampNanos cannot be greater than maxTimestampNanos"))
return
}

// ensure window is at most 2 days
if maxTimestampNanos-minTimestampNanos > MaxTstampSecsInterval*NanosInSecond {
_AddBadRequestError(ww, fmt.Sprintf("GetPostsStateless: minTimestampNanos/maxTimestampNanos cannot be more than 2 hours apart"))
return
}

postEntries,
profileEntryMap,
readerStateMap,
err = fes.GetPostEntriesForFollowFeed(startPostHash, readerPublicKeyBytes, numToFetch, utxoView,
requestData.MediaRequired, requestData.OnlyNFTs, requestData.OnlyPosts)
err = fes.GetPostEntriesForFollowFeed(startPostHash, readerPublicKeyBytes, minTimestampNanos, maxTimestampNanos,
numToFetch, utxoView, requestData.MediaRequired, requestData.OnlyNFTs, requestData.OnlyPosts)
// if we're getting posts for follow feed, no comments are returned (they aren't necessary)
commentsByPostHash = make(map[lib.BlockHash][]*lib.PostEntry)
} else if requestData.GetPostsForGlobalWhitelist {
Expand Down