forked from mirrors/bookwyrm
87 lines
2.5 KiB
Python
87 lines
2.5 KiB
Python
""" puttin' books on shelves """
|
|
import re
|
|
from django.db import models
|
|
|
|
from bookwyrm import activitypub
|
|
from .activitypub_mixin import CollectionItemMixin, OrderedCollectionMixin
|
|
from .base_model import BookWyrmModel
|
|
from . import fields
|
|
|
|
|
|
class Shelf(OrderedCollectionMixin, BookWyrmModel):
|
|
""" a list of books owned by a user """
|
|
|
|
TO_READ = "to-read"
|
|
READING = "reading"
|
|
READ_FINISHED = "read"
|
|
|
|
READ_STATUS_IDENTIFIERS = (TO_READ, READING, READ_FINISHED)
|
|
|
|
name = fields.CharField(max_length=100)
|
|
identifier = models.CharField(max_length=100)
|
|
user = fields.ForeignKey(
|
|
"User", on_delete=models.PROTECT, activitypub_field="owner"
|
|
)
|
|
editable = models.BooleanField(default=True)
|
|
privacy = fields.PrivacyField()
|
|
books = models.ManyToManyField(
|
|
"Edition",
|
|
symmetrical=False,
|
|
through="ShelfBook",
|
|
through_fields=("shelf", "book"),
|
|
)
|
|
|
|
activity_serializer = activitypub.Shelf
|
|
|
|
def save(self, *args, **kwargs):
|
|
""" set the identifier """
|
|
super().save(*args, **kwargs)
|
|
if not self.identifier:
|
|
slug = re.sub(r"[^\w]", "", self.name).lower()
|
|
self.identifier = "%s-%d" % (slug, self.id)
|
|
super().save(*args, **kwargs)
|
|
|
|
@property
|
|
def collection_queryset(self):
|
|
""" list of books for this shelf, overrides OrderedCollectionMixin """
|
|
return self.books.all().order_by("shelfbook")
|
|
|
|
def get_remote_id(self):
|
|
""" shelf identifier instead of id """
|
|
base_path = self.user.remote_id
|
|
return "%s/shelf/%s" % (base_path, self.identifier)
|
|
|
|
class Meta:
|
|
""" user/shelf unqiueness """
|
|
|
|
unique_together = ("user", "identifier")
|
|
|
|
|
|
class ShelfBook(CollectionItemMixin, BookWyrmModel):
|
|
""" many to many join table for books and shelves """
|
|
|
|
book = fields.ForeignKey(
|
|
"Edition", on_delete=models.PROTECT, activitypub_field="object"
|
|
)
|
|
shelf = fields.ForeignKey(
|
|
"Shelf", on_delete=models.PROTECT, activitypub_field="target"
|
|
)
|
|
user = fields.ForeignKey(
|
|
"User", on_delete=models.PROTECT, activitypub_field="actor"
|
|
)
|
|
|
|
activity_serializer = activitypub.Add
|
|
object_field = "book"
|
|
collection_field = "shelf"
|
|
|
|
def save(self, *args, **kwargs):
|
|
if not self.user:
|
|
self.user = self.shelf.user
|
|
super().save(*args, **kwargs)
|
|
|
|
class Meta:
|
|
"""an opinionated constraint!
|
|
you can't put a book on shelf twice"""
|
|
|
|
unique_together = ("book", "shelf")
|
|
ordering = ("-created_date",)
|