moviewyrm/bookwyrm/models/list.py

103 lines
3.2 KiB
Python
Raw Normal View History

2021-03-08 16:49:10 +00:00
""" make a list of books!! """
from django.apps import apps
2021-01-31 05:00:36 +00:00
from django.db import models
from django.utils import timezone
2021-01-31 05:00:36 +00:00
from bookwyrm import activitypub
2021-01-31 16:08:52 +00:00
from bookwyrm.settings import DOMAIN
from .activitypub_mixin import CollectionItemMixin, OrderedCollectionMixin
from .base_model import BookWyrmModel
2021-01-31 05:00:36 +00:00
from . import fields
2021-03-08 16:49:10 +00:00
CurationType = models.TextChoices(
"Curation",
[
"closed",
"open",
"curated",
],
)
2021-01-31 05:00:36 +00:00
class List(OrderedCollectionMixin, BookWyrmModel):
2021-03-08 16:49:10 +00:00
""" a list of books """
2021-01-31 05:00:36 +00:00
name = fields.CharField(max_length=100)
user = fields.ForeignKey(
2021-03-08 16:49:10 +00:00
"User", on_delete=models.PROTECT, activitypub_field="owner"
)
description = fields.TextField(blank=True, null=True, activitypub_field="summary")
2021-02-02 17:37:46 +00:00
privacy = fields.PrivacyField()
2021-01-31 05:00:36 +00:00
curation = fields.CharField(
2021-03-08 16:49:10 +00:00
max_length=255, default="closed", choices=CurationType.choices
2021-01-31 05:00:36 +00:00
)
books = models.ManyToManyField(
2021-03-08 16:49:10 +00:00
"Edition",
2021-01-31 05:00:36 +00:00
symmetrical=False,
2021-03-08 16:49:10 +00:00
through="ListItem",
through_fields=("book_list", "book"),
2021-01-31 05:00:36 +00:00
)
activity_serializer = activitypub.BookList
2021-01-31 16:08:52 +00:00
def get_remote_id(self):
2021-03-08 16:49:10 +00:00
""" don't want the user to be in there in this case """
return "https://%s/list/%d" % (DOMAIN, self.id)
2021-01-31 16:08:52 +00:00
2021-01-31 05:00:36 +00:00
@property
def collection_queryset(self):
2021-03-08 16:49:10 +00:00
""" list of books for this shelf, overrides OrderedCollectionMixin """
return self.books.filter(listitem__approved=True).all().order_by("listitem")
2021-01-31 05:00:36 +00:00
2021-02-01 01:34:06 +00:00
class Meta:
2021-03-08 16:49:10 +00:00
""" default sorting """
ordering = ("-updated_date",)
2021-02-01 01:34:06 +00:00
2021-01-31 05:00:36 +00:00
class ListItem(CollectionItemMixin, BookWyrmModel):
2021-03-08 16:49:10 +00:00
""" ok """
2021-01-31 05:00:36 +00:00
book = fields.ForeignKey(
2021-03-08 16:49:10 +00:00
"Edition", on_delete=models.PROTECT, activitypub_field="object"
)
2021-01-31 05:00:36 +00:00
book_list = fields.ForeignKey(
2021-03-08 16:49:10 +00:00
"List", on_delete=models.CASCADE, activitypub_field="target"
)
user = fields.ForeignKey(
2021-03-08 16:49:10 +00:00
"User", on_delete=models.PROTECT, activitypub_field="actor"
2021-01-31 05:00:36 +00:00
)
notes = fields.TextField(blank=True, null=True)
approved = models.BooleanField(default=True)
order = fields.IntegerField(blank=True, null=True)
2021-03-08 16:49:10 +00:00
endorsement = models.ManyToManyField("User", related_name="endorsers")
2021-01-31 05:00:36 +00:00
2021-02-23 23:51:02 +00:00
activity_serializer = activitypub.Add
2021-03-08 16:49:10 +00:00
object_field = "book"
collection_field = "book_list"
2021-01-31 05:00:36 +00:00
def save(self, *args, **kwargs):
2021-03-08 16:49:10 +00:00
""" create a notification too """
created = not bool(self.id)
super().save(*args, **kwargs)
# tick the updated date on the parent list
self.book_list.updated_date = timezone.now()
self.book_list.save(broadcast=False)
list_owner = self.book_list.user
# create a notification if somoene ELSE added to a local user's list
if created and list_owner.local and list_owner != self.user:
2021-03-08 16:49:10 +00:00
model = apps.get_model("bookwyrm.Notification", require_ready=True)
model.objects.create(
user=list_owner,
related_user=self.user,
related_list_item=self,
2021-03-08 16:49:10 +00:00
notification_type="ADD",
)
2021-01-31 05:00:36 +00:00
class Meta:
2021-03-08 16:49:10 +00:00
""" an opinionated constraint! you can't put a book on a list twice """
unique_together = ("book", "book_list")
ordering = ("-created_date",)