diff --git a/api_koreader/models.py b/api_koreader/models.py index 6d7c46f1e15282968578ec69d7714acb8278063e..3d3b1f53d025b3e1ecbaa9843a4fa6b62cc08a71 100644 --- a/api_koreader/models.py +++ b/api_koreader/models.py @@ -7,8 +7,8 @@ from django.db.models.signals import post_save from django.dispatch import receiver from accounts.models import User +from api_koreader.xpointer_cfi_utils import epub_kr_to_cfi, epub_cfi_to_kr from reader.models import Book, UserBook -from .xpointer_cfi_utils import epub_kr_to_cfi, epub_cfi_to_kr # Create your models here. @@ -22,6 +22,9 @@ class SyncDocumentEntry(models.Model): updated_at = models.DateTimeField(auto_now=True) created_at = models.DateTimeField(auto_now_add=True, editable=False) + def __str__(self): + return f"{self.user} - {self.key}" + @receiver(post_save, sender=SyncDocumentEntry) def post_save_document(sender, instance: SyncDocumentEntry, **kwargs): # Stop recursion @@ -34,15 +37,7 @@ def post_save_document(sender, instance: SyncDocumentEntry, **kwargs): if user_book_qs: # Get User book user_book = user_book_qs.first() - # Detect type of file - if book.file_type == "epub": - user_book.last_progress_cfi = epub_kr_to_cfi(io.BytesIO(book.original_file.open("rb").read()), instance.progress) - else: - user_book.last_progress_cfi = instance.progress - user_book.percentage_read = instance.percentage - user_book.last_progress_device = "KoReader - " + instance.device - user_book.last_read = instance.updated_at - user_book.save() + sde_to_ub(instance, user_book) @receiver(post_save, sender=UserBook) def post_save_userbook(sender, instance: UserBook, **kwargs): @@ -53,12 +48,32 @@ def post_save_userbook(sender, instance: UserBook, **kwargs): sync_doc_q: QuerySet[SyncDocumentEntry] = SyncDocumentEntry.objects.filter(user=instance.user, key__iexact=instance.book.partial_md5) if sync_doc_q.first(): sync_doc: SyncDocumentEntry = sync_doc_q.first() - if instance.book.file_type == "epub": - sync_doc.progress = epub_cfi_to_kr(io.BytesIO(instance.book.original_file.open("rb").read()), instance.last_progress_cfi) - else: - sync_doc.progress = instance.last_progress_cfi - sync_doc.percentage = instance.percentage_read - sync_doc.device = instance.last_progress_device - sync_doc.updated_at = instance.last_read - sync_doc.device_id = hashlib.md5(sync_doc.device.encode()).hexdigest() # Generate a device ID - sync_doc.save() \ No newline at end of file + ub_to_sde(instance, sync_doc) + + +def sde_to_ub(instance: SyncDocumentEntry, user_book: UserBook): + # Detect type of file + if user_book.book.file_type == "epub": + user_book.last_progress_cfi = epub_kr_to_cfi(io.BytesIO(user_book.book.original_file.open("rb").read()), + instance.progress) + else: + user_book.last_progress_cfi = instance.progress + user_book.percentage_read = instance.percentage + user_book.last_progress_device = "KoReader - " + instance.device + user_book.last_read = instance.updated_at + user_book.save() + return user_book + + +def ub_to_sde(instance: UserBook, sync_doc: SyncDocumentEntry): + if instance.book.file_type == "epub": + sync_doc.progress = epub_cfi_to_kr(io.BytesIO(instance.book.original_file.open("rb").read()), + instance.last_progress_cfi) + else: + sync_doc.progress = instance.last_progress_cfi + sync_doc.percentage = instance.percentage_read + sync_doc.device = instance.last_progress_device + sync_doc.updated_at = instance.last_read + sync_doc.device_id = hashlib.md5(sync_doc.device.encode()).hexdigest() # Generate a device ID + sync_doc.save() + return sync_doc diff --git a/api_koreader/views.py b/api_koreader/views.py index c9299f77aea2270715931c3a1c525228852631dc..e1d0285443c50c4bfb6f5478bf3d0f3b41107c9b 100644 --- a/api_koreader/views.py +++ b/api_koreader/views.py @@ -1,7 +1,6 @@ import json from json import JSONDecodeError -from django.db.transaction import commit from django.http import JsonResponse, HttpResponse from django.utils import timezone from django.views.decorators.csrf import csrf_exempt @@ -9,7 +8,8 @@ from django.views.decorators.http import require_POST, require_GET from accounts.models import User, AppPassword from api_koreader.forms import SyncDocumentEntryForm -from api_koreader.models import SyncDocumentEntry +from api_koreader.models import SyncDocumentEntry, ub_to_sde +from reader.models import UserBook def process_auth_user(request) -> tuple[None, HttpResponse] | tuple[User, None]: @@ -123,7 +123,7 @@ def get_progress(request, document): ret_obj = {} - document_obj = SyncDocumentEntry.objects.filter(user=user, key=document).first() + document_obj = SyncDocumentEntry.objects.filter(user=user, key__iexact=document).first() if document_obj is not None: ret_obj["progress"] = document_obj.progress ret_obj["percentage"] = document_obj.percentage @@ -131,5 +131,21 @@ def get_progress(request, document): ret_obj["device_id"] = document_obj.device_id ret_obj["device"] = document_obj.device ret_obj["timestamp"] = int(document_obj.updated_at.timestamp()) + else: + # Try checking for a UserBook object and create a SyncDocumentEntry if it exists + ub_obj: UserBook = UserBook.objects.filter(user=user, book__partial_md5__iexact=document).first() + if ub_obj is not None: + # Create a SyncDocumentEntry + new_obj = SyncDocumentEntry( + user=user, + key=document + ) + ub_to_sde(ub_obj, new_obj) # Convert UserBook to SyncDocumentEntry - this will also save + ret_obj["progress"] = new_obj.progress + ret_obj["percentage"] = new_obj.percentage + ret_obj["document"] = new_obj.key + ret_obj["device_id"] = new_obj.device_id + ret_obj["device"] = new_obj.device + ret_obj["timestamp"] = int(new_obj.updated_at.timestamp()) return JsonResponse(ret_obj)