Skip to content

Commit f42de90

Browse files
Service order adjustments (#15)
- Set service order, fixes #14 - Only process necessary archives
1 parent 95ed2dc commit f42de90

7 files changed

Lines changed: 91 additions & 22 deletions

File tree

perdoo/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ def setup_logging(debug: bool = False) -> None:
6464
console_handler.setLevel(logging.DEBUG if debug else logging.INFO)
6565
console_handler.setFormatter(logging.Formatter("%(message)s"))
6666
file_handler = logging.FileHandler(filename=log_folder / "perdoo.log")
67+
file_handler.setLevel(logging.DEBUG)
6768
logging.basicConfig(
6869
format="[%(asctime)s] [%(levelname)-8s] {%(name)s} | %(message)s",
6970
datefmt="%Y-%m-%d %H:%M:%S",

perdoo/__main__.py

Lines changed: 50 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
from perdoo.models.metadata import Format, Meta, Source, Tool
2020
from perdoo.models.metron_info import InformationSource
2121
from perdoo.services import Comicvine, League, Marvel, Metron
22-
from perdoo.settings import OutputFormat, Settings
22+
from perdoo.settings import OutputFormat, Service, Settings
2323
from perdoo.utils import Details, Identifications, get_metadata_id, list_files, sanitize
2424

2525
LOGGER = logging.getLogger("perdoo")
@@ -47,14 +47,15 @@ def convert_collection(path: Path, output: OutputFormat) -> None:
4747
archive_type.convert(old_archive=archive)
4848

4949

50-
def read_meta(archive: BaseArchive) -> tuple[Meta, Details]:
50+
def read_meta(archive: BaseArchive) -> tuple[Meta | None, Details | None]:
5151
filenames = archive.list_filenames()
5252

5353
def read_meta_file(cls: type[InfoModel], filename: str) -> InfoModel | None:
5454
if filename in filenames:
5555
return cls.from_bytes(content=archive.read_file(filename=filename))
5656
return None
5757

58+
# region Read Metadata
5859
try:
5960
metadata = read_meta_file(cls=Metadata, filename="/Metadata.xml") or read_meta_file(
6061
cls=Metadata, filename="Metadata.xml"
@@ -97,6 +98,9 @@ def read_meta_file(cls: type[InfoModel], filename: str) -> InfoModel | None:
9798
return meta, details
9899
except ValidationError:
99100
LOGGER.error("%s contains an invalid Metadata file", archive.path.name) # noqa: TRY400
101+
# endregion
102+
103+
# region Read MetronInfo
100104
try:
101105
metron_info = read_meta_file(cls=MetronInfo, filename="/MetronInfo.xml") or read_meta_file(
102106
cls=MetronInfo, filename="MetronInfo.xml"
@@ -139,6 +143,9 @@ def read_meta_file(cls: type[InfoModel], filename: str) -> InfoModel | None:
139143
return Meta(date_=date.today(), tool=Tool(value="MetronInfo")), details
140144
except ValidationError:
141145
LOGGER.error("%s contains an invalid MetronInfo file", archive.path.name) # noqa: TRY400
146+
# endregion
147+
148+
# region Read ComicInfo
142149
try:
143150
comic_info = read_meta_file(cls=ComicInfo, filename="/ComicInfo.xml") or read_meta_file(
144151
cls=ComicInfo, filename="ComicInfo.xml"
@@ -151,11 +158,28 @@ def read_meta_file(cls: type[InfoModel], filename: str) -> InfoModel | None:
151158
return Meta(date_=date.today(), tool=Tool(value="ComicInfo")), details
152159
except ValidationError:
153160
LOGGER.error("%s contains an invalid ComicInfo file", archive.path.name) # noqa: TRY400
154-
155-
return Meta(date_=date.today(), tool=Tool(value="Manual")), Details(
156-
series=Identifications(search=Prompt.ask("Series title", console=CONSOLE)),
157-
issue=Identifications(),
158-
)
161+
# endregion
162+
163+
return None, None
164+
165+
166+
def load_archives(
167+
path: Path, output: OutputFormat, force: bool = False
168+
) -> list[tuple[Path, BaseArchive, Details | None]]:
169+
archives = []
170+
with CONSOLE.status(f"Searching for {output} files"):
171+
for file in list_files(path, f".{output}"):
172+
archive = get_archive(path=file)
173+
LOGGER.debug("Reading %s", file.stem)
174+
meta, details = read_meta(archive=archive)
175+
if not meta or not details:
176+
archives.append((file, archive, details))
177+
continue
178+
difference = abs(date.today() - meta.date_)
179+
if force or meta.tool != Tool() or difference.days >= 28:
180+
archives.append((file, archive, details))
181+
continue
182+
return archives
159183

160184

161185
def fetch_from_services(
@@ -181,7 +205,15 @@ def fetch_from_services(
181205
LOGGER.warning("No external services configured")
182206
return None, None, None
183207

184-
for service in (marvel, metron, comicvine, league):
208+
services = {
209+
Service.COMICVINE: comicvine,
210+
Service.LEAGUE_OF_COMIC_GEEKS: league,
211+
Service.MARVEL: marvel,
212+
Service.METRON: metron,
213+
}
214+
215+
for service_name in settings.service_order:
216+
service = services[service_name]
185217
if not service:
186218
continue
187219
LOGGER.info("Fetching details from %s", type(service).__name__)
@@ -243,6 +275,7 @@ def process_pages(
243275
from perdoo.models.metadata import Page as MetadataPage
244276
from perdoo.models.metron_info import Page as MetronPage
245277

278+
LOGGER.info("Processing pages")
246279
rename_images(folder=folder, filename=filename)
247280
image_list = list_files(folder, *IMAGE_EXTENSIONS)
248281
metadata_pages = set()
@@ -272,16 +305,17 @@ def process_pages(
272305
def start(settings: Settings, force: bool = False) -> None:
273306
LOGGER.info("Starting Perdoo")
274307
convert_collection(path=settings.collection_folder, output=settings.output.format)
275-
for file in list_files(settings.collection_folder, f".{settings.output.format}"):
276-
archive = get_archive(path=file)
308+
archives = load_archives(
309+
path=settings.collection_folder, output=settings.output.format, force=force
310+
)
311+
312+
for file, archive, details in archives:
277313
CONSOLE.rule(file.stem)
278314
LOGGER.info("Processing %s", file.stem)
279-
meta, details = read_meta(archive=archive)
280-
281-
if not force:
282-
difference = abs(date.today() - meta.date_)
283-
if meta.tool == Tool() and difference.days < 28:
284-
continue
315+
details = details or Details( # noqa: PLW2901
316+
series=Identifications(search=Prompt.ask("Series title", console=CONSOLE)),
317+
issue=Identifications(),
318+
)
285319

286320
metadata, metron_info, comic_info = fetch_from_services(settings=settings, details=details)
287321
new_file = generate_filename(
@@ -293,7 +327,6 @@ def start(settings: Settings, force: bool = False) -> None:
293327
temp_folder = Path(temp_str)
294328
if not archive.extract_files(destination=temp_folder):
295329
return
296-
LOGGER.info("Processing %s pages", file.stem)
297330
process_pages(
298331
folder=temp_folder,
299332
metadata=metadata,

perdoo/archives/cb7.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,9 @@ def convert(old_archive: BaseArchive) -> CB7Archive | None:
7878
temp_folder = Path(temp_str)
7979
if not old_archive.extract_files(destination=temp_folder):
8080
return None
81-
archive_file = CB7Archive.archive_files(src=temp_folder, filename=old_archive.path.stem)
81+
archive_file = CB7Archive.archive_files(
82+
src=temp_folder, output_name=old_archive.path.stem
83+
)
8284
if not archive_file:
8385
return None
8486
new_filepath = old_archive.path.parent / f"{old_archive.path.stem}.cb7"

perdoo/archives/cbt.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,9 @@ def convert(old_archive: BaseArchive) -> CBTArchive | None:
7373
temp_folder = Path(temp_str)
7474
if not old_archive.extract_files(destination=temp_folder):
7575
return None
76-
archive_file = CBTArchive.archive_files(src=temp_folder, filename=old_archive.path.stem)
76+
archive_file = CBTArchive.archive_files(
77+
src=temp_folder, output_name=old_archive.path.stem
78+
)
7779
if not archive_file:
7880
return None
7981
new_filepath = old_archive.path.parent / f"{old_archive.path.stem}.cbt"

perdoo/archives/cbz.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,9 @@ def convert(old_archive: BaseArchive) -> CBZArchive | None:
6161
temp_folder = Path(temp_str)
6262
if not old_archive.extract_files(destination=temp_folder):
6363
return None
64-
archive_file = CBZArchive.archive_files(src=temp_folder, filename=old_archive.path.stem)
64+
archive_file = CBZArchive.archive_files(
65+
src=temp_folder, output_name=old_archive.path.stem
66+
)
6567
if not archive_file:
6668
return None
6769
new_filepath = old_archive.path.parent / f"{old_archive.path.stem}.cbz"

perdoo/services/marvel.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525

2626
class Marvel(BaseService[Series, Comic]):
2727
def __init__(self: Marvel, settings: MarvelSettings):
28-
cache = SqliteCache(db_name=str(get_cache_dir() / "mokkari.sqlite"), expire=14)
28+
cache = SqliteCache(db_name=str(get_cache_dir() / "esak.sqlite"), expire=14)
2929
self.session = Esak(
3030
public_key=settings.public_key, private_key=settings.private_key, cache=cache
3131
)
@@ -40,7 +40,7 @@ def _get_series_id(self: Marvel, title: str | None) -> int | None:
4040
if not options:
4141
LOGGER.warning("Unable to find any Series with the title: '%s'", title)
4242
index = create_menu(
43-
options=[f"{x.id} | {x.title} ({x.start_year})" for x in options],
43+
options=[f"{x.id} | {x.title}" for x in options],
4444
title="Marvel Series",
4545
default="None of the Above",
4646
)

perdoo/settings.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,28 @@ def __str__(self: OutputFormat) -> str:
7777
return self.value
7878

7979

80+
class Service(Enum):
81+
COMICVINE = "Comicvine"
82+
LEAGUE_OF_COMIC_GEEKS = "League of Comic Geeks"
83+
MARVEL = "Marvel"
84+
METRON = "Metron"
85+
86+
@staticmethod
87+
def load(value: str) -> Service:
88+
for entry in Service:
89+
if entry.value.casefold() == value.casefold():
90+
return entry
91+
raise ValueError(f"`{value}` isn't a valid Service")
92+
93+
def __lt__(self: Service, other) -> int: # noqa: ANN001
94+
if not isinstance(other, type(self)):
95+
raise NotImplementedError
96+
return self.value < other.value
97+
98+
def __str__(self: Service) -> str:
99+
return self.value
100+
101+
80102
class Output(SettingsModel):
81103
create_comic_info: bool = True
82104
create_metron_info: bool = True
@@ -99,6 +121,12 @@ class Settings(SettingsModel):
99121
league_of_comic_geeks: LeagueofComicGeeks = LeagueofComicGeeks()
100122
marvel: Marvel = Marvel()
101123
metron: Metron = Metron()
124+
service_order: list[Service] = [
125+
Service.METRON,
126+
Service.MARVEL,
127+
Service.COMICVINE,
128+
Service.LEAGUE_OF_COMIC_GEEKS,
129+
]
102130
output: Output = Output()
103131

104132
@classmethod
@@ -113,6 +141,7 @@ def save(self: Settings) -> Settings:
113141
with self._filename.open("wb") as stream:
114142
content = self.dict(by_alias=False)
115143
content["collection_folder"] = str(content["collection_folder"])
144+
content["service_order"] = [str(x) for x in content["service_order"]]
116145
content["output"]["format"] = str(content["output"]["format"])
117146
tomlwriter.dump(content, stream)
118147
return self

0 commit comments

Comments
 (0)