X-Git-Url: https://git.mdrn.pl/wolnelektury.git/blobdiff_plain/044ee915f89f30b2935dbbcb4a5d5e4a91cbfca9..102acc0b6eb715826f26b5082611604cf6ebe240:/src/bookmarks/models.py diff --git a/src/bookmarks/models.py b/src/bookmarks/models.py index 234d0519d..8747ffbd3 100644 --- a/src/bookmarks/models.py +++ b/src/bookmarks/models.py @@ -1,24 +1,113 @@ import uuid +from django.apps import apps from django.db import models +from django.utils.timezone import now +from social.syncable import Syncable -class Bookmark(models.Model): +class Bookmark(Syncable, models.Model): uuid = models.UUIDField(unique=True, default=uuid.uuid4, editable=False) user = models.ForeignKey('auth.User', models.CASCADE) book = models.ForeignKey('catalogue.Book', models.CASCADE) anchor = models.CharField(max_length=100, blank=True) + audio_timestamp = models.IntegerField(null=True, blank=True) + mode = models.CharField(max_length=64, choices=[ + ('text', 'text'), + ('audio', 'audio'), + ], default='text') created_at = models.DateTimeField(auto_now_add=True) note = models.TextField(blank=True) + updated_at = models.DateTimeField(auto_now=True) + reported_timestamp = models.DateTimeField(default=now) + deleted = models.BooleanField(default=False) + + syncable_fields = [ + 'deleted', 'note', + ] def __str__(self): return str(self.uuid) + def save(self, *args, **kwargs): + # TODO: placeholder. + try: + audio_l = self.book.get_audio_length() + except: + audio_l = 60 + if self.anchor: + self.mode = 'text' + if audio_l: + self.audio_timestamp = audio_l * .4 + if self.audio_timestamp: + self.mode = 'audio' + if self.audio_timestamp > audio_l: + self.audio_timestamp = audio_l + if audio_l: + self.anchor = 'f20' + return super().save(*args, **kwargs) + + @classmethod + def create_from_data(cls, user, data): + if data.get('location'): + return cls.get_by_location(user, data['location'], create=True) + elif data.get('book') and data.get('anchor'): + return cls.objects.create(user=user, book=data['book'], anchor=data['anchor']) + elif data.get('book') and data.get('audio_timestamp'): + return cls.objects.create(user=user, book=data['book'], audio_timestamp=data['audio_timestamp']) + @property def timestamp(self): - return self.created_at.timestamp() + return self.updated_at.timestamp() def location(self): - return f'{self.book.slug}/{self.anchor}' + if self.mode == 'text': + return f'{self.book.slug}/{self.anchor}' + else: + return f'{self.book.slug}/audio/{self.audio_timestamp}' + + @classmethod + def get_by_location(cls, user, location, create=False): + Book = apps.get_model('catalogue', 'Book') + try: + slug, anchor = location.split('/', 1) + except: + return None + if '/' in anchor: + try: + mode, audio_timestamp = anchor.split('/', 1) + assert mode == 'audio' + audio_timestamp = int(audio_timestamp) + except: + return None + anchor = '' + instance = cls.objects.filter( + user=user, + book__slug=slug, + mode=mode, + audio_timestamp=audio_timestamp, + ).first() + else: + mode = 'text' + audio_timestamp = None + instance = cls.objects.filter( + user=user, + book__slug=slug, + mode='text', + anchor=anchor, + ).first() + if instance is None and create: + try: + book = Book.objects.get(slug=slug) + except Book.DoesNotExist: + return None + instance = cls.objects.create( + user=user, + book=book, + mode=mode, + anchor=anchor, + audio_timestamp=audio_timestamp, + ) + return instance def get_for_json(self): return {