def ttdb(input): ''' Returns imdbid <=> thetvdbid. if you input imdbid, it returns thetvdbid and vice versa ''' _regex = '^.t.{0,9}' tvdb.KEYS.API_KEY = conf.ttdb_key search = tvdb.Search() if re.search(_regex, input, re.IGNORECASE): search = tvdb.Search() try: response = search.series(imdbId=input) except: return False finally: try: rating_key = response[0]['id'] return rating_key except: return False else: search = tvdb.Series(input) try: response = search.info() except: return False imdbid = response['imdbId'] return imdbid
def _get_series(self, parts: MediaNameParse, parent_parts: MediaNameParse): ''' use defaulted series ID ''' if parts.series_id: try: results = tvdb.Series(id=parts.series_id).info() add_unique_elements(self.series_list, results) logger.debug( f'Found "{results["seriesName"]}" for series ID "{parts.series_id}"' ) except HTTPError as e: logger.error( f'TVDB did not find series using defaulted series ID "{parts.series_id}". Error: {err_str(e)}' ) if self.series_list: return parent_title = parent_parts.title if parent_parts else '' parent_year = parent_parts.year if parent_parts else '' ''' search for series with title ''' for title, year in ((parts.title, parts.year), (parent_title, parent_year)): results = None if title and year: try: results = tvdb.Search().series(name=f'{title} {year}') add_unique_elements(self.series_list, results) logger.debug( f'Found {len(results)} series using "{title} {year}": {[s["seriesName"] for s in results]}' ) except HTTPError as e: logger.debug( f'TVDB returned zero series\' using "{title} {year}". Error: {err_str(e)}' ) if title and not results: try: results = tvdb.Search().series(name=title) add_unique_elements(self.series_list, results) logger.debug( f'Found {len(results)} series using "{title}": {[s["seriesName"] for s in results]}' ) except HTTPError as e: logger.debug( f'TVDB returned zero series\' using "{title}". Error: {err_str(e)}' ) for series in self.series_list: if series.get('seriesName').lower() in (parts.title.lower(), parent_title.lower()): add_unique_elements(self.series_exact_match_list, series)
def naruto_add_ep_names(): path = 'C:/Users/Dylan/Torrents/TV Shows/Naruto Shippuden/' search = tvdb.Search() response = search.series('Naruto Shippuden') show = tvdb.Series(search.series[0]['id']) response = show.info() print(show.seriesName) episodes = show.Episodes.all() for season_num in range(17, 19): season_path = path + folder_name_format(season_num) + '/' original_files = os.listdir(season_path) for file in original_files: extension = get_extension(file) # abs_episode = get_ndig_ep(file, n=3) # episode = next(ep for ep in episodes if ep['absoluteNumber'] == abs_episode) # season = episode['airedSeason'] # episode_name = str(episode['absoluteNumber']) + ' ' + episode['episodeName'] # episode_name = episode_name.replace('/', 'and') # episode_name = episode_name.replace(':', '-') # name = file_name_format(show.seriesName, season, episode['airedEpisodeNumber'], episode_name, extension) season, episode = get_sxxexx(file) episode_name = next( str(ep['absoluteNumber']) + ' ' + ep['episodeName'] for ep in episodes if ep['airedEpisodeNumber'] == episode and ep['airedSeason'] == season) name = file_name_format(show.seriesName, season, episode, episode_name, extension) source = season_path + file dest = season_path + name print(source) print(dest) print() os.rename(source, dest)
def lookup_episode(self, seriesName, episodeName, id=0): """ Lookup a TV episode from thetvdb, matches based on levenstein distance comparisson :param seriesName: series name :param episodeName: episide name :return: series_id and episode_id as strings """ episodeName = episodeName.strip() if seriesName is None or episodeName is None: return (None, None) if seriesName != self.last_series_name: logging.info(" - Searching thetvdb for:{}".format(seriesName)) search = tvdb.Search() response = search.series(seriesName) s = search.series if id > 0: for s in response: if s['id'] == id: show = tvdb.Series(id) break elif id == 0: show = tvdb.Series(s[0]['id']) else: logging.info( ' - Unable to find series id:{} - terminating'.format(id)) return (None, None) self.last_series_name = seriesName self.last_series_obj = show show = self.last_series_obj episodes = show.Episodes.all() logging.info(" - Found {} episodes".format(len(episodes))) if (len(episodes) == 0): return ("error", "no episodes found") if episodes == []: return (None, None) for i, e in enumerate(episodes[::-1]): ep_name = e['episodeName'] if ep_name is not None: n = Levenshtein.distance(episodeName, ep_name) if n <= MATCH_TOLERANCE: e_id = e['airedEpisodeNumber'] s_id = e['airedSeason'] logging.info( " - Matched [{0}] to episode name: [{1}]".format( episodeName, ep_name)) return (str(s_id), str(e_id)) logging.info(" - UNABLE TO MATCH: {}".format(episodeName)) return ("error", "expected series not found")
def hunterx(): path = 'C:/Users/Dylan/Torrents/TV Shows/Hunter x Hunter/Series/' search = tvdb.Search() response = search.series('Hunter x Hunter (2011)') show = tvdb.Series(search.series[0]['id']) response = show.info() episodes = show.Episodes.all() print(episodes[0]) for ep in episodes: print(f"{ep['airedEpisodeNumber']} | {ep['absoluteNumber']}") original_files = os.listdir(path) for file in original_files: extension = get_extension(file) season, episode_num = get_sxxexxx(file) ep = next(ep for ep in episodes if ep['absoluteNumber'] == episode_num) episode = ep['airedEpisodeNumber'] season = ep['airedSeason'] episode_name = check_file_name(ep['episodeName']) print() print(episode_name) name = file_name_format(show.seriesName, season, episode, episode_name, extension) source = path + file dest = path + name print(source) print(dest) shutil.move(source, dest)
def naruto_18(): path = '/home/dylan/local_server/dyn0402/Torrents/TV Shows/Naruto Shippuden/' search = tvdb.Search() response = search.series('Naruto Shippuden') show = tvdb.Series(search.series[0]['id']) response = show.info() print(show.seriesName) episodes = show.Episodes.all() # print(episodes[300]) # print([episode['episodeName'] for episode in episodes if episode['airedSeason'] == 17]) original_files = os.listdir(path + 'Season 18') for file in original_files: extension = get_extension(file) season, episode = get_sxxexx(file) season -= 1 episode += 11 episode_name = next(ep['episodeName'] for ep in episodes if ep['airedEpisodeNumber'] == episode and ep['airedSeason'] == season) name = file_name_format(show.seriesName, season, episode, episode_name, extension) source = path + 'Season 18/' + file dest = path + 'Season 17/' + name print(source) print(dest) print()
def query_for_series(title: str = None): if not title: return try: return tvdb.Search().series(name=title) except HTTPError: return {}
def serieSearch(name): search = tvdb.Search() reponse = search.series(name) idtv = search.series[0]['id'] title = search.series[0]['seriesName'] poster = search.series[0]['banner'] print(idtv, title, poster) serieEpisode(idtv, reponse)
def get_image(name): # print("using key %s" % tvdb.KEYS.API_KEY) search = tvdb.Search() try: search.series(name) serieid = search.series[0]['id'] show = tvdb.Series(serieid) return show.info()['banner'] except: return ""
def search_series_api(title: str, settings, imdb_id: str = ''): search = tvdb.Search() ret = None try: ret = search.series(title, language=settings.getSettingString( 'language'), imdbId=imdb_id) except: pass ADDON.setSetting('token', tvdb.KEYS.API_TOKEN) return ret
def search_series_by_slug_api(slug: str, settings): search = tvdb.Search() ret = None try: ret = search.series(slug=slug, language=settings.getSettingString('language')) except: pass ADDON.setSetting('token', tvdb.KEYS.API_TOKEN) return ret
def call_tvdb(self): tvdb.KEYS.API_KEY = environ["TVDBKEY"] results = [] title = self.title.replace( self.year, "").strip() if self.year else self.title.strip() search = tvdb.Search() response = search.series(title) if self.year: for r in response: if self.year in r["firstAired"]: results.append(r["seriesName"]) else: results += response return results
def getShow(): search = tvdb.Search() response = search.series(input("Series: ")) show_id = 0 wrap2 = textwrap.TextWrapper(initial_indent="\t\t", subsequent_indent="\t\t") if len(response) > 1: print("Multiple responses, please pick one") for index, val in enumerate(response): print("[{0}]".format(str(index + 1)), end=" ") prettyprint_series(val, wrap2) show_id = response[int(input("Number:")) - 1]["id"] else: prettyprint_series(response[0], wrap2) if input("Is this correct? (Y/N)").lower() == "y": show_id = response[0]["id"] return show_id
def naruto_box_to_season(): # path = '/home/dylan/local_server/dyn0402/Torrents/TV Shows/Naruto Shippuden/' path = 'C:/Users/Dylan/Torrents/TV Shows/Naruto Shippuden/' search = tvdb.Search() response = search.series('Naruto Shippuden') show = tvdb.Series(search.series[0]['id']) response = show.info() print(show.seriesName) episodes = show.Episodes.all() print(episodes[300]) for box in range(32, 34): box_path = path + f'Box Set {box}' + '/' # box_path = [x[0] for x in os.walk(box_path)][1]+'/' # print(box_path) original_files = os.listdir(box_path) # print(original_files) for file in original_files: extension = get_extension(file) if extension == 'txt': continue abs_episode = get_ndig_ep(file, n=3) if abs_episode in range(413, 417): episode = next(ep for ep in episodes if ep['absoluteNumber'] == abs_episode) season = episode['airedSeason'] episode_name = str( episode['absoluteNumber']) + ' ' + episode['episodeName'] episode_name = episode_name.replace('/', 'and') name = file_name_format(show.seriesName, season, episode['airedEpisodeNumber'], episode_name, extension) source = box_path + file dest = path + folder_name_format(season) + '/' + name print(source) print(dest) print() shutil.move(source, dest)
def mandalorian(): path = '/home/dylan/local_server/dyn0402/Torrents/TV Shows/The Mandalorian/Season 1/' search = tvdb.Search() response = search.series('The Mandalorian') show = tvdb.Series(search.series[0]['id']) response = show.info() episodes = show.Episodes.all() original_files = os.listdir(path) for file in original_files: extension = get_extension(file) season, episode = get_sxxexx(file) episode_name = next(ep['episodeName'] for ep in episodes if ep['airedEpisodeNumber'] == episode) print(episode_name) name = file_name_format(show.seriesName, season, episode, episode_name, extension) source = path + file dest = path + name print() print(source) print(dest) shutil.move(source, dest)
def test_search_series(self): src = SRC_STR name = SRC_NAME search = tvdb.Search() response = search.series(src) self.assertEqual(search.series[0]['seriesName'], name)
def main(): series_name = raw_input( "What's the name of anime? eg naruto One Piece . Be precise line caps etc: " ) search = tvdb.Search() matched_names = search.series(series_name) i = 1 for series in matched_names: sep() if 'overview' not in series: print('No :', i) print('Series name : ', series['seriesName']) else: print('No :', i) print('Series name : ', series['seriesName']) print('Overview : ', series['overview']) sep() i = i + 1 id = raw_input("Please enter the Series NUMBER from the above list ") seriesid = matched_names[int(id) - 1]['id'] print('seriesid:' + str(seriesid)) print('Series name : ', matched_names[int(id) - 1]['seriesName'], 'SELECTED') prepareressult = raw_input( "Do you want to prepare folder(y/n)(read docs!) ") if prepareressult == 'y': os.system("python prepare.py") print("all required files are in folder and continuing") sep() else: print("assuming all required files are in folder and continuing") sep() removeresult = raw_input( "Remove text to only leave episode number(y/n)(read docs!) ") if removeresult == 'y': remove() print("all required files are in correct format and continuing") sep() else: print( "assuming all required files are in correct format and continuing") sep() renameresult = raw_input("Rename episodes(y/n)(read docs!) ") if renameresult == 'y': os.system("python renamer.py " + str(seriesid)) print( 'If any files remaining copy them toa different folder and do the rename' ) sep() else: print( 'If any files remaining copy them toa different folder and do the rename' ) sep() oraganizeresult = raw_input( "Do you want to oraganize result back into season folders(y/n)(read docs!) " ) if oraganizeresult == 'y': os.system("python organiser.py") print("continuing after organization complete") sep() else: print("continuing after organization complete") sep() downloadresult = raw_input( "Do you want to download metadata for everything(y/n)(read docs!) ") if downloadresult == 'y': os.system("python downloader.py " + str(seriesid)) print( "hope everything went smoothly for you **BUY ME coffee if you are happy** " ) sep() else: print( "hope everything went smoothly for you **BUY ME coffee if you are happy** " ) sep() return
import os from pprint import pprint as pp import sys import tvdbsimple as tvdb api_key = os.environ.get('TVDB_APIKEY') or sys.exit('set api key in env') tvdb.KEYS.API_KEY = api_key search = tvdb.Search() reponse = search.series("mr robot") first_hit = search.series[0] pp(first_hit) showid = first_hit['id'] show = tvdb.Series(showid) episodes = show.Episodes.all() pp(episodes)
def getData(self, metadata, type, media): Log.Info("[" + AGENT_NAME + "] [MyAnimeListUtils] " + "Requesting Information from MyAnimeList.net") utils = Utils() detailUrl = MYANIMELIST_URL_MAIN + MYANIMELIST_URL_DETAILS.format(id=metadata.id) try: Log.Info("[" + AGENT_NAME + "] [MyAnimeListUtils] " + "Fetching URL " + str(detailUrl)) detailResult = JSON.ObjectFromString(HTTP.Request(detailUrl, sleep=2.0, cacheTime=MYANIMELIST_CACHE_TIME).content) except Exception as e: Log.Error("[" + AGENT_NAME + "] [MyAnimeListUtils] " + "No Detail Information were available " + str(e)) return '''Parse the main Elements of the response''' apiAnimeId = None # the ID of the Anime (plex metadata.id, myanimelist id) apiAnimeTitle = None # the Title of the Anime (plex metadata.title, myanimelist title) apiAnimeSummary = None # the Summary of the Anime (plex metadata.summary, myanimelist synopsis) apiAnimeRating = None # the Rating of the Anime (plex metadata.rating, myanimelist members_score) apiAnimeAvailableAt = None # the Date of the Anime first aired (plex metadata.originally_available_at, myanimelist start_date) apiAnimeContentRating = None # the Content rating of the Anime (plex metadata.content_rating, myanimelist classification) apiAnimeCovers = None # the Covers of the Anime (plex metadata.posters, myanimelist image_url) apiAnimeDuration = None # the Duration of an Anime Episode (plex metadata.duration, myanimelist duration) apiAnimeGenres = None # the Genres of the Anime (plex metadata.genres, myanimelist genres) apiAnimeProducers = None # the Producers of the Anime (plex metadata.studio, myanimelist producers) ### TODO: Switch to Studios when they are available in the API (or add Producers to metadata when this is possible in Plex) if detailResult is not None: # get the ID if it is available apiAnimeId = utils.getJSONValue("id", detailResult) Log.Debug("[" + AGENT_NAME + "] [MyAnimeListUtils] " + "ID: " + str(apiAnimeId)) if apiAnimeId is not None: metadata.id = str(apiAnimeId) # get the Title if it is available apiAnimeTitle = utils.getJSONValue("title", detailResult) try: Log.Info("[" + AGENT_NAME + "] [MyAnimeListUtils] " + "Fetching URL " + str(searchUrl)) search = tvdb.Search() meep = search.series(str(apiAnimeTitle)) apiAnimeTitle = meep[0]['seriesName'] except Exception as e: Log.Info("[" + AGENT_NAME + "] " + "search results could not be requested " + str(e)) return Log.Debug("[" + AGENT_NAME + "] [MyAnimeListUtils] " + "Title: " + str(apiAnimeTitle)) if apiAnimeTitle is not None: metadata.title = str(apiAnimeTitle) # get the Summary if it is available apiAnimeSummary = utils.getJSONValue("synopsis", detailResult) Log.Debug("[" + AGENT_NAME + "] [MyAnimeListUtils] " + "Summary: " + str(apiAnimeSummary)) if apiAnimeSummary is not None: metadata.summary = str(utils.removeTags(apiAnimeSummary)) # get the Rating if it is available apiAnimeRating = utils.getJSONValue("members_score", detailResult) Log.Debug("[" + AGENT_NAME + "] [MyAnimeListUtils] " + "Rating: " + str(apiAnimeRating)) if apiAnimeRating is not None: metadata.rating = float(apiAnimeRating) # get the first aired Date if it is available tmpYear = utils.getJSONValue("start_date", detailResult) if(tmpYear is not None): try: apiAnimeAvailableAt = datetime.strptime(str(tmpYear), "%Y-%m-%d") Log.Debug("[" + AGENT_NAME + "] [MyAnimeListUtils] " + "Year: " + str(apiAnimeAvailableAt)) if apiAnimeAvailableAt is not None: metadata.originally_available_at = apiAnimeAvailableAt except Exception as e: Log.Error("[" + AGENT_NAME + "] [MyAnimeListUtils] " + "There was an Error while adding the Aired Date " + str(e)) # get the content rating if it is available apiAnimeContentRating = utils.getJSONValue("classification", detailResult) Log.Debug("[" + AGENT_NAME + "] [MyAnimeListUtils] " + "Content Rating: " + str(apiAnimeContentRating)) if apiAnimeContentRating is not None: metadata.content_rating = str(apiAnimeContentRating) # get the covers if they are available apiAnimeCovers = utils.getJSONValue("image_url", detailResult) Log.Debug("[" + AGENT_NAME + "] [MyAnimeListUtils] " + "Cover: " + str(apiAnimeCovers)) if apiAnimeCovers is not None: if not apiAnimeCovers: Log.Warn("[" + AGENT_NAME + "] [MyAnimeListUtils] " + "Image was empty") else: if metadata.posters[str(apiAnimeCovers)] is None: #metadata.posters[str(apiAnimeCovers)] = Proxy.Media(HTTP.Request(str(apiAnimeCovers), sleep=2.0).content) request = urllib2.Request(str(apiAnimeCovers)) response = urllib2.urlopen(request, context=ssl.SSLContext(ssl.PROTOCOL_SSLv23)) content = response.read() metadata.posters[str(apiAnimeCovers)] = Proxy.Media(content) else: Log.Debug("[" + AGENT_NAME + "] [MyAnimeListUtils] " + "Image is already present") # get the duration if it is available tmpDuration = utils.getJSONValue("duration", detailResult) if(tmpDuration is not None): apiAnimeDuration = tmpDuration * 60000 Log.Debug("[" + AGENT_NAME + "] [MyAnimeListUtils] " + "Duration: " + str(apiAnimeDuration)) if apiAnimeDuration is not None: metadata.duration = int(apiAnimeDuration) # get the genres if they are available apiAnimeGenres = utils.getJSONValue("genres", detailResult) Log.Debug("[" + AGENT_NAME + "] [MyAnimeListUtils] " + "Genres: " + str(apiAnimeGenres)) if apiAnimeGenres is not None and len(apiAnimeGenres) > 0: for genre in apiAnimeGenres: metadata.genres.add(str(genre)) # get the producers if they are available # TODO: plex only has Studios currently and the Atarashii API does not provide the Studios from MyAnimeList (yet) # When either of those are available this needs to be fixed tmpProducers = utils.getJSONValue("producers", detailResult) if(tmpProducers is not None): Log.Debug("[" + AGENT_NAME + "] [MyAnimeListUtils] " + "Producers: " + str(tmpProducers)) if tmpProducers is not None and len(tmpProducers) > 0: apiAnimeProducers = "" for idx, producer in enumerate(tmpProducers): apiAnimeProducers += str(producer) if idx < len(tmpProducers) - 1: apiAnimeProducers += ", " metadata.studio = str(apiAnimeProducers) ''' Add specific data for TV-Shows ''' if type == "tvshow": Log.Debug("[" + AGENT_NAME + "] [MyAnimeListUtils] " + "Adding TV-Show specific data") apiAnimeEpisodeCount = None pages = None # get the episode count if it is available apiAnimeEpisodeCount = utils.getJSONValue("episodes", detailResult) Log.Debug("[" + AGENT_NAME + "] [MyAnimeListUtils] " + "Episodes: " + str(apiAnimeEpisodeCount)) if apiAnimeEpisodeCount is not None and apiAnimeEpisodeCount is not 0: metadata.seasons[1].episode_count = int(apiAnimeEpisodeCount) else: metadata.seasons[1].episode_count = int(len(media.seasons[1].episodes)) pages = int(math.ceil(float(metadata.seasons[1].episode_count) / 100)) # fetch the episodes in 100 chunks if pages is not None: for page in range(1, pages + 1): episodesUrl = MYANIMELIST_URL_MAIN + MYANIMELIST_URL_EPISODES.format(id=metadata.id,page=page) try: Log.Info("[" + AGENT_NAME + "] [MyAnimeListUtils] " + "Fetching URL " + str(episodesUrl)) episodeResult = JSON.ObjectFromString(HTTP.Request(episodesUrl, sleep=2.0, cacheTime=MYANIMELIST_CACHE_TIME).content) except Exception as e: Log.Info("[" + AGENT_NAME + "] " + "episode results could not be requested " + str(e)) return if "error" in episodeResult: Log.Warn("[" + AGENT_NAME + "] " + "Episode Information are not available (" + str(episodeResult["error"]) + ") (might want to add them to MyAnimeList.net)!") break for episode in episodeResult: apiEpisodeNumber = None # the Number of the episode apiEpisodeTitle = None # the title of the Episode apiEpisodeAirDate = None # the air date of the Episode # get the episode Number apiEpisodeNumber = utils.getJSONValue("number", episode) # get the episode title apiEpisodeTitle = utils.getJSONValue("title", episode) # get the episode air date apiEpisodeAirDate = utils.getJSONValue("air_date", episode) if apiEpisodeNumber is not None: plexEpisode = metadata.seasons[1].episodes[int(apiEpisodeNumber)] # add the Episode Title if it is available, if not use a default title if apiEpisodeTitle is not None: plexEpisode.title = str(apiEpisodeTitle) else: plexEpisode.title = "Episode: #" + str(apiEpisodeNumber) # add the episode air date if it is available, if not use the current date if apiEpisodeAirDate is not None: plexEpisode.originally_available_at = datetime.strptime(str(apiEpisodeAirDate), "%Y-%m-%d") else: plexEpisode.originally_available_at = datetime.now() Log.Debug("Episode " + str(apiEpisodeNumber) + ": " + str(apiEpisodeTitle) + " - " + str(apiEpisodeAirDate)) ''' Add specific data for Movies ''' if type == "movie": Log.Debug("[" + AGENT_NAME + "] [MyAnimeListUtils] " + "Adding Movie specific data") Log.Debug("[" + AGENT_NAME + "] [MyAnimeListUtils] " + "nothing specific to add") return
def search(self, name, results, lang): manualIdMatch = re.match(r'^myanimelist-id:([0-9]+)$', str(name)) if manualIdMatch: manualId = manualIdMatch.group(1) Log.Info("[" + AGENT_NAME + "] [MyAnimeListUtils] " + "Searching for Anime by ID: " + str(manualId)) searchUrl = MYANIMELIST_URL_MAIN + MYANIMELIST_URL_DETAILS.format(id=str(manualId)) wrapSearchResultsInArray = True forcePerfectAnimeMatchScore = True else: Log.Info("[" + AGENT_NAME + "] [MyAnimeListUtils] " + "Searching for Anime: " + str(name)) searchUrl = MYANIMELIST_URL_MAIN + MYANIMELIST_URL_SEARCH.format(title=String.Quote(name, usePlus=True)) wrapSearchResultsInArray = False forcePerfectAnimeMatchScore = False utils = Utils() try: Log.Info("[" + AGENT_NAME + "] [MyAnimeListUtils] " + "Fetching URL " + str(searchUrl)) searchResults = JSON.ObjectFromString(HTTP.Request(searchUrl, sleep=2.0, cacheTime=MYANIMELIST_CACHE_TIME).content) except Exception as e: Log.Info("[" + AGENT_NAME + "] " + "search results could not be requested " + str(e)) return if wrapSearchResultsInArray: searchResults = [searchResults] Log.Info("[" + AGENT_NAME + "] [MyAnimeListUtils] " + str(len(searchResults)) + " Results found") for series in searchResults: # get the ID if it is available apiAnimeId = str(utils.getJSONValue("id", series)) # get the title if it is available apiAnimeTitle = str(utils.getJSONValue("title", series)) try: Log.Info("[" + AGENT_NAME + "] [MyAnimeListUtils] " + "Fetching URL " + str(searchUrl)) search = tvdb.Search() meep = search.series(str(apiAnimeTitle)) apiAnimeTitleEng = meep[0]['seriesName'] except Exception as e: Log.Info("[" + AGENT_NAME + "] " + "search results could not be requested " + str(e)) return # get the year if it is available apiAnimeYear = str(utils.getJSONValue("start_date", series)).split("-")[0] # calculate the match score if forcePerfectAnimeMatchScore: animeMatchScore = 100 elif len(apiAnimeTitle) > 0: animeMatchScore = utils.getMatchScore(apiAnimeTitle, name) # append results to search results Log.Debug("[" + AGENT_NAME + "] " + "Anime Found - ID=" + str(apiAnimeId) + " Title=" + str(apiAnimeTitle) + " Alias=" + str(apiAnimeTitleEng) + " Year=" + str(apiAnimeYear) + " MatchScore=" + str(animeMatchScore)) results.Append(MetadataSearchResult(id=apiAnimeId, name=apiAnimeTitleEng, year=apiAnimeYear, score=animeMatchScore, lang=lang)) return