From a33b00d77e9db9180c314de4dd2af8bd608850ba Mon Sep 17 00:00:00 2001 From: Timmy Welch Date: Thu, 22 Dec 2022 10:43:00 -0800 Subject: [PATCH] Update ComicTalker documentation --- comictalker/talkerbase.py | 62 +++++++++++++++++++++----------- comictalker/talkers/comicvine.py | 13 ++++--- 2 files changed, 49 insertions(+), 26 deletions(-) diff --git a/comictalker/talkerbase.py b/comictalker/talkerbase.py index 8f71c67..92cf3d3 100644 --- a/comictalker/talkerbase.py +++ b/comictalker/talkerbase.py @@ -1,5 +1,3 @@ -"""A template for an information source -""" # Copyright 2012-2014 Anthony Beville # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -25,15 +23,13 @@ from comictalker.resulttypes import ComicIssue, ComicSeries logger = logging.getLogger(__name__) -# NOTE: Series and Volume are synonymous. Some sources (ComicVine) use "volume" and others (MangaUpdates) use "series". - class SourceDetails: def __init__( self, name: str = "", ident: str = "", - logo: str = "", # Will be scaled if greater than 100px width and 250px height in comictalker/talkers/logos + logo: str = "", ): self.name = name self.id = ident @@ -146,10 +142,8 @@ class ComicTalker: def __init__(self, version: str, cache_folder: pathlib.Path, api_url: str = "", api_key: str = "") -> None: # Identity name for the information source etc. - self.source_details: SourceDetails = ( - SourceDetails() - ) # Can use this to test if custom talker has been configured - self.static_options: SourceStaticOptions = SourceStaticOptions() + self.source_details = SourceDetails() + self.static_options = SourceStaticOptions() self.api_key = api_key self.cache_folder = cache_folder self.version = version @@ -166,7 +160,10 @@ class ComicTalker: self.api_url = tmp_url.geturl() def check_api_key(self, key: str, url: str) -> bool: - """If the talker has or requires an API key, this function should test its validity""" + """ + This function should return true if the given api key and url are valid. + If the Talker does not use an api key it should validate that the url works. + """ raise NotImplementedError def search_for_series( @@ -176,25 +173,48 @@ class ComicTalker: refresh_cache: bool = False, literal: bool = False, ) -> list[ComicSeries]: - """Searches for the series with the given series_name - callback is used for... - refresh_cache signals if the data in the cache should be used - literal indicates that no articles (a, the, etc.) should be removed when searching""" + """ + This function should return a list of series that match the given series name + according to the source the Talker uses. + Sanitizing the series name is the responsibility of the talker. + If `literal` == True then it is requested that no filtering or + transformation/sanitizing of the title or results be performed by the talker. + A sensible amount of results should be returned. + For example the `ComicVineTalker` stops requesting new pages after the results + become too different from the `series_name` by use of the `titles_match` function + provided by the `comicapi.utils` module, and only allows a maximum of 5 pages + """ raise NotImplementedError def fetch_issues_by_series(self, series_id: int) -> list[ComicIssue]: """Expected to return a list of issues with a given series ID""" raise NotImplementedError - def fetch_comic_data(self, issue_id: int = 0, series_id: int = 0, issue_number: str = "") -> GenericMetadata: - """This function is expected to handle a few possibilities: - 1. Only series_id passed in: Retrieve the SERIES/VOLUME information only - 2. series_id and issue_number: Retrieve the ISSUE information - 3. Only issue_id: Retrieve the ISSUE information""" + def fetch_comic_data( + self, issue_id: int | None = None, series_id: int | None = None, issue_number: str = "" + ) -> GenericMetadata: + """ + This function should return an instance of GenericMetadata for a single issue. + It is guaranteed that either `issue_id` or (`series_id` and `issue_number` is set). + Below is an example of how this function might be implemented: + + if issue_number and series_id: + return self.fetch_issue_data(series_id, issue_number) + elif issue_id: + return self.fetch_issue_data_by_issue_id(issue_id) + else: + return GenericMetadata() + """ raise NotImplementedError def fetch_issues_by_series_issue_num_and_year( - self, series_id_list: list[int], issue_number: str, year: str | int | None + self, series_id_list: list[int], issue_number: str, year: int | None ) -> list[ComicIssue]: - """Searches for a list of issues within the given year. Used solely by issueidentifer""" + """ + This function should return a single issue for each series id in + the `series_id_list` and it should match the issue_number. + Preferably it should also only return issues published in the given `year`. + If there is no year given (`year` == None) or the Talker does not have issue publication info + return the results unfiltered. + """ raise NotImplementedError diff --git a/comictalker/talkers/comicvine.py b/comictalker/talkers/comicvine.py index a42976c..5bab9fb 100644 --- a/comictalker/talkers/comicvine.py +++ b/comictalker/talkers/comicvine.py @@ -1,4 +1,5 @@ -"""ComicVine information source +""" +ComicVine information source """ # Copyright 2012-2014 Anthony Beville # @@ -459,12 +460,14 @@ class ComicVineTalker(ComicTalker): return formatted_search_results # Get issue or series information - def fetch_comic_data(self, issue_id: int = 0, series_id: int = 0, issue_number: str = "") -> GenericMetadata: + def fetch_comic_data( + self, issue_id: int | None = None, series_id: int | None = None, issue_number: str = "" + ) -> GenericMetadata: comic_data = GenericMetadata() - if issue_number and series_id: - comic_data = self.fetch_issue_data(series_id, issue_number) - elif issue_id: + if issue_id: comic_data = self.fetch_issue_data_by_issue_id(issue_id) + elif issue_number and series_id: + comic_data = self.fetch_issue_data(series_id, issue_number) return comic_data