Skip to content

Commit df7cc45

Browse files
Go back to using my own archive implementation
Drop support for exporting as CBT
1 parent efe9962 commit df7cc45

27 files changed

+544
-336
lines changed

.pre-commit-config.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
repos:
22
- repo: https://github.com/astral-sh/ruff-pre-commit
3-
rev: v0.14.11
3+
rev: v0.14.13
44
hooks:
55
- id: ruff-format
66
- id: ruff-check

README.md

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,6 @@ File will be created on first run.
144144
```toml
145145
[output]
146146
folder = "~/.local/share/perdoo"
147-
format = "cbz"
148147

149148
[output.comic_info]
150149
create = true
@@ -184,10 +183,6 @@ password = "<Metron Password>"
184183
The folder where the output files will be stored.
185184
Defaults to `~/.local/share/perdoo`.
186185

187-
- `output.format`
188-
The output file format for the comic archives.
189-
Defaults to `cbz`.
190-
191186
- `output.comic_info.create`
192187
Whether to create a ComicInfo.xml file in the output archive.
193188
Defaults to `true`.

perdoo/__main__.py

Lines changed: 14 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,12 @@
1111

1212
from perdoo import __version__, get_cache_root, setup_logging
1313
from perdoo.cli import archive_app, settings_app
14-
from perdoo.comic import SUPPORTED_IMAGE_EXTENSIONS, Comic, ComicArchiveError, ComicMetadataError
14+
from perdoo.comic import Comic
15+
from perdoo.comic.errors import ComicArchiveError, ComicMetadataError
16+
from perdoo.comic.metadata import ComicInfo, MetronInfo
17+
from perdoo.comic.metadata.comic_info import Page
18+
from perdoo.comic.metadata.metron_info import Id, InformationSource
1519
from perdoo.console import CONSOLE
16-
from perdoo.metadata import ComicInfo, MetronInfo
17-
from perdoo.metadata.comic_info import Page
18-
from perdoo.metadata.metron_info import Id, InformationSource
1920
from perdoo.services import BaseService, Comicvine, Metron
2021
from perdoo.settings import Service, Services, Settings
2122
from perdoo.utils import (
@@ -74,7 +75,7 @@ def _load_comics(target: Path) -> list[Comic]:
7475
files = list_files(target) if target.is_dir() else [target]
7576
for file in files:
7677
try:
77-
comics.append(Comic(file=file))
78+
comics.append(Comic(filepath=file))
7879
except (ComicArchiveError, ComicMetadataError) as err: # noqa: PERF203
7980
LOGGER.error("Failed to load '%s' as a Comic: %s", file, err)
8081
return comics
@@ -132,13 +133,12 @@ def get_search_details(
132133
def load_page_info(entry: Comic, comic_info: ComicInfo) -> list[Page]:
133134
from PIL import Image # noqa: PLC0415
134135

135-
from perdoo.metadata.comic_info import PageType # noqa: PLC0415
136+
from perdoo.comic import IMAGE_EXTENSIONS # noqa: PLC0415
137+
from perdoo.comic.metadata.comic_info import PageType # noqa: PLC0415
136138

137139
pages = set()
138140
image_files = [
139-
x
140-
for x in entry.archive.get_filename_list()
141-
if Path(x).suffix.lower() in SUPPORTED_IMAGE_EXTENSIONS
141+
x for x in entry.archive.list_filenames() if Path(x).suffix.lower() in IMAGE_EXTENSIONS
142142
]
143143
for idx, file in enumerate(image_files):
144144
page = next((x for x in comic_info.pages if x.image == idx), None)
@@ -169,7 +169,6 @@ def sync_metadata(
169169
) -> tuple[MetronInfo | None, ComicInfo | None]:
170170
for service_name in settings.services.order:
171171
if service := services.get(service_name):
172-
LOGGER.info("Searching %s for matching issue", type(service).__name__)
173172
metron_info, comic_info = service.fetch(search=search)
174173
if metron_info or comic_info:
175174
return metron_info, comic_info
@@ -252,21 +251,19 @@ def run(
252251
comics = _load_comics(target=target)
253252
for index, entry in enumerate(comics):
254253
CONSOLE.rule(
255-
f"[{index + 1}/{len(comics)}] Importing {entry.path.name}",
254+
f"[{index + 1}/{len(comics)}] Importing {entry.filepath.name}",
256255
align="left",
257256
style="subtitle",
258257
)
259258
if not skip_convert:
260-
with CONSOLE.status(
261-
f"Converting to '{settings.output.format}'", spinner="simpleDotsScrolling"
262-
):
263-
entry.convert(extension=settings.output.format)
259+
with CONSOLE.status("Converting to '.cbz'", spinner="simpleDotsScrolling"):
260+
entry.convert_to(extension="cbz")
264261

265262
metadata: tuple[MetronInfo | None, ComicInfo | None] = (entry.metron_info, entry.comic_info)
266263

267264
if sync != SyncOption.SKIP:
268-
search = get_search_details(metadata=metadata, filename=entry.path.stem)
269-
search.filename = entry.path.stem
265+
search = get_search_details(metadata=metadata, filename=entry.filepath.stem)
266+
search.filename = entry.filepath.stem
270267
last_modified = date(1900, 1, 1)
271268
if sync == SyncOption.OUTDATED:
272269
metron_info, _ = metadata

perdoo/cli/archive.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@ def view(
2424
bool, Option("--hide-metron-info", help="Don't show the MetronInfo details.")
2525
] = False,
2626
) -> None:
27-
comic = Comic(file=target)
28-
CONSOLE.print(f"Archive format: '{comic.path.suffix}'")
27+
comic = Comic(filepath=target)
28+
CONSOLE.print(f"Archive format: '{comic.filepath.suffix}'")
2929
if not hide_metron_info:
3030
if not comic.metron_info:
3131
CONSOLE.print("No MetronInfo found")

perdoo/comic.py

Lines changed: 0 additions & 198 deletions
This file was deleted.

perdoo/comic/__init__.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
__all__ = ["IMAGE_EXTENSIONS", "Comic"]
2+
3+
from perdoo.comic.comic import IMAGE_EXTENSIONS, Comic

perdoo/comic/archive/__init__.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
__all__ = ["Archive", "CB7Archive", "CBRArchive", "CBTArchive", "CBZArchive"]
2+
3+
from perdoo.comic.archive._base import Archive
4+
from perdoo.comic.archive.rar import CBRArchive
5+
from perdoo.comic.archive.sevenzip import CB7Archive
6+
from perdoo.comic.archive.tar import CBTArchive
7+
from perdoo.comic.archive.zip import CBZArchive

perdoo/comic/archive/_base.py

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
__all__ = ["Archive"]
2+
3+
from abc import ABC, abstractmethod
4+
from pathlib import Path
5+
from typing import ClassVar
6+
7+
from perdoo.comic.errors import ComicArchiveError
8+
9+
try:
10+
from typing import Self # Python >= 3.11
11+
except ImportError:
12+
from typing_extensions import Self # Python < 3.11
13+
14+
15+
class Archive(ABC):
16+
_registry: ClassVar[list[type["Archive"]]] = []
17+
EXTENSION: ClassVar[str] = ""
18+
19+
def __init__(self, filepath: Path) -> None:
20+
self._filepath = filepath
21+
22+
def __init_subclass__(cls, **kwargs) -> None: # noqa: ANN003
23+
super().__init_subclass__(**kwargs)
24+
Archive._registry.append(cls)
25+
26+
@property
27+
def filepath(self) -> Path:
28+
return self._filepath
29+
30+
@classmethod
31+
def load(cls, filepath: Path) -> Self:
32+
for _cls in cls._registry:
33+
if _cls.is_archive(filepath):
34+
return _cls(filepath=filepath)
35+
raise ComicArchiveError(f"Unsupported archive format: {filepath.suffix.lower()}")
36+
37+
@classmethod
38+
@abstractmethod
39+
def is_archive(cls, path: Path) -> bool: ...
40+
41+
@abstractmethod
42+
def list_filenames(self) -> list[str]: ...
43+
44+
def exists(self, filename: str) -> bool:
45+
return filename in self.list_filenames()
46+
47+
@abstractmethod
48+
def read_file(self, filename: str) -> bytes: ...
49+
50+
def write_file(self, filename: str, data: str | bytes) -> None: # noqa: ARG002
51+
raise ComicArchiveError(f"Unable to write {filename} to {self.filepath.name}.")
52+
53+
def remove_file(self, filename: str) -> None:
54+
raise ComicArchiveError(f"Unable to delete {filename} in {self.filepath.name}.")
55+
56+
@abstractmethod
57+
def extract_files(self, destination: Path) -> None: ...
58+
59+
@classmethod
60+
def archive_files(cls, src: Path, output_name: str, files: list[Path]) -> Self: # noqa: ARG003
61+
raise ComicArchiveError(f"Unable to archive files to {output_name}.")
62+
63+
@classmethod
64+
def convert_from(cls, old_archive: "Archive") -> Self:
65+
raise ComicArchiveError(
66+
f"Unable to convert {old_archive.filepath.name} to a {cls.EXTENSION}"
67+
)

0 commit comments

Comments
 (0)