Buried-In-Code / Perdoo

Perdoo's goal is to help sort and organize your comic collection by using the information stored in metadata files inside the comic archives.
MIT License
2 stars 1 forks source link

Error when selecting "n" after selection "None of the Above" on comic selection #19

Closed DomenicF closed 3 months ago

DomenicF commented 3 months ago

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'.

The full log is pasted below:

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.

Buried-In-Code commented 3 months ago

The issue with this one is, I have it creating the Info files based on the Service responses, however I didn't properly handle if comes back with None, either from a service error or user selecting 'N'