Skip to content

Commit bbfc272

Browse files
authored
feat: render .cbt thumbnails. (#1116)
1 parent 2df92f2 commit bbfc272

File tree

1 file changed

+24
-4
lines changed

1 file changed

+24
-4
lines changed

src/tagstudio/qt/previews/renderer.py

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,13 @@
77
import hashlib
88
import math
99
import os
10+
import tarfile
1011
import xml.etree.ElementTree as ET
1112
import zipfile
1213
from copy import deepcopy
1314
from io import BytesIO
1415
from pathlib import Path
15-
from typing import TYPE_CHECKING, cast
16+
from typing import TYPE_CHECKING, Literal, cast
1617
from warnings import catch_warnings
1718
from xml.etree.ElementTree import Element
1819

@@ -92,6 +93,23 @@
9293
logger.exception('[ThumbRenderer] Could not import the "pillow_jxl" module')
9394

9495

96+
class _TarFile(tarfile.TarFile):
97+
"""Wrapper around tarfile.TarFile to mimic zipfile.ZipFile's API."""
98+
99+
def __init__(self, filepath: Path, mode: Literal["r"]) -> None:
100+
super().__init__(filepath, mode)
101+
102+
def namelist(self) -> list[str]:
103+
return self.getnames()
104+
105+
def read(self, name: str) -> bytes:
106+
return self.extractfile(name).read()
107+
108+
109+
type _Archive_T = type[zipfile.ZipFile] | type[rarfile.RarFile] | type[_TarFile]
110+
type _Archive = zipfile.ZipFile | rarfile.RarFile | _TarFile
111+
112+
95113
class ThumbRenderer(QObject):
96114
"""A class for rendering image and file thumbnails."""
97115

@@ -871,9 +889,11 @@ def _epub_cover(filepath: Path, ext: str) -> Image.Image | None:
871889
"""
872890
im: Image.Image | None = None
873891
try:
874-
archiver: type[zipfile.ZipFile] | type[rarfile.RarFile] = zipfile.ZipFile
892+
archiver: _Archive_T = zipfile.ZipFile
875893
if ext == ".cbr":
876894
archiver = rarfile.RarFile
895+
elif ext == ".cbt":
896+
archiver = _TarFile
877897

878898
with archiver(filepath, "r") as archive:
879899
if "ComicInfo.xml" in archive.namelist():
@@ -899,12 +919,12 @@ def _epub_cover(filepath: Path, ext: str) -> Image.Image | None:
899919

900920
@staticmethod
901921
def __cover_from_comic_info(
902-
archive: zipfile.ZipFile | rarfile.RarFile, comic_info: Element, cover_type: str
922+
archive: _Archive, comic_info: Element, cover_type: str
903923
) -> Image.Image | None:
904924
"""Extract the cover specified in ComicInfo.xml.
905925
906926
Args:
907-
archive (zipfile.ZipFile | rarfile.RarFile): The current ePub file.
927+
archive (_Archive): The current ePub file.
908928
comic_info (Element): The parsed ComicInfo.xml.
909929
cover_type (str): The type of cover to load.
910930

0 commit comments

Comments
 (0)