diff --git a/vrobbler/apps/books/models.py b/vrobbler/apps/books/models.py index e0bd5fe..04135ed 100644 --- a/vrobbler/apps/books/models.py +++ b/vrobbler/apps/books/models.py @@ -208,6 +208,10 @@ class Book(LongPlayScrobblableMixin): def get_absolute_url(self): return reverse("books:book_detail", kwargs={"slug": self.uuid}) + @property + def resume_start_url(self): + return reverse("scrobbles:start", kwargs={"uuid": self.uuid}) + "?resume=1" + @classmethod def get_from_comicvine( cls, title: str, overwrite: bool = False, force_new: bool = False diff --git a/vrobbler/apps/scrobbles/models.py b/vrobbler/apps/scrobbles/models.py index 1ead781..995c3e5 100644 --- a/vrobbler/apps/scrobbles/models.py +++ b/vrobbler/apps/scrobbles/models.py @@ -593,6 +593,17 @@ class Scrobble(TimeStampedModel): self.stop_timestamp - self.timestamp ).seconds + if ( + self.log + and isinstance(self.log, dict) + and self.log.get("page_start") is not None + and self.log.get("page_end") is not None + and "pages_read" not in self.log + ): + self.log["pages_read"] = ( + self.log["page_end"] - self.log["page_start"] + 1 + ) + return super(Scrobble, self).save(*args, **kwargs) def get_absolute_url(self): @@ -1452,38 +1463,38 @@ class Scrobble(TimeStampedModel): return False def calculate_reading_stats(self, commit=True): - # --- Sort safely by numeric page_number --- - def safe_page_number(entry): - try: - return int(getattr("page_number", entry), 0) - except (ValueError, TypeError): - return float("inf") # push invalid entries to the end - page_data = self.log.get("page_data") - if not page_data: - logger.warning("No page data found to calculate") - return + if page_data: + # --- Sort safely by numeric page_number --- + def safe_page_number(entry): + try: + return int(getattr("page_number", entry), 0) + except (ValueError, TypeError): + return float("inf") - if isinstance(page_data, dict): - logger.warning("Page data is dict, migrate koreader data") - return + if isinstance(page_data, dict): + logger.warning("Page data is dict, migrate koreader data") + return - page_data.sort(key=safe_page_number) + page_data.sort(key=safe_page_number) - # --- Extract valid numeric page numbers --- - valid_pages = [] - for page in page_data: - try: - valid_pages.append(int(page["page_number"])) - except (ValueError, TypeError): - continue + valid_pages = [] + for page in page_data: + try: + valid_pages.append(int(page["page_number"])) + except (ValueError, TypeError): + continue - # --- Compute stats --- - if valid_pages: - self.log["page_start"] = min(valid_pages) - self.log["page_end"] = max(valid_pages) - self.log["pages_read"] = len(set(valid_pages)) + if valid_pages: + self.log["page_start"] = min(valid_pages) + self.log["page_end"] = max(valid_pages) + self.log["pages_read"] = len(set(valid_pages)) + else: + page_start = self.log.get("page_start") + page_end = self.log.get("page_end") + if page_start is not None and page_end is not None: + self.log["pages_read"] = page_end - page_start + 1 - if commit: - self.save(update_fields=["log"]) + if commit and "pages_read" in self.log: + self.save(update_fields=["log"]) diff --git a/vrobbler/apps/scrobbles/views.py b/vrobbler/apps/scrobbles/views.py index a4969f5..09dd38f 100644 --- a/vrobbler/apps/scrobbles/views.py +++ b/vrobbler/apps/scrobbles/views.py @@ -768,7 +768,25 @@ def scrobble_start(request, uuid): scrobble = None user_id = request.user.id if media_obj: - media_obj.scrobble_for_user(user_id) + log_data = None + if ( + request.GET.get("resume") + and media_obj.__class__.__name__ == Scrobble.MediaType.BOOK + ): + last_scrobble = ( + Scrobble.objects.filter( + book=media_obj, + user_id=user_id, + ) + .filter(Q(long_play_complete=False) | Q(long_play_complete__isnull=True)) + .filter(log__page_end__isnull=False) + .order_by("-timestamp") + .first() + ) + if last_scrobble and last_scrobble.logdata: + next_page = last_scrobble.logdata.page_end + 1 + log_data = {"page_start": next_page} + media_obj.scrobble_for_user(user_id, log=log_data) if scrobble: messages.add_message( diff --git a/vrobbler/templates/books/book_detail.html b/vrobbler/templates/books/book_detail.html index 8e7c3b1..1ed11fa 100644 --- a/vrobbler/templates/books/book_detail.html +++ b/vrobbler/templates/books/book_detail.html @@ -35,11 +35,7 @@

{{scrobbles.count}} scrobbles

- {% for s in scrobbles %} - {% if forloop.first %} -

Resume reading

- {% endif %} - {% endfor %} +

Resume reading

{% if charts %}