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_HDBLURAY(self): self.assertEqual( Quality.HDBLURAY, Quality.nameQuality("Test.Show.S01E02.720p.BluRay.x264-GROUP")) self.assertEqual( Quality.HDBLURAY, Quality.nameQuality("Test.Show.S01E02.720p.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_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_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_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_UNKNOWN(self): self.assertEqual(Quality.UNKNOWN, Quality.nameQuality("Test.Show.S01E02-SiCKBEARD"))
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_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 _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.srLogger.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.srLogger.debug("Search string: %s " % search_string) sickrage.srLogger.debug("Search URL: %s" % searchURL) data = self.getURL(searchURL) if not data: sickrage.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.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.srLogger.debug("Torrent is subtitled, skipping: %s " % title) continue if self.engrelease and not self._is_english(result): sickrage.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 is not 'RSS': sickrage.srLogger.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.srLogger.debug("Found result: %s " % title) items[mode].append(item) except Exception: sickrage.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_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 _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.srLogger.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.srLogger.debug("Search string: %s " % search_string) sickrage.srLogger.debug("Search URL: %s" % searchURL) data = self.getURL(searchURL) if not data: sickrage.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.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.srLogger.debug( "Torrent is subtitled, skipping: %s " % title) continue if self.engrelease and not self._is_english( result): sickrage.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 is not 'RSS': sickrage.srLogger.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.srLogger.debug( "Found result: %s " % title) items[mode].append(item) except Exception: sickrage.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_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_FULLHDTV(self): self.assertEqual(Quality.FULLHDTV, Quality.nameQuality("Test.Show.S01E02.1080p.HDTV.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 _getProperList(self): """ Walk providers for propers """ propers = {} search_date = datetime.today() - timedelta(days=2) origThreadName = threading.currentThread().getName() # for each provider get a list of the for providerID, providerObj in {k: v for k, v in sortedProviderDict( sickrage.srConfig.RANDOMIZE_PROVIDERS).items() if v.isActive}.items(): threading.currentThread().setName(origThreadName + " :: [" + providerObj.name + "]") sickrage.srLogger.info("Searching for any new PROPER releases from " + providerObj.name) try: curPropers = providerObj.findPropers(search_date) except AuthException as e: sickrage.srLogger.debug("Authentication error: {}".format(e.message)) continue except Exception as e: sickrage.srLogger.debug("Error while searching " + providerObj.name + ", skipping: {}".format(e.message)) sickrage.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.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.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.srLogger.debug("Unable to parse the filename " + curProper.name + " into a valid episode") continue except InvalidShowException: sickrage.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.srLogger.debug( "Ignoring " + curProper.name + " because it's for a full season rather than specific episode") continue sickrage.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.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.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][b"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][b"version"]) oldRelease_group = (sqlResults[0][b"release_group"]) if oldVersion > -1 and oldVersion < bestResult.version: sickrage.srLogger.info( "Found new anime v" + str(bestResult.version) + " to replace existing v" + str(oldVersion)) else: continue if oldRelease_group != bestResult.release_group: sickrage.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.srLogger.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')) 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] result.score += 1 if 'ep_ab_num' in named_groups: ep_ab_num = self._convert_number(match.group('ep_ab_num')) 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] result.score += 1 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 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 = sickrage.srCore.INDEXER_API(bestResult.show.indexer).api_params.copy() if bestResult.show.lang: lINDEXER_API_PARMS[b'language'] = bestResult.show.lang t = sickrage.srCore.INDEXER_API(bestResult.show.indexer).indexer(**lINDEXER_API_PARMS) epObj = t[bestResult.show.indexerid].airedOn(bestResult.air_date)[0] season_number = int(epObj[b"seasonnumber"]) episode_numbers = [int(epObj[b"episodenumber"])] except indexer_episodenotfound: sickrage.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.srLogger.warning( "Unable to contact " + sickrage.srCore.INDEXER_API(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.srLogger.debug("Converted parsed result {} into {}".format(bestResult.original_name, bestResult)) # CPU sleep time.sleep(1) return bestResult
def _getProperList(self): """ Walk providers for propers """ propers = {} search_date = datetime.today() - timedelta(days=2) origThreadName = threading.currentThread().getName() # for each provider get a list of the for providerID, providerObj in { k: v for k, v in sortedProviderDict( sickrage.srConfig.RANDOMIZE_PROVIDERS).items() if v.isActive }.items(): threading.currentThread().setName(origThreadName + " :: [" + providerObj.name + "]") sickrage.srLogger.info( "Searching for any new PROPER releases from " + providerObj.name) try: curPropers = providerObj.findPropers(search_date) except AuthException as e: sickrage.srLogger.debug("Authentication error: {}".format( e.message)) continue except Exception as e: sickrage.srLogger.debug("Error while searching " + providerObj.name + ", skipping: {}".format(e.message)) sickrage.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.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.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.srLogger.debug("Unable to parse the filename " + curProper.name + " into a valid episode") continue except InvalidShowException: sickrage.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.srLogger.debug( "Ignoring " + curProper.name + " because it's for a full season rather than specific episode" ) continue sickrage.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.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.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][b"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][b"version"]) oldRelease_group = (sqlResults[0][b"release_group"]) if oldVersion > -1 and oldVersion < bestResult.version: sickrage.srLogger.info("Found new anime v" + str(bestResult.version) + " to replace existing v" + str(oldVersion)) else: continue if oldRelease_group != bestResult.release_group: sickrage.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.srLogger.info("Found a proper that we need: " + str(bestResult.name)) finalPropers.append(bestResult) return finalPropers