Skip to content

Commit

Permalink
Add ComicInfo -> Metroninfo Migration Function (#160)
Browse files Browse the repository at this point in the history
* Add `migrate_ci_to_mi` function
* Refactor title print functions
* Add option for `migrate`
* Require latest darkseid
  • Loading branch information
bpepple authored Nov 30, 2024
1 parent bcc68cb commit c37c8e9
Show file tree
Hide file tree
Showing 8 changed files with 91 additions and 32 deletions.
3 changes: 3 additions & 0 deletions metrontagger/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,9 @@ def get_configs(opts: Namespace) -> MetronTaggerSettings: # noqa: PLR0912
if opts.comicinfo:
config.use_comic_info = opts.comicinfo

if opts.migrate:
config.migrate = opts.migrate

return config


Expand Down
6 changes: 6 additions & 0 deletions metrontagger/options.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,12 @@ def make_parser() -> argparse.ArgumentParser:
action="store_true",
default=False,
)
parser.add_argument(
"--migrate",
help="Migrate information from a ComicInfo.xml into a *new* MetronInfo.xml",
action="store_true",
default=False,
)
parser.add_argument(
"--version",
action="version",
Expand Down
72 changes: 52 additions & 20 deletions metrontagger/run.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
from metrontagger.filerenamer import FileRenamer
from metrontagger.filesorter import FileSorter
from metrontagger.logging import init_logging
from metrontagger.utils import create_print_title

if TYPE_CHECKING:
from metrontagger.settings import MetronTaggerSettings
Expand All @@ -40,6 +41,42 @@ def __init__(self: Runner, config: MetronTaggerSettings) -> None:

self.config = config

@staticmethod
def migrate_ci_to_mi(file_list: list[Path]) -> None:
"""
Migrate ComicInfo.xml metadata to MetronInfo.xml format.
This static method processes a list of comic files, checking for existing ComicInfo.xml metadata and
migrating it to the MetronInfo.xml format if applicable. It provides feedback on the migration process
through printed messages.
Args:
file_list (list[Path]): A list of Path objects representing the comic files to be processed.
Returns:
None
"""

msg = create_print_title("Migrating ComicInfo.xml to MetronInfo.xml:")
questionary.print(msg, style=Styles.TITLE)

for item in file_list:
comic = Comic(item)
if comic.has_metadata(MetadataFormat.COMIC_RACK) and not comic.has_metadata(
MetadataFormat.METRON_INFO
):
md = comic.read_metadata(MetadataFormat.COMIC_RACK)
if comic.write_metadata(md, MetadataFormat.METRON_INFO):
questionary.print(
f"Migrated information to new MetronInfo.xml for '{comic}'",
style=Styles.SUCCESS,
)
else:
questionary.print(
f"There was an error writing MetronInfo.xml for '{comic}'",
style=Styles.ERROR,
)

def rename_comics(self: Runner, file_list: list[Path]) -> list[Path]:
"""Rename comic archives based on metadata.
Expand All @@ -52,11 +89,8 @@ def rename_comics(self: Runner, file_list: list[Path]) -> list[Path]:
Returns:
list[Path]: The updated list of file paths after renaming.
"""

questionary.print(
"\nStarting comic archive renaming:\n-------------------------------",
style=Styles.TITLE,
)
msg = create_print_title("Renaming ComicInfo.xml to MetronInfo.xml:")
questionary.print(msg, style=Styles.TITLE)

# Lists to track filename changes
new_file_names: list[Path] = []
Expand Down Expand Up @@ -113,8 +147,8 @@ def _export_to_zip(self: Runner, file_list: list[Path]) -> None:
Returns:
None
"""

questionary.print("\nExporting to cbz:\n-----------------", style=Styles.TITLE)
msg = create_print_title("Exporting to CBZ:")
questionary.print(msg, style=Styles.TITLE)
for comic in file_list:
ca = Comic(str(comic))
if ca.is_rar():
Expand All @@ -139,8 +173,8 @@ def _validate_comic_info(
self: Runner, file_list: list[Path], remove_ci: bool = False
) -> None:
"""Validate ComicInfo metadata in comic archives."""

questionary.print("\nValidating ComicInfo:\n---------------------", style=Styles.TITLE)
msg = create_print_title("Validating ComicInfo:")
questionary.print(msg, style=Styles.TITLE)
for comic in file_list:
ca = Comic(comic)
has_comic_rack = ca.has_metadata(MetadataFormat.COMIC_RACK)
Expand Down Expand Up @@ -212,10 +246,8 @@ def _sort_comic_list(self: Runner, file_list: list[Path]) -> None:
)
return

questionary.print(
"\nStarting sorting of comic archives:\n----------------------------------",
style=Styles.TITLE,
)
msg = create_print_title("Starting Sorting of Comic Archives:")
questionary.print(msg, style=Styles.TITLE)
file_sorter = FileSorter(self.config.sort_dir)
for comic in file_list:
result = file_sorter.sort_comics(comic)
Expand All @@ -233,11 +265,8 @@ def _comics_with_no_metadata(self: Runner, file_list: list[Path]) -> None:
Returns:
None
"""

questionary.print(
"\nShowing files without metadata:\n-------------------------------",
style=Styles.TITLE,
)
msg = create_print_title("Showing Files Without Metadata:")
questionary.print(msg, style=Styles.TITLE)

if not (self.config.use_comic_info or self.config.use_metron_info):
return
Expand All @@ -264,8 +293,8 @@ def _delete_metadata(self: Runner, file_list: list[Path]) -> None:
Returns:
None
"""

questionary.print("\nRemoving metadata:\n-----------------", style=Styles.TITLE)
msg = create_print_title("Removing Metadata:")
questionary.print(msg, style=Styles.TITLE)
for item in file_list:
comic_archive = Comic(item)
formats_removed = []
Expand Down Expand Up @@ -533,6 +562,9 @@ def run(self: Runner) -> None: # noqa: PLR0912
else:
t.identify_comics(file_list, self.config)

if self.config.migrate:
self.migrate_ci_to_mi(file_list)

if self.config.rename:
file_list = self.rename_comics(file_list)

Expand Down
1 change: 1 addition & 0 deletions metrontagger/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ def __init__(self: MetronTaggerSettings, config_dir: str | None = None) -> None:
self.validate: bool = False
self.remove_non_valid: bool = False
self.duplicates: bool = False
self.migrate: bool = False

# Rename settings
self.rename_template = "%series% v%volume% #%issue% (%year%)"
Expand Down
14 changes: 7 additions & 7 deletions metrontagger/talker.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@

from metrontagger import __version__
from metrontagger.styles import Styles
from metrontagger.utils import create_query_params
from metrontagger.utils import create_print_title, create_query_params

LOGGER = getLogger(__name__)

Expand Down Expand Up @@ -383,12 +383,14 @@ def _post_process_matches(self: Talker) -> None:
"""
# Print file matching results.
if self.match_results.good_matches:
questionary.print("\nSuccessful matches:\n------------------", style=Styles.TITLE)
msg = create_print_title("Successful Matches:")
questionary.print(msg, style=Styles.TITLE)
for comic in self.match_results.good_matches:
questionary.print(f"{comic}", style=Styles.SUCCESS)

if self.match_results.no_matches:
questionary.print("\nNo matches:\n------------------", style=Styles.TITLE)
msg = create_print_title("No Matches:")
questionary.print(msg, style=Styles.TITLE)
for comic in self.match_results.no_matches:
questionary.print(f"{comic}", style=Styles.WARNING)

Expand Down Expand Up @@ -474,10 +476,8 @@ def identify_comics(
Returns:
None
"""
questionary.print(
"\nStarting online search and tagging:\n----------------------------------",
style=Styles.TITLE,
)
msg = create_print_title("Starting Online Search and Tagging:")
questionary.print(msg, style=Styles.TITLE)

for fn in file_list:
if config.ignore_existing:
Expand Down
17 changes: 17 additions & 0 deletions metrontagger/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,23 @@
from urllib.parse import quote_plus


def create_print_title(txt: str) -> str:
"""Create a formatted title string for printing.
This function generates a title string that includes the provided text, formatted with newlines
and a line of dashes beneath it for visual separation. It is useful for enhancing the readability
of printed output by clearly delineating sections.
Args:
txt (str): The text to be used as the title.
Returns:
str: The formatted title string, including newlines and dashes.
"""
result = f"\n{txt}\n"
return result + "-" * len(txt)


def cleanup_string(path_name: int | str | None) -> str | None:
"""Clean up and sanitize a string for use as a path name.
Expand Down
8 changes: 4 additions & 4 deletions poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ imagehash = "^4.3.1"
pandas = "^2.2.1"
comicfn2dict = "^0.2.4"
tqdm = "^4.66.4"
darkseid = "^5.0.1"
darkseid = "^5.1.0"

[tool.poetry.group.dev.dependencies]
pre-commit = "^3.6.2"
Expand Down

0 comments on commit c37c8e9

Please sign in to comment.