diff --git a/medusa/providers/torrent/json/animebytes.py b/medusa/providers/torrent/json/animebytes.py index cc3b5461cd..c2bef33a5c 100644 --- a/medusa/providers/torrent/json/animebytes.py +++ b/medusa/providers/torrent/json/animebytes.py @@ -108,6 +108,10 @@ def search(self, search_strings, age=0, ep_obj=None, **kwargs): log.debug('No data returned from provider') continue + if not jdata.get('Matches') and 'error' in jdata: + log.warning('No results returned. Error: {error}', {'error': jdata['error']}) + break + if jdata['Matches'] == 0: log.debug('0 results returned from provider for this search') continue @@ -145,182 +149,191 @@ def is_season_exception(series_name): continue for row in torrent_rows: - properties_string = row.get('Property').rstrip(' |').replace(' ', '') - # Hack for the h264 10bit stuff - properties_string = properties_string.replace('h26410-bit', 'h264|hi10p') - properties = properties_string.split('|') - download_url = row.get('Link') - if not (download_url or all(properties)): - continue - - # Get rid of freeleech from properties - if properties[-1] == 'Freeleech': - del properties[-1] - elif self.freeleech: - # Discard if we wanted free leech - continue - - tags = '{torrent_source}.{torrent_container}.{torrent_codec}.{torrent_res}.' \ - '{torrent_audio}'.format(torrent_source=properties[0], - torrent_container=properties[1], - torrent_codec=properties[2], - torrent_res=properties[3], - torrent_audio=properties[4]) - - last_field = re.match(r'(.*)\((.*)\)', properties[-1]) - - # subs = last_field.group(1) if last_field else '' - release_group = '-{0}'.format(last_field.group(2)) if last_field else '' - - release_type = OTHER - season = None - episode = None - multi_ep_start = None - multi_ep_end = None - title = None - - # Attempt and get a season or episode number - title_info = row.get('EditionData').get('EditionTitle') - - if title_info != '': - if title_info.startswith('Episodes'): - multi_ep_match = re.match(r'Episodes (\d+)-(\d+)', title_info) - if multi_ep_match: - multi_ep_start = multi_ep_match.group(1) - multi_ep_end = multi_ep_match.group(2) - release_type = MULTI_EP - release_type = OTHER - elif title_info.startswith('Episode'): - episode_match = re.match('^Episode.([0-9]+)', title_info) - if episode_match: - episode = episode_match.group(1) + try: + properties_string = row.get('Property').rstrip(' |').replace(' ', '') + # Hack for the h264 10bit stuff + properties_string = properties_string.replace('h26410-bit', 'h264|hi10p') + properties = properties_string.split('|') + download_url = row.get('Link') + if not (download_url or all(properties)): + continue + + # Get rid of freeleech from properties + if properties[-1] == 'Freeleech': + del properties[-1] + elif self.freeleech: + # Discard if we wanted free leech + continue + + try: + tags = '{torrent_source}.{torrent_container}.{torrent_codec}.{torrent_res}.' \ + '{torrent_audio}'.format(torrent_source=properties[0], + torrent_container=properties[1], + torrent_codec=properties[2], + torrent_res=properties[3], + torrent_audio=properties[4]) + except Exception as error: + log.warning('Could not get the desired amount of tags from {properties}. Error: {error}', + {'properties': properties_string, 'error': error}) + continue + + last_field = re.match(r'(.*)\((.*)\)', properties[-1]) + + # subs = last_field.group(1) if last_field else '' + release_group = '-{0}'.format(last_field.group(2)) if last_field else '' + + release_type = OTHER + season = None + episode = None + multi_ep_start = None + multi_ep_end = None + title = None + + # Attempt and get a season or episode number + title_info = row.get('EditionData').get('EditionTitle') + + if title_info != '': + if title_info.startswith('Episodes'): + multi_ep_match = re.match(r'Episodes (\d+)-(\d+)', title_info) + if multi_ep_match: + multi_ep_start = multi_ep_match.group(1) + multi_ep_end = multi_ep_match.group(2) + release_type = MULTI_EP + release_type = OTHER + elif title_info.startswith('Episode'): + episode_match = re.match('^Episode.([0-9]+)', title_info) + if episode_match: + episode = episode_match.group(1) + else: + log.warning('Could not get episode number from title_info: {title_info}', + {'title_info': title_info}) + + release_type = SINGLE_EP + + season_match = re.match(r'.+[sS]eason.(\d+)$', group.get('SeriesName')) + if season_match: + season = season_match.group(1) + elif title_info.startswith('Season'): + if re.match(r'Season.[0-9]+-[0-9]+.\([0-9-]+\)', title_info): + # We can read the season AND the episodes, but we can only process multiep. + # So i've chosen to use it like 12-23 or 1-12. + match = re.match(r'Season.([0-9]+)-([0-9]+).\(([0-9-]+)\)', title_info) + episode = match.group(3).upper() + season = '{0}-{1}'.format(match.group(1), match.group(2)) + release_type = MULTI_SEASON + else: + season = re.match('Season.([0-9]+)', title_info).group(1) + release_type = SEASON_PACK + elif group.get('GroupName') != 'TV Special': + # This is a season pack. + # 13 episodes -> SXXEXX-EXX + episode = int(group.get('EpCount')) + multi_ep_start = 1 + multi_ep_end = episode if episode > 0 else None + # Because we sometime get names without a season number, like season scene exceptions. + # This is the most reliable way of creating a multi-episode release name. + release_type = MULTI_EP + + # These are probably specials which we just can't handle anyways + if release_type == OTHER: + continue + + if release_type == SINGLE_EP: + # Create the single episode release_name (use the shows default title) + if is_season_exception(group.get('SeriesName')) or not season: + # If this is a season exception, we can't parse the release name like: + # Show.Title.Season.3.Exception.S01E01... + # As that will confuse the parser, as it already has a season available. + # We have to omit the season, to have it search for a season exception. + title = '{title}.{episode}.{tags}' \ + '{release_group}'.format(title=group.get('SeriesName'), + episode='E{0:02d}'.format(int(episode)), + tags=tags, + release_group=release_group) else: - log.warning('Could not get episode number from title_info: {title_info}', - {'title_info': title_info}) - - release_type = SINGLE_EP - - season_match = re.match(r'.+[sS]eason.(\d+)$', group.get('SeriesName')) - if season_match: - season = season_match.group(1) - elif title_info.startswith('Season'): - if re.match(r'Season.[0-9]+-[0-9]+.\([0-9-]+\)', title_info): - # We can read the season AND the episodes, but we can only process multiep. - # So i've chosen to use it like 12-23 or 1-12. - match = re.match(r'Season.([0-9]+)-([0-9]+).\(([0-9-]+)\)', title_info) - episode = match.group(3).upper() - season = '{0}-{1}'.format(match.group(1), match.group(2)) - release_type = MULTI_SEASON + title = '{title}.{season}.{episode}.{tags}' \ + '{release_group}'.format(title=group.get('SeriesName'), + season='S{0:02d}'.format(int(season)), + episode='E{0:02d}'.format(int(episode)), + tags=tags, + release_group=release_group) + if release_type == MULTI_EP: + # Create the multi-episode release_name + # Multiple.Episode.TV.Show.SXXEXX-EXX[Episode.Part].[Episode.Title].TAGS.[LANGUAGE].720p.FORMAT.x264-GROUP + if is_season_exception(group.get('SeriesName')): + # If this is a season exception, we can't parse the release name like: + # Show.Title.Season.3.Exception.S01E01-E13... + # As that will confuse the parser, as it already has a season available. + # We have to omit the season, to have it search for a season exception. + # Example: Show.Title.Season.3.Exception.E01-E13... + title = '{title}.{multi_episode_start}-{multi_episode_end}.{tags}' \ + '{release_group}'.format(title=group.get('SeriesName'), + multi_episode_start='E{0:02d}'.format(int(multi_ep_start)), + multi_episode_end='E{0:02d}'.format(int(multi_ep_end)) if multi_ep_end else 'Unknown', + tags=tags, + release_group=release_group) else: - season = re.match('Season.([0-9]+)', title_info).group(1) - release_type = SEASON_PACK - elif group.get('GroupName') != 'TV Special': - # This is a season pack. - # 13 episodes -> SXXEXX-EXX - episode = int(group.get('EpCount')) - multi_ep_start = 1 - multi_ep_end = episode if episode > 0 else None - # Because we sometime get names without a season number, like season scene exceptions. - # This is the most reliable way of creating a multi-episode release name. - release_type = MULTI_EP - - # These are probably specials which we just can't handle anyways - if release_type == OTHER: - continue + title = '{title}.{season}{multi_episode_start}-{multi_episode_end}.{tags}' \ + '{release_group}'.format(title=group.get('SeriesName'), + season='S{0:02d}'.format(season) if season else 'S01', + multi_episode_start='E{0:02d}'.format(int(multi_ep_start)), + multi_episode_end='E{0:02d}'.format(int(multi_ep_end)) if multi_ep_end else 'Unknown', + tags=tags, + release_group=release_group) + if release_type == SEASON_PACK: + # Create the season pack release_name + # if `Season` is already in the SeriesName, we ommit adding it another time. + title = '{title}.{season}.{tags}' \ + '{release_group}'.format(title=group.get('SeriesName'), + season='S{0:02d}'.format(int(season)) if season else 'S01', + tags=tags, + release_group=release_group) - if release_type == SINGLE_EP: - # Create the single episode release_name (use the shows default title) - if is_season_exception(group.get('SeriesName')) or not season: - # If this is a season exception, we can't parse the release name like: - # Show.Title.Season.3.Exception.S01E01... - # As that will confuse the parser, as it already has a season available. - # We have to omit the season, to have it search for a season exception. + if release_type == MULTI_SEASON: + # Create the multi season pack release_name + # Multiple.Episode.TV.Show.EXX-EXX[Episode.Part].[Episode.Title].TAGS.[LANGUAGE].720p.FORMAT.x264-GROUP title = '{title}.{episode}.{tags}' \ '{release_group}'.format(title=group.get('SeriesName'), - episode='E{0:02d}'.format(int(episode)), + episode=episode, tags=tags, release_group=release_group) - else: - title = '{title}.{season}.{episode}.{tags}' \ - '{release_group}'.format(title=group.get('SeriesName'), - season='S{0:02d}'.format(int(season)), - episode='E{0:02d}'.format(int(episode)), - tags=tags, - release_group=release_group) - if release_type == MULTI_EP: - # Create the multi-episode release_name - # Multiple.Episode.TV.Show.SXXEXX-EXX[Episode.Part].[Episode.Title].TAGS.[LANGUAGE].720p.FORMAT.x264-GROUP - if is_season_exception(group.get('SeriesName')): - # If this is a season exception, we can't parse the release name like: - # Show.Title.Season.3.Exception.S01E01-E13... - # As that will confuse the parser, as it already has a season available. - # We have to omit the season, to have it search for a season exception. - # Example: Show.Title.Season.3.Exception.E01-E13... - title = '{title}.{multi_episode_start}-{multi_episode_end}.{tags}' \ - '{release_group}'.format(title=group.get('SeriesName'), - multi_episode_start='E{0:02d}'.format(int(multi_ep_start)), - multi_episode_end='E{0:02d}'.format(int(multi_ep_end)) if multi_ep_end else 'Unknown', - tags=tags, - release_group=release_group) - else: - title = '{title}.{season}{multi_episode_start}-{multi_episode_end}.{tags}' \ - '{release_group}'.format(title=group.get('SeriesName'), - season='S{0:02d}'.format(season) if season else 'S01', - multi_episode_start='E{0:02d}'.format(int(multi_ep_start)), - multi_episode_end='E{0:02d}'.format(int(multi_ep_end)) if multi_ep_end else 'Unknown', - tags=tags, - release_group=release_group) - if release_type == SEASON_PACK: - # Create the season pack release_name - # if `Season` is already in the SeriesName, we ommit adding it another time. - title = '{title}.{season}.{tags}' \ - '{release_group}'.format(title=group.get('SeriesName'), - season='S{0:02d}'.format(int(season)) if season else 'S01', - tags=tags, - release_group=release_group) - - if release_type == MULTI_SEASON: - # Create the multi season pack release_name - # Multiple.Episode.TV.Show.EXX-EXX[Episode.Part].[Episode.Title].TAGS.[LANGUAGE].720p.FORMAT.x264-GROUP - title = '{title}.{episode}.{tags}' \ - '{release_group}'.format(title=group.get('SeriesName'), - episode=episode, - tags=tags, - release_group=release_group) - - seeders = row.get('Seeders') - leechers = row.get('Leechers') - pubdate = self.parse_pubdate(row.get('UploadTime')) - # This is a workaround for an animebytes caching issue where newly created torrents are cached with - # zero seeders and leechers - if seeders == 0 and leechers == 0 and datetime.now(timezone.utc) - pubdate < timedelta(hours=1): - seeders = 1 + seeders = row.get('Seeders') + leechers = row.get('Leechers') + pubdate = self.parse_pubdate(row.get('UploadTime')) + + # This is a workaround for an animebytes caching issue where newly created torrents are cached with + # zero seeders and leechers + if seeders == 0 and leechers == 0 and datetime.now(timezone.utc) - pubdate < timedelta(hours=1): + seeders = 1 + + # Filter unseeded torrent + if seeders < self.minseed: + if mode != 'RSS': + log.debug("Discarding torrent because it doesn't meet the" + ' minimum seeders: {0}. Seeders: {1}', + title, seeders) + continue + + size = convert_size(row.get('Size'), default=-1) + + item = { + 'title': title, + 'link': download_url, + 'size': size, + 'seeders': seeders, + 'leechers': leechers, + 'pubdate': pubdate, + } - # Filter unseeded torrent - if seeders < self.minseed: if mode != 'RSS': - log.debug("Discarding torrent because it doesn't meet the" - ' minimum seeders: {0}. Seeders: {1}', - title, seeders) - continue + log.debug('Found result: {0} with {1} seeders and {2} leechers', + title, seeders, leechers) - size = convert_size(row.get('Size'), default=-1) - - item = { - 'title': title, - 'link': download_url, - 'size': size, - 'seeders': seeders, - 'leechers': leechers, - 'pubdate': pubdate, - } - - if mode != 'RSS': - log.debug('Found result: {0} with {1} seeders and {2} leechers', - title, seeders, leechers) + items.append(item) - items.append(item) + except Exception as error: + log.warning('Error trying to parse result. Error: {error}', {'error': error}) return items