mirror of
https://github.com/ajurna/cbwebreader.git
synced 2026-11-02 10:36:55 +00:00
**Replace Flake8 with Ruff, refactor type hints, and enhance archive processing logic**
- Removed `flake8` and `flake8-annotations` from dependencies, replaced by `ruff` for linting. - Introduced cleaner type hinting and modern Python annotations (PEP 604 style) across multiple modules. - Moved archive processing to a dedicated helper (`comic.archives`) for improved maintainability. - Updated and simplified logic for archive file retrieval, directory cleaning, and user access validation. - Improved error handling and added support for user classification restrictions in API responses.
This commit is contained in:
1 parent
147a3a54ef
commit
1148f4072b
13 files changed
+236
-227
No files matched your search
+17
-23
@@ -1,16 +1,13 @@
|
||||
import io
|
||||
import mimetypes
|
||||
import uuid
|
||||
import zipfile
|
||||
from functools import reduce
|
||||
from pathlib import Path
|
||||
from typing import Optional, List, Union, Tuple, Final, IO
|
||||
from typing import IO, Final
|
||||
|
||||
# noinspection PyPackageRequirements
|
||||
import pymupdf
|
||||
import rarfile
|
||||
from PIL import Image, UnidentifiedImageError
|
||||
from PIL.Image import Image as Image_type
|
||||
from django.conf import settings
|
||||
from django.contrib.auth.models import User
|
||||
from django.core.files.uploadedfile import InMemoryUploadedFile
|
||||
@@ -19,7 +16,10 @@ from django.db.models import UniqueConstraint
|
||||
from django_boost.models.fields import AutoOneToOneField
|
||||
from imagekit.models import ProcessedImageField
|
||||
from imagekit.processors import ResizeToFill
|
||||
from PIL import Image, UnidentifiedImageError
|
||||
from PIL.Image import Image as Image_type
|
||||
|
||||
from comic.archives import get_archive_files
|
||||
from comic.errors import NotCompatibleArchive
|
||||
|
||||
if settings.UNRAR_TOOL:
|
||||
@@ -84,7 +84,7 @@ class Directory(models.Model):
|
||||
return reduce(lambda x, y: Path(x, y), path_items)
|
||||
return Path(path_items[0])
|
||||
|
||||
def get_path_items(self, path_items: Optional[List] = None) -> List[Path]:
|
||||
def get_path_items(self, path_items: list | None = None) -> list[Path]:
|
||||
if path_items is None:
|
||||
path_items = []
|
||||
path_items.append(self.name)
|
||||
@@ -92,7 +92,7 @@ class Directory(models.Model):
|
||||
self.parent.get_path_items(path_items)
|
||||
return path_items
|
||||
|
||||
def get_path_objects(self, path_items: Optional[List] = None) -> List["Directory"]:
|
||||
def get_path_objects(self, path_items: list | None = None) -> list[Directory]:
|
||||
if path_items is None:
|
||||
path_items = []
|
||||
path_items.append(self)
|
||||
@@ -141,7 +141,7 @@ class ComicBook(models.Model):
|
||||
return Path(base_dir, self.directory.get_path(), self.file_name)
|
||||
return Path(base_dir, self.file_name)
|
||||
|
||||
def get_image(self, page: int) -> Union[Tuple[IO[bytes], str], Tuple[bool, bool]]:
|
||||
def get_image(self, page: int) -> tuple[IO[bytes], str] | tuple[bool, bool]:
|
||||
if self.file_name.lower().endswith('.pdf'):
|
||||
# noinspection PyUnresolvedReferences
|
||||
doc = pymupdf.open(self.get_pdf())
|
||||
@@ -168,15 +168,16 @@ class ComicBook(models.Model):
|
||||
except zipfile.BadZipfile:
|
||||
return False, False
|
||||
|
||||
file_name, file_mime = self.get_archive_files(archive)[page]
|
||||
file_name, file_mime = get_archive_files(archive)[page]
|
||||
return archive.open(file_name), file_mime
|
||||
|
||||
def generate_thumbnail_pdf(self, page_index: int = 0) -> Tuple[io.BytesIO, Image_type, str]:
|
||||
def generate_thumbnail_pdf(self, page_index: int = 0) -> tuple[io.BytesIO, Image_type, str]:
|
||||
img, pil_data = self._get_pdf_image(page_index if page_index else 0)
|
||||
return img, pil_data, 'Image/JPEG'
|
||||
|
||||
def generate_thumbnail_archive(self, page_index: int = 0) -> Union[Tuple[io.BytesIO, Image_type, str],
|
||||
Tuple[bool, bool, bool]]:
|
||||
def generate_thumbnail_archive(
|
||||
self, page_index: int = 0
|
||||
) -> tuple[io.BytesIO, Image_type, str] | tuple[bool, bool, bool]:
|
||||
img, content_type, pil_data = False, False, False
|
||||
if page_index:
|
||||
img, content_type = self.get_image(page_index)
|
||||
@@ -209,7 +210,7 @@ class ComicBook(models.Model):
|
||||
)
|
||||
self.save()
|
||||
|
||||
def _get_pdf_image(self, page_index: int) -> Tuple[io.BytesIO, Image_type]:
|
||||
def _get_pdf_image(self, page_index: int) -> tuple[io.BytesIO, Image_type]:
|
||||
doc = pymupdf.open(self.get_pdf())
|
||||
page = doc[page_index]
|
||||
pix = page.get_pixmap()
|
||||
@@ -222,7 +223,7 @@ class ComicBook(models.Model):
|
||||
return img, pil_data
|
||||
|
||||
@staticmethod
|
||||
def process_comic_book(comic_file_path: Path, directory: "Directory" = False) -> Union["ComicBook", Path]:
|
||||
def process_comic_book(comic_file_path: Path, directory: Directory = False) -> ComicBook | Path:
|
||||
try:
|
||||
book = ComicBook.objects.get(file_name=comic_file_path.name, version=0)
|
||||
book.directory = directory
|
||||
@@ -240,7 +241,7 @@ class ComicBook(models.Model):
|
||||
return comic_file_path
|
||||
|
||||
if archive_type == 'archive':
|
||||
book.page_count = len(book.get_archive_files(archive))
|
||||
book.page_count = len(get_archive_files(archive))
|
||||
elif archive_type == 'pdf':
|
||||
book.page_count = archive.page_count
|
||||
|
||||
@@ -252,7 +253,7 @@ class ComicBook(models.Model):
|
||||
return Path(settings.COMIC_BOOK_VOLUME, self.directory.get_path(), self.file_name)
|
||||
return Path(settings.COMIC_BOOK_VOLUME, self.file_name)
|
||||
|
||||
def get_archive(self) -> Tuple[Union[rarfile.RarFile, zipfile.ZipFile, pymupdf.Document], str]:
|
||||
def get_archive(self) -> tuple[rarfile.RarFile | zipfile.ZipFile | pymupdf.Document, str]:
|
||||
archive_path = self.get_archive_path
|
||||
try:
|
||||
return rarfile.RarFile(archive_path), 'archive'
|
||||
@@ -273,17 +274,10 @@ class ComicBook(models.Model):
|
||||
def get_page_count(self) -> int:
|
||||
archive, archive_type = self.get_archive()
|
||||
if archive_type == 'archive':
|
||||
return len(self.get_archive_files(archive))
|
||||
return len(get_archive_files(archive))
|
||||
elif archive_type == 'pdf':
|
||||
return archive.page_count
|
||||
|
||||
@staticmethod
|
||||
def get_archive_files(archive: Union[zipfile.ZipFile, rarfile.RarFile]) -> List[Tuple[str, str]]:
|
||||
return [
|
||||
(x, mimetypes.guess_type(x)[0]) for x in sorted(archive.namelist())
|
||||
if not x.endswith('/') and mimetypes.guess_type(x)[0] and not x.endswith('xml')
|
||||
]
|
||||
|
||||
|
||||
class ComicStatus(models.Model):
|
||||
user = models.ForeignKey(User, unique=False, null=False, on_delete=models.CASCADE)
|
||||
|
||||
Reference in new issue
Block a user