Skip to content

Commit 9319b6e

Browse files
authored
feat: render .cb7 thumbnails. (#1118)
1 parent 00aeb04 commit 9319b6e

File tree

2 files changed

+24
-3
lines changed

2 files changed

+24
-3
lines changed

pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ dependencies = [
2020
"pillow-avif-plugin~=1.5",
2121
"pillow-heif~=0.22",
2222
"pillow-jxl-plugin~=1.3",
23+
"py7zr==1.0.0",
2324
"pydantic~=2.10",
2425
"pydub~=0.25",
2526
"PySide6==6.8.0.*",

src/tagstudio/qt/previews/renderer.py

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import cv2
2121
import numpy as np
2222
import pillow_avif # noqa: F401 # pyright: ignore[reportUnusedImport]
23+
import py7zr
2324
import rarfile
2425
import rawpy
2526
import srctools
@@ -93,6 +94,21 @@
9394
logger.exception('[ThumbRenderer] Could not import the "pillow_jxl" module')
9495

9596

97+
class _SevenZipFile(py7zr.SevenZipFile):
98+
"""Wrapper around py7zr.SevenZipFile to mimic zipfile.ZipFile's API."""
99+
100+
def __init__(self, filepath: Path, mode: Literal["r"]) -> None:
101+
super().__init__(filepath, mode)
102+
103+
def read(self, name: str) -> bytes:
104+
# SevenZipFile must be reset after every extraction
105+
# See https://py7zr.readthedocs.io/en/stable/api.html#py7zr.SevenZipFile.extract
106+
self.reset()
107+
factory = py7zr.io.BytesIOFactory(limit=10485760) # 10 MiB
108+
self.extract(targets=[name], factory=factory)
109+
return factory.get(name).read()
110+
111+
96112
class _TarFile(tarfile.TarFile):
97113
"""Wrapper around tarfile.TarFile to mimic zipfile.ZipFile's API."""
98114

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

108124

109-
type _Archive_T = type[zipfile.ZipFile] | type[rarfile.RarFile] | type[_TarFile]
110-
type _Archive = zipfile.ZipFile | rarfile.RarFile | _TarFile
125+
type _Archive_T = (
126+
type[zipfile.ZipFile] | type[rarfile.RarFile] | type[_SevenZipFile] | type[_TarFile]
127+
)
128+
type _Archive = zipfile.ZipFile | rarfile.RarFile | _SevenZipFile | _TarFile
111129

112130

113131
class ThumbRenderer(QObject):
@@ -890,7 +908,9 @@ def _epub_cover(filepath: Path, ext: str) -> Image.Image | None:
890908
im: Image.Image | None = None
891909
try:
892910
archiver: _Archive_T = zipfile.ZipFile
893-
if ext == ".cbr":
911+
if ext == ".cb7":
912+
archiver = _SevenZipFile
913+
elif ext == ".cbr":
894914
archiver = rarfile.RarFile
895915
elif ext == ".cbt":
896916
archiver = _TarFile

0 commit comments

Comments
 (0)