summaryrefslogtreecommitdiffstats
path: root/activities/models/timeline_event.py
diff options
context:
space:
mode:
Diffstat (limited to 'activities/models/timeline_event.py')
-rw-r--r--activities/models/timeline_event.py85
1 files changed, 85 insertions, 0 deletions
diff --git a/activities/models/timeline_event.py b/activities/models/timeline_event.py
new file mode 100644
index 0000000..43fc458
--- /dev/null
+++ b/activities/models/timeline_event.py
@@ -0,0 +1,85 @@
+from django.db import models
+
+
+class TimelineEvent(models.Model):
+ """
+ Something that has happened to an identity that we want them to see on one
+ or more timelines, like posts, likes and follows.
+ """
+
+ class Types(models.TextChoices):
+ post = "post"
+ mention = "mention"
+ like = "like"
+ follow = "follow"
+ boost = "boost"
+
+ # The user this event is for
+ identity = models.ForeignKey(
+ "users.Identity",
+ on_delete=models.CASCADE,
+ related_name="timeline_events",
+ )
+
+ # What type of event it is
+ type = models.CharField(max_length=100, choices=Types.choices)
+
+ # The subject of the event (which is used depends on the type)
+ subject_post = models.ForeignKey(
+ "activities.Post",
+ on_delete=models.CASCADE,
+ blank=True,
+ null=True,
+ related_name="timeline_events_about_us",
+ )
+ subject_identity = models.ForeignKey(
+ "users.Identity",
+ on_delete=models.CASCADE,
+ blank=True,
+ null=True,
+ related_name="timeline_events_about_us",
+ )
+
+ created = models.DateTimeField(auto_now_add=True)
+
+ class Meta:
+ index_together = [
+ # This relies on a DB that can use left subsets of indexes
+ ("identity", "type", "subject_post", "subject_identity"),
+ ("identity", "type", "subject_identity"),
+ ]
+
+ ### Alternate constructors ###
+
+ @classmethod
+ def add_follow(cls, identity, source_identity):
+ """
+ Adds a follow to the timeline if it's not there already
+ """
+ return cls.objects.get_or_create(
+ identity=identity,
+ type=cls.Types.follow,
+ subject_identity=source_identity,
+ )[0]
+
+ @classmethod
+ def add_post(cls, identity, post):
+ """
+ Adds a post to the timeline if it's not there already
+ """
+ return cls.objects.get_or_create(
+ identity=identity,
+ type=cls.Types.post,
+ subject_post=post,
+ )[0]
+
+ @classmethod
+ def add_like(cls, identity, post):
+ """
+ Adds a like to the timeline if it's not there already
+ """
+ return cls.objects.get_or_create(
+ identity=identity,
+ type=cls.Types.like,
+ subject_post=post,
+ )[0]