bookwyrm/fedireads/models/status.py

182 lines
5.7 KiB
Python
Raw Normal View History

2020-02-11 23:17:21 +00:00
''' models for storing different kinds of Activities '''
2020-04-22 13:53:22 +00:00
import urllib.parse
2020-03-30 00:40:51 +00:00
from django.utils import timezone
2020-02-11 23:17:21 +00:00
from django.core.validators import MaxValueValidator, MinValueValidator
from django.db import models
from model_utils.managers import InheritanceManager
from fedireads import activitypub
2020-05-10 20:38:47 +00:00
from .base_model import FedireadsModel
2020-02-11 23:17:21 +00:00
2020-02-17 03:17:11 +00:00
class Status(FedireadsModel):
''' any post, like a reply to a review, etc '''
user = models.ForeignKey('User', on_delete=models.PROTECT)
status_type = models.CharField(max_length=255, default='Note')
content = models.TextField(blank=True, null=True)
2020-02-17 02:45:25 +00:00
mention_users = models.ManyToManyField('User', related_name='mention_user')
2020-04-22 13:53:22 +00:00
mention_books = models.ManyToManyField(
'Edition', related_name='mention_book')
activity_type = models.CharField(max_length=255, default='Note')
2020-02-15 22:38:46 +00:00
local = models.BooleanField(default=True)
privacy = models.CharField(max_length=255, default='public')
sensitive = models.BooleanField(default=False)
# the created date can't be this, because of receiving federated posts
2020-03-30 00:40:51 +00:00
published_date = models.DateTimeField(default=timezone.now)
2020-02-19 07:26:42 +00:00
favorites = models.ManyToManyField(
'User',
symmetrical=False,
through='Favorite',
through_fields=('status', 'user'),
related_name='user_favorites'
)
reply_parent = models.ForeignKey(
'self',
null=True,
on_delete=models.PROTECT
)
objects = InheritanceManager()
@property
def activitypub_serialize(self):
return activitypub.get_status(self)
2020-03-21 23:50:49 +00:00
class Comment(Status):
''' like a review but without a rating and transient '''
book = models.ForeignKey('Edition', on_delete=models.PROTECT)
2020-03-21 23:50:49 +00:00
def save(self, *args, **kwargs):
self.status_type = 'Comment'
self.activity_type = 'Note'
2020-04-08 16:40:47 +00:00
super().save(*args, **kwargs)
@property
def activitypub_serialize(self):
return activitypub.get_comment(self)
2020-04-08 16:40:47 +00:00
class Quotation(Status):
''' like a review but without a rating and transient '''
book = models.ForeignKey('Edition', on_delete=models.PROTECT)
quote = models.TextField()
def save(self, *args, **kwargs):
self.status_type = 'Quotation'
self.activity_type = 'Note'
2020-03-21 23:50:49 +00:00
super().save(*args, **kwargs)
@property
def activitypub_serialize(self):
return activitypub.get_quotation(self)
class Review(Status):
''' a book review '''
2020-04-03 19:43:49 +00:00
name = models.CharField(max_length=255, null=True)
book = models.ForeignKey('Edition', on_delete=models.PROTECT)
rating = models.IntegerField(
default=None,
null=True,
blank=True,
validators=[MinValueValidator(1), MaxValueValidator(5)]
)
2020-02-11 23:17:21 +00:00
def save(self, *args, **kwargs):
self.status_type = 'Review'
self.activity_type = 'Article'
2020-02-11 23:17:21 +00:00
super().save(*args, **kwargs)
@property
def activitypub_serialize(self):
return activitypub.get_review(self)
2020-02-19 07:26:42 +00:00
class Favorite(FedireadsModel):
''' fav'ing a post '''
user = models.ForeignKey('User', on_delete=models.PROTECT)
status = models.ForeignKey('Status', on_delete=models.PROTECT)
2020-03-21 22:21:27 +00:00
class Meta:
unique_together = ('user', 'status')
2020-02-21 06:19:19 +00:00
class Boost(Status):
''' boost'ing a post '''
boosted_status = models.ForeignKey(
'Status',
on_delete=models.PROTECT,
related_name="boosters")
def save(self, *args, **kwargs):
self.status_type = 'Boost'
self.activity_type = 'Announce'
super().save(*args, **kwargs)
2020-04-01 21:55:32 +00:00
# This constraint can't work as it would cross tables.
# class Meta:
# unique_together = ('user', 'boosted_status')
2020-02-21 06:19:19 +00:00
class Tag(FedireadsModel):
''' freeform tags for books '''
user = models.ForeignKey('User', on_delete=models.PROTECT)
book = models.ForeignKey('Edition', on_delete=models.PROTECT)
2020-02-21 17:10:27 +00:00
name = models.CharField(max_length=100)
identifier = models.CharField(max_length=100)
def save(self, *args, **kwargs):
if not self.id:
# add identifiers to new tags
self.identifier = urllib.parse.quote_plus(self.name)
2020-02-21 17:10:27 +00:00
super().save(*args, **kwargs)
2020-02-21 06:19:19 +00:00
class Meta:
unique_together = ('user', 'book', 'name')
2020-03-07 22:50:29 +00:00
2020-04-02 18:05:10 +00:00
class ReadThrough(FedireadsModel):
''' Store progress through a book in the database. '''
user = models.ForeignKey('User', on_delete=models.PROTECT)
book = models.ForeignKey('Book', on_delete=models.PROTECT)
pages_read = models.IntegerField(
null=True,
blank=True)
start_date = models.DateTimeField(
blank=True,
null=True)
finish_date = models.DateTimeField(
blank=True,
null=True)
NotificationType = models.TextChoices(
2020-04-20 16:10:19 +00:00
'NotificationType',
2020-04-22 11:43:10 +00:00
'FAVORITE REPLY TAG FOLLOW FOLLOW_REQUEST BOOST IMPORT')
2020-03-07 22:50:29 +00:00
class Notification(FedireadsModel):
''' you've been tagged, liked, followed, etc '''
user = models.ForeignKey('User', on_delete=models.PROTECT)
related_book = models.ForeignKey(
'Edition', on_delete=models.PROTECT, null=True)
2020-03-07 22:50:29 +00:00
related_user = models.ForeignKey(
'User',
on_delete=models.PROTECT, null=True, related_name='related_user')
related_status = models.ForeignKey(
'Status', on_delete=models.PROTECT, null=True)
2020-04-22 11:43:10 +00:00
related_import = models.ForeignKey(
'ImportJob', on_delete=models.PROTECT, null=True)
2020-03-07 22:50:29 +00:00
read = models.BooleanField(default=False)
notification_type = models.CharField(
max_length=255, choices=NotificationType.choices)
class Meta:
constraints = [
models.CheckConstraint(
check=models.Q(notification_type__in=NotificationType.values),
name="notification_type_valid",
)
2020-03-07 22:50:29 +00:00
]