Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ dependencies = [
"pillow-avif-plugin~=1.5",
"pillow-heif~=0.22",
"pillow-jxl-plugin~=1.3",
"py7zr==1.0.0",
"pydantic~=2.10",
"pydub~=0.25",
"PySide6==6.8.0.*",
Expand Down
26 changes: 23 additions & 3 deletions src/tagstudio/qt/previews/renderer.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import cv2
import numpy as np
import pillow_avif # noqa: F401 # pyright: ignore[reportUnusedImport]
import py7zr
import rarfile
import rawpy
import srctools
Expand Down Expand Up @@ -93,6 +94,21 @@
logger.exception('[ThumbRenderer] Could not import the "pillow_jxl" module')


class _SevenZipFile(py7zr.SevenZipFile):
"""Wrapper around py7zr.SevenZipFile to mimic zipfile.ZipFile's API."""

def __init__(self, filepath: Path, mode: Literal["r"]) -> None:
super().__init__(filepath, mode)

def read(self, name: str) -> bytes:
# SevenZipFile must be reset after every extraction
# See https://py7zr.readthedocs.io/en/stable/api.html#py7zr.SevenZipFile.extract
self.reset()
factory = py7zr.io.BytesIOFactory(limit=10485760) # 10 MiB
self.extract(targets=[name], factory=factory)
return factory.get(name).read()


class _TarFile(tarfile.TarFile):
"""Wrapper around tarfile.TarFile to mimic zipfile.ZipFile's API."""

Expand All @@ -106,8 +122,10 @@ def read(self, name: str) -> bytes:
return self.extractfile(name).read()


type _Archive_T = type[zipfile.ZipFile] | type[rarfile.RarFile] | type[_TarFile]
type _Archive = zipfile.ZipFile | rarfile.RarFile | _TarFile
type _Archive_T = (
type[zipfile.ZipFile] | type[rarfile.RarFile] | type[_SevenZipFile] | type[_TarFile]
)
type _Archive = zipfile.ZipFile | rarfile.RarFile | _SevenZipFile | _TarFile


class ThumbRenderer(QObject):
Expand Down Expand Up @@ -890,7 +908,9 @@ def _epub_cover(filepath: Path, ext: str) -> Image.Image | None:
im: Image.Image | None = None
try:
archiver: _Archive_T = zipfile.ZipFile
if ext == ".cbr":
if ext == ".cb7":
archiver = _SevenZipFile
elif ext == ".cbr":
archiver = rarfile.RarFile
elif ext == ".cbt":
archiver = _TarFile
Expand Down