This commit is contained in:
2026-05-23 22:15:55 +02:00
parent 067ca89f48
commit ec1342d146
3 changed files with 25 additions and 6 deletions
+1 -1
View File
@@ -789,7 +789,7 @@ class ComicInfoBuilder:
if favs is not None: rows.append(f"<tr><td {_TD}>Favorites</td><td>{favs:,}</td></tr>") if favs is not None: rows.append(f"<tr><td {_TD}>Favorites</td><td>{favs:,}</td></tr>")
if rows: if rows:
link = f'<a href="{url}">MyAnimeList</a>' if url else "MyAnimeList" link = f'<a href="{url}" target="_blank">MyAnimeList</a>' if url else "MyAnimeList"
parts.append(f"<p>{link} stats as of {as_of}:</p><table>{''.join(rows)}</table>") parts.append(f"<p>{link} stats as of {as_of}:</p><table>{''.join(rows)}</table>")
# 2. Description — Markdown → HTML (middle) ----------------------- # 2. Description — Markdown → HTML (middle) -----------------------
+2 -2
View File
@@ -432,7 +432,7 @@ def _build_character_description(details: dict) -> str:
url = details.get("url") or "" url = details.get("url") or ""
favorites = details.get("favorites") favorites = details.get("favorites")
if url and favorites is not None: if url and favorites is not None:
parts.append(f'<p><a href="{url}">Favorites: {favorites:,}</a></p>') parts.append(f'<p><a href="{url}" target="_blank">Favorites: {favorites:,}</a></p>')
about = (details.get("about") or "").strip() about = (details.get("about") or "").strip()
if about: if about:
parts.append(_plain_to_html(about)) parts.append(_plain_to_html(about))
@@ -469,7 +469,7 @@ def _build_person_description(details: dict) -> str:
f'<td><a href="{website}">{website}</a></td></tr>' f'<td><a href="{website}">{website}</a></td></tr>'
) )
if favorites is not None: if favorites is not None:
fav_cell = (f'<a href="{url}">{favorites:,}</a>' if url fav_cell = (f'<a href="{url}" target="_blank">{favorites:,}</a>' if url
else f"{favorites:,}") else f"{favorites:,}")
rows.append( rows.append(
f"<tr><td {_TD}>Member Favorites</td><td>{fav_cell}</td></tr>") f"<tr><td {_TD}>Member Favorites</td><td>{fav_cell}</td></tr>")
+22 -3
View File
@@ -69,12 +69,30 @@ _SOURCE_LABEL_RE = re.compile(
re.IGNORECASE, re.IGNORECASE,
) )
# Characters that Windows (and SMB shares) forbid in path components.
_WIN_ILLEGAL_RE = re.compile(r'[\\/*?"<>|]')
def _natural_key(name: str) -> list: def _natural_key(name: str) -> list:
return [int(p) if p.isdigit() else p.lower() return [int(p) if p.isdigit() else p.lower()
for p in re.split(r"(\d+)", name)] for p in re.split(r"(\d+)", name)]
def _sanitize_dirname(name: str) -> str:
"""
Makes a string safe to use as a Windows (or SMB) directory name.
Rules applied:
- ": " or ":" surrounded by optional spaces -> " - "
("Call of the Night: Paradise Arc" -> "Call of the Night - Paradise Arc")
- Remaining Windows-illegal chars (\\ / * ? " < > |) are stripped.
- Leading/trailing dots and spaces are removed (Windows restriction).
"""
name = re.sub(r"\s*:\s*", " - ", name)
name = _WIN_ILLEGAL_RE.sub("", name)
return name.strip(". ")
_SUWAYOMI_WANTED = {"Title", "Series", "Number", "Summary", _SUWAYOMI_WANTED = {"Title", "Series", "Number", "Summary",
"Writer", "Penciller", "Genre", "Web", "Writer", "Penciller", "Genre", "Web",
"Year", "Month", "Day"} "Year", "Month", "Day"}
@@ -326,8 +344,9 @@ class SuwayomiMover:
except Exception as exc: except Exception as exc:
print(f" [warn] metadata fetch failed: {exc}") print(f" [warn] metadata fetch failed: {exc}")
# Destination folder uses the MangaBaka canonical title. # Destination folder uses the MangaBaka canonical title, sanitized for
dest_series = self._dst / mangabaka_title # Windows / SMB paths (no colons, illegal chars, leading/trailing dots).
dest_series = self._dst / _sanitize_dirname(mangabaka_title)
dest_series.mkdir(parents=True, exist_ok=True) dest_series.mkdir(parents=True, exist_ok=True)
chapter_results: list[dict] = [] chapter_results: list[dict] = []
@@ -403,7 +422,7 @@ if __name__ == "__main__":
) )
# Process a single series # Process a single series
result = mover.process_series("Yofukashi no Uta") result = mover.process_series("Yofukashi no Uta_ Rakuen-hen")
ok = sum(1 for c in result["chapters"] if c["ok"]) ok = sum(1 for c in result["chapters"] if c["ok"])
failed = sum(1 for c in result["chapters"] if not c["ok"]) failed = sum(1 for c in result["chapters"] if not c["ok"])
print(f"\nDone: {ok} ok, {failed} failed") print(f"\nDone: {ok} ok, {failed} failed")