diff options
author | 2021-06-13 18:42:28 +0200 | |
---|---|---|
committer | 2021-06-13 18:42:28 +0200 | |
commit | b4288f3c47a9ff9254b933dcb9ee7274d4a4135c (patch) | |
tree | 3fe1bb1ab8d4b8c5d9a83df708e5088f35c3150a /internal/timeline/index.go | |
parent | Tidy + timeline embetterment (#38) (diff) | |
download | gotosocial-b4288f3c47a9ff9254b933dcb9ee7274d4a4135c.tar.xz |
Timeline manager (#40)
* start messing about with timeline manager
* i have no idea what i'm doing
* i continue to not know what i'm doing
* it's coming along
* bit more progress
* update timeline with new posts as they come in
* lint and fmt
* Select accounts where empty string
* restructure a bunch, get unfaves working
* moving stuff around
* federate status deletes properly
* mention regex better but not 100% there
* fix regex
* some more hacking away at the timeline code phew
* fix up some little things
* i can't even
* more timeline stuff
* move to ulid
* fiddley
* some lil fixes for kibou compatibility
* timelines working pretty alright!
* tidy + lint
Diffstat (limited to 'internal/timeline/index.go')
-rw-r--r-- | internal/timeline/index.go | 143 |
1 files changed, 143 insertions, 0 deletions
diff --git a/internal/timeline/index.go b/internal/timeline/index.go new file mode 100644 index 000000000..56f5c14df --- /dev/null +++ b/internal/timeline/index.go @@ -0,0 +1,143 @@ +package timeline + +import ( + "errors" + "fmt" + "time" + + "github.com/superseriousbusiness/gotosocial/internal/db" + "github.com/superseriousbusiness/gotosocial/internal/gtsmodel" +) + +func (t *timeline) IndexBefore(statusID string, include bool, amount int) error { + // filtered := []*gtsmodel.Status{} + // offsetStatus := statusID + + // grabloop: + // for len(filtered) < amount { + // statuses, err := t.db.GetStatusesWhereFollowing(t.accountID, amount, offsetStatus, include, true) + // if err != nil { + // if _, ok := err.(db.ErrNoEntries); !ok { + // return fmt.Errorf("IndexBeforeAndIncluding: error getting statuses from db: %s", err) + // } + // break grabloop // we just don't have enough statuses left in the db so index what we've got and then bail + // } + + // for _, s := range statuses { + // relevantAccounts, err := t.db.PullRelevantAccountsFromStatus(s) + // if err != nil { + // continue + // } + // visible, err := t.db.StatusVisible(s, t.account, relevantAccounts) + // if err != nil { + // continue + // } + // if visible { + // filtered = append(filtered, s) + // } + // offsetStatus = s.ID + // } + // } + + // for _, s := range filtered { + // if err := t.IndexOne(s.CreatedAt, s.ID); err != nil { + // return fmt.Errorf("IndexBeforeAndIncluding: error indexing status with id %s: %s", s.ID, err) + // } + // } + + return nil +} + +func (t *timeline) IndexBehind(statusID string, amount int) error { + filtered := []*gtsmodel.Status{} + offsetStatus := statusID + +grabloop: + for len(filtered) < amount { + statuses, err := t.db.GetStatusesWhereFollowing(t.accountID, offsetStatus, "", "", amount, false) + if err != nil { + if _, ok := err.(db.ErrNoEntries); ok { + break grabloop // we just don't have enough statuses left in the db so index what we've got and then bail + } + return fmt.Errorf("IndexBehindAndIncluding: error getting statuses from db: %s", err) + } + + for _, s := range statuses { + relevantAccounts, err := t.db.PullRelevantAccountsFromStatus(s) + if err != nil { + continue + } + visible, err := t.db.StatusVisible(s, t.account, relevantAccounts) + if err != nil { + continue + } + if visible { + filtered = append(filtered, s) + } + offsetStatus = s.ID + } + } + + for _, s := range filtered { + if err := t.IndexOne(s.CreatedAt, s.ID); err != nil { + return fmt.Errorf("IndexBehindAndIncluding: error indexing status with id %s: %s", s.ID, err) + } + } + + return nil +} + +func (t *timeline) IndexOneByID(statusID string) error { + return nil +} + +func (t *timeline) IndexOne(statusCreatedAt time.Time, statusID string) error { + t.Lock() + defer t.Unlock() + + postIndexEntry := &postIndexEntry{ + statusID: statusID, + } + + return t.postIndex.insertIndexed(postIndexEntry) +} + +func (t *timeline) IndexAndPrepareOne(statusCreatedAt time.Time, statusID string) error { + t.Lock() + defer t.Unlock() + + postIndexEntry := &postIndexEntry{ + statusID: statusID, + } + + if err := t.postIndex.insertIndexed(postIndexEntry); err != nil { + return fmt.Errorf("IndexAndPrepareOne: error inserting indexed: %s", err) + } + + if err := t.prepare(statusID); err != nil { + return fmt.Errorf("IndexAndPrepareOne: error preparing: %s", err) + } + + return nil +} + +func (t *timeline) OldestIndexedPostID() (string, error) { + var id string + if t.postIndex == nil || t.postIndex.data == nil { + // return an empty string if postindex hasn't been initialized yet + return id, nil + } + + e := t.postIndex.data.Back() + + if e == nil { + // return an empty string if there's no back entry (ie., the index list hasn't been initialized yet) + return id, nil + } + + entry, ok := e.Value.(*postIndexEntry) + if !ok { + return id, errors.New("OldestIndexedPostID: could not parse e as a postIndexEntry") + } + return entry.statusID, nil +} |