I have not tested other API's (as I do not have access to the others at this time), but, this issue is happening with the Comicvine API.
When asked to "Try again" and selecting "n" on comic identification, the program exits with exit code 1 and the error AttributeError: 'NoneType' object has no attribute 'issue'
.
Perdoo v0.2.0
Python v3.12.4
INFO Starting Perdoo
────────── Descender Compendium (2024) (Digital) ──────────
INFO Processing Descender Compendium (2024) (Digital)
Series title: Descender
INFO Fetching details from Comicvine
+------------------------------ Comicvine Series ------------------------------+
| 1: 80426 | Image | Descender (2015) |
| 2: 106862 | Image | Descender Deluxe Edition (2017) |
| 3: 90103 | Image | Descender: Machine Moon (2016) |
| 4: 102251 | Image | Descender: Orbital Mechanics (2017) |
| 5: 107643 | Image | Descender: Rise of the Robots (2018) |
| 6: 96656 | Image | Descender: Singularities (2016) |
| 7: 113701 | Image | Descender: The Machine War (2018) |
| 8: 84421 | Image | Descender: Tin Stars (2015) |
| 9: 86365 | Image | Image Firsts: Descender (2015) |
| 10: 105168 | Splitter | Descender (2015) |
| 0: None of the Above |
+------------------------------------------------------------------------------+
Select (0): 0
Try Again [y/n]: n
╭───────────────────── Traceback (most recent call last) ──────────────────────╮
│ /home/d/Development/Python/Perdoo/perdoo/__main__.py:396 in <module> │
│ │
│ 393 │
│ 394 │
│ 395 if __name__ == "__main__": │
│ ❱ 396 │ main() │
│ 397 │
│ │
│ ╭───────────────────────────────── locals ─────────────────────────────────╮ │
│ │ annotations = _Feature((3, 7, 0, 'beta', 1), None, 16777216) │ │
│ │ ARCHIVE_EXTENSIONS = ('.cb7', '.cbr', '.cbt', '.cbz') │ │
│ │ ArgumentParser = <class 'argparse.ArgumentParser'> │ │
│ │ BaseArchive = <class 'perdoo.archives._base.BaseArchive'> │ │
│ │ CB7Archive = <class 'perdoo.archives.cb7.CB7Archive'> │ │
│ │ CBTArchive = <class 'perdoo.archives.cbt.CBTArchive'> │ │
│ │ CBZArchive = <class 'perdoo.archives.cbz.CBZArchive'> │ │
│ │ ComicInfo = <class 'perdoo.models.comic_info.ComicInfo'> │ │
│ │ Comicvine = <class 'perdoo.services.comicvine.Comicvine'> │ │
│ │ CONSOLE = <console width=80 None> │ │
│ │ convert_collection = <function convert_collection at 0x7e28f467f380> │ │
│ │ date = <class 'datetime.date'> │ │
│ │ Details = <class 'perdoo.utils.Details'> │ │
│ │ fetch_from_services = <function fetch_from_services at 0x7e28f1f2f7e0> │ │
│ │ Format = <enum 'Format'> │ │
│ │ generate_filename = <function generate_filename at 0x7e28f1cc8040> │ │
│ │ get_archive = <function get_archive at 0x7e28f3f47600> │ │
│ │ get_metadata_id = <function get_metadata_id at 0x7e28f286f560> │ │
│ │ Identifications = <class 'perdoo.utils.Identifications'> │ │
│ │ IMAGE_EXTENSIONS = ('.jpg', '.jpeg', '.png', '.webp') │ │
│ │ InfoModel = <class 'perdoo.models._base.InfoModel'> │ │
│ │ InformationSource = <enum 'InformationSource'> │ │
│ │ League = <class 'perdoo.services.league.League'> │ │
│ │ list_files = <function list_files at 0x7e28f39eae80> │ │
│ │ load_archives = <function load_archives at 0x7e28f1f2f740> │ │
│ │ LOGGER = <Logger perdoo (DEBUG)> │ │
│ │ logging = <module 'logging' from │ │
│ │ '/usr/lib/python3.12/logging/__init__.py'> │ │
│ │ main = <function main at 0x7e28f1b50900> │ │
│ │ Marvel = <class 'perdoo.services.marvel.Marvel'> │ │
│ │ Meta = <class 'perdoo.models.metadata.Meta'> │ │
│ │ Metadata = <class 'perdoo.models.metadata.Metadata'> │ │
│ │ Metron = <class 'perdoo.services.metron.Metron'> │ │
│ │ MetronInfo = <class 'perdoo.models.metron_info.MetronInfo'> │ │
│ │ Namespace = <class 'argparse.Namespace'> │ │
│ │ OutputFormat = <enum 'OutputFormat'> │ │
│ │ parse_arguments = <function parse_arguments at 0x7e28f4dee200> │ │
│ │ Path = <class 'pathlib.Path'> │ │
│ │ process_pages = <function process_pages at 0x7e28f1b50b80> │ │
│ │ Prompt = <class 'rich.prompt.Prompt'> │ │
│ │ python_version = <function python_version at 0x7e28f4751b20> │ │
│ │ read_meta = <function read_meta at 0x7e28f2605f80> │ │
│ │ rename_images = <function rename_images at 0x7e28f1b50ae0> │ │
│ │ sanitize = <function sanitize at 0x7e28f286f4c0> │ │
│ │ Service = <enum 'Service'> │ │
│ │ Settings = <class 'perdoo.settings.Settings'> │ │
│ │ setup_logging = <function setup_logging at 0x7e28f3b234c0> │ │
│ │ shutil = <module 'shutil' from │ │
│ │ '/usr/lib/python3.12/shutil.py'> │ │
│ │ Source = <enum 'Source'> │ │
│ │ start = <function start at 0x7e28f1b50a40> │ │
│ │ TemporaryDirectory = <class 'tempfile.TemporaryDirectory'> │ │
│ │ Tool = <class 'perdoo.models.metadata.Tool'> │ │
│ │ ValidationError = <class │ │
│ │ 'pydantic_core._pydantic_core.ValidationError'> │ │
│ ╰──────────────────────────────────────────────────────────────────────────╯ │
│ │
│ /home/d/Development/Python/Perdoo/perdoo/__main__.py:390 in main │
│ │
│ 387 │ │ settings = Settings.load().save() │
│ 388 │ │ if args.debug: │
│ 389 │ │ │ CONSOLE.print(f"Settings: {settings}") │
│ ❱ 390 │ │ start(settings=settings, force=args.force) │
│ 391 │ except KeyboardInterrupt: │
│ 392 │ │ pass │
│ 393 │
│ │
│ ╭───────────────────────────────── locals ─────────────────────────────────╮ │
│ │ args = Namespace(force=False, debug=False) │ │
│ │ settings = Settings( │ │
│ │ │ collection_folder=PosixPath('/home/d/Comics'), │ │
│ │ │ comicvine=Comicvine( │ │
│ │ │ │ api_key='<snip>' │ │
│ │ │ ), │ │
│ │ │ league_of_comic_geeks=LeagueofComicGeeks( │ │
│ │ │ │ client_id='', │ │
│ │ │ │ client_secret='', │ │
│ │ │ │ access_token='' │ │
│ │ │ ), │ │
│ │ │ marvel=Marvel(public_key='', private_key=''), │ │
│ │ │ metron=Metron(password='', username=''), │ │
│ │ │ service_order=[ │ │
│ │ │ │ <Service.METRON: 'Metron'>, │ │
│ │ │ │ <Service.MARVEL: 'Marvel'>, │ │
│ │ │ │ <Service.COMICVINE: 'Comicvine'>, │ │
│ │ │ │ <Service.LEAGUE_OF_COMIC_GEEKS: 'League of Comic │ │
│ │ Geeks'> │ │
│ │ │ ], │ │
│ │ │ output=Output( │ │
│ │ │ │ create_comic_info=True, │ │
│ │ │ │ create_metron_info=True, │ │
│ │ │ │ create_metadata=True, │ │
│ │ │ │ format=<OutputFormat.CBZ: 'cbz'> │ │
│ │ │ ) │ │
│ │ ) │ │
│ ╰──────────────────────────────────────────────────────────────────────────╯ │
│ │
│ /home/d/Development/Python/Perdoo/perdoo/__main__.py:321 in start │
│ │
│ 318 │ │ ) │
│ 319 │ │ │
│ 320 │ │ metadata, metron_info, comic_info = fetch_from_services(settin │
│ ❱ 321 │ │ new_file = generate_filename( │
│ 322 │ │ │ root=settings.collection_folder, │
│ 323 │ │ │ extension=settings.output.format.value, │
│ 324 │ │ │ metadata=metadata, │
│ │
│ ╭───────────────────────────────── locals ─────────────────────────────────╮ │
│ │ archive = <perdoo.archives.cbz.CBZArchive object at 0x7e28f1b01610> │ │
│ │ archives = [ │ │
│ │ │ ( │ │
│ │ │ │ PosixPath('/home/d/Comics/Descender Compendium │ │
│ │ (2024) (Digital).cbz'), │ │
│ │ │ │ <perdoo.archives.cbz.CBZArchive object at │ │
│ │ 0x7e28f1b01610>, │ │
│ │ │ │ None │ │
│ │ │ ), │ │
│ │ │ ( │ │
│ │ │ │ PosixPath('/home/d/Comics/Dog Biscuits - Alex │ │
│ │ Graham.cbz'), │ │
│ │ │ │ <perdoo.archives.cbr.CBRArchive object at │ │
│ │ 0x7e28f1c2f920>, │ │
│ │ │ │ None │ │
│ │ │ ), │ │
│ │ │ ( │ │
│ │ │ │ PosixPath('/home/d/Comics/Joker-Harley - Criminal │ │
│ │ Sanity.cbz'), │ │
│ │ │ │ <perdoo.archives.cbz.CBZArchive object at │ │
│ │ 0x7e28f1ec03b0>, │ │
│ │ │ │ None │ │
│ │ │ ), │ │
│ │ │ ( │ │
│ │ │ │ PosixPath('/home/d/Comics/Memetic (2015) (Digital) │ │
│ │ .cbz'), │ │
│ │ │ │ <perdoo.archives.cbz.CBZArchive object at │ │
│ │ 0x7e28f2220410>, │ │
│ │ │ │ None │ │
│ │ │ ) │ │
│ │ ] │ │
│ │ comic_info = None │ │
│ │ details = Details( │ │
│ │ │ series=Identifications( │ │
│ │ │ │ search='Descender', │ │
│ │ │ │ comicvine=None, │ │
│ │ │ │ league=None, │ │
│ │ │ │ marvel=None, │ │
│ │ │ │ metron=None │ │
│ │ │ ), │ │
│ │ │ issue=Identifications( │ │
│ │ │ │ search=None, │ │
│ │ │ │ comicvine=None, │ │
│ │ │ │ league=None, │ │
│ │ │ │ marvel=None, │ │
│ │ │ │ metron=None │ │
│ │ │ ) │ │
│ │ ) │ │
│ │ file = PosixPath('/home/d/Comics/Descender Compendium (2024) │ │
│ │ (Digital).cbz') │ │
│ │ force = False │ │
│ │ metadata = None │ │
│ │ metron_info = None │ │
│ │ settings = Settings( │ │
│ │ │ collection_folder=PosixPath('/home/d/Comics'), │ │
│ │ │ comicvine=Comicvine( │ │
│ │ │ │ api_key='<snip>' │ │
│ │ │ ), │ │
│ │ │ league_of_comic_geeks=LeagueofComicGeeks( │ │
│ │ │ │ client_id='', │ │
│ │ │ │ client_secret='', │ │
│ │ │ │ access_token='' │ │
│ │ │ ), │ │
│ │ │ marvel=Marvel(public_key='', private_key=''), │ │
│ │ │ metron=Metron(password='', username=''), │ │
│ │ │ service_order=[ │ │
│ │ │ │ <Service.METRON: 'Metron'>, │ │
│ │ │ │ <Service.MARVEL: 'Marvel'>, │ │
│ │ │ │ <Service.COMICVINE: 'Comicvine'>, │ │
│ │ │ │ <Service.LEAGUE_OF_COMIC_GEEKS: 'League of Comic │ │
│ │ Geeks'> │ │
│ │ │ ], │ │
│ │ │ output=Output( │ │
│ │ │ │ create_comic_info=True, │ │
│ │ │ │ create_metron_info=True, │ │
│ │ │ │ create_metadata=True, │ │
│ │ │ │ format=<OutputFormat.CBZ: 'cbz'> │ │
│ │ │ ) │ │
│ │ ) │ │
│ ╰──────────────────────────────────────────────────────────────────────────╯ │
│ │
│ /home/d/Development/Python/Perdoo/perdoo/__main__.py:227 in │
│ generate_filename │
│ │
│ 224 │
│ 225 │
│ 226 def generate_filename(root: Path, extension: str, metadata: Metadata) │
│ ❱ 227 │ publisher_filename = metadata.issue.series.publisher.title │
│ 228 │ series_filename = ( │
│ 229 │ │ f"{metadata.issue.series.title} v{metadata.issue.series.volume │
│ 230 │ │ if metadata.issue.series.volume > 1 │
│ │
│ ╭──────────────── locals ─────────────────╮ │
│ │ extension = 'cbz' │ │
│ │ metadata = None │ │
│ │ root = PosixPath('/home/d/Comics') │ │
│ ╰─────────────────────────────────────────╯ │
╰──────────────────────────────────────────────────────────────────────────────╯
AttributeError: 'NoneType' object has no attribute 'issue'
Process finished with exit code 1
Please let me know if you would like any more information.