''' make a list of books!! ''' from django.apps import apps from django.db import models from bookwyrm import activitypub from bookwyrm.settings import DOMAIN from .activitypub_mixin import CollectionItemMixin, OrderedCollectionMixin from .base_model import BookWyrmModel from . import fields CurationType = models.TextChoices('Curation', [ 'closed', 'open', 'curated', ]) class List(OrderedCollectionMixin, BookWyrmModel): ''' a list of books ''' name = fields.CharField(max_length=100) user = fields.ForeignKey( 'User', on_delete=models.PROTECT, activitypub_field='owner') description = fields.TextField( blank=True, null=True, activitypub_field='summary') privacy = fields.PrivacyField() curation = fields.CharField( max_length=255, default='closed', choices=CurationType.choices ) books = models.ManyToManyField( 'Edition', symmetrical=False, through='ListItem', through_fields=('book_list', 'book'), ) activity_serializer = activitypub.BookList def get_remote_id(self): ''' don't want the user to be in there in this case ''' return 'https://%s/list/%d' % (DOMAIN, self.id) @property def collection_queryset(self): ''' list of books for this shelf, overrides OrderedCollectionMixin ''' return self.books.filter( listitem__approved=True ).all().order_by('listitem') class Meta: ''' default sorting ''' ordering = ('-updated_date',) class ListItem(CollectionItemMixin, BookWyrmModel): ''' ok ''' book = fields.ForeignKey( 'Edition', on_delete=models.PROTECT, activitypub_field='object') book_list = fields.ForeignKey( 'List', on_delete=models.CASCADE, activitypub_field='target') user = fields.ForeignKey( 'User', on_delete=models.PROTECT, activitypub_field='actor' ) notes = fields.TextField(blank=True, null=True) approved = models.BooleanField(default=True) order = fields.IntegerField(blank=True, null=True) endorsement = models.ManyToManyField('User', related_name='endorsers') activity_serializer = activitypub.Add object_field = 'book' collection_field = 'book_list' def save(self, *args, **kwargs): ''' create a notification too ''' created = not bool(self.id) super().save(*args, **kwargs) 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: model = apps.get_model('bookwyrm.Notification', require_ready=True) model.objects.create( user=list_owner, related_user=self.user, related_list_item=self, notification_type='ADD', ) class Meta: ''' an opinionated constraint! you can't put a book on a list twice ''' unique_together = ('book', 'book_list') ordering = ('-created_date',)