Skip to content

Commit 23a8e53

Browse files
Switch from custom menu, to questionary
1 parent d706bac commit 23a8e53

14 files changed

Lines changed: 1085 additions & 562 deletions

File tree

.github/workflows/publishing.yaml

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,28 +10,44 @@ jobs:
1010
runs-on: ubuntu-latest
1111

1212
steps:
13-
- uses: actions/checkout@v4
14-
- uses: actions/setup-python@v5
15-
with:
16-
python-version: '3.13'
17-
- name: Install pypa/build
18-
run: pip install build
19-
- name: Build a binary wheel and a source tarball
20-
run: python -m build
13+
- uses: actions/checkout@v5
14+
- uses: astral-sh/setup-uv@v5
15+
- name: Setup Python
16+
run: uv python install 3.13
17+
- name: Build wheel and source tarball
18+
run: uv build
2119
- uses: actions/upload-artifact@v4
2220
with:
2321
name: python-package-distributions
2422
path: dist/
2523

26-
publish-to-pypi:
27-
if: startsWith(github.ref, 'refs/tags/')
24+
validate:
25+
name: Validate dist
2826
needs:
2927
- build
28+
permissions: {}
29+
runs-on: ubuntu-latest
30+
31+
steps:
32+
- uses: actions/download-artifact@v5
33+
with:
34+
name: python-package-distributions
35+
path: dist/
36+
- uses: astral-sh/setup-uv@v5
37+
- name: Setup Python
38+
run: uv python install 3.13
39+
- name: Validate dist
40+
run: uv run --with twine twine check dist/*
3041

42+
publish:
3143
environment:
3244
name: pypi
3345
url: https://pypi.org/p/perdoo
46+
if: startsWith(github.ref, 'refs/tags/')
3447
name: Publish to PyPI
48+
needs:
49+
- build
50+
- validate
3551
permissions:
3652
id-token: write
3753
runs-on: ubuntu-latest

.pre-commit-config.yaml

Lines changed: 15 additions & 7 deletions
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.12.4
3+
rev: v0.13.1
44
hooks:
55
- id: ruff-format
66
- id: ruff-check
@@ -16,19 +16,27 @@ repos:
1616
- --wrap=keep
1717
exclude: ".github\/ISSUE_TEMPLATE\/.*.md"
1818
- repo: https://github.com/pre-commit/pre-commit-hooks
19-
rev: v5.0.0
19+
rev: v6.0.0
2020
hooks:
21+
- id: check-added-large-files
2122
- id: check-ast
2223
- id: check-builtin-literals
2324
- id: check-case-conflict
2425
- id: check-docstring-first
26+
# - id: check-executables-have-shebangs
27+
- id: check-illegal-windows-names
28+
# - id: check-json
2529
- id: check-merge-conflict
2630
args:
2731
- --assume-in-merge
32+
- id: check-shebang-scripts-are-executable
2833
- id: check-toml
34+
- id: check-vcs-permalinks
35+
- id: check-xml
2936
- id: check-yaml
3037
args:
3138
- --allow-multiple-documents
39+
- id: debug-statements
3240
- id: end-of-file-fixer
3341
exclude_types:
3442
- json
@@ -39,17 +47,17 @@ repos:
3947
args:
4048
- --fix=auto
4149
- id: name-tests-test
42-
- id: pretty-format-json
43-
args:
44-
- --autofix
45-
- --indent=2
50+
# - id: pretty-format-json
51+
# args:
52+
# - --autofix
53+
# - --indent=2
4654
- id: trailing-whitespace
4755
args:
4856
- --markdown-linebreak-ext=md
4957
exclude_types:
5058
- svg
5159
- repo: https://github.com/pappasam/toml-sort
52-
rev: v0.24.2
60+
rev: v0.24.3
5361
hooks:
5462
- id: toml-sort
5563
args:

perdoo/__main__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -265,9 +265,9 @@ def run(
265265
if not skip_clean:
266266
with CONSOLE.status("Cleaning Archive", spinner="simpleDotsScrolling"):
267267
entry.clean_archive()
268-
if settings.output.metron_info.create:
268+
if settings.output.metron_info.create and metadata[0]:
269269
entry.write_metadata(metadata=metadata[0])
270-
if settings.output.comic_info.create:
270+
if settings.output.comic_info.create and metadata[1]:
271271
metadata[1].pages = (
272272
load_page_info(entry=entry, comic_info=metadata[1])
273273
if settings.output.comic_info.handle_pages

perdoo/cli/archive.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,12 @@ def view(
2727
comic = Comic(file=target)
2828
CONSOLE.print(f"Archive format: '{comic.path.suffix}'")
2929
if not hide_metron_info:
30-
comic.metron_info.display()
30+
if not comic.metron_info:
31+
CONSOLE.print("No MetronInfo found")
32+
else:
33+
comic.metron_info.display()
3134
if not hide_comic_info:
32-
comic.comic_info.display()
35+
if not comic.comic_info:
36+
CONSOLE.print("No ComicInfo found")
37+
else:
38+
comic.comic_info.display()

perdoo/console.py

Lines changed: 1 addition & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
1-
__all__ = ["CONSOLE", "create_menu"]
1+
__all__ = ["CONSOLE"]
22

33
import logging
44

55
from rich.console import Console
6-
from rich.panel import Panel
7-
from rich.prompt import IntPrompt
86
from rich.theme import Theme
97

108
LOGGER = logging.getLogger(__name__)
@@ -26,42 +24,3 @@
2624
}
2725
)
2826
)
29-
30-
31-
def create_menu(
32-
options: list[str],
33-
title: str | None = None,
34-
subtitle: str | None = None,
35-
prompt: str = "Select",
36-
default: str | None = None,
37-
) -> int | None:
38-
if not options:
39-
return 0
40-
panel_text = []
41-
padding = len(str(len(options)))
42-
for index, item in enumerate(options):
43-
panel_text.append(
44-
f"[markdown.item.number]{index + 1:>{padding}}.[/] [prompt.choices]{item}[/]"
45-
)
46-
if default:
47-
panel_text.append(f"[markdown.item.number]{0:>{padding}}.[/] [prompt.default]{default}[/]")
48-
CONSOLE.print(
49-
Panel(
50-
"\n".join(panel_text),
51-
title=f"[title]{title}[/]" if title else None,
52-
subtitle=f"[subtitle]{subtitle}[/]" if subtitle else None,
53-
border_style="prompt.border",
54-
)
55-
)
56-
selected = IntPrompt.ask(prompt=prompt, default=0 if default else None, console=CONSOLE)
57-
if (
58-
selected is None
59-
or selected < 0
60-
or selected > len(options)
61-
or (selected == 0 and not default)
62-
):
63-
LOGGER.warning("Invalid Option: %s", selected)
64-
return create_menu(
65-
options=options, title=title, subtitle=subtitle, prompt=prompt, default=default
66-
)
67-
return selected

perdoo/services/comicvine.py

Lines changed: 61 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
from datetime import datetime
66

77
from natsort import humansorted, ns
8+
from prompt_toolkit.styles import Style
9+
from questionary import Choice, select
810
from requests.exceptions import JSONDecodeError
911
from rich.prompt import Confirm, Prompt
1012
from simyan.comicvine import Comicvine as Simyan
@@ -14,14 +16,15 @@
1416
from simyan.sqlite_cache import SQLiteCache
1517

1618
from perdoo import get_cache_root
17-
from perdoo.console import CONSOLE, create_menu
19+
from perdoo.console import CONSOLE
1820
from perdoo.metadata import ComicInfo, MetronInfo
1921
from perdoo.metadata.metron_info import InformationSource
2022
from perdoo.services._base import BaseService
2123
from perdoo.settings import Comicvine as ComicvineSettings
2224
from perdoo.utils import IssueSearch, Search, SeriesSearch
2325

2426
LOGGER = logging.getLogger(__name__)
27+
DEFAULT_CHOICE = Choice(title="None of the Above", value=None)
2528

2629

2730
class Comicvine(BaseService[Volume, Issue]):
@@ -42,27 +45,39 @@ def _search_series(self, name: str | None, volume: int | None, year: int | None)
4245
)
4346
if year:
4447
options = [x for x in options if x.start_year == year]
45-
if not options:
48+
if options:
49+
search = name
50+
if volume:
51+
search += f" v{volume}"
52+
if year:
53+
search += f" ({year})"
54+
choices = [
55+
Choice(
56+
title=[
57+
(
58+
"class:dim",
59+
f"{x.id} | {x.publisher.name if x.publisher and x.publisher.name else ''} | ", # noqa: E501
60+
),
61+
("class:title", f"{x.name} ({x.start_year})"),
62+
],
63+
description=f"https://comicvine.gamespot.com/volumes/4050-{x.id}",
64+
value=x,
65+
)
66+
for x in options
67+
]
68+
choices.append(DEFAULT_CHOICE)
69+
selected = select(
70+
f"Searching for Comicvine Volume '{search}'",
71+
default=DEFAULT_CHOICE,
72+
choices=choices,
73+
style=Style([("dim", "dim")]),
74+
).ask()
75+
if selected and selected != DEFAULT_CHOICE.title:
76+
return selected.id
77+
else:
4678
LOGGER.warning(
4779
"Unable to find any Volumes with the Name and StartYear: '%s %s'", name, year
4880
)
49-
search = name
50-
if volume:
51-
search += f" v{volume}"
52-
if year:
53-
search += f" ({year})"
54-
index = create_menu(
55-
options=[
56-
f"{x.id} | {x.publisher.name if x.publisher and x.publisher.name else ''}"
57-
f" | {x.name} ({x.start_year})"
58-
for x in options
59-
],
60-
title="Comicvine Volume",
61-
subtitle=f"Searching for Volume '{search}'",
62-
default="None of the Above",
63-
)
64-
if index != 0:
65-
return options[index - 1].id
6681
if year:
6782
LOGGER.info("Searching again without the StartYear")
6883
return self._search_series(name=name, volume=volume, year=None)
@@ -111,14 +126,33 @@ def _search_issue(self, series_id: int, number: str | None) -> int | None:
111126
series_id,
112127
number,
113128
)
114-
index = create_menu(
115-
options=[f"{x.id} | {x.number} - {x.name or ''}" for x in options],
116-
title="Comicvine Issue",
117-
subtitle=f"Searching for Issue #{number}" if number else "",
118-
default="None of the Above",
119-
)
120-
if index != 0:
121-
return options[index - 1].id
129+
if options:
130+
choices = [
131+
Choice(
132+
title=[
133+
("class:dim", f"{x.id} | "),
134+
("class:title", f"{x.number} - {x.name or ''}"),
135+
],
136+
description=f"https://comicvine.gamespot.com/issues/4000-{x.id}",
137+
value=x,
138+
)
139+
for x in options
140+
]
141+
choices.append(DEFAULT_CHOICE)
142+
selected = select(
143+
f"Searching for Comicvine Issue #{number}",
144+
default=DEFAULT_CHOICE,
145+
choices=choices,
146+
style=Style([("dim", "dim")]),
147+
).ask()
148+
if selected and selected != DEFAULT_CHOICE.title:
149+
return selected.id
150+
else:
151+
LOGGER.warning(
152+
"Unable to find any Issues with the Volume and IssueNumber: '%s %s'",
153+
series_id,
154+
number,
155+
)
122156
if number:
123157
LOGGER.info("Searching again without the IssueNumber")
124158
return self._search_issue(series_id=series_id, number=None)

0 commit comments

Comments
 (0)