2020import cv2
2121import numpy as np
2222import pillow_avif # noqa: F401 # pyright: ignore[reportUnusedImport]
23+ import py7zr
2324import rarfile
2425import rawpy
2526import srctools
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+
96112class _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
113131class 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