def test_RAWHDTV(self): from sickrage.core.common import Quality self.assertEqual(Quality.RAWHDTV, Quality.nameQuality("Test.Show.S01E02.720p.HDTV.DD5.1.MPEG2-GROUP")) self.assertEqual(Quality.RAWHDTV, Quality.nameQuality("Test.Show.S01E02.1080i.HDTV.DD2.0.MPEG2-GROUP")) self.assertEqual(Quality.RAWHDTV, Quality.nameQuality("Test.Show.S01E02.1080i.HDTV.H.264.DD2.0-GROUP")) self.assertEqual(Quality.RAWHDTV, Quality.nameQuality("Test Show - S01E02 - 1080i HDTV MPA1.0 H.264 - GROUP")) self.assertEqual(Quality.RAWHDTV, Quality.nameQuality("Test.Show.S01E02.1080i.HDTV.DD.5.1.h264-GROUP"))
def test_HDTV(self): self.assertEqual( Quality.HDTV, Quality.nameQuality("Test.Show.S01E02.720p.HDTV.x264-GROUP")) self.assertEqual( Quality.HDTV, Quality.nameQuality("Test.Show.S01E02.HR.WS.PDTV.x264-GROUP"))
def test_FULLHDBLURAY(self): self.assertEqual( Quality.FULLHDBLURAY, Quality.nameQuality("Test.Show.S01E02.1080p.BluRay.x264-GROUP")) self.assertEqual( Quality.FULLHDBLURAY, Quality.nameQuality("Test.Show.S01E02.1080p.HDDVD.x264-GROUP"))
def test_HDTV(self): from sickrage.core.common import Quality self.assertEqual( Quality.HDTV, Quality.nameQuality("Test.Show.S01E02.720p.HDTV.x264-GROUP")) self.assertEqual( Quality.HDTV, Quality.nameQuality("Test.Show.S01E02.HR.WS.PDTV.x264-GROUP"))
def test_FULLHDBLURAY(self): from sickrage.core.common import Quality self.assertEqual( Quality.FULLHDBLURAY, Quality.nameQuality("Test.Show.S01E02.1080p.BluRay.x264-GROUP")) self.assertEqual( Quality.FULLHDBLURAY, Quality.nameQuality("Test.Show.S01E02.1080p.HDDVD.x264-GROUP"))
def test_RAWHDTV(self): self.assertEqual(Quality.RAWHDTV, Quality.nameQuality("Test.Show.S01E02.720p.HDTV.DD5.1.MPEG2-GROUP")) self.assertEqual(Quality.RAWHDTV, Quality.nameQuality("Test.Show.S01E02.1080i.HDTV.DD2.0.MPEG2-GROUP")) self.assertEqual(Quality.RAWHDTV, Quality.nameQuality("Test.Show.S01E02.1080i.HDTV.H.264.DD2.0-GROUP")) self.assertEqual(Quality.RAWHDTV, Quality.nameQuality("Test Show - S01E02 - 1080i HDTV MPA1.0 H.264 - GROUP")) self.assertEqual(Quality.RAWHDTV, Quality.nameQuality("Test.Show.S01E02.1080i.HDTV.DD.5.1.h264-GROUP"))
def test_HDWEBDL(self): self.assertEqual( Quality.HDWEBDL, Quality.nameQuality("Test.Show.S01E02.720p.WEB-DL-GROUP")) self.assertEqual( Quality.HDWEBDL, Quality.nameQuality("Test.Show.S01E02.720p.WEBRip-GROUP")) self.assertEqual( Quality.HDWEBDL, Quality.nameQuality( "Test.Show.S01E02.WEBRip.720p.H.264.AAC.2.0-GROUP")) self.assertEqual( Quality.HDWEBDL, Quality.nameQuality( "Test.Show.S01E02.720p.WEB-DL.AAC2.0.H.264-GROUP")) self.assertEqual( Quality.HDWEBDL, Quality.nameQuality( "Test Show S01E02 720p WEB-DL AAC2 0 H 264-GROUP")) self.assertEqual( Quality.HDWEBDL, Quality.nameQuality( "Test_Show.S01E02_720p_WEB-DL_AAC2.0_H264-GROUP")) self.assertEqual( Quality.HDWEBDL, Quality.nameQuality( "Test.Show.S01E02.720p.WEB-DL.AAC2.0.H264-GROUP")) self.assertEqual( Quality.HDWEBDL, Quality.nameQuality( "Test.Show.S01E02.720p.iTunes.Rip.H264.AAC-GROUP"))
def test_HDWEBDL(self): from sickrage.core.common import Quality self.assertEqual(Quality.HDWEBDL, Quality.nameQuality("Test.Show.S01E02.720p.WEB-DL-GROUP")) self.assertEqual(Quality.HDWEBDL, Quality.nameQuality("Test.Show.S01E02.720p.WEBRip-GROUP")) self.assertEqual(Quality.HDWEBDL, Quality.nameQuality("Test.Show.S01E02.WEBRip.720p.H.264.AAC.2.0-GROUP")) self.assertEqual(Quality.HDWEBDL, Quality.nameQuality("Test.Show.S01E02.720p.WEB-DL.AAC2.0.H.264-GROUP")) self.assertEqual(Quality.HDWEBDL, Quality.nameQuality("Test Show S01E02 720p WEB-DL AAC2 0 H 264-GROUP")) self.assertEqual(Quality.HDWEBDL, Quality.nameQuality("Test_Show.S01E02_720p_WEB-DL_AAC2.0_H264-GROUP")) self.assertEqual(Quality.HDWEBDL, Quality.nameQuality("Test.Show.S01E02.720p.WEB-DL.AAC2.0.H264-GROUP")) self.assertEqual(Quality.HDWEBDL, Quality.nameQuality("Test.Show.S01E02.720p.iTunes.Rip.H264.AAC-GROUP")) self.assertEqual(Quality.HDWEBDL, Quality.nameQuality("Test.Show.S01E02.720p.AMZN.WEBRip.DDP5.1.x264-GROUP"))
def test_FULLHDWEBDL(self): self.assertEqual( Quality.FULLHDWEBDL, Quality.nameQuality("Test.Show.S01E02.1080p.WEB-DL-GROUP")) self.assertEqual( Quality.FULLHDWEBDL, Quality.nameQuality("Test.Show.S01E02.1080p.WEBRip-GROUP")) self.assertEqual( Quality.FULLHDWEBDL, Quality.nameQuality( "Test.Show.S01E02.WEBRip.1080p.H.264.AAC.2.0-GROUP")) self.assertEqual( Quality.FULLHDWEBDL, Quality.nameQuality( "Test.Show.S01E02.WEBRip.1080p.H264.AAC.2.0-GROUP")) self.assertEqual( Quality.FULLHDWEBDL, Quality.nameQuality( "Test.Show.S01E02.1080p.iTunes.H.264.AAC-GROUP")) self.assertEqual( Quality.FULLHDWEBDL, Quality.nameQuality( "Test Show S01E02 1080p iTunes H 264 AAC-GROUP")) self.assertEqual( Quality.FULLHDWEBDL, Quality.nameQuality( "Test_Show_S01E02_1080p_iTunes_H_264_AAC-GROUP"))
def test_FULLHDWEBDL(self): from sickrage.core.common import Quality self.assertEqual(Quality.FULLHDWEBDL, Quality.nameQuality("Test.Show.S01E02.1080p.WEB-DL-GROUP")) self.assertEqual(Quality.FULLHDWEBDL, Quality.nameQuality("Test.Show.S01E02.1080p.WEBRip-GROUP")) self.assertEqual(Quality.FULLHDWEBDL, Quality.nameQuality("Test.Show.S01E02.WEBRip.1080p.H.264.AAC.2.0-GROUP")) self.assertEqual(Quality.FULLHDWEBDL, Quality.nameQuality("Test.Show.S01E02.WEBRip.1080p.H264.AAC.2.0-GROUP")) self.assertEqual(Quality.FULLHDWEBDL, Quality.nameQuality("Test.Show.S01E02.1080p.iTunes.H.264.AAC-GROUP")) self.assertEqual(Quality.FULLHDWEBDL, Quality.nameQuality("Test Show S01E02 1080p iTunes H 264 AAC-GROUP")) self.assertEqual(Quality.FULLHDWEBDL, Quality.nameQuality("Test_Show_S01E02_1080p_iTunes_H_264_AAC-GROUP"))
def test_HDWEBDL(self): self.assertEqual(Quality.HDWEBDL, Quality.nameQuality("Test.Show.S01E02.720p.WEB-DL-GROUP")) self.assertEqual(Quality.HDWEBDL, Quality.nameQuality("Test.Show.S01E02.720p.WEBRip-GROUP")) self.assertEqual(Quality.HDWEBDL, Quality.nameQuality("Test.Show.S01E02.WEBRip.720p.H.264.AAC.2.0-GROUP")) self.assertEqual(Quality.HDWEBDL, Quality.nameQuality("Test.Show.S01E02.720p.WEB-DL.AAC2.0.H.264-GROUP")) self.assertEqual(Quality.HDWEBDL, Quality.nameQuality("Test Show S01E02 720p WEB-DL AAC2 0 H 264-GROUP")) self.assertEqual(Quality.HDWEBDL, Quality.nameQuality("Test_Show.S01E02_720p_WEB-DL_AAC2.0_H264-GROUP")) self.assertEqual(Quality.HDWEBDL, Quality.nameQuality("Test.Show.S01E02.720p.WEB-DL.AAC2.0.H264-GROUP")) self.assertEqual(Quality.HDWEBDL, Quality.nameQuality("Test.Show.S01E02.720p.iTunes.Rip.H264.AAC-GROUP"))
def test_HDWEBDL(self): from sickrage.core.common import Quality self.assertEqual( Quality.HDWEBDL, Quality.nameQuality("Test.Show.S01E02.720p.WEB-DL-GROUP")) self.assertEqual( Quality.HDWEBDL, Quality.nameQuality("Test.Show.S01E02.720p.WEBRip-GROUP")) self.assertEqual( Quality.HDWEBDL, Quality.nameQuality( "Test.Show.S01E02.WEBRip.720p.H.264.AAC.2.0-GROUP")) self.assertEqual( Quality.HDWEBDL, Quality.nameQuality( "Test.Show.S01E02.720p.WEB-DL.AAC2.0.H.264-GROUP")) self.assertEqual( Quality.HDWEBDL, Quality.nameQuality( "Test Show S01E02 720p WEB-DL AAC2 0 H 264-GROUP")) self.assertEqual( Quality.HDWEBDL, Quality.nameQuality( "Test_Show.S01E02_720p_WEB-DL_AAC2.0_H264-GROUP")) self.assertEqual( Quality.HDWEBDL, Quality.nameQuality( "Test.Show.S01E02.720p.WEB-DL.AAC2.0.H264-GROUP")) self.assertEqual( Quality.HDWEBDL, Quality.nameQuality( "Test.Show.S01E02.720p.iTunes.Rip.H264.AAC-GROUP")) self.assertEqual( Quality.HDWEBDL, Quality.nameQuality( "Test.Show.S01E02.720p.AMZN.WEBRip.DDP5.1.x264-GROUP"))
def test_FULLHDTV(self): from sickrage.core.common import Quality self.assertEqual(Quality.FULLHDTV, Quality.nameQuality("Test.Show.S01E02.1080p.HDTV.x264-GROUP"))
def parse(self, data, mode): """ Parse search results for items. :param data: The raw response from a search :param mode: The current mode used to search, e.g. RSS :return: A list of items found """ results = [] hdtext = [ ' Versione 720p', ' V 720p', ' V 720', ' V HEVC', ' V HEVC', ' V 1080', ' Versione 1080p', ' 720p HEVC', ' Ver 720', ' 720p HEVC', ' 720p' ] with bs4_parser(data) as html: torrent_table = html.find(class_='showrelease_tb') torrent_rows = torrent_table('tr') if torrent_table else [] # Continue only if at least one release is found if len(torrent_rows) < 3: sickrage.app.log.debug( 'Data returned from provider does not contain any torrents' ) return results # Skip column headers for row in torrent_table('tr')[1:]: cells = row('td') if not cells: continue try: title = unidecode(cells[6].text) title = title.replace('·', '').replace(',', '') title = title.replace('by', '-').strip() title = title.strip('-').strip() download_url = cells[1].find('a')['href'] if not all([title, download_url]): continue leechers = try_int(cells[3].text) seeders = try_int(cells[4].text, 1) filename_qt = self._reverse_quality( self._episode_quality(title)) for text in hdtext: title1 = title title = title.replace(text, filename_qt) if title != title1: break if Quality.nameQuality(title) == Quality.UNKNOWN: title += filename_qt if self._has_only_subs(title) and not self.subtitle: sickrage.app.log.debug( 'Torrent is only subtitled, skipping: {}'.format( title)) continue if self.engrelease and not self._is_english(title): sickrage.app.log.debug( "Torrent isn't english audio/subtitled, skipping: {} " .format(title)) continue size = -1 results += [{ 'title': title, 'link': download_url, 'size': size, 'seeders': seeders, 'leechers': leechers }] if mode != 'RSS': sickrage.app.log.debug( "Found result: {}".format(title)) except Exception: sickrage.app.log.error('Failed parsing provider') return results
def _getProperList(self): """ Walk providers for propers """ propers = {} search_date = datetime.datetime.today() - datetime.timedelta(days=2) origThreadName = threading.currentThread().getName() # for each provider get a list of the for providerID, providerObj in sickrage.srCore.providersDict.sort( randomize=sickrage.srCore.srConfig.RANDOMIZE_PROVIDERS).items( ): # check provider type and provider is enabled if not sickrage.srCore.srConfig.USE_NZBS and providerObj.type in [ NZBProvider.type, NewznabProvider.type ]: continue elif not sickrage.srCore.srConfig.USE_TORRENTS and providerObj.type in [ TorrentProvider.type, TorrentRssProvider.type ]: continue elif not providerObj.isEnabled: continue threading.currentThread().setName(origThreadName + " :: [" + providerObj.name + "]") sickrage.srCore.srLogger.info( "Searching for any new PROPER releases from " + providerObj.name) try: curPropers = providerObj.find_propers(search_date) except AuthException as e: sickrage.srCore.srLogger.warning( "Authentication error: {}".format(e.message)) continue except Exception as e: sickrage.srCore.srLogger.debug( "Error while searching " + providerObj.name + ", skipping: {}".format(e.message)) sickrage.srCore.srLogger.debug(traceback.format_exc()) continue # if they haven't been added by a different provider than add the proper to the list for x in curPropers: if not re.search(r'(^|[\. _-])(proper|repack)([\. _-]|$)', x.name, re.I): sickrage.srCore.srLogger.debug( 'findPropers returned a non-proper, we have caught and skipped it.' ) continue name = self._genericName(x.name) if not name in propers: sickrage.srCore.srLogger.debug("Found new proper: " + x.name) x.provider = providerObj propers[name] = x threading.currentThread().setName(origThreadName) # take the list of unique propers and get it sorted by sortedPropers = sorted(propers.values(), key=operator.attrgetter('date'), reverse=True) finalPropers = [] for curProper in sortedPropers: try: myParser = NameParser(False) parse_result = myParser.parse(curProper.name) except InvalidNameException: sickrage.srCore.srLogger.debug( "Unable to parse the filename " + curProper.name + " into a valid episode") continue except InvalidShowException: sickrage.srCore.srLogger.debug( "Unable to parse the filename " + curProper.name + " into a valid show") continue if not parse_result.series_name: continue if not parse_result.episode_numbers: sickrage.srCore.srLogger.debug( "Ignoring " + curProper.name + " because it's for a full season rather than specific episode" ) continue sickrage.srCore.srLogger.debug("Successful match! Result " + parse_result.original_name + " matched to show " + parse_result.show.name) # set the indexerid in the db to the show's indexerid curProper.indexerid = parse_result.show.indexerid # set the indexer in the db to the show's indexer curProper.indexer = parse_result.show.indexer # populate our Proper instance curProper.show = parse_result.show curProper.season = parse_result.season_number if parse_result.season_number is not None else 1 curProper.episode = parse_result.episode_numbers[0] curProper.release_group = parse_result.release_group curProper.version = parse_result.version curProper.quality = Quality.nameQuality(curProper.name, parse_result.is_anime) curProper.content = None # filter release bestResult = pickBestResult(curProper, parse_result.show) if not bestResult: sickrage.srCore.srLogger.debug( "Proper " + curProper.name + " were rejected by our release filters.") continue # only get anime proper if it has release group and version if bestResult.show.is_anime: if not bestResult.release_group and bestResult.version == -1: sickrage.srCore.srLogger.debug( "Proper " + bestResult.name + " doesn't have a release group and version, ignoring it" ) continue # check if we actually want this proper (if it's the right quality) dbData = [ x['doc'] for x in sickrage.srCore.mainDB().db.get_many( 'tv_episodes', bestResult.indexerid, with_doc=True) if x['doc']['season'] == bestResult.season and x['doc']['episode'] == bestResult.episode ] if not dbData: continue # only keep the proper if we have already retrieved the same quality ep (don't get better/worse ones) oldStatus, oldQuality = Quality.splitCompositeStatus( int(dbData[0]["status"])) if oldStatus not in (DOWNLOADED, SNATCHED) or oldQuality != bestResult.quality: continue # check if we actually want this proper (if it's the right release group and a higher version) if bestResult.show.is_anime: dbData = [ x['doc'] for x in sickrage.srCore.mainDB.db.get_many( 'tv_episodes', bestResult.indexerid, with_doc=True) if x['doc']['season'] == bestResult.season and x['doc']['episode'] == bestResult.episode ] oldVersion = int(dbData[0]["version"]) oldRelease_group = (dbData[0]["release_group"]) if -1 < oldVersion < bestResult.version: sickrage.srCore.srLogger.info("Found new anime v" + str(bestResult.version) + " to replace existing v" + str(oldVersion)) else: continue if oldRelease_group != bestResult.release_group: sickrage.srCore.srLogger.info( "Skipping proper from release group: " + bestResult.release_group + ", does not match existing release group: " + oldRelease_group) continue # if the show is in our list and there hasn't been a proper already added for that particular episode then add it to our list of propers if bestResult.indexerid != -1 and ( bestResult.indexerid, bestResult.season, bestResult.episode) not in map( operator.attrgetter('indexerid', 'season', 'episode'), finalPropers): sickrage.srCore.srLogger.info("Found a proper that we need: " + str(bestResult.name)) finalPropers.append(bestResult) return finalPropers
def _getProperList(self): """ Walk providers for propers """ propers = {} search_date = datetime.datetime.today() - datetime.timedelta(days=2) origThreadName = threading.currentThread().getName() # for each provider get a list of the for providerID, providerObj in sickrage.srCore.providersDict.sort( randomize=sickrage.srCore.srConfig.RANDOMIZE_PROVIDERS).items(): # check provider type and provider is enabled if not sickrage.srCore.srConfig.USE_NZBS and providerObj.type in [NZBProvider.type, NewznabProvider.type]: continue elif not sickrage.srCore.srConfig.USE_TORRENTS and providerObj.type in [TorrentProvider.type, TorrentRssProvider.type]: continue elif not providerObj.isEnabled: continue threading.currentThread().setName(origThreadName + " :: [" + providerObj.name + "]") sickrage.srCore.srLogger.info("Searching for any new PROPER releases from " + providerObj.name) try: curPropers = providerObj.findPropers(search_date) except AuthException as e: sickrage.srCore.srLogger.debug("Authentication error: {}".format(e.message)) continue except Exception as e: sickrage.srCore.srLogger.debug( "Error while searching " + providerObj.name + ", skipping: {}".format(e.message)) sickrage.srCore.srLogger.debug(traceback.format_exc()) continue # if they haven't been added by a different provider than add the proper to the list for x in curPropers: if not re.search(r'(^|[\. _-])(proper|repack)([\. _-]|$)', x.name, re.I): sickrage.srCore.srLogger.debug('findPropers returned a non-proper, we have caught and skipped it.') continue name = self._genericName(x.name) if not name in propers: sickrage.srCore.srLogger.debug("Found new proper: " + x.name) x.provider = providerObj propers[name] = x threading.currentThread().setName(origThreadName) # take the list of unique propers and get it sorted by sortedPropers = sorted(propers.values(), key=operator.attrgetter('date'), reverse=True) finalPropers = [] for curProper in sortedPropers: try: myParser = NameParser(False) parse_result = myParser.parse(curProper.name) except InvalidNameException: sickrage.srCore.srLogger.debug( "Unable to parse the filename " + curProper.name + " into a valid episode") continue except InvalidShowException: sickrage.srCore.srLogger.debug("Unable to parse the filename " + curProper.name + " into a valid show") continue if not parse_result.series_name: continue if not parse_result.episode_numbers: sickrage.srCore.srLogger.debug( "Ignoring " + curProper.name + " because it's for a full season rather than specific episode") continue sickrage.srCore.srLogger.debug( "Successful match! Result " + parse_result.original_name + " matched to show " + parse_result.show.name) # set the indexerid in the db to the show's indexerid curProper.indexerid = parse_result.show.indexerid # set the indexer in the db to the show's indexer curProper.indexer = parse_result.show.indexer # populate our Proper instance curProper.show = parse_result.show curProper.season = parse_result.season_number if parse_result.season_number is not None else 1 curProper.episode = parse_result.episode_numbers[0] curProper.release_group = parse_result.release_group curProper.version = parse_result.version curProper.quality = Quality.nameQuality(curProper.name, parse_result.is_anime) curProper.content = None # filter release bestResult = pickBestResult(curProper, parse_result.show) if not bestResult: sickrage.srCore.srLogger.debug("Proper " + curProper.name + " were rejected by our release filters.") continue # only get anime proper if it has release group and version if bestResult.show.is_anime: if not bestResult.release_group and bestResult.version == -1: sickrage.srCore.srLogger.debug( "Proper " + bestResult.name + " doesn't have a release group and version, ignoring it") continue # check if we actually want this proper (if it's the right quality) sqlResults = main_db.MainDB().select( "SELECT status FROM tv_episodes WHERE showid = ? AND season = ? AND episode = ?", [bestResult.indexerid, bestResult.season, bestResult.episode]) if not sqlResults: continue # only keep the proper if we have already retrieved the same quality ep (don't get better/worse ones) oldStatus, oldQuality = Quality.splitCompositeStatus(int(sqlResults[0]["status"])) if oldStatus not in (DOWNLOADED, SNATCHED) or oldQuality != bestResult.quality: continue # check if we actually want this proper (if it's the right release group and a higher version) if bestResult.show.is_anime: sqlResults = main_db.MainDB().select( "SELECT release_group, version FROM tv_episodes WHERE showid = ? AND season = ? AND episode = ?", [bestResult.indexerid, bestResult.season, bestResult.episode]) oldVersion = int(sqlResults[0]["version"]) oldRelease_group = (sqlResults[0]["release_group"]) if oldVersion > -1 and oldVersion < bestResult.version: sickrage.srCore.srLogger.info( "Found new anime v" + str(bestResult.version) + " to replace existing v" + str(oldVersion)) else: continue if oldRelease_group != bestResult.release_group: sickrage.srCore.srLogger.info( "Skipping proper from release group: " + bestResult.release_group + ", does not match existing release group: " + oldRelease_group) continue # if the show is in our list and there hasn't been a proper already added for that particular episode then add it to our list of propers if bestResult.indexerid != -1 and (bestResult.indexerid, bestResult.season, bestResult.episode) not in map( operator.attrgetter('indexerid', 'season', 'episode'), finalPropers): sickrage.srCore.srLogger.info("Found a proper that we need: " + str(bestResult.name)) finalPropers.append(bestResult) return finalPropers
def test_FULLHDTV(self): self.assertEqual( Quality.FULLHDTV, Quality.nameQuality("Test.Show.S01E02.1080p.HDTV.x264-GROUP"))
def test_SDDVD(self): from sickrage.core.common import Quality self.assertEqual( Quality.SDDVD, Quality.nameQuality("Test.Show.S01E02.DVDRiP.XViD-GROUP")) self.assertEqual( Quality.SDDVD, Quality.nameQuality("Test.Show.S01E02.DVDRiP.DiVX-GROUP")) self.assertEqual( Quality.SDDVD, Quality.nameQuality("Test.Show.S01E02.DVDRiP.x264-GROUP")) self.assertEqual( Quality.SDDVD, Quality.nameQuality("Test.Show.S01E02.DVDRip.WS.XViD-GROUP")) self.assertEqual( Quality.SDDVD, Quality.nameQuality("Test.Show.S01E02.DVDRip.WS.DiVX-GROUP")) self.assertEqual( Quality.SDDVD, Quality.nameQuality("Test.Show.S01E02.DVDRip.WS.x264-GROUP")) self.assertEqual( Quality.SDDVD, Quality.nameQuality("Test.Show.S01E02.BDRIP.XViD-GROUP")) self.assertEqual( Quality.SDDVD, Quality.nameQuality("Test.Show.S01E02.BDRIP.DiVX-GROUP")) self.assertEqual( Quality.SDDVD, Quality.nameQuality("Test.Show.S01E02.BDRIP.x264-GROUP")) self.assertEqual( Quality.SDDVD, Quality.nameQuality("Test.Show.S01E02.BDRIP.WS.XViD-GROUP")) self.assertEqual( Quality.SDDVD, Quality.nameQuality("Test.Show.S01E02.BDRIP.WS.DiVX-GROUP")) self.assertEqual( Quality.SDDVD, Quality.nameQuality("Test.Show.S01E02.BDRIP.WS.x264-GROUP"))
def test_HDTV(self): from sickrage.core.common import Quality self.assertEqual(Quality.HDTV, Quality.nameQuality("Test.Show.S01E02.720p.HDTV.x264-GROUP")) self.assertEqual(Quality.HDTV, Quality.nameQuality("Test.Show.S01E02.HR.WS.PDTV.x264-GROUP"))
def test_SDDVD(self): self.assertEqual( Quality.SDDVD, Quality.nameQuality("Test.Show.S01E02.DVDRiP.XViD-GROUP")) self.assertEqual( Quality.SDDVD, Quality.nameQuality("Test.Show.S01E02.DVDRiP.DiVX-GROUP")) self.assertEqual( Quality.SDDVD, Quality.nameQuality("Test.Show.S01E02.DVDRiP.x264-GROUP")) self.assertEqual( Quality.SDDVD, Quality.nameQuality("Test.Show.S01E02.DVDRip.WS.XViD-GROUP")) self.assertEqual( Quality.SDDVD, Quality.nameQuality("Test.Show.S01E02.DVDRip.WS.DiVX-GROUP")) self.assertEqual( Quality.SDDVD, Quality.nameQuality("Test.Show.S01E02.DVDRip.WS.x264-GROUP")) self.assertEqual( Quality.SDDVD, Quality.nameQuality("Test.Show.S01E02.BDRIP.XViD-GROUP")) self.assertEqual( Quality.SDDVD, Quality.nameQuality("Test.Show.S01E02.BDRIP.DiVX-GROUP")) self.assertEqual( Quality.SDDVD, Quality.nameQuality("Test.Show.S01E02.BDRIP.x264-GROUP")) self.assertEqual( Quality.SDDVD, Quality.nameQuality("Test.Show.S01E02.BDRIP.WS.XViD-GROUP")) self.assertEqual( Quality.SDDVD, Quality.nameQuality("Test.Show.S01E02.BDRIP.WS.DiVX-GROUP")) self.assertEqual( Quality.SDDVD, Quality.nameQuality("Test.Show.S01E02.BDRIP.WS.x264-GROUP"))
def test_UNKNOWN(self): self.assertEqual(Quality.UNKNOWN, Quality.nameQuality("Test.Show.S01E02-SiCKBEARD"))
def test_UNKNOWN(self): self.assertEqual(Quality.UNKNOWN, Quality.nameQuality("Test.Show.S01E02-SICKRAGE"))
def test_FULLHDBLURAY(self): self.assertEqual(Quality.FULLHDBLURAY, Quality.nameQuality("Test.Show.S01E02.1080p.BluRay.x264-GROUP")) self.assertEqual(Quality.FULLHDBLURAY, Quality.nameQuality("Test.Show.S01E02.1080p.HDDVD.x264-GROUP"))
def parse(self, data, mode): """ Parse search results for items. :param data: The raw response from a search :param mode: The current mode used to search, e.g. RSS :return: A list of items found """ results = [] hdtext = [' Versione 720p', ' V 720p', ' V 720', ' V HEVC', ' V HEVC', ' V 1080', ' Versione 1080p', ' 720p HEVC', ' Ver 720', ' 720p HEVC', ' 720p'] with bs4_parser(data) as html: torrent_table = html.find(class_='showrelease_tb') torrent_rows = torrent_table('tr') if torrent_table else [] # Continue only if at least one release is found if len(torrent_rows) < 3: sickrage.app.log.debug('Data returned from provider does not contain any torrents') return results # Skip column headers for row in torrent_table('tr')[1:]: cells = row('td') if not cells: continue try: title = unidecode(cells[6].text) title = title.replace('·', '').replace(',', '') title = title.replace('by', '-').strip() title = title.strip('-').strip() download_url = cells[1].find('a')['href'] if not all([title, download_url]): continue leechers = try_int(cells[3].text) seeders = try_int(cells[4].text, 1) filename_qt = self._reverse_quality(self._episode_quality(title)) for text in hdtext: title1 = title title = title.replace(text, filename_qt) if title != title1: break if Quality.nameQuality(title) == Quality.UNKNOWN: title += filename_qt if self._has_only_subs(title) and not self.subtitle: sickrage.app.log.debug('Torrent is only subtitled, skipping: {}'.format(title)) continue if self.engrelease and not self._is_english(title): sickrage.app.log.debug("Torrent isn't english audio/subtitled, skipping: {} ".format(title)) continue size = -1 item = { 'title': title, 'link': download_url, 'size': size, 'seeders': seeders, 'leechers': leechers, } if mode != 'RSS': sickrage.app.log.debug('Found result: {}'.format(title)) results.append(item) except Exception: sickrage.app.log.error('Failed parsing provider') return results
def _doSearch(self, search_params, search_mode="eponly", epcount=0, age=0, epObj=None): results = [] items = {"Season": [], "Episode": [], "RSS": []} self.categories = "cat=" + str(self.cat) if not self._doLogin(): return results for mode in search_params.keys(): sickrage.LOGGER.debug("Search Mode: %s" % mode) for search_string in search_params[mode]: if mode is "RSS": self.page = 2 last_page = 0 y = int(self.page) if search_string == "": continue search_string = str(search_string).replace(".", " ") for x in range(0, y): z = x * 20 if last_page: break if mode is not "RSS": searchURL = (self.urls["search_page"] + "&filter={2}").format(z, self.categories, search_string) else: searchURL = self.urls["search_page"].format(z, self.categories) if mode is not "RSS": sickrage.LOGGER.debug("Search string: %s " % search_string) sickrage.LOGGER.debug("Search URL: %s" % searchURL) data = self.getURL(searchURL) if not data: sickrage.LOGGER.debug("No data returned from provider") continue try: with BS4Parser(data, markup_type="HTML", features=["html5lib", "permissive"]) as html: torrent_table = html.find("table", attrs={"class": "copyright"}) torrent_rows = torrent_table.find_all("tr") if torrent_table else [] # Continue only if one Release is found if len(torrent_rows) < 3: sickrage.LOGGER.debug("Data returned from provider does not contain any torrents") last_page = 1 continue if len(torrent_rows) < 42: last_page = 1 for result in torrent_table.find_all("tr")[2:]: try: link = result.find("td").find("a") title = link.string download_url = ( self.urls["download"] % result.find_all("td")[8].find("a")["href"][-8:] ) leechers = result.find_all("td")[3].find_all("td")[1].text leechers = int(leechers.strip("[]")) seeders = result.find_all("td")[3].find_all("td")[2].text seeders = int(seeders.strip("[]")) # FIXME size = -1 except (AttributeError, TypeError): continue filename_qt = self._reverseQuality(self._episodeQuality(result)) for text in self.hdtext: title1 = title title = title.replace(text, filename_qt) if title != title1: break if Quality.nameQuality(title) == Quality.UNKNOWN: title += filename_qt if not self._is_italian(result) and not self.subtitle: sickrage.LOGGER.debug("Torrent is subtitled, skipping: %s " % title) continue if self.engrelease and not self._is_english(result): sickrage.LOGGER.debug( "Torrent isnt english audio/subtitled , skipping: %s " % title ) continue search_show = re.split(r"([Ss][\d{1,2}]+)", search_string)[0] show_title = search_show rindex = re.search(r"([Ss][\d{1,2}]+)", title) if rindex: show_title = title[: rindex.start()] ep_params = title[rindex.start() :] if ( show_title.lower() != search_show.lower() and search_show.lower() in show_title.lower() and ep_params ): title = search_show + ep_params if not all([title, download_url]): continue if self._is_season_pack(title): title = re.sub(r"([Ee][\d{1,2}\-?]+)", "", title) # Filter unseeded torrent if seeders < self.minseed or leechers < self.minleech: if mode is not "RSS": sickrage.LOGGER.debug( "Discarding torrent because it doesn't meet the minimum seeders or leechers: {0} (S:{1} L:{2})".format( title, seeders, leechers ) ) continue item = title, download_url, size, seeders, leechers if mode is not "RSS": sickrage.LOGGER.debug("Found result: %s " % title) items[mode].append(item) except Exception: sickrage.LOGGER.error("Failed parsing provider. Traceback: %s" % traceback.format_exc()) # For each search mode sort all the items by seeders if available if available items[mode].sort(key=lambda tup: tup[3], reverse=True) results += items[mode] return results
def test_FULLHDTV(self): from sickrage.core.common import Quality self.assertEqual( Quality.FULLHDTV, Quality.nameQuality("Test.Show.S01E02.1080p.HDTV.x264-GROUP"))
def test_UNKNOWN(self): from sickrage.core.common import Quality self.assertEqual(Quality.UNKNOWN, Quality.nameQuality("Test.Show.S01E02-SICKRAGE"))
def _getProperList(self): """ Walk providers for propers """ propers = {} search_date = datetime.datetime.today() - datetime.timedelta(days=2) origThreadName = threading.currentThread().getName() recently_aired = [] for show in sickrage.app.showlist: self._lastProperSearch = self._get_lastProperSearch(show.indexerid) for episode in sickrage.app.main_db.get_many('tv_episodes', show.indexerid): if episode['airdate'] >= str(search_date.toordinal()): if episode['status'] in Quality.DOWNLOADED + Quality.SNATCHED + Quality.SNATCHED_BEST: recently_aired += [episode] self._set_lastProperSearch(show.indexerid, datetime.datetime.today().toordinal()) if not recently_aired: sickrage.app.log.info('No recently aired episodes, nothing to search for') return [] # for each provider get a list of the for providerID, providerObj in sickrage.app.search_providers.sort( randomize=sickrage.app.config.randomize_providers).items(): # check provider type and provider is enabled if not sickrage.app.config.use_nzbs and providerObj.type in [NZBProvider.type, NewznabProvider.type]: continue elif not sickrage.app.config.use_torrents and providerObj.type in [TorrentProvider.type, TorrentRssProvider.type]: continue elif not providerObj.isEnabled: continue threading.currentThread().setName(origThreadName + " :: [" + providerObj.name + "]") sickrage.app.log.info("Searching for any new PROPER releases from " + providerObj.name) try: curPropers = providerObj.find_propers(recently_aired) except AuthException as e: sickrage.app.log.warning("Authentication error: {}".format(e)) continue except Exception as e: sickrage.app.log.debug( "Error while searching " + providerObj.name + ", skipping: {}".format(e)) sickrage.app.log.debug(traceback.format_exc()) continue # if they haven't been added by a different provider than add the proper to the list for x in curPropers: if not re.search(r'(^|[. _-])(proper|repack)([. _-]|$)', x.name, re.I): sickrage.app.log.debug('findPropers returned a non-proper, we have caught and skipped it.') continue name = self._genericName(x.name) if name not in propers: sickrage.app.log.debug("Found new proper: " + x.name) x.provider = providerObj propers[name] = x threading.currentThread().setName(origThreadName) # take the list of unique propers and get it sorted by sortedPropers = sorted(propers.values(), key=operator.attrgetter('date'), reverse=True) finalPropers = [] for curProper in sortedPropers: try: myParser = NameParser(False) parse_result = myParser.parse(curProper.name) except InvalidNameException: sickrage.app.log.debug( "Unable to parse the filename " + curProper.name + " into a valid episode") continue except InvalidShowException: sickrage.app.log.debug("Unable to parse the filename " + curProper.name + " into a valid show") continue if not parse_result.series_name: continue if not parse_result.episode_numbers: sickrage.app.log.debug( "Ignoring " + curProper.name + " because it's for a full season rather than specific episode") continue sickrage.app.log.debug( "Successful match! Result " + parse_result.original_name + " matched to show " + parse_result.show.name) # set the indexerid in the db to the show's indexerid curProper.indexerid = parse_result.indexerid # set the indexer in the db to the show's indexer curProper.indexer = parse_result.show.indexer # populate our Proper instance curProper.show = parse_result.show curProper.season = parse_result.season_number if parse_result.season_number is not None else 1 curProper.episode = parse_result.episode_numbers[0] curProper.release_group = parse_result.release_group curProper.version = parse_result.version curProper.quality = Quality.nameQuality(curProper.name, parse_result.is_anime) curProper.content = None # filter release bestResult = pickBestResult(curProper, parse_result.show) if not bestResult: sickrage.app.log.debug("Proper " + curProper.name + " were rejected by our release filters.") continue # only get anime proper if it has release group and version if bestResult.show.is_anime: if not bestResult.release_group and bestResult.version == -1: sickrage.app.log.debug( "Proper " + bestResult.name + " doesn't have a release group and version, ignoring it") continue # check if we actually want this proper (if it's the right quality) dbData = [x for x in sickrage.app.main_db().get_many('tv_episodes', bestResult.indexerid) if x['season'] == bestResult.season and x['episode'] == bestResult.episode] if not dbData: continue # only keep the proper if we have already retrieved the same quality ep (don't get better/worse ones) oldStatus, oldQuality = Quality.splitCompositeStatus(int(dbData[0]["status"])) if oldStatus not in (DOWNLOADED, SNATCHED) or oldQuality != bestResult.quality: continue # check if we actually want this proper (if it's the right release group and a higher version) if bestResult.show.is_anime: dbData = [x for x in sickrage.app.main_db.get_many('tv_episodes', bestResult.indexerid) if x['season'] == bestResult.season and x['episode'] == bestResult.episode] oldVersion = int(dbData[0]["version"]) oldRelease_group = (dbData[0]["release_group"]) if -1 < oldVersion < bestResult.version: sickrage.app.log.info( "Found new anime v" + str(bestResult.version) + " to replace existing v" + str(oldVersion)) else: continue if oldRelease_group != bestResult.release_group: sickrage.app.log.info( "Skipping proper from release group: " + bestResult.release_group + ", does not match existing release group: " + oldRelease_group) continue # if the show is in our list and there hasn't been a proper already added for that particular episode then add it to our list of propers if bestResult.indexerid != -1 and (bestResult.indexerid, bestResult.season, bestResult.episode) not in map( operator.attrgetter('indexerid', 'season', 'episode'), finalPropers): sickrage.app.log.info("Found a proper that we need: " + str(bestResult.name)) finalPropers.append(bestResult) return finalPropers
def _parse_string(self, name): if not name: return matches = [] bestResult = None for (cur_regex_num, cur_regex_name, cur_regex) in self.compiled_regexes: match = cur_regex.match(name) if not match: continue result = ParseResult(name) result.which_regex = [cur_regex_name] result.score = 0 - cur_regex_num named_groups = match.groupdict().keys() if 'series_name' in named_groups: result.series_name = match.group('series_name') if result.series_name: result.series_name = self.clean_series_name(result.series_name) result.score += 1 if 'series_num' in named_groups and match.group('series_num'): result.score += 1 if 'season_num' in named_groups: tmp_season = int(match.group('season_num')) if cur_regex_name == 'bare' and tmp_season in (19, 20): continue result.season_number = tmp_season result.score += 1 if 'ep_num' in named_groups: ep_num = self._convert_number(match.group('ep_num')) result.score += 1 if 'extra_ep_num' in named_groups and match.group('extra_ep_num'): result.episode_numbers = range(ep_num, self._convert_number(match.group('extra_ep_num')) + 1) result.score += 1 else: result.episode_numbers = [ep_num] if 'ep_ab_num' in named_groups: ep_ab_num = self._convert_number(match.group('ep_ab_num')) result.score += 1 if 'extra_ab_ep_num' in named_groups and match.group('extra_ab_ep_num'): result.ab_episode_numbers = range(ep_ab_num, self._convert_number(match.group('extra_ab_ep_num')) + 1) result.score += 1 else: result.ab_episode_numbers = [ep_ab_num] if 'air_date' in named_groups: air_date = match.group('air_date') try: result.air_date = parser.parse(air_date, fuzzy=True).date() result.score += 1 except Exception: continue if 'extra_info' in named_groups: tmp_extra_info = match.group('extra_info') # Show.S04.Special or Show.S05.Part.2.Extras is almost certainly not every episode in the season if tmp_extra_info and cur_regex_name == 'season_only' and re.search( r'([. _-]|^)(special|extra)s?\w*([. _-]|$)', tmp_extra_info, re.I): continue result.extra_info = tmp_extra_info result.score += 1 if 'release_group' in named_groups: result.release_group = match.group('release_group') result.score += 1 if 'version' in named_groups: # assigns version to anime file if detected using anime regex. Non-anime regex receives -1 version = match.group('version') if version: result.version = version else: result.version = 1 else: result.version = -1 matches.append(result) if len(matches): # pick best match with highest score based on placement bestResult = max(sorted(matches, reverse=True, key=lambda x: x.which_regex), key=lambda x: x.score) show = None if not self.naming_pattern: # try and create a show object for this result show = self.get_show(bestResult.series_name, self.tryIndexers) # confirm passed in show object indexer id matches result show object indexer id if show: if self.showObj and show.indexerid != self.showObj.indexerid: show = None bestResult.show = show elif not show and self.showObj: bestResult.show = self.showObj # if this is a naming pattern test or result doesn't have a show object then return best result if not bestResult.show or self.naming_pattern: return bestResult # get quality bestResult.quality = Quality.nameQuality(name, bestResult.show.is_anime) new_episode_numbers = [] new_season_numbers = [] new_absolute_numbers = [] # if we have an air-by-date show then get the real season/episode numbers if bestResult.is_air_by_date: from sickrage.core.databases import main_db airdate = bestResult.air_date.toordinal() sql_result = main_db.MainDB().select( "SELECT season, episode FROM tv_episodes WHERE showid = ? AND indexer = ? AND airdate = ?", [bestResult.show.indexerid, bestResult.show.indexer, airdate]) season_number = None episode_numbers = [] if sql_result: season_number = int(sql_result[0][0]) episode_numbers = [int(sql_result[0][1])] if not season_number or not len(episode_numbers): try: lINDEXER_API_PARMS = srIndexerApi(bestResult.show.indexer).api_params.copy() if bestResult.show.lang: lINDEXER_API_PARMS['language'] = bestResult.show.lang t = srIndexerApi(bestResult.show.indexer).indexer(**lINDEXER_API_PARMS) epObj = t[bestResult.show.indexerid].airedOn(bestResult.air_date)[0] season_number = int(epObj["seasonnumber"]) episode_numbers = [int(epObj["episodenumber"])] except indexer_episodenotfound: sickrage.srCore.srLogger.warning( "Unable to find episode with date " + bestResult.air_date + " for show " + bestResult.show.name + ", skipping") episode_numbers = [] except indexer_error as e: sickrage.srCore.srLogger.warning( "Unable to contact " + srIndexerApi(bestResult.show.indexer).name + ": {}".format( e)) episode_numbers = [] for epNo in episode_numbers: s = season_number e = epNo if bestResult.show.is_scene: (s, e) = get_indexer_numbering(bestResult.show.indexerid, bestResult.show.indexer, season_number, epNo) new_episode_numbers.append(e) new_season_numbers.append(s) elif bestResult.show.is_anime and len(bestResult.ab_episode_numbers): scene_season = get_scene_exception_by_name(bestResult.series_name)[1] for epAbsNo in bestResult.ab_episode_numbers: a = epAbsNo if bestResult.show.is_scene: a = get_indexer_absolute_numbering(bestResult.show.indexerid, bestResult.show.indexer, epAbsNo, True, scene_season) (s, e) = get_all_episodes_from_absolute_number(bestResult.show, [a]) new_absolute_numbers.append(a) new_episode_numbers.extend(e) new_season_numbers.append(s) elif bestResult.season_number and len(bestResult.episode_numbers): for epNo in bestResult.episode_numbers: s = bestResult.season_number e = epNo if bestResult.show.is_scene: (s, e) = get_indexer_numbering(bestResult.show.indexerid, bestResult.show.indexer, bestResult.season_number, epNo) if bestResult.show.is_anime: a = get_absolute_number_from_season_and_episode(bestResult.show, s, e) if a: new_absolute_numbers.append(a) new_episode_numbers.append(e) new_season_numbers.append(s) # need to do a quick sanity check heregex. It's possible that we now have episodes # from more than one season (by tvdb numbering), and this is just too much # for sickrage, so we'd need to flag it. new_season_numbers = list(set(new_season_numbers)) # remove duplicates if len(new_season_numbers) > 1: raise InvalidNameException("Scene numbering results episodes from " "seasons %s, (i.e. more than one) and " "sickrage does not support this. " "Sorry." % new_season_numbers) # I guess it's possible that we'd have duplicate episodes too, so lets # eliminate them new_episode_numbers = list(set(new_episode_numbers)) new_episode_numbers.sort() # maybe even duplicate absolute numbers so why not do them as well new_absolute_numbers = list(set(new_absolute_numbers)) new_absolute_numbers.sort() if len(new_absolute_numbers): bestResult.ab_episode_numbers = new_absolute_numbers if len(new_season_numbers) and len(new_episode_numbers): bestResult.episode_numbers = new_episode_numbers bestResult.season_number = new_season_numbers[0] if bestResult.show.is_scene: sickrage.srCore.srLogger.debug( "Converted parsed result {} into {}".format(bestResult.original_name, bestResult)) # CPU sleep time.sleep(1) return bestResult
def test_SDDVD(self): from sickrage.core.common import Quality self.assertEqual(Quality.SDDVD, Quality.nameQuality("Test.Show.S01E02.DVDRiP.XViD-GROUP")) self.assertEqual(Quality.SDDVD, Quality.nameQuality("Test.Show.S01E02.DVDRiP.DiVX-GROUP")) self.assertEqual(Quality.SDDVD, Quality.nameQuality("Test.Show.S01E02.DVDRiP.x264-GROUP")) self.assertEqual(Quality.SDDVD, Quality.nameQuality("Test.Show.S01E02.DVDRip.WS.XViD-GROUP")) self.assertEqual(Quality.SDDVD, Quality.nameQuality("Test.Show.S01E02.DVDRip.WS.DiVX-GROUP")) self.assertEqual(Quality.SDDVD, Quality.nameQuality("Test.Show.S01E02.DVDRip.WS.x264-GROUP")) self.assertEqual(Quality.SDDVD, Quality.nameQuality("Test.Show.S01E02.BDRIP.XViD-GROUP")) self.assertEqual(Quality.SDDVD, Quality.nameQuality("Test.Show.S01E02.BDRIP.DiVX-GROUP")) self.assertEqual(Quality.SDDVD, Quality.nameQuality("Test.Show.S01E02.BDRIP.x264-GROUP")) self.assertEqual(Quality.SDDVD, Quality.nameQuality("Test.Show.S01E02.BDRIP.WS.XViD-GROUP")) self.assertEqual(Quality.SDDVD, Quality.nameQuality("Test.Show.S01E02.BDRIP.WS.DiVX-GROUP")) self.assertEqual(Quality.SDDVD, Quality.nameQuality("Test.Show.S01E02.BDRIP.WS.x264-GROUP"))
def search(self, search_params, search_mode='eponly', epcount=0, age=0, epObj=None): results = [] items = {'Season': [], 'Episode': [], 'RSS': []} self.categories = "cat=" + str(self.cat) if not self.login(): return results for mode in search_params.keys(): sickrage.srCore.srLogger.debug("Search Mode: %s" % mode) for search_string in search_params[mode]: if mode == 'RSS': self.page = 2 last_page = 0 y = int(self.page) if search_string == '': continue search_string = str(search_string).replace('.', ' ') for x in range(0, y): z = x * 20 if last_page: break if mode != 'RSS': searchURL = (self.urls['search_page'] + '&filter=%s') % (z, self.categories, search_string) else: searchURL = self.urls['search_page'] % (z, self.categories) if mode != 'RSS': sickrage.srCore.srLogger.debug("Search string: %s " % search_string) sickrage.srCore.srLogger.debug("Search URL: %s" % searchURL) try: data = sickrage.srCore.srWebSession.get(searchURL).text except Exception: sickrage.srCore.srLogger.debug("No data returned from provider") continue try: with bs4_parser(data) as html: torrent_table = html.find('table', attrs={'class': 'copyright'}) torrent_rows = torrent_table.find_all('tr') if torrent_table else [] # Continue only if one Release is found if len(torrent_rows) < 3: sickrage.srCore.srLogger.debug( "Data returned from provider does not contain any torrents") last_page = 1 continue if len(torrent_rows) < 42: last_page = 1 for result in torrent_table.find_all('tr')[2:]: try: link = result.find('td').find('a') title = link.string download_url = self.urls['download'] % result.find_all('td')[8].find('a')['href'][ -8:] leechers = result.find_all('td')[3].find_all('td')[1].text leechers = int(leechers.strip('[]')) seeders = result.find_all('td')[3].find_all('td')[2].text seeders = int(seeders.strip('[]')) # FIXME size = -1 except (AttributeError, TypeError): continue filename_qt = self._reverseQuality(self._episodeQuality(result)) for text in self.hdtext: title1 = title title = title.replace(text, filename_qt) if title != title1: break if Quality.nameQuality(title) == Quality.UNKNOWN: title += filename_qt if not self._is_italian(result) and not self.subtitle: sickrage.srCore.srLogger.debug("Torrent is subtitled, skipping: %s " % title) continue if self.engrelease and not self._is_english(result): sickrage.srCore.srLogger.debug( "Torrent isnt english audio/subtitled , skipping: %s " % title) continue search_show = re.split(r'([Ss][\d{1,2}]+)', search_string)[0] show_title = search_show rindex = re.search(r'([Ss][\d{1,2}]+)', title) if rindex: show_title = title[:rindex.start()] ep_params = title[rindex.start():] if show_title.lower() != search_show.lower() \ and search_show.lower() in show_title.lower() and ep_params: title = search_show + ep_params if not all([title, download_url]): continue if self._is_season_pack(title): title = re.sub(r'([Ee][\d{1,2}\-?]+)', '', title) # Filter unseeded torrent if seeders < self.minseed or leechers < self.minleech: if mode != 'RSS': sickrage.srCore.srLogger.debug( "Discarding torrent because it doesn't meet the minimum seeders or leechers: %s (S:%s L:%s)" % ( title, seeders, leechers)) continue item = title, download_url, size, seeders, leechers if mode != 'RSS': sickrage.srCore.srLogger.debug("Found result: %s " % title) items[mode].append(item) except Exception: sickrage.srCore.srLogger.error( "Failed parsing provider. Traceback: %s" % traceback.format_exc()) # For each search mode sort all the items by seeders if available if available items[mode].sort(key=lambda tup: tup[3], reverse=True) results += items[mode] return results
def test_SDTV(self): self.assertEqual(Quality.SDTV, Quality.nameQuality("Test.Show.S01E02.PDTV.XViD-GROUP")) self.assertEqual(Quality.SDTV, Quality.nameQuality("Test.Show.S01E02.PDTV.x264-GROUP")) self.assertEqual(Quality.SDTV, Quality.nameQuality("Test.Show.S01E02.HDTV.XViD-GROUP")) self.assertEqual(Quality.SDTV, Quality.nameQuality("Test.Show.S01E02.HDTV.x264-GROUP")) self.assertEqual(Quality.SDTV, Quality.nameQuality("Test.Show.S01E02.DSR.XViD-GROUP")) self.assertEqual(Quality.SDTV, Quality.nameQuality("Test.Show.S01E02.DSR.x264-GROUP")) self.assertEqual(Quality.SDTV, Quality.nameQuality("Test.Show.S01E02.TVRip.XViD-GROUP")) self.assertEqual(Quality.SDTV, Quality.nameQuality("Test.Show.S01E02.TVRip.x264-GROUP")) self.assertEqual(Quality.SDTV, Quality.nameQuality("Test.Show.S01E02.WEBRip.XViD-GROUP")) self.assertEqual(Quality.SDTV, Quality.nameQuality("Test.Show.S01E02.WEBRip.x264-GROUP")) self.assertEqual(Quality.SDTV, Quality.nameQuality("Test.Show.S01E02.WEB-DL.x264-GROUP")) self.assertEqual(Quality.SDTV, Quality.nameQuality("Test.Show.S01E02.WEB-DL.AAC2.0.H.264-GROUP")) self.assertEqual(Quality.SDTV, Quality.nameQuality("Test.Show.S01E02 WEB-DL H 264-GROUP")) self.assertEqual(Quality.SDTV, Quality.nameQuality("Test.Show.S01E02_WEB-DL_H_264-GROUP")) self.assertEqual(Quality.SDTV, Quality.nameQuality("Test.Show.S01E02.WEB-DL.AAC2.0.H264-GROUP"))
def test_SDDVD(self): self.assertEqual(Quality.SDDVD, Quality.nameQuality("Test.Show.S01E02.DVDRiP.XViD-GROUP")) self.assertEqual(Quality.SDDVD, Quality.nameQuality("Test.Show.S01E02.DVDRiP.DiVX-GROUP")) self.assertEqual(Quality.SDDVD, Quality.nameQuality("Test.Show.S01E02.DVDRiP.x264-GROUP")) self.assertEqual(Quality.SDDVD, Quality.nameQuality("Test.Show.S01E02.DVDRip.WS.XViD-GROUP")) self.assertEqual(Quality.SDDVD, Quality.nameQuality("Test.Show.S01E02.DVDRip.WS.DiVX-GROUP")) self.assertEqual(Quality.SDDVD, Quality.nameQuality("Test.Show.S01E02.DVDRip.WS.x264-GROUP")) self.assertEqual(Quality.SDDVD, Quality.nameQuality("Test.Show.S01E02.BDRIP.XViD-GROUP")) self.assertEqual(Quality.SDDVD, Quality.nameQuality("Test.Show.S01E02.BDRIP.DiVX-GROUP")) self.assertEqual(Quality.SDDVD, Quality.nameQuality("Test.Show.S01E02.BDRIP.x264-GROUP")) self.assertEqual(Quality.SDDVD, Quality.nameQuality("Test.Show.S01E02.BDRIP.WS.XViD-GROUP")) self.assertEqual(Quality.SDDVD, Quality.nameQuality("Test.Show.S01E02.BDRIP.WS.DiVX-GROUP")) self.assertEqual(Quality.SDDVD, Quality.nameQuality("Test.Show.S01E02.BDRIP.WS.x264-GROUP"))
def test_HDTV(self): self.assertEqual(Quality.HDTV, Quality.nameQuality("Test.Show.S01E02.720p.HDTV.x264-GROUP")) self.assertEqual(Quality.HDTV, Quality.nameQuality("Test.Show.S01E02.HR.WS.PDTV.x264-GROUP"))
def test_SDTV(self): self.assertEqual( Quality.SDTV, Quality.nameQuality("Test.Show.S01E02.PDTV.XViD-GROUP")) self.assertEqual( Quality.SDTV, Quality.nameQuality("Test.Show.S01E02.PDTV.x264-GROUP")) self.assertEqual( Quality.SDTV, Quality.nameQuality("Test.Show.S01E02.HDTV.XViD-GROUP")) self.assertEqual( Quality.SDTV, Quality.nameQuality("Test.Show.S01E02.HDTV.x264-GROUP")) self.assertEqual( Quality.SDTV, Quality.nameQuality("Test.Show.S01E02.DSR.XViD-GROUP")) self.assertEqual( Quality.SDTV, Quality.nameQuality("Test.Show.S01E02.DSR.x264-GROUP")) self.assertEqual( Quality.SDTV, Quality.nameQuality("Test.Show.S01E02.TVRip.XViD-GROUP")) self.assertEqual( Quality.SDTV, Quality.nameQuality("Test.Show.S01E02.TVRip.x264-GROUP")) self.assertEqual( Quality.SDTV, Quality.nameQuality("Test.Show.S01E02.WEBRip.XViD-GROUP")) self.assertEqual( Quality.SDTV, Quality.nameQuality("Test.Show.S01E02.WEBRip.x264-GROUP")) self.assertEqual( Quality.SDTV, Quality.nameQuality("Test.Show.S01E02.WEB-DL.x264-GROUP")) self.assertEqual( Quality.SDTV, Quality.nameQuality("Test.Show.S01E02.WEB-DL.AAC2.0.H.264-GROUP")) self.assertEqual( Quality.SDTV, Quality.nameQuality("Test.Show.S01E02 WEB-DL H 264-GROUP")) self.assertEqual( Quality.SDTV, Quality.nameQuality("Test.Show.S01E02_WEB-DL_H_264-GROUP")) self.assertEqual( Quality.SDTV, Quality.nameQuality("Test.Show.S01E02.WEB-DL.AAC2.0.H264-GROUP"))
def test_FULLHDTV(self): self.assertEqual(Quality.FULLHDTV, Quality.nameQuality("Test.Show.S01E02.1080p.HDTV.x264-GROUP"))
def _parse_string(self, name, skip_scene_detection=False): if not name: return matches = [] bestResult = None for (cur_regex_num, cur_regex_name, cur_regex) in self.compiled_regexes: match = cur_regex.match(name) if not match: continue result = ParseResult(name) result.which_regex = {cur_regex_name} result.score = 0 - cur_regex_num named_groups = match.groupdict().keys() if 'series_name' in named_groups: result.series_name = match.group('series_name') if result.series_name: result.series_name = self.clean_series_name( result.series_name) result.score += 1 if 'series_num' in named_groups and match.group('series_num'): result.score += 1 if 'season_num' in named_groups: tmp_season = int(match.group('season_num')) if cur_regex_name == 'bare' and tmp_season in (19, 20): continue if cur_regex_name == 'fov' and tmp_season > 500: continue result.season_number = tmp_season result.score += 1 if 'ep_num' in named_groups: ep_num = self._convert_number(match.group('ep_num')) if 'extra_ep_num' in named_groups and match.group( 'extra_ep_num'): tmp_episodes = range( ep_num, self._convert_number(match.group('extra_ep_num')) + 1) # if len(tmp_episodes) > 6: # continue else: tmp_episodes = [ep_num] result.episode_numbers = tmp_episodes result.score += 3 if 'ep_ab_num' in named_groups: ep_ab_num = self._convert_number(match.group('ep_ab_num')) result.score += 1 if 'extra_ab_ep_num' in named_groups and match.group( 'extra_ab_ep_num'): result.ab_episode_numbers = range( ep_ab_num, self._convert_number(match.group('extra_ab_ep_num')) + 1) result.score += 1 else: result.ab_episode_numbers = [ep_ab_num] if 'air_date' in named_groups: air_date = match.group('air_date') try: result.air_date = parser.parse(air_date, fuzzy=True).date() result.score += 1 except Exception: continue if 'extra_info' in named_groups: tmp_extra_info = match.group('extra_info') # Show.S04.Special or Show.S05.Part.2.Extras is almost certainly not every episode in the season if tmp_extra_info and cur_regex_name == 'season_only' and re.search( r'([. _-]|^)(special|extra)s?\w*([. _-]|$)', tmp_extra_info, re.I): continue result.extra_info = tmp_extra_info result.score += 1 if 'release_group' in named_groups: result.release_group = match.group('release_group') result.score += 1 if 'version' in named_groups: # assigns version to anime file if detected using anime regex. Non-anime regex receives -1 version = match.group('version') if version: result.version = version else: result.version = 1 else: result.version = -1 matches.append(result) if len(matches): # pick best match with highest score based on placement bestResult = max(sorted(matches, reverse=True, key=lambda x: x.which_regex), key=lambda x: x.score) bestResult.show = self.showObj bestResult.indexerid = self.showObj.indexerid if self.showObj else 0 if not self.naming_pattern: # try and create a show object for this result bestResult.show, bestResult.indexerid = self.get_show( bestResult.series_name) # confirm passed in show object indexer id matches result show object indexer id if self.showObj and bestResult.show: if self.showObj.indexerid == bestResult.show.indexerid: bestResult.show = self.showObj else: bestResult.show = None bestResult.indexerid = 0 elif self.showObj and not bestResult.show and not self.validate_show: bestResult.show = self.showObj # if this is a naming pattern test or result doesn't have a show object then return best result if not bestResult.show or self.naming_pattern: return bestResult # get quality bestResult.quality = Quality.nameQuality(name, bestResult.show.is_anime) new_episode_numbers = [] new_season_numbers = [] new_absolute_numbers = [] # if we have an air-by-date show then get the real season/episode numbers if bestResult.is_air_by_date: airdate = bestResult.air_date.toordinal() dbData = [ x for x in sickrage.app.main_db.get_many( 'tv_episodes', bestResult.show.indexerid) if x['indexer'] == bestResult.show.indexer and x['airdate'] == airdate ] season_number = None episode_numbers = [] if dbData: season_number = int(dbData[0]['season']) episode_numbers = [int(dbData[0]['episode'])] if not season_number or not episode_numbers: try: lINDEXER_API_PARMS = IndexerApi( bestResult.show.indexer).api_params.copy() lINDEXER_API_PARMS[ 'language'] = bestResult.show.lang or sickrage.app.config.indexer_default_language t = IndexerApi(bestResult.show.indexer).indexer( **lINDEXER_API_PARMS) epObj = t[bestResult.show.indexerid].airedOn( bestResult.air_date)[0] season_number = int(epObj["airedseason"]) episode_numbers = [int(epObj["airedepisodenumber"])] except indexer_episodenotfound: if bestResult.in_showlist: sickrage.app.log.warning( "Unable to find episode with date {air_date} for show {show}, " "skipping".format(air_date=bestResult.air_date, show=bestResult.show.name)) episode_numbers = [] except indexer_error as e: sickrage.app.log.warning( "Unable to contact " + IndexerApi(bestResult.show.indexer).name + ": {}".format(e)) episode_numbers = [] for epNo in episode_numbers: s = season_number e = epNo if bestResult.show.is_scene and not skip_scene_detection: (s, e) = get_indexer_numbering(bestResult.show.indexerid, bestResult.show.indexer, season_number, epNo) new_episode_numbers.append(e) new_season_numbers.append(s) elif bestResult.show.is_anime and bestResult.ab_episode_numbers: for epAbsNo in bestResult.ab_episode_numbers: a = epAbsNo if bestResult.show.is_scene: scene_season = get_scene_exception_by_name( bestResult.series_name)[1] a = get_indexer_absolute_numbering( bestResult.show.indexerid, bestResult.show.indexer, epAbsNo, True, scene_season) (s, e ) = bestResult.show.get_all_episodes_from_absolute_number( [a]) new_absolute_numbers.append(a) new_episode_numbers.extend(e) new_season_numbers.append(s) elif bestResult.season_number and bestResult.episode_numbers: for epNo in bestResult.episode_numbers: s = bestResult.season_number e = epNo if bestResult.show.is_scene and not skip_scene_detection: (s, e) = get_indexer_numbering( bestResult.show.indexerid, bestResult.show.indexer, bestResult.season_number, epNo) if bestResult.show.is_anime: a = get_absolute_number_from_season_and_episode( bestResult.show, s, e) if a: new_absolute_numbers.append(a) new_episode_numbers.append(e) new_season_numbers.append(s) # need to do a quick sanity check heregex. It's possible that we now have episodes # from more than one season (by tvdb numbering), and this is just too much # for sickrage, so we'd need to flag it. new_season_numbers = list( set(new_season_numbers)) # remove duplicates if len(new_season_numbers) > 1: raise InvalidNameException( "Scene numbering results episodes from " "seasons %s, (i.e. more than one) and " "sickrage does not support this. " "Sorry." % new_season_numbers) # I guess it's possible that we'd have duplicate episodes too, so lets # eliminate them new_episode_numbers = list(set(new_episode_numbers)) new_episode_numbers.sort() # maybe even duplicate absolute numbers so why not do them as well new_absolute_numbers = list(set(new_absolute_numbers)) new_absolute_numbers.sort() if len(new_absolute_numbers): bestResult.ab_episode_numbers = new_absolute_numbers if len(new_season_numbers) and len(new_episode_numbers): bestResult.episode_numbers = new_episode_numbers bestResult.season_number = new_season_numbers[0] if bestResult.show.is_scene and not skip_scene_detection: sickrage.app.log.debug( "Scene converted parsed result {} into {}".format( bestResult.original_name, bestResult)) # CPU sleep time.sleep(0.02) return bestResult
def test_FULLHDBLURAY(self): from sickrage.core.common import Quality self.assertEqual(Quality.FULLHDBLURAY, Quality.nameQuality("Test.Show.S01E02.1080p.BluRay.x264-GROUP")) self.assertEqual(Quality.FULLHDBLURAY, Quality.nameQuality("Test.Show.S01E02.1080p.HDDVD.x264-GROUP"))