Merge branch 'main' into progress_update
This commit is contained in:
@ -17,7 +17,7 @@ from .readthrough import ReadThrough, ProgressUpdate, ProgressMode
|
||||
|
||||
from .tag import Tag, UserTag
|
||||
|
||||
from .user import User, KeyPair
|
||||
from .user import User, KeyPair, AnnualGoal
|
||||
from .relationship import UserFollows, UserFollowRequest, UserBlocks
|
||||
from .federated_server import FederatedServer
|
||||
|
||||
|
@ -225,6 +225,9 @@ class OrderedCollectionPageMixin(ActivitypubMixin):
|
||||
def to_ordered_collection(self, queryset, \
|
||||
remote_id=None, page=False, **kwargs):
|
||||
''' an ordered collection of whatevers '''
|
||||
if not queryset.ordered:
|
||||
raise RuntimeError('queryset must be ordered')
|
||||
|
||||
remote_id = remote_id or self.remote_id
|
||||
if page:
|
||||
return to_ordered_collection_page(
|
||||
|
@ -182,7 +182,6 @@ class Edition(Book):
|
||||
activity_serializer = activitypub.Edition
|
||||
name_field = 'title'
|
||||
|
||||
@property
|
||||
def get_rank(self):
|
||||
''' calculate how complete the data is on this edition '''
|
||||
if self.parent_work and self.parent_work.default_edition == self:
|
||||
@ -208,7 +207,7 @@ class Edition(Book):
|
||||
self.isbn_13 = isbn_10_to_13(self.isbn_10)
|
||||
|
||||
# set rank
|
||||
self.edition_rank = self.get_rank
|
||||
self.edition_rank = self.get_rank()
|
||||
|
||||
return super().save(*args, **kwargs)
|
||||
|
||||
|
@ -39,7 +39,7 @@ class Shelf(OrderedCollectionMixin, BookWyrmModel):
|
||||
@property
|
||||
def collection_queryset(self):
|
||||
''' list of books for this shelf, overrides OrderedCollectionMixin '''
|
||||
return self.books.all()
|
||||
return self.books.all().order_by('shelfbook')
|
||||
|
||||
def get_remote_id(self):
|
||||
''' shelf identifier instead of id '''
|
||||
@ -90,3 +90,4 @@ class ShelfBook(ActivitypubMixin, BookWyrmModel):
|
||||
''' an opinionated constraint!
|
||||
you can't put a book on shelf twice '''
|
||||
unique_together = ('book', 'shelf')
|
||||
ordering = ('-created_date',)
|
||||
|
@ -6,6 +6,7 @@ from django.apps import apps
|
||||
from django.contrib.auth.models import AbstractUser
|
||||
from django.db import models
|
||||
from django.dispatch import receiver
|
||||
from django.utils import timezone
|
||||
|
||||
from bookwyrm import activitypub
|
||||
from bookwyrm.connectors import get_data
|
||||
@ -18,7 +19,7 @@ from bookwyrm.utils import regex
|
||||
from .base_model import OrderedCollectionPageMixin
|
||||
from .base_model import ActivitypubMixin, BookWyrmModel
|
||||
from .federated_server import FederatedServer
|
||||
from . import fields
|
||||
from . import fields, Review
|
||||
|
||||
|
||||
class User(OrderedCollectionPageMixin, AbstractUser):
|
||||
@ -221,6 +222,57 @@ class KeyPair(ActivitypubMixin, BookWyrmModel):
|
||||
return activity_object
|
||||
|
||||
|
||||
class AnnualGoal(BookWyrmModel):
|
||||
''' set a goal for how many books you read in a year '''
|
||||
user = models.ForeignKey('User', on_delete=models.PROTECT)
|
||||
goal = models.IntegerField()
|
||||
year = models.IntegerField(default=timezone.now().year)
|
||||
privacy = models.CharField(
|
||||
max_length=255,
|
||||
default='public',
|
||||
choices=fields.PrivacyLevels.choices
|
||||
)
|
||||
|
||||
class Meta:
|
||||
''' unqiueness constraint '''
|
||||
unique_together = ('user', 'year')
|
||||
|
||||
def get_remote_id(self):
|
||||
''' put the year in the path '''
|
||||
return '%s/goal/%d' % (self.user.remote_id, self.year)
|
||||
|
||||
@property
|
||||
def books(self):
|
||||
''' the books you've read this year '''
|
||||
return self.user.readthrough_set.filter(
|
||||
finish_date__year__gte=self.year
|
||||
).order_by('finish_date').all()
|
||||
|
||||
|
||||
@property
|
||||
def ratings(self):
|
||||
''' ratings for books read this year '''
|
||||
book_ids = [r.book.id for r in self.books]
|
||||
reviews = Review.objects.filter(
|
||||
user=self.user,
|
||||
book__in=book_ids,
|
||||
)
|
||||
return {r.book.id: r.rating for r in reviews}
|
||||
|
||||
|
||||
@property
|
||||
def progress_percent(self):
|
||||
return int(float(self.book_count / self.goal) * 100)
|
||||
|
||||
|
||||
@property
|
||||
def book_count(self):
|
||||
''' how many books you've read this year '''
|
||||
return self.user.readthrough_set.filter(
|
||||
finish_date__year__gte=self.year).count()
|
||||
|
||||
|
||||
|
||||
@receiver(models.signals.post_save, sender=User)
|
||||
#pylint: disable=unused-argument
|
||||
def execute_after_save(sender, instance, created, *args, **kwargs):
|
||||
|
Reference in New Issue
Block a user