diff --git a/comic/models.py b/comic/models.py
index aef6877..6f89ff4 100644
--- a/comic/models.py
+++ b/comic/models.py
@@ -1,3 +1,4 @@
+import io
import mimetypes
import uuid
import zipfile
@@ -8,15 +9,15 @@ from os import listdir
from pathlib import Path
from typing import Optional, List, Union, Tuple
-import PyPDF4
-import PyPDF4.utils
+import fitz
import rarfile
-from PIL import Image
+from PIL import Image, UnidentifiedImageError
from django.conf import settings
from django.contrib.auth.models import User
from django.core.files.uploadedfile import InMemoryUploadedFile
from django.db import models
from django.db.transaction import atomic
+from django.templatetags.static import static
from django.utils.http import urlsafe_base64_encode
from imagekit.models import ProcessedImageField
from imagekit.processors import ResizeToFill
@@ -62,22 +63,18 @@ class Directory(models.Model):
return self.thumbnail.url
else:
self.generate_thumbnail()
- return self.thumbnail.url
+ if self.thumbnail:
+ return self.thumbnail.url
+ else:
+ return static('img/placeholder.png')
def generate_thumbnail(self):
- book = ComicBook.objects.filter(directory=self).order_by('file_name').first()
+ book: ComicBook = ComicBook.objects.filter(directory=self).order_by('file_name').first()
if not book:
return
- img, content_type = book.get_image(0)
- pil_data = Image.open(img)
- self.thumbnail = InMemoryUploadedFile(
- img,
- None,
- f'{self.name}.jpg',
- content_type,
- pil_data.tell(),
- None
- )
+ if not book.thumbnail:
+ book.generate_thumbnail()
+ self.thumbnail = book.thumbnail
self.save()
@property
@@ -176,9 +173,32 @@ class ComicBook(models.Model):
self.generate_thumbnail()
return self.thumbnail.url
- def generate_thumbnail(self, page_index: int = 0):
- img, content_type = self.get_image(page_index)
- pil_data = Image.open(img)
+ def generate_thumbnail(self, page_index: int = None):
+
+ if Path(self.file_name).suffix.lower() == '.pdf':
+ if page_index:
+ img, pil_data = self._get_pdf_image(page_index)
+ else:
+ img, pil_data = self._get_pdf_image(0)
+ content_type = 'Image/JPEG'
+ else:
+ if page_index:
+ img, content_type = self.get_image(page_index)
+ pil_data = Image.open(img)
+ else:
+ for x in range(ComicPage.objects.filter(Comic=self).count()):
+ try:
+ img, content_type = self.get_image(x)
+ pil_data = Image.open(img)
+ break
+ except UnidentifiedImageError:
+ continue
+ try:
+ img
+ content_type
+ pil_data
+ except NameError:
+ return
self.thumbnail = InMemoryUploadedFile(
img,
None,
@@ -189,6 +209,18 @@ class ComicBook(models.Model):
)
self.save()
+ def _get_pdf_image(self, page_index: int):
+ doc = fitz.open(self.get_pdf())
+ page = doc[page_index]
+ pix = page.get_pixmap()
+ mode = "RGBA" if pix.alpha else "RGB"
+ pil_data = Image.frombytes(mode, [pix.width, pix.height], pix.samples)
+ img = io.BytesIO()
+ pil_data.save(img, format="JPEG")
+ img.seek(0)
+ return img, pil_data
+
+
def is_last_page(self, page):
if (self.page_count - 1) == page:
return True
@@ -351,7 +383,7 @@ class ComicBook(models.Model):
else:
return Path(settings.COMIC_BOOK_VOLUME, self.file_name)
- def get_archive(self) -> Tuple[Union[rarfile.RarFile, zipfile.ZipFile, PyPDF4.PdfFileReader], str]:
+ def get_archive(self) -> Tuple[Union[rarfile.RarFile, zipfile.ZipFile, fitz.Document], str]:
archive_path = self.get_archive_path
try:
return rarfile.RarFile(archive_path), 'archive'
@@ -363,8 +395,8 @@ class ComicBook(models.Model):
pass
try:
- return PyPDF4.PdfFileReader(str(archive_path)), 'pdf'
- except PyPDF4.utils.PyPdfError:
+ return fitz.open(str(archive_path)), 'pdf'
+ except RuntimeError:
pass
raise NotCompatibleArchive
diff --git a/comic/templates/base.html b/comic/templates/base.html
index 6b22f41..d34c512 100644
--- a/comic/templates/base.html
+++ b/comic/templates/base.html
@@ -9,7 +9,7 @@
-
+
{% block title %}CB Reader{% endblock %}
@@ -28,7 +28,7 @@