summaryrefslogtreecommitdiff
path: root/internal/timeline/timeline.go
diff options
context:
space:
mode:
authorLibravatar Tobi Smethurst <31960611+tsmethurst@users.noreply.github.com>2021-06-13 18:42:28 +0200
committerLibravatar GitHub <noreply@github.com>2021-06-13 18:42:28 +0200
commitb4288f3c47a9ff9254b933dcb9ee7274d4a4135c (patch)
tree3fe1bb1ab8d4b8c5d9a83df708e5088f35c3150a /internal/timeline/timeline.go
parentTidy + timeline embetterment (#38) (diff)
downloadgotosocial-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/timeline.go')
-rw-r--r--internal/timeline/timeline.go139
1 files changed, 139 insertions, 0 deletions
diff --git a/internal/timeline/timeline.go b/internal/timeline/timeline.go
new file mode 100644
index 000000000..7408436dc
--- /dev/null
+++ b/internal/timeline/timeline.go
@@ -0,0 +1,139 @@
+/*
+ GoToSocial
+ Copyright (C) 2021 GoToSocial Authors admin@gotosocial.org
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+package timeline
+
+import (
+ "sync"
+ "time"
+
+ "github.com/sirupsen/logrus"
+ apimodel "github.com/superseriousbusiness/gotosocial/internal/api/model"
+ "github.com/superseriousbusiness/gotosocial/internal/db"
+ "github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
+ "github.com/superseriousbusiness/gotosocial/internal/typeutils"
+)
+
+// Timeline represents a timeline for one account, and contains indexed and prepared posts.
+type Timeline interface {
+ /*
+ RETRIEVAL FUNCTIONS
+ */
+
+ Get(amount int, maxID string, sinceID string, minID string) ([]*apimodel.Status, error)
+ // GetXFromTop returns x amount of posts from the top of the timeline, from newest to oldest.
+ GetXFromTop(amount int) ([]*apimodel.Status, error)
+ // GetXBehindID returns x amount of posts from the given id onwards, from newest to oldest.
+ // This will NOT include the status with the given ID.
+ //
+ // This corresponds to an api call to /timelines/home?max_id=WHATEVER
+ GetXBehindID(amount int, fromID string) ([]*apimodel.Status, error)
+ // GetXBeforeID returns x amount of posts up to the given id, from newest to oldest.
+ // This will NOT include the status with the given ID.
+ //
+ // This corresponds to an api call to /timelines/home?since_id=WHATEVER
+ GetXBeforeID(amount int, sinceID string, startFromTop bool) ([]*apimodel.Status, error)
+ // GetXBetweenID returns x amount of posts from the given maxID, up to the given id, from newest to oldest.
+ // This will NOT include the status with the given IDs.
+ //
+ // This corresponds to an api call to /timelines/home?since_id=WHATEVER&max_id=WHATEVER_ELSE
+ GetXBetweenID(amount int, maxID string, sinceID string) ([]*apimodel.Status, error)
+
+ /*
+ INDEXING FUNCTIONS
+ */
+
+ // IndexOne puts a status into the timeline at the appropriate place according to its 'createdAt' property.
+ IndexOne(statusCreatedAt time.Time, statusID string) error
+
+ // OldestIndexedPostID returns the id of the rearmost (ie., the oldest) indexed post, or an error if something goes wrong.
+ // If nothing goes wrong but there's no oldest post, an empty string will be returned so make sure to check for this.
+ OldestIndexedPostID() (string, error)
+
+ /*
+ PREPARATION FUNCTIONS
+ */
+
+ // PrepareXFromTop instructs the timeline to prepare x amount of posts from the top of the timeline.
+ PrepareFromTop(amount int) error
+ // PrepareBehind instructs the timeline to prepare the next amount of entries for serialization, from position onwards.
+ // If include is true, then the given status ID will also be prepared, otherwise only entries behind it will be prepared.
+ PrepareBehind(statusID string, amount int) error
+ // IndexOne puts a status into the timeline at the appropriate place according to its 'createdAt' property,
+ // and then immediately prepares it.
+ IndexAndPrepareOne(statusCreatedAt time.Time, statusID string) error
+ // OldestPreparedPostID returns the id of the rearmost (ie., the oldest) prepared post, or an error if something goes wrong.
+ // If nothing goes wrong but there's no oldest post, an empty string will be returned so make sure to check for this.
+ OldestPreparedPostID() (string, error)
+
+ /*
+ INFO FUNCTIONS
+ */
+
+ // ActualPostIndexLength returns the actual length of the post index at this point in time.
+ PostIndexLength() int
+
+ /*
+ UTILITY FUNCTIONS
+ */
+
+ // Reset instructs the timeline to reset to its base state -- cache only the minimum amount of posts.
+ Reset() error
+ // Remove removes a status from both the index and prepared posts.
+ //
+ // If a status has multiple entries in a timeline, they will all be removed.
+ //
+ // The returned int indicates the amount of entries that were removed.
+ Remove(statusID string) (int, error)
+}
+
+// timeline fulfils the Timeline interface
+type timeline struct {
+ postIndex *postIndex
+ preparedPosts *preparedPosts
+ accountID string
+ account *gtsmodel.Account
+ db db.DB
+ tc typeutils.TypeConverter
+ log *logrus.Logger
+ sync.Mutex
+}
+
+// NewTimeline returns a new Timeline for the given account ID
+func NewTimeline(accountID string, db db.DB, typeConverter typeutils.TypeConverter, log *logrus.Logger) Timeline {
+ return &timeline{
+ postIndex: &postIndex{},
+ preparedPosts: &preparedPosts{},
+ accountID: accountID,
+ db: db,
+ tc: typeConverter,
+ log: log,
+ }
+}
+
+func (t *timeline) Reset() error {
+ return nil
+}
+
+func (t *timeline) PostIndexLength() int {
+ if t.postIndex == nil || t.postIndex.data == nil {
+ return 0
+ }
+
+ return t.postIndex.data.Len()
+}