diff --git a/gui/slick/interfaces/default/config_postProcessing.tmpl b/gui/slick/interfaces/default/config_postProcessing.tmpl index bda37130..fe45f6f4 100644 --- a/gui/slick/interfaces/default/config_postProcessing.tmpl +++ b/gui/slick/interfaces/default/config_postProcessing.tmpl @@ -627,6 +627,183 @@ +
+ + +
+ +
+
+ +
+ +
+
+ +
+ + +
+ +
+

Sample:

+
+   +
+
+
+ +
+

diff --git a/gui/slick/interfaces/default/displayShow.tmpl b/gui/slick/interfaces/default/displayShow.tmpl index cbe8f24e..75b63e53 100644 --- a/gui/slick/interfaces/default/displayShow.tmpl +++ b/gui/slick/interfaces/default/displayShow.tmpl @@ -154,6 +154,7 @@ Flat Folders: \"Y" Paused: \"Y" Air-by-Date: \"Y" + Sports: \"Y" DVD Order: \"Y" #if $bestQualities Archive First Match: \"Y" @@ -239,7 +240,7 @@ \"Y" $epResult["episode"] - #if int($show.air_by_date) != 1 + #if int($show.air_by_date) != 1 and int($show.sports) != 1 #if (epResult["season"], epResult["episode"]) in $xem_numbering: #set ($dfltSeas, $dfltEpis) = $xem_numbering[(epResult["season"], epResult["episode"])] #else diff --git a/gui/slick/interfaces/default/editShow.tmpl b/gui/slick/interfaces/default/editShow.tmpl index 4dbae7e6..17bec06a 100644 --- a/gui/slick/interfaces/default/editShow.tmpl +++ b/gui/slick/interfaces/default/editShow.tmpl @@ -108,6 +108,10 @@ This DOES NOT allow Sick Beard to download non-english TV episodes!

(check this if the show is released as Show.03.02.2010 rather than Show.S02E03)

+Sports: +
+(check this if the show is a sporting or MMA event) +

DVD Order:
(check this if you wish to use the DVD order instead of the Airing order) diff --git a/gui/slick/interfaces/default/testRename.tmpl b/gui/slick/interfaces/default/testRename.tmpl index 17213484..13f9a04e 100644 --- a/gui/slick/interfaces/default/testRename.tmpl +++ b/gui/slick/interfaces/default/testRename.tmpl @@ -23,6 +23,8 @@
#if int($show.air_by_date) == 1 and $sickbeard.NAMING_CUSTOM_ABD: $sickbeard.NAMING_ABD_PATTERN +#elif int($show.sports) == 1 and $sickbeard.NAMING_CUSTOM_SPORTS: + $sickbeard.NAMING_SPORTS_PATTERN #else $sickbeard.NAMING_PATTERN #end if diff --git a/gui/slick/js/configPostProcessing.js b/gui/slick/js/configPostProcessing.js index ffc3a63f..e40b57f4 100644 --- a/gui/slick/js/configPostProcessing.js +++ b/gui/slick/js/configPostProcessing.js @@ -119,6 +119,47 @@ $(document).ready(function () { } + function fill_sports_examples() { + var pattern = $('#naming_sports_pattern').val(); + + $.get(sbRoot + '/config/postProcessing/testNaming', {pattern: pattern, sports: 'True'}, + function (data) { + if (data) { + $('#naming_sports_example').text(data + '.ext'); + $('#naming_sports_example_div').show(); + } else { + $('#naming_sports_example_div').hide(); + } + }); + + $.get(sbRoot + '/config/postProcessing/isNamingValid', {pattern: pattern, sports: 'True'}, + function (data) { + if (data == "invalid") { + $('#naming_sports_pattern').qtip('option', { + 'content.text': 'This pattern is invalid.', + 'style.classes': 'qtip-rounded qtip-shadow qtip-red' + }); + $('#naming_sports_pattern').qtip('toggle', true); + $('#naming_sports_pattern').css('background-color', '#FFDDDD'); + } else if (data == "seasonfolders") { + $('#naming_sports_pattern').qtip('option', { + 'content.text': 'This pattern would be invalid without the folders, using it will force "Flatten" off for all shows.', + 'style.classes': 'qtip-rounded qtip-shadow qtip-red' + }); + $('#naming_sports_pattern').qtip('toggle', true); + $('#naming_sports_pattern').css('background-color', '#FFFFDD'); + } else { + $('#naming_sports_pattern').qtip('option', { + 'content.text': 'This pattern is valid.', + 'style.classes': 'qtip-rounded qtip-shadow qtip-green' + }); + $('#naming_sports_pattern').qtip('toggle', false); + $('#naming_sports_pattern').css('background-color', '#FFFFFF'); + } + }); + + } + function setup_naming() { // if it is a custom selection then show the text box if ($('#name_presets :selected').val() == "Custom...") { @@ -141,12 +182,23 @@ $(document).ready(function () { fill_abd_examples(); } + function setup_sports_naming() { + // if it is a custom selection then show the text box + if ($('#name_sports_presets :selected').val() == "Custom...") { + $('#naming_sports_custom').show(); + } else { + $('#naming_sports_custom').hide(); + $('#naming_sports_pattern').val($('#name_sports_presets :selected').attr('id')); + } + fill_sports_examples(); + } + $('#unpack').change(function () { if(this.checked) { israr_supported(); } else { $('#unpack').qtip('toggle', false); - } + } }); $('#name_presets').change(function () { @@ -161,6 +213,14 @@ $(document).ready(function () { setup_abd_naming(); }); + $('#name_sports_presets').change(function () { + setup_sports_naming(); + }); + + $('#naming_custom_sports').change(function () { + setup_sports_naming(); + }); + $('#naming_multi_ep').change(fill_examples); $('#naming_pattern').focusout(fill_examples); $('#naming_pattern').keyup(function () { @@ -176,12 +236,22 @@ $(document).ready(function () { }, 500); }); + $('#naming_sports_pattern').focusout(fill_examples); + $('#naming_sports_pattern').keyup(function () { + typewatch(function () { + fill_sports_examples(); + }, 500); + }); + $('#show_naming_key').click(function () { $('#naming_key').toggle(); }); $('#show_naming_abd_key').click(function () { $('#naming_abd_key').toggle(); }); + $('#show_naming_sports_key').click(function () { + $('#naming_sports_key').toggle(); + }); $('#do_custom').click(function () { $('#naming_pattern').val($('#name_presets :selected').attr('id')); $('#naming_custom').show(); @@ -189,6 +259,7 @@ $(document).ready(function () { }); setup_naming(); setup_abd_naming(); + setup_sports_naming(); // -- start of metadata options div toggle code -- $('#metadataType').on('change keyup', function () { @@ -295,7 +366,7 @@ $(document).ready(function () { position: { viewport: $(window), at: 'top center', - my: 'bottom center', + my: 'bottom center' }, style: { tip: { @@ -315,7 +386,7 @@ $(document).ready(function () { position: { viewport: $(window), at: 'center left', - my: 'center right', + my: 'center right' }, style: { tip: { diff --git a/sickbeard/__init__.py b/sickbeard/__init__.py index f9fd1629..cdda1e70 100644 --- a/sickbeard/__init__.py +++ b/sickbeard/__init__.py @@ -151,6 +151,8 @@ NAMING_MULTI_EP = None NAMING_PATTERN = None NAMING_ABD_PATTERN = None NAMING_CUSTOM_ABD = None +NAMING_SPORTS_PATTERN = None +NAMING_CUSTOM_SPORTS = None NAMING_FORCE_FOLDERS = False NAMING_STRIP_YEAR = None @@ -480,7 +482,7 @@ def initialize(consoleLogging=True): versionCheckScheduler, VERSION_NOTIFY, AUTO_UPDATE, PROCESS_AUTOMATICALLY, UNPACK, \ KEEP_PROCESSED_DIR, PROCESS_METHOD, TV_DOWNLOAD_DIR, MIN_SEARCH_FREQUENCY, DEFAULT_UPDATE_FREQUENCY,MIN_UPDATE_FREQUENCY,UPDATE_FREQUENCY,\ showQueueScheduler, searchQueueScheduler, ROOT_DIRS, CACHE_DIR, ACTUAL_CACHE_DIR, \ - NAMING_PATTERN, NAMING_MULTI_EP, NAMING_FORCE_FOLDERS, NAMING_ABD_PATTERN, NAMING_CUSTOM_ABD, NAMING_STRIP_YEAR, \ + NAMING_PATTERN, NAMING_MULTI_EP, NAMING_FORCE_FOLDERS, NAMING_ABD_PATTERN, NAMING_CUSTOM_ABD, NAMING_SPORTS_PATTERN, NAMING_CUSTOM_SPORTS, NAMING_STRIP_YEAR, \ RENAME_EPISODES, properFinderScheduler, PROVIDER_ORDER, autoPostProcesserScheduler, \ WOMBLE, OMGWTFNZBS, OMGWTFNZBS_USERNAME, OMGWTFNZBS_APIKEY, providerList, newznabProviderList, torrentRssProviderList, \ EXTRA_SCRIPTS, USE_TWITTER, TWITTER_USERNAME, TWITTER_PASSWORD, TWITTER_PREFIX, \ @@ -602,6 +604,8 @@ def initialize(consoleLogging=True): NAMING_PATTERN = check_setting_str(CFG, 'General', 'naming_pattern', 'Season %0S/%SN - S%0SE%0E - %EN') NAMING_ABD_PATTERN = check_setting_str(CFG, 'General', 'naming_abd_pattern', '%Y/%0M/%SN - %A.D - %EN') NAMING_CUSTOM_ABD = check_setting_int(CFG, 'General', 'naming_custom_abd', 0) + NAMING_SPORTS_PATTERN = check_setting_str(CFG, 'General', 'naming_sports_pattern', '%Y/%0M/%SN - %A.D - %EN') + NAMING_CUSTOM_SPORTS = check_setting_int(CFG, 'General', 'naming_custom_sports', 0) NAMING_MULTI_EP = check_setting_int(CFG, 'General', 'naming_multi_ep', 1) NAMING_FORCE_FOLDERS = naming.check_force_season_folders() NAMING_STRIP_YEAR = bool(check_setting_int(CFG, 'General', 'naming_strip_year', 0)) @@ -1315,6 +1319,8 @@ def save_config(): new_config['General']['naming_pattern'] = NAMING_PATTERN new_config['General']['naming_custom_abd'] = int(NAMING_CUSTOM_ABD) new_config['General']['naming_abd_pattern'] = NAMING_ABD_PATTERN + new_config['General']['naming_custom_sports'] = int(NAMING_CUSTOM_SPORTS) + new_config['General']['naming_sports_pattern'] = NAMING_SPORTS_PATTERN new_config['General']['naming_multi_ep'] = int(NAMING_MULTI_EP) new_config['General']['launch_browser'] = int(LAUNCH_BROWSER) new_config['General']['update_shows_on_start'] = int(UPDATE_SHOWS_ON_START) diff --git a/sickbeard/databases/mainDB.py b/sickbeard/databases/mainDB.py index 23f4ad2e..a2e4cde6 100644 --- a/sickbeard/databases/mainDB.py +++ b/sickbeard/databases/mainDB.py @@ -27,8 +27,7 @@ from sickbeard import encodingKludge as ek from sickbeard.name_parser.parser import NameParser, InvalidNameException MIN_DB_VERSION = 9 # oldest db version we support migrating from -MAX_DB_VERSION = 29 - +MAX_DB_VERSION = 30 class MainSanityCheck(db.DBSanityCheck): def check(self): @@ -657,7 +656,6 @@ class ConvertInfoToIndexerScheme(ConvertIMDBInfoToIndexerScheme): self.incDBVersion() - class AddArchiveFirstMatchOption(ConvertInfoToIndexerScheme): def test(self): return self.checkDBVersion() >= 26 @@ -671,7 +669,6 @@ class AddArchiveFirstMatchOption(ConvertInfoToIndexerScheme): self.incDBVersion() - class AddSceneNumbering(AddArchiveFirstMatchOption): def test(self): return self.checkDBVersion() >= 27 @@ -726,3 +723,26 @@ class AddRequireAndIgnoreWords(ConvertIndexerToInteger): self.addColumn("tv_shows", "rls_ignore_words", "TEXT", "") self.incDBVersion() + +class AddSportsOption(AddRequireAndIgnoreWords): + def test(self): + return self.checkDBVersion() >= 30 + + def execute(self): + backupDatabase(30) + + logger.log(u"Adding column sports to tvshows") + if not self.hasColumn("tv_shows", "sports"): + self.addColumn("tv_shows", "sports", "NUMERIC", "0") + + if self.hasColumn("tv_shows", "air_by_date") and self.hasColumn("tv_shows", "sports"): + # update sports column + logger.log(u"[4/4] Updating tv_shows to reflect the correct sports value...", logger.MESSAGE) + ql = [] + historyQuality = self.connection.select("SELECT * FROM tv_shows WHERE LOWER(classification) = 'sports' AND air_by_date = 1 AND sports = 0") + for cur_entry in historyQuality: + ql.append(["UPDATE tv_shows SET sports = ? WHERE show_id = ?", [cur_entry["air_by_date"], cur_entry["show_id"]]]) + ql.append(["UPDATE tv_shows SET air_by_date = 0 WHERE show_id = ?", [cur_entry["show_id"]]]) + self.connection.mass_action(ql) + + self.incDBVersion() \ No newline at end of file diff --git a/sickbeard/helpers.py b/sickbeard/helpers.py index 6f3a2a7c..19b40e91 100644 --- a/sickbeard/helpers.py +++ b/sickbeard/helpers.py @@ -974,14 +974,6 @@ def get_show_by_name(name, showList, useIndexer=False): return None -def suffix(d): - return 'th' if 11 <= d <= 13 else {1: 'st', 2: 'nd', 3: 'rd'}.get(d % 10, 'th') - - -def custom_strftime(format, t): - return t.strftime(format).replace('{S}', str(t.day) + suffix(t.day)) - - def is_hidden_folder(folder): """ Returns True if folder is hidden. diff --git a/sickbeard/logger.py b/sickbeard/logger.py index 32156b72..9e360307 100644 --- a/sickbeard/logger.py +++ b/sickbeard/logger.py @@ -98,7 +98,7 @@ class SBRotatingLogHandler(object): # define a Handler which writes INFO messages or higher to the sys.stderr console = logging.StreamHandler() - console.setLevel(logging.INFO) + console.setLevel(logging.DEBUG) # set a format which is simpler for console use console.setFormatter(DispatchingFormatter( diff --git a/sickbeard/name_parser/parser.py b/sickbeard/name_parser/parser.py index aefd2b26..5d87539d 100644 --- a/sickbeard/name_parser/parser.py +++ b/sickbeard/name_parser/parser.py @@ -33,11 +33,16 @@ from time import strptime class NameParser(object): - def __init__(self, file_name=True): + ALL_REGEX = -1 + NORMAL_REGEX = 0 + SPORTS_REGEX = 1 + + def __init__(self, file_name=True, regexMode=0): self.file_name = file_name + self.regexMode = regexMode self.compiled_regexes = [] - self._compile_regexes() + self._compile_regexes(regexMode) def clean_series_name(self, series_name): """Cleans up series name by removing any . and _ @@ -63,8 +68,24 @@ class NameParser(object): series_name = re.sub("^\[.*\]", "", series_name) return series_name.strip() - def _compile_regexes(self): - for (cur_pattern_name, cur_pattern) in regexes.ep_regexes: + def _compile_regexes(self, regexMode): + if regexMode <= self.ALL_REGEX: + logger.log(u"Using ALL regexs" , logger.DEBUG) + uncompiled_regex = regexes.sports_regexs+regexes.ep_regexes + + elif regexMode == self.NORMAL_REGEX: + logger.log(u"Using NORMAL regexs" , logger.DEBUG) + uncompiled_regex = regexes.ep_regexes + + elif regexMode == self.SPORTS_REGEX: + logger.log(u"Using SPORTS regexs" , logger.DEBUG) + uncompiled_regex = regexes.sports_regexs + + else: + logger.log(u"This is a programing ERROR. Fallback Using NORMAL regexs" , logger.ERROR) + uncompiled_regex = regexes.ep_regexes + + for (cur_pattern_name, cur_pattern) in uncompiled_regex: try: cur_regex = re.compile(cur_pattern, re.VERBOSE | re.IGNORECASE) except re.error, errormsg: @@ -107,18 +128,22 @@ class NameParser(object): result.episode_numbers = [ep_num] if 'air_year' in named_groups and 'air_month' in named_groups and 'air_day' in named_groups: - if 'scene_sports_date_format' in cur_regex_name: - year = match.group('air_year') - month = strptime(match.group('air_month')[:3], '%b').tm_mon - day = re.sub("(st|nd|rd|th)", "", match.group('air_day')) + if 'sports' in cur_regex_name: + year = int(match.group('air_year')) + month = match.group('air_month') + day = int(re.sub("(st|nd|rd|th)", "", match.group('air_day'))) else: year = int(match.group('air_year')) month = int(match.group('air_month')) day = int(match.group('air_day')) try: - dtStr = '%s-%s-%s' % (year, month, day) - result.air_date = datetime.datetime.strptime(dtStr, "%Y-%m-%d").date() + if 'sports' in cur_regex_name: + dtStr = '%s-%s-%s' % (day, month, year) + result.air_date = result.sports_date = datetime.datetime.strptime(dtStr, "%d-%b-%Y").date() + else: + dtStr = '%s-%s-%s' % (year, month, day) + result.air_date = datetime.datetime.strptime(dtStr, "%Y-%m-%d").date() except ValueError, e: raise InvalidNameException(e.message) @@ -220,6 +245,7 @@ class NameParser(object): # build the ParseResult object final_result.air_date = self._combine_results(file_name_result, dir_name_result, 'air_date') + final_result.sports_date = self._combine_results(file_name_result, dir_name_result, 'sports_date') if not final_result.air_date: final_result.season_number = self._combine_results(file_name_result, dir_name_result, 'season_number') @@ -255,71 +281,19 @@ class NameParser(object): return final_result @classmethod - def series_name_to_indexer_id(cls, series_name, check_scene_exceptions=True, check_database=True, - check_indexer=False): - """ - Given a series name, return it's tvdbd_id. - Returns None if not found. - - This is mostly robbed from postProcessor._analyze_name - """ - + def series_name_to_indexer_id(cls, series_name): # do a scene reverse-lookup to get a list of all possible names name_list = sickbeard.show_name_helpers.sceneToNormalShowNames(series_name) # for each possible interpretation of that scene name - if check_scene_exceptions: - for cur_name in name_list: - logger.log(u"Checking scene exceptions for a match on " + cur_name, logger.DEBUG) - scene_id = sickbeard.scene_exceptions.get_scene_exception_by_name(cur_name) - if scene_id: return scene_id - - # see if we can find the name directly in the DB, if so use it - if check_database: - for cur_name in name_list: - logger.log(u"Looking up " + str(cur_name) + " in the DB", logger.DEBUG) - db_result = sickbeard.helpers.searchDBForShow(cur_name) - if db_result: return db_result[1] - - # see if we can find the name with a TVDB lookup - if check_indexer: - for cur_name in name_list: - for indexer in sickbeard.indexerApi().indexers: - try: - lINDEXER_API_PARMS = sickbeard.indexerApi(indexer).api_params.copy() - - lINDEXER_API_PARMS['custom_ui'] = classes.ShowListUI - - t = sickbeard.indexerApi(indexer).indexer(**lINDEXER_API_PARMS) - - logger.log(u"Looking up name " + str(cur_name) + " on " + sickbeard.indexerApi(indexer).name, - logger.DEBUG) - showObj = t[cur_name] - except (sickbeard.indexer_exception): - # if none found, search on all languages - try: - lINDEXER_API_PARMS = sickbeard.indexerApi(indexer).api_params.copy() - - lINDEXER_API_PARMS['custom_ui'] = classes.ShowListUI - lINDEXER_API_PARMS['search_all_languages'] = True - - t = sickbeard.indexerApi(indexer).indexer(**lINDEXER_API_PARMS) - - logger.log( - u"Looking up name " + str(cur_name) + " in all languages on " + sickbeard.indexerApi( - indexer).name, logger.DEBUG) - showObj = t[cur_name] - except (sickbeard.indexer_exception, IOError): - pass - - continue - except (IOError): - continue - - return showObj["id"] - - return None - + for cur_name in name_list: + logger.log(u"Checking scene exceptions and database for a match on " + cur_name, logger.DEBUG) + scene_id = sickbeard.scene_exceptions.get_scene_exception_by_name(cur_name) + db_result = sickbeard.helpers.searchDBForShow(cur_name) + if scene_id: + return scene_id + elif db_result: + return db_result[1] class ParseResult(object): def __init__(self, @@ -329,7 +303,8 @@ class ParseResult(object): episode_numbers=None, extra_info=None, release_group=None, - air_date=None + air_date=None, + sports_date=None ): self.original_name = original_name @@ -345,6 +320,7 @@ class ParseResult(object): self.release_group = release_group self.air_date = air_date + self.sports_date = sports_date self.which_regex = None @@ -364,6 +340,8 @@ class ParseResult(object): return False if self.air_date != other.air_date: return False + if self.sports_date != other.sports_date: + return False return True @@ -380,6 +358,8 @@ class ParseResult(object): if self.air_by_date: to_return += str(self.air_date) + if self.sports: + to_return += str(self.sports_date) if self.extra_info: to_return += ' - ' + self.extra_info @@ -387,26 +367,33 @@ class ParseResult(object): to_return += ' (' + self.release_group + ')' to_return += ' [ABD: ' + str(self.air_by_date) + ']' + to_return += ' [SPORTS: ' + str(self.sports) + ']' + to_return += ' [whichReg: ' + str(self.which_regex) + ']' return to_return.encode('utf-8') def _is_air_by_date(self): - if self.season_number == None and len(self.episode_numbers) == 0 and self.air_date: + if self.season_number == None and len(self.episode_numbers) == 0 and self.air_date and not self.sports_date: return True return False - air_by_date = property(_is_air_by_date) + def _is_sports(self): + if self.season_number == None and len(self.episode_numbers) == 0 and self.sports_date: + return True + return False + sports = property(_is_sports) + def fix_scene_numbering(self): """ The changes the parsed result (which is assumed to be scene numbering) to tvdb numbering, if necessary. """ - if self.air_by_date: return self # scene numbering does not apply to air-by-date + if self.air_by_date or self.sports: return self # scene numbering does not apply to air-by-date if self.season_number == None: return self # can't work without a season if len(self.episode_numbers) == 0: return self # need at least one episode - indexer_id = NameParser.series_name_to_indexer_id(self.series_name, True, True, False) + indexer_id = NameParser.series_name_to_indexer_id(self.series_name) new_episode_numbers = [] new_season_numbers = [] diff --git a/sickbeard/name_parser/regexes.py b/sickbeard/name_parser/regexes.py index 822a7dbf..80835f02 100644 --- a/sickbeard/name_parser/regexes.py +++ b/sickbeard/name_parser/regexes.py @@ -96,19 +96,6 @@ ep_regexes = [ -(?P[^- ]+))?)?$ # Group '''), - ('scene_sports_date_format', - # Show.Name.2010.Nov.23rd.Source.Quality.Etc-Group - # Show Name - 2010-Nov-23rd - Ep Name - ''' - ^(?P.*?(UEFA|MLB|ESPN|WWE|MMA|UFC|TNA|EPL|NASCAR|NBA|NFL|NHL|NRL|PGA|SUPER LEAGUE|FORMULA|FIFA|NETBALL|MOTOGP).*?)[. _-]+ - (?P\d{1,3}\d{1,3}.*?)[. _-]+ # Parts - (?P\d{1,2}[a-zA-Z]{2})[. _-]+ # 23rd and seperator - (?P[a-zA-Z]{3,})[. _-]+ # Nov and seperator - (?P\d{4})[. _-]+ # 2010 - (?P.*?(?.*?)$ # Group - '''), - ('stupid', # tpz-abc102 ''' @@ -198,3 +185,30 @@ ep_regexes = [ ''' ), ] + +sports_regexs = [ + ('sports_event', + # Show.Name.123.Event.Nov.23rd.2010.Source.Quality.Etc-Group + ''' + ^(?P.*?(UEFA|MLB|ESPN|WWE|MMA|UFC|TNA|EPL|NASCAR|NBA|NFL|NHL|NRL|PGA|SUPER LEAGUE|FORMULA|FIFA|NETBALL|MOTOGP).*?)[. _-]+ + (?P\d{1,3}\d{1,3}.*?)[. _-]+ + (?P.*?)[. _-]+ + (?P\d{1,2}[a-zA-Z]{2})[. _-]+ + (?P[a-zA-Z]{3,})[. _-]+ + (?P\d{4})[. _-]+ + (?P.*?(?.*?)$ + '''), + + ('sports_event_without_parts', + # Show.Name.Event.Nov.23rd.2010.Source.Quality.Etc-Group + ''' + ^(?P.*?(UEFA|MLB|ESPN|WWE|MMA|UFC|TNA|EPL|NASCAR|NBA|NFL|NHL|NRL|PGA|SUPER LEAGUE|FORMULA|FIFA|NETBALL|MOTOGP).*?)[. _-]+ + (?P.*?)[. _-]+ + (?P\d{1,2}[a-zA-Z]{2})[. _-]+ + (?P[a-zA-Z]{3,})[. _-]+ + (?P\d{4})[. _-]+ + (?P.*?(?.*?)$ + '''), +] \ No newline at end of file diff --git a/sickbeard/naming.py b/sickbeard/naming.py index 1f08b49a..b44a6263 100644 --- a/sickbeard/naming.py +++ b/sickbeard/naming.py @@ -40,13 +40,17 @@ name_abd_presets = ('%SN - %A-D - %EN', '%Y/%0M/%S.N.%A.D.%E.N-%RG' ) +name_sports_presets = ('%SN - %A-D - %EN', + '%S.N.%A.D.%E.N.%Q.N', + '%Y/%0M/%S.N.%A.D.%E.N-%RG' +) class TVShow(): def __init__(self): self.name = "Show Name" self.genre = "Comedy" self.air_by_date = 0 - + self.sports = 0 class TVEpisode(tv.TVEpisode): def __init__(self, season, episode, name): @@ -114,11 +118,28 @@ def check_valid_abd_naming(pattern=None): return valid +def check_valid_sports_naming(pattern=None): + """ + Checks if the name is can be parsed back to its original form for an sports format. -def validate_name(pattern, multi=None, file_only=False, abd=False): - ep = _generate_sample_ep(multi, abd) + Returns true if the naming is valid, false if not. + """ + if pattern == None: + pattern = sickbeard.NAMING_PATTERN - parser = NameParser(True) + logger.log(u"Checking whether the pattern " + pattern + " is valid for an sports episode", logger.DEBUG) + valid = validate_name(pattern, sports=True) + + return valid + +def validate_name(pattern, multi=None, file_only=False, abd=False, sports=False): + ep = _generate_sample_ep(multi, abd, sports) + + regexMode = 0 + if sports: + regexMode = 1 + + parser = NameParser(True, regexMode) new_name = ep.formatted_filename(pattern, multi) + '.ext' new_path = ep.formatted_dir(pattern, multi) @@ -143,6 +164,10 @@ def validate_name(pattern, multi=None, file_only=False, abd=False): if result.air_date != ep.airdate: logger.log(u"Air date incorrect in parsed episode, pattern isn't valid", logger.DEBUG) return False + elif sports: + if result.sports_date != ep.airdate: + logger.log(u"Sports air date incorrect in parsed episode, pattern isn't valid", logger.DEBUG) + return False else: if result.season_number != ep.season: logger.log(u"Season incorrect in parsed episode, pattern isn't valid", logger.DEBUG) @@ -154,13 +179,16 @@ def validate_name(pattern, multi=None, file_only=False, abd=False): return True -def _generate_sample_ep(multi=None, abd=False): +def _generate_sample_ep(multi=None, abd=False, sports=False): # make a fake episode object ep = TVEpisode(2, 3, "Ep Name") ep._status = Quality.compositeStatus(DOWNLOADED, Quality.HDTV) ep._airdate = datetime.date(2011, 3, 9) + if abd: ep._release_name = 'Show.Name.2011.03.09.HDTV.XviD-RLSGROUP' + elif sports: + ep._release_name = 'Show.Name.09.03.2011.HDTV.XviD-RLSGROUP' else: ep._release_name = 'Show.Name.S02E03.HDTV.XviD-RLSGROUP' @@ -182,7 +210,7 @@ def _generate_sample_ep(multi=None, abd=False): return ep -def test_name(pattern, multi=None, abd=False): - ep = _generate_sample_ep(multi, abd) +def test_name(pattern, multi=None, abd=False, sports=False): + ep = _generate_sample_ep(multi, abd, sports) return {'name': ep.formatted_filename(pattern, multi), 'dir': ep.formatted_dir(pattern, multi)} \ No newline at end of file diff --git a/sickbeard/postProcessor.py b/sickbeard/postProcessor.py index 20505d5c..7cc48fce 100644 --- a/sickbeard/postProcessor.py +++ b/sickbeard/postProcessor.py @@ -464,6 +464,9 @@ class PostProcessor(object): if parse_result.air_by_date: season = -1 episodes = [parse_result.air_date] + elif parse_result.sports: + season = -1 + episodes = [parse_result.sports_date] else: season = parse_result.season_number episodes = parse_result.episode_numbers @@ -585,7 +588,7 @@ class PostProcessor(object): # for air-by-date shows we need to look up the season/episode from tvdb if season == -1 and indexer_id and episodes: - self._log(u"Looks like this is an air-by-date show, attempting to convert the date to season/episode", + self._log(u"Looks like this is an air-by-date or sports show, attempting to convert the date to season/episode", logger.DEBUG) # try to get language set for this show diff --git a/sickbeard/properFinder.py b/sickbeard/properFinder.py index a7105722..842fbeae 100644 --- a/sickbeard/properFinder.py +++ b/sickbeard/properFinder.py @@ -115,6 +115,9 @@ class ProperFinder(): if parse_result.air_by_date: curProper.season = -1 curProper.episode = parse_result.air_date + elif parse_result.sports: + curProper.season = -1 + curProper.episode = parse_result.sports_date else: curProper.season = parse_result.season_number if parse_result.season_number != None else 1 curProper.episode = parse_result.episode_numbers[0] diff --git a/sickbeard/providers/btn.py b/sickbeard/providers/btn.py index 032891c4..da527b53 100644 --- a/sickbeard/providers/btn.py +++ b/sickbeard/providers/btn.py @@ -191,7 +191,7 @@ class BTNProvider(generic.TorrentProvider): return (title, url) - def _get_season_search_strings(self, show, season, episode, abd=False): + def _get_season_search_strings(self, show, season, episode): if not show: return [] @@ -215,15 +215,14 @@ class BTNProvider(generic.TorrentProvider): # Search for entire seasons: no need to do special things for air by date shows whole_season_params['category'] = 'Season' whole_season_params['name'] = 'Season ' + str(season) - search_params.append(whole_season_params) # Search for episodes in the season - search_params.append(self._get_episode_search_strings(show, season, episode, abd)[0]) + search_params.append(self._get_episode_search_strings(show, season, episode)[0]) return search_params - def _get_episode_search_strings(self, show, season, episode, abd=False): + def _get_episode_search_strings(self, show, season, episode, add_string=''): if not episode: return [{}] @@ -237,13 +236,18 @@ class BTNProvider(generic.TorrentProvider): else: search_params['series'] = sanitizeSceneName(show.name) - if abd: + if show.air_by_date: date_str = str(episode) # BTN uses dots in dates, we just search for the date since that # combined with the series identifier should result in just one episode search_params['name'] = date_str.replace('-', '.') + if show.sports: + date_str = str(episode) + # BTN uses dots in dates, we just search for the date since that + # combined with the series identifier should result in just one episode + search_params['name'] = date_str.replace('-', '.') else: # Do a general name search for the episode, formatted like SXXEYY search_params['name'] = "S%02dE%02d" % (season, episode) diff --git a/sickbeard/providers/dtt.py b/sickbeard/providers/dtt.py index d4c8c8d7..20ae468e 100644 --- a/sickbeard/providers/dtt.py +++ b/sickbeard/providers/dtt.py @@ -52,7 +52,7 @@ class DTTProvider(generic.TorrentProvider): def _dtt_show_id(self, show_name): return sanitizeSceneName(show_name).replace('.', '-').lower() - def _get_season_search_strings(self, show, season, episode, abd=False): + def _get_season_search_strings(self, show, season, episode): search_string = [] for show_name in set(show_name_helpers.allPossibleShowNames(show)): @@ -61,8 +61,8 @@ class DTTProvider(generic.TorrentProvider): return search_string - def _get_episode_search_strings(self, show, season, episode, abd=False): - return self._get_season_search_strings(show, season, episode, abd) + def _get_episode_search_strings(self, show, season, episode, add_string=''): + return self._get_season_search_strings(show, season, episode) def _doSearch(self, search_params, show=None, age=None): diff --git a/sickbeard/providers/ezrss.py b/sickbeard/providers/ezrss.py index 0a9927d0..04856033 100644 --- a/sickbeard/providers/ezrss.py +++ b/sickbeard/providers/ezrss.py @@ -61,8 +61,8 @@ class EZRSSProvider(generic.TorrentProvider): results = {} - if show.air_by_date: - logger.log(self.name + u" doesn't support air-by-date backlog because of limitations on their RSS search.", + if show.air_by_date or show.sports: + logger.log(self.name + u" doesn't support air-by-date or sports backloging because of limitations on their RSS search.", logger.WARNING) return results @@ -70,7 +70,7 @@ class EZRSSProvider(generic.TorrentProvider): return results - def _get_season_search_strings(self, show, season, episode, abd=False): + def _get_season_search_strings(self, show, season, episode): params = {} @@ -81,11 +81,11 @@ class EZRSSProvider(generic.TorrentProvider): params['season'] = season - params['episode'] = self._get_episode_search_strings(show, season, episode, abd)[0]['episode'] + params['episode'] = self._get_episode_search_strings(show, season, episode)[0]['episode'] return [params] - def _get_episode_search_strings(self, show, season, episode, abd=False): + def _get_episode_search_strings(self, show, season, episode, add_string=''): params = {} @@ -94,7 +94,9 @@ class EZRSSProvider(generic.TorrentProvider): params['show_name'] = helpers.sanitizeSceneName(show.name, ezrss=True).replace('.', ' ').encode('utf-8') - if abd: + if show.air_by_date: + params['date'] = str(episode) + if show.sports: params['date'] = str(episode) else: params['season'] = season diff --git a/sickbeard/providers/generic.py b/sickbeard/providers/generic.py index 64efe0dc..fde5aeb4 100644 --- a/sickbeard/providers/generic.py +++ b/sickbeard/providers/generic.py @@ -30,10 +30,11 @@ import itertools import operator import collections import urlparse -from lib.feedparser import feedparser import sickbeard +from lib import requests +from lib.feedparser import feedparser from sickbeard import helpers, classes, logger, db from sickbeard.common import Quality, MULTI_EP_RESULT, SEASON_RESULT #, SEED_POLICY_TIME, SEED_POLICY_RATIO from sickbeard import tvcache @@ -54,11 +55,16 @@ class GenericProvider: self.providerType = None self.name = name self.url = '' + self.session = None self.supportsBacklog = False self.cache = tvcache.TVCache(self) + self.session = requests.session() + self.session.verify = False + self.session.headers.update({'user-agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.107 Safari/537.36'}) + def getID(self): return GenericProvider.makeID(self.name) @@ -214,10 +220,10 @@ class GenericProvider: def _doSearch(self, search_params, show=None, age=None): return [] - def _get_season_search_strings(self, show, season, episode, abd=False): + def _get_season_search_strings(self, show, season, episode): return [] - def _get_episode_search_strings(self, show, season, episode, abd=False): + def _get_episode_search_strings(self, show, season, episode, add_string=''): return [] def _get_title_and_url(self, item): @@ -245,11 +251,15 @@ class GenericProvider: self._checkAuth() + regexMethod = 0 + if show.sports: + regexMethod = 1 + for ep_obj in ep_objs: # get scene season/episode info scene_season = ep_obj.scene_season scene_episode = ep_obj.scene_episode - if show.air_by_date: + if show.air_by_date or show.sports: scene_episode = ep_obj.airdate if not seasonSearch: @@ -268,10 +278,10 @@ class GenericProvider: return results if seasonSearch: - for curString in self._get_season_search_strings(show, scene_season, scene_episode, show.air_by_date): + for curString in self._get_season_search_strings(show, scene_season, scene_episode): itemList += self._doSearch(curString, show=show) else: - for curString in self._get_episode_search_strings(show, scene_season, scene_episode, show.air_by_date): + for curString in self._get_episode_search_strings(show, scene_season, scene_episode): itemList += self._doSearch(curString, show=show) for item in itemList: @@ -282,16 +292,16 @@ class GenericProvider: # parse the file name try: - myParser = NameParser(False) + myParser = NameParser(False, regexMethod) parse_result = myParser.parse(title, True) except InvalidNameException: logger.log(u"Unable to parse the filename " + title + " into a valid episode", logger.WARNING) continue - if not show.air_by_date: + if not show.air_by_date and not show.sports: # this check is meaningless for non-season searches if (parse_result.season_number != None and parse_result.season_number != season) or ( - parse_result.season_number == None and season != 1): + parse_result.season_number == None and season != 1): logger.log(u"The result " + title + " doesn't seem to be a valid episode for season " + str( season) + ", ignoring", logger.DEBUG) continue @@ -301,15 +311,25 @@ class GenericProvider: actual_episodes = parse_result.episode_numbers else: - if not parse_result.air_by_date: + if show.air_by_date and not parse_result.air_by_date: logger.log( u"This is supposed to be an air-by-date search but the result " + title + " didn't parse as one, skipping it", logger.DEBUG) continue + if show.sports and not parse_result.sports: + logger.log( + u"This is supposed to be an sports search but the result " + title + " didn't parse as one, skipping it", + logger.DEBUG) + continue + myDB = db.DBConnection() - sql_results = myDB.select("SELECT season, episode FROM tv_episodes WHERE showid = ? AND airdate = ?", - [show.indexerid, parse_result.air_date.toordinal()]) + if parse_result.air_by_date: + sql_results = myDB.select("SELECT season, episode FROM tv_episodes WHERE showid = ? AND airdate = ?", + [show.indexerid, parse_result.air_date.toordinal()]) + elif parse_result.sports: + sql_results = myDB.select("SELECT season, episode FROM tv_episodes WHERE showid = ? AND airdate = ?", + [show.indexerid, parse_result.sports_date.toordinal()]) if len(sql_results) != 1: logger.log( diff --git a/sickbeard/providers/hdbits.py b/sickbeard/providers/hdbits.py index ceaeeb48..e295704d 100644 --- a/sickbeard/providers/hdbits.py +++ b/sickbeard/providers/hdbits.py @@ -122,7 +122,7 @@ class HDBitsProvider(generic.TorrentProvider): logger.log(u"Unable to parse the filename " + title + " into a valid episode", logger.WARNING) continue - if episode.show.air_by_date: + if episode.show.air_by_date or episode.sports: if parse_result.air_date != episode.airdate: logger.log(u"Episode " + title + " didn't air on " + str(episode.airdate) + ", skipping it", logger.DEBUG) diff --git a/sickbeard/providers/hdtorrents.py b/sickbeard/providers/hdtorrents.py index df937676..3c319034 100644 --- a/sickbeard/providers/hdtorrents.py +++ b/sickbeard/providers/hdtorrents.py @@ -61,8 +61,6 @@ class HDTorrentsProvider(generic.TorrentProvider): self.categories = "&category[]=59&category[]=60&category[]=30&category[]=38" - self.session = requests.Session() - self.cookies = None def isEnabled(self): @@ -112,7 +110,7 @@ class HDTorrentsProvider(generic.TorrentProvider): return True - def _get_season_search_strings(self, show, season, episode, abd=False): + def _get_season_search_strings(self, show, season, episode): if not show: return [] @@ -121,21 +119,27 @@ class HDTorrentsProvider(generic.TorrentProvider): ep_string = show_name + ' S%02d' % int(season) #1) ShowName SXX search_string['Season'].append(ep_string) - search_string['Episode'] = self._get_episode_search_strings(show, season, episode, abd)[0]['Episode'] + search_string['Episode'] = self._get_episode_search_strings(show, season, episode)[0]['Episode'] return [search_string] - def _get_episode_search_strings(self, show, season, episode, abd=False, add_string=''): + def _get_episode_search_strings(self, show, season, episode, add_string=''): search_string = {'Episode': []} if not episode: return [] - if abd: + if show.air_by_date: for show_name in set(show_name_helpers.allPossibleShowNames(show)): ep_string = sanitizeSceneName(show_name) + ' ' + \ str(episode).replace('-', '|') + '|' + \ - helpers.custom_strftime('%b', str(episode)) + episode.strftime('%b') + search_string['Episode'].append(ep_string) + elif show.sports: + for show_name in set(show_name_helpers.allPossibleShowNames(show)): + ep_string = sanitizeSceneName(show_name) + ' ' + \ + str(episode).replace('-', '|') + '|' + \ + episode.strftime('%b') search_string['Episode'].append(ep_string) else: for show_name in set(show_name_helpers.allPossibleShowNames(show)): @@ -273,7 +277,6 @@ class HDTorrentsProvider(generic.TorrentProvider): if not headers: headers = [] - try: parsed = list(urlparse.urlparse(url)) parsed[2] = re.sub("/{2,}", "/", parsed[2]) # replace two or more / with one @@ -307,7 +310,13 @@ class HDTorrentsProvider(generic.TorrentProvider): for sqlShow in sqlResults: curShow = helpers.findCertainShow(sickbeard.showList, int(sqlShow["showid"])) curEp = curShow.getEpisode(int(sqlShow["season"]), int(sqlShow["episode"])) - searchString = self._get_episode_search_strings(curShow, curEp.scene_season, curEp.scene_episode, curShow.air_by_date, add_string='PROPER|REPACK') + + season = curEp.scene_season + episode = curEp.scene_episode + if curShow.air_by_date or curShow.sports: + episode = curEp.airdate + + searchString = self._get_episode_search_strings(curShow, season, episode, add_string='PROPER|REPACK') for item in self._doSearch(searchString[0], show=curShow): title, url = self._get_title_and_url(item) diff --git a/sickbeard/providers/iptorrents.py b/sickbeard/providers/iptorrents.py index 381e4a4e..82f5e1d6 100644 --- a/sickbeard/providers/iptorrents.py +++ b/sickbeard/providers/iptorrents.py @@ -37,6 +37,7 @@ from lib.requests import exceptions from bs4 import BeautifulSoup from lib.unidecode import unidecode from sickbeard.helpers import sanitizeSceneName +from sickbeard.show_name_helpers import allPossibleShowNames class IPTorrentsProvider(generic.TorrentProvider): @@ -55,8 +56,6 @@ class IPTorrentsProvider(generic.TorrentProvider): self.url = self.urls['base_url'] - self.session = None - self.categorie = 'l73=1&l78=1&l66=1&l65=1&l79=1&l5=1&l4=1' def isEnabled(self): @@ -93,7 +92,7 @@ class IPTorrentsProvider(generic.TorrentProvider): return True - def _get_season_search_strings(self, show, season, episode, abd=False): + def _get_season_search_strings(self, show, season, episode): if not show: return [] @@ -102,22 +101,28 @@ class IPTorrentsProvider(generic.TorrentProvider): ep_string = show_name + ' S%02d' % int(season) #1) ShowName SXX search_string['Season'].append(ep_string) - search_string['Episode'] = self._get_episode_search_strings(show, season, episode, abd)[0]['Episode'] + search_string['Episode'] = self._get_episode_search_strings(show, season, episode)[0]['Episode'] return [search_string] - def _get_episode_search_strings(self, show, season, episode, abd=False, add_string=''): + def _get_episode_search_strings(self, show, season, episode, add_string=''): search_string = {'Episode': []} if not episode: return [] - if abd: - for show_name in set(show_name_helpers.allPossibleShowNames(show)): + if show.air_by_date: + for show_name in set(allPossibleShowNames(show)): ep_string = sanitizeSceneName(show_name) + ' ' + \ str(episode).replace('-', '|') + '|' + \ - helpers.custom_strftime('%b', str(episode)) + episode.strftime('%b') + search_string['Episode'].append(ep_string) + if show.sports: + for show_name in set(allPossibleShowNames(show)): + ep_string = sanitizeSceneName(show_name) + ' ' + \ + str(episode).replace('-', '|') + '|' + \ + episode.strftime('%b') search_string['Episode'].append(ep_string) else: for show_name in set(show_name_helpers.allPossibleShowNames(show)): @@ -254,7 +259,7 @@ class IPTorrentsProvider(generic.TorrentProvider): for sqlShow in sqlResults: curShow = helpers.findCertainShow(sickbeard.showList, int(sqlShow["showid"])) curEp = curShow.getEpisode(int(sqlShow["season"]), int(sqlShow["episode"])) - searchString = self._get_episode_search_strings(curShow, curEp.scene_season, curEp.scene_episode, curShow.air_by_date, add_string='PROPER|REPACK') + searchString = self._get_episode_search_strings(curShow, curEp.scene_season, curEp.scene_episode, curShow.air_by_date or curShow.sports, add_string='PROPER|REPACK') for item in self._doSearch(searchString[0], show=curShow): title, url = self._get_title_and_url(item) diff --git a/sickbeard/providers/kat.py b/sickbeard/providers/kat.py index 6916c70f..66bea24b 100644 --- a/sickbeard/providers/kat.py +++ b/sickbeard/providers/kat.py @@ -61,8 +61,6 @@ class KATProvider(generic.TorrentProvider): self.searchurl = self.url + 'usearch/%s/?field=seeders&sorder=desc' #order by seed - self.session = requests.Session() - def isEnabled(self): return sickbeard.KAT @@ -166,7 +164,7 @@ class KATProvider(generic.TorrentProvider): logger.log(u"Failed parsing " + self.name + " Traceback: " + traceback.format_exc(), logger.ERROR) - def _get_season_search_strings(self, show, season, episode, abd=False): + def _get_season_search_strings(self, show, season, episode): search_string = {'Season': [], 'Episode': []} if not show: @@ -181,9 +179,9 @@ class KATProvider(generic.TorrentProvider): ep_string = show_name + ' Season ' + str(season) + ' -Ep*' + ' category:tv' #2) ShowName Season X search_string['Season'].append(ep_string) - search_string['Episode'] = self._get_episode_search_strings(show, season, episode, abd)[0]['Episode'] + search_string['Episode'] = self._get_episode_search_strings(show, season, episode)[0]['Episode'] - def _get_episode_search_strings(self, show, season, episode, abd=False, add_string=''): + def _get_episode_search_strings(self, show, season, episode, add_string=''): search_string = {'Episode': []} if not show: @@ -191,12 +189,18 @@ class KATProvider(generic.TorrentProvider): self.show = show - if abd: + if show.air_by_date: for show_name in set(allPossibleShowNames(show)): ep_string = sanitizeSceneName(show_name) + ' ' + \ str(episode).replace('-','|') + '|' + \ - helpers.custom_strftime('%b', str(episode)) + episode.strftime('%b') + search_string['Episode'].append(ep_string) + if show.sports: + for show_name in set(allPossibleShowNames(show)): + ep_string = sanitizeSceneName(show_name) + ' ' + \ + str(episode).replace('-', '|') + '|' + \ + episode.strftime('%b') search_string['Episode'].append(ep_string) else: for show_name in set(allPossibleShowNames(show)): @@ -388,7 +392,13 @@ class KATProvider(generic.TorrentProvider): for sqlShow in sqlResults: curShow = helpers.findCertainShow(sickbeard.showList, int(sqlShow["showid"])) curEp = curShow.getEpisode(int(sqlShow["season"]), int(sqlShow["episode"])) - searchString = self._get_episode_search_strings(curShow, curEp.scene_season, curEp.scene_episode, curShow.air_by_date, add_string='PROPER|REPACK') + + season = curEp.scene_season + episode = curEp.scene_episode + if curShow.air_by_date or curShow.sports: + episode = curEp.airdate + + searchString = self._get_episode_search_strings(curShow, season, episode, add_string='PROPER|REPACK') for item in self._doSearch(searchString[0], show=curShow): title, url = self._get_title_and_url(item) diff --git a/sickbeard/providers/newzbin.py b/sickbeard/providers/newzbin.py index a38daec7..db39293d 100644 --- a/sickbeard/providers/newzbin.py +++ b/sickbeard/providers/newzbin.py @@ -251,11 +251,11 @@ class NewzbinProvider(generic.NZBProvider): return data - def _get_season_search_strings(self, show, season, episode, abd=False): - return ['^' + x for x in show_name_helpers.makeSceneSeasonSearchString(show, season, episode, abd)] + def _get_season_search_strings(self, show, season, episode): + return ['^' + x for x in show_name_helpers.makeSceneSeasonSearchString(show, season, episode)] - def _get_episode_search_strings(self, show, season, episode, abd=False): - return ['^' + x for x in show_name_helpers.makeSceneSearchString(show, season, episode, abd)] + def _get_episode_search_strings(self, show, season, episode, add_string=''): + return ['^' + x for x in show_name_helpers.makeSceneSearchString(show, season, episode)] def _doSearch(self, searchStr, show=None, age=None): diff --git a/sickbeard/providers/newznab.py b/sickbeard/providers/newznab.py index 9805da82..51e432bb 100644 --- a/sickbeard/providers/newznab.py +++ b/sickbeard/providers/newznab.py @@ -80,7 +80,7 @@ class NewznabProvider(generic.NZBProvider): def isEnabled(self): return self.enabled - def _get_season_search_strings(self, show, season, episode, abd=False): + def _get_season_search_strings(self, show, season, episode): if not show: return [{}] @@ -100,13 +100,13 @@ class NewznabProvider(generic.NZBProvider): cur_params['season'] = str(season) # episode - cur_params['episode'] = self._get_episode_search_strings(show, season, episode, abd)[0]['ep'] + cur_params['episode'] = self._get_episode_search_strings(show, season, episode)[0]['ep'] to_return.append(cur_params) return to_return - def _get_episode_search_strings(self, show, season, episode, abd=False): + def _get_episode_search_strings(self, show, season, episode, add_string=''): params = {} @@ -116,7 +116,12 @@ class NewznabProvider(generic.NZBProvider): # search params['q'] = helpers.sanitizeSceneName(show.name) - if abd: + if show.air_by_date: + date_str = str(episode) + + params['season'] = date_str.partition('-')[0] + params['ep'] = date_str.partition('-')[2].replace('-', '/') + elif show.sports: date_str = str(episode) params['season'] = date_str.partition('-')[0] diff --git a/sickbeard/providers/nextgen.py b/sickbeard/providers/nextgen.py index 641c96cd..b3a90185 100644 --- a/sickbeard/providers/nextgen.py +++ b/sickbeard/providers/nextgen.py @@ -63,6 +63,7 @@ class NextGenProvider(generic.TorrentProvider): self.categories = '&c7=1&c24=1&c17=1&c22=1&c42=1&c46=1&c26=1&c28=1&c43=1&c4=1&c31=1&c45=1&c33=1' self.last_login_check = None + self.login_opener = None def isEnabled(self): @@ -130,7 +131,7 @@ class NextGenProvider(generic.TorrentProvider): logger.log(u'Failed to login:' + str(error), logger.ERROR) return False - def _get_season_search_strings(self, show, season, episode, abd=False): + def _get_season_search_strings(self, show, season, episode): if not show: return [] @@ -140,22 +141,28 @@ class NextGenProvider(generic.TorrentProvider): ep_string = show_name + ' S%02d' % int(season) #1) ShowName SXX search_string['Season'].append(ep_string) - search_string['Episode'] = self._get_episode_search_strings(show, season, episode, abd)[0]['Episode'] + search_string['Episode'] = self._get_episode_search_strings(show, season, episode)[0]['Episode'] return [search_string] - def _get_episode_search_strings(self, show, season, episode, abd=False, add_string=''): + def _get_episode_search_strings(self, show, season, episode, add_string=''): search_string = {'Episode': []} if not episode: return [] - if abd: + if show.air_by_date: for show_name in set(show_name_helpers.allPossibleShowNames(show)): ep_string = sanitizeSceneName(show_name) + ' ' + \ str(episode).replace('-', '|') + '|' + \ - helpers.custom_strftime('%b', str(episode)) + episode.strftime('%b') + search_string['Episode'].append(ep_string) + elif show.sports: + for show_name in set(show_name_helpers.allPossibleShowNames(show)): + ep_string = sanitizeSceneName(show_name) + ' ' + \ + str(episode).replace('-', '|') + '|' + \ + episode.strftime('%b') search_string['Episode'].append(ep_string) else: for show_name in set(show_name_helpers.allPossibleShowNames(show)): @@ -301,7 +308,7 @@ class NextGenProvider(generic.TorrentProvider): for sqlShow in sqlResults: curShow = helpers.findCertainShow(sickbeard.showList, int(sqlShow["showid"])) curEp = curShow.getEpisode(int(sqlShow["season"]), int(sqlShow["episode"])) - searchString = self._get_episode_search_strings(curShow, curEp.scene_season, curEp.scene_episode, curShow.air_by_date, add_string='PROPER|REPACK') + searchString = self._get_episode_search_strings(curShow, curEp.scene_season, curEp.scene_episode, add_string='PROPER|REPACK') for item in self._doSearch(searchString[0], show=curShow): title, url = self._get_title_and_url(item) diff --git a/sickbeard/providers/nyaatorrents.py b/sickbeard/providers/nyaatorrents.py index 97f88505..9a462b71 100644 --- a/sickbeard/providers/nyaatorrents.py +++ b/sickbeard/providers/nyaatorrents.py @@ -58,13 +58,13 @@ class NyaaProvider(generic.TorrentProvider): results = generic.TorrentProvider.getSearchResults(self, show, season, ep_objs, seasonSearch, manualSearch) return results - def _get_season_search_strings(self, show, season, episode, abd=False): + def _get_season_search_strings(self, show, season, episode): names = [] names.extend(show_name_helpers.makeSceneShowSearchStrings(show)) return names - def _get_episode_search_strings(self, show, season, episode, abd=False): - return self._get_season_search_strings(show, season, episode, abd) + def _get_episode_search_strings(self, show, season, episode, add_string=''): + return self._get_season_search_strings(show, season, episode) def _doSearch(self, search_string, show=None, age=None): diff --git a/sickbeard/providers/nzbs_org_old.py b/sickbeard/providers/nzbs_org_old.py index cd49f17f..2111bc37 100644 --- a/sickbeard/providers/nzbs_org_old.py +++ b/sickbeard/providers/nzbs_org_old.py @@ -53,11 +53,11 @@ class NZBsProvider(generic.NZBProvider): if sickbeard.NZBS_UID in (None, "") or sickbeard.NZBS_HASH in (None, ""): raise exceptions.AuthException("NZBs.org authentication details are empty, check your config") - def _get_season_search_strings(self, show, season, episode, abd=False): - return ['^' + x for x in show_name_helpers.makeSceneSeasonSearchString(show, season, episode, abd)] + def _get_season_search_strings(self, show, season, episode): + return ['^' + x for x in show_name_helpers.makeSceneSeasonSearchString(show, season, episode)] - def _get_episode_search_strings(self, show, season, episode, abd=False): - return ['^' + x for x in show_name_helpers.makeSceneSearchString(show, season, episode, abd)] + def _get_episode_search_strings(self, show, season, episode, add_string=''): + return ['^' + x for x in show_name_helpers.makeSceneSearchString(show, season, episode)] def _doSearch(self, curString, show=None, age=None): diff --git a/sickbeard/providers/nzbsrus.py b/sickbeard/providers/nzbsrus.py index 2c547850..e2283f13 100644 --- a/sickbeard/providers/nzbsrus.py +++ b/sickbeard/providers/nzbsrus.py @@ -42,11 +42,11 @@ class NZBsRUSProvider(generic.NZBProvider): if sickbeard.NZBSRUS_UID in (None, "") or sickbeard.NZBSRUS_HASH in (None, ""): raise exceptions.AuthException("NZBs'R'US authentication details are empty, check your config") - def _get_season_search_strings(self, show, season, episode, abd=False): - return ['^' + x for x in show_name_helpers.makeSceneSeasonSearchString(show, season, episode, abd)] + def _get_season_search_strings(self, show, season, episode): + return ['^' + x for x in show_name_helpers.makeSceneSeasonSearchString(show, season, episode)] - def _get_episode_search_strings(self, show, season, episode, abd=False): - return ['^' + x for x in show_name_helpers.makeSceneSearchString(show, season, episode, abd)] + def _get_episode_search_strings(self, show, season, episode, add_string=''): + return ['^' + x for x in show_name_helpers.makeSceneSearchString(show, season, episode)] def _doSearch(self, search, show=None, age=None): params = {'uid': sickbeard.NZBSRUS_UID, diff --git a/sickbeard/providers/omgwtfnzbs.py b/sickbeard/providers/omgwtfnzbs.py index 5ad09de0..ff6c9ef6 100644 --- a/sickbeard/providers/omgwtfnzbs.py +++ b/sickbeard/providers/omgwtfnzbs.py @@ -85,11 +85,11 @@ class OmgwtfnzbsProvider(generic.NZBProvider): return True - def _get_season_search_strings(self, show, season, episode, abd=False): - return [x for x in show_name_helpers.makeSceneSeasonSearchString(show, season, episode, abd)] + def _get_season_search_strings(self, show, season, episode): + return [x for x in show_name_helpers.makeSceneSeasonSearchString(show, season, episode)] - def _get_episode_search_strings(self, show, season, episode, abd=False): - return [x for x in show_name_helpers.makeSceneSearchString(show, season, episode, abd)] + def _get_episode_search_strings(self, show, season, episode, add_string=''): + return [x for x in show_name_helpers.makeSceneSearchString(show, season, episode)] def _get_title_and_url(self, item): return (item['release'], item['getnzb']) diff --git a/sickbeard/providers/publichd.py b/sickbeard/providers/publichd.py index c1bd732e..db7d9cfd 100644 --- a/sickbeard/providers/publichd.py +++ b/sickbeard/providers/publichd.py @@ -61,8 +61,6 @@ class PublicHDProvider(generic.TorrentProvider): self.categories = {'Season': ['23'], 'Episode': ['7', '14', '24'], 'RSS': ['7', '14', '23', '24']} - self.session = requests.Session() - def isEnabled(self): return sickbeard.PUBLICHD @@ -74,7 +72,7 @@ class PublicHDProvider(generic.TorrentProvider): quality = Quality.sceneQuality(item[0]) return quality - def _get_season_search_strings(self, show, season, episode, abd=False): + def _get_season_search_strings(self, show, season, episode): if not show: return [] @@ -87,22 +85,28 @@ class PublicHDProvider(generic.TorrentProvider): ep_string = show_name + ' Season ' + str(season) #2) ShowName Season X search_string['Season'].append(ep_string) - search_string['Episode'] = self._get_episode_search_strings(show, season, episode, abd)[0]['Episode'] + search_string['Episode'] = self._get_episode_search_strings(show, season, episode)[0]['Episode'] return [search_string] - def _get_episode_search_strings(self, show, season, episode, abd=False, add_string=''): + def _get_episode_search_strings(self, show, season, episode, add_string=''): search_string = {'Episode': []} if not episode: return [] - if abd: + if show.air_by_date: for show_name in set(allPossibleShowNames(show)): ep_string = sanitizeSceneName(show_name) + ' ' + \ str(episode).replace('-', '|') + '|' + \ - helpers.custom_strftime('%b', str(episode)) + episode.strftime('%b') + search_string['Episode'].append(ep_string) + elif show.sports: + for show_name in set(allPossibleShowNames(show)): + ep_string = sanitizeSceneName(show_name) + ' ' + \ + str(episode).replace('-', '|') + '|' + \ + episode.strftime('%b') search_string['Episode'].append(ep_string) else: for show_name in set(allPossibleShowNames(show)): @@ -276,7 +280,13 @@ class PublicHDProvider(generic.TorrentProvider): for sqlShow in sqlResults: curShow = helpers.findCertainShow(sickbeard.showList, int(sqlShow["showid"])) curEp = curShow.getEpisode(int(sqlShow["season"]), int(sqlShow["episode"])) - searchString = self._get_episode_search_strings(curShow, curEp.scene_season, curEp.scene_episode, curShow.air_by_date, add_string='PROPER|REPACK') + + season = curEp.scene_season + episode = curEp.scene_episode + if curShow.air_by_date or curShow.sports: + episode = curEp.airdate + + searchString = self._get_episode_search_strings(curShow, season, episode, add_string='PROPER|REPACK') for item in self._doSearch(searchString[0], show=curShow): title, url = self._get_title_and_url(item) diff --git a/sickbeard/providers/rsstorrent.py b/sickbeard/providers/rsstorrent.py index aea676ef..9a320f30 100644 --- a/sickbeard/providers/rsstorrent.py +++ b/sickbeard/providers/rsstorrent.py @@ -42,7 +42,6 @@ class TorrentRssProvider(generic.TorrentProvider): self.url = re.sub('\/$', '', url) self.enabled = True self.supportsBacklog = False - self.session = requests.Session() def configStr(self): return self.name + '|' + self.url + '|' + str(int(self.enabled)) diff --git a/sickbeard/providers/scc.py b/sickbeard/providers/scc.py index c92b0ee6..d57a982e 100644 --- a/sickbeard/providers/scc.py +++ b/sickbeard/providers/scc.py @@ -63,8 +63,6 @@ class SCCProvider(generic.TorrentProvider): self.categories = "c27=27&c17=17&c11=11" - self.session = None - self.headers = {'user-agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.107 Safari/537.36'} def isEnabled(self): @@ -101,7 +99,7 @@ class SCCProvider(generic.TorrentProvider): return True - def _get_season_search_strings(self, show, season, episode, abd=False): + def _get_season_search_strings(self, show, season, episode): if not show: return [] @@ -111,22 +109,28 @@ class SCCProvider(generic.TorrentProvider): ep_string = show_name + ' S%02d' % int(season) #1) ShowName SXX search_string['Season'].append(ep_string) - search_string['Episode'] = self._get_episode_search_strings(show, season, episode, abd)[0]['Episode'] + search_string['Episode'] = self._get_episode_search_strings(show, season, episode)[0]['Episode'] return [search_string] - def _get_episode_search_strings(self, show, season, episode, abd=False, add_string=''): + def _get_episode_search_strings(self, show, season, episode, add_string=''): search_string = {'Episode': []} if not episode: return [] - if abd: + if show.air_by_date: for show_name in set(show_name_helpers.allPossibleShowNames(show)): ep_string = sanitizeSceneName(show_name) + ' ' + \ str(episode).replace('-', '|') + '|' + \ - helpers.custom_strftime('%b', str(episode)) + episode.strftime('%b') + search_string['Episode'].append(ep_string) + elif show.sports: + for show_name in set(show_name_helpers.allPossibleShowNames(show)): + ep_string = sanitizeSceneName(show_name) + ' ' + \ + str(episode).replace('-', '|') + '|' + \ + episode.strftime('%b') search_string['Episode'].append(ep_string) else: for show_name in set(show_name_helpers.allPossibleShowNames(show)): @@ -278,7 +282,13 @@ class SCCProvider(generic.TorrentProvider): for sqlShow in sqlResults: curShow = helpers.findCertainShow(sickbeard.showList, int(sqlShow["showid"])) curEp = curShow.getEpisode(int(sqlShow["season"]), int(sqlShow["episode"])) - searchString = self._get_episode_search_strings(curShow, curEp.scene_season, curEp.scene_episode, curShow.air_by_date, add_string='PROPER|REPACK') + + season = curEp.scene_season + episode = curEp.scene_episode + if curShow.air_by_date or curShow.sports: + episode = curEp.airdate + + searchString = self._get_episode_search_strings(curShow, season, episode, add_string='PROPER|REPACK') for item in self._doSearch(searchString[0], show=curShow): title, url = self._get_title_and_url(item) diff --git a/sickbeard/providers/speedcd.py b/sickbeard/providers/speedcd.py index accc05f4..f585f750 100644 --- a/sickbeard/providers/speedcd.py +++ b/sickbeard/providers/speedcd.py @@ -58,10 +58,6 @@ class SpeedCDProvider(generic.TorrentProvider): self.categories = {'Season': {'c14':1}, 'Episode': {'c2':1, 'c49':1}, 'RSS': {'c14':1, 'c2':1, 'c49':1}} - self.session = requests.Session() - - self.headers = {'user-agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.107 Safari/537.36'} - def isEnabled(self): return sickbeard.SPEEDCD @@ -80,7 +76,6 @@ class SpeedCDProvider(generic.TorrentProvider): } self.session = requests.Session() - self.session.headers.update(self.headers) try: response = self.session.post(self.urls['login'], data=login_params, timeout=30, verify=False) @@ -95,7 +90,7 @@ class SpeedCDProvider(generic.TorrentProvider): return True - def _get_season_search_strings(self, show, season, episode, abd=False): + def _get_season_search_strings(self, show, season, episode): if not show: return [] @@ -107,22 +102,28 @@ class SpeedCDProvider(generic.TorrentProvider): search_string['Season'].append(ep_string) #Building the search string with the episodes we need - search_string['Episode'] = self._get_episode_search_strings(show, season, episode, abd)[0]['Episode'] + search_string['Episode'] = self._get_episode_search_strings(show, season, episode)[0]['Episode'] return [search_string] - def _get_episode_search_strings(self, show, season, episode, abd=False, add_string=''): + def _get_episode_search_strings(self, show, season, episode, add_string=''): search_string = {'Episode': []} if not episode: return [] - if abd: + if show.air_by_date: for show_name in set(show_name_helpers.allPossibleShowNames(show)): ep_string = sanitizeSceneName(show_name) + ' ' + \ str(episode).replace('-', '|') + '|' + \ - helpers.custom_strftime('%b', str(episode)) + episode.strftime('%b') + search_string['Episode'].append(ep_string) + elif show.sports: + for show_name in set(show_name_helpers.allPossibleShowNames(show)): + ep_string = sanitizeSceneName(show_name) + ' ' + \ + str(episode).replace('-', '|') + '|' + \ + episode.strftime('%b') search_string['Episode'].append(ep_string) else: for show_name in set(show_name_helpers.allPossibleShowNames(show)): @@ -237,7 +238,13 @@ class SpeedCDProvider(generic.TorrentProvider): for sqlShow in sqlResults: curShow = helpers.findCertainShow(sickbeard.showList, int(sqlShow["showid"])) curEp = curShow.getEpisode(int(sqlShow["season"]), int(sqlShow["episode"])) - searchString = self._get_episode_search_strings(curShow, curEp.scene_season, curEp.scene_episode, curShow.air_by_date, add_string='PROPER|REPACK') + + season = curEp.scene_season + episode = curEp.scene_episode + if curShow.air_by_date or curShow.sports: + episode = curEp.airdate + + searchString = self._get_episode_search_strings(curShow, season, episode,add_string='PROPER|REPACK') for item in self._doSearch(searchString[0], show=curShow): title, url = self._get_title_and_url(item) diff --git a/sickbeard/providers/thepiratebay.py b/sickbeard/providers/thepiratebay.py index 847bddca..cbad7f7d 100644 --- a/sickbeard/providers/thepiratebay.py +++ b/sickbeard/providers/thepiratebay.py @@ -72,8 +72,6 @@ class ThePirateBayProvider(generic.TorrentProvider): self.re_title_url = '/torrent/(?P\d+)/(?P.*?)//1".+?(?P<url>magnet.*?)//1".+?(?P<seeders>\d+)</td>.+?(?P<leechers>\d+)</td>' - self.session = requests.Session() - def isEnabled(self): return sickbeard.THEPIRATEBAY @@ -172,7 +170,7 @@ class ThePirateBayProvider(generic.TorrentProvider): return title - def _get_season_search_strings(self, show, season, episode, abd=False): + def _get_season_search_strings(self, show, season, episode): if not show: return [] @@ -187,11 +185,11 @@ class ThePirateBayProvider(generic.TorrentProvider): ep_string = show_name + ' Season ' + str(season) + ' -Ep*' #2) ShowName Season X search_string['Season'].append(ep_string) - search_string['Episode'] = self._get_episode_search_strings(show, season, episode, abd)[0]['Episode'] + search_string['Episode'] = self._get_episode_search_strings(show, season, episode)[0]['Episode'] return [search_string] - def _get_episode_search_strings(self, show, season, episode, abd=False, add_string=''): + def _get_episode_search_strings(self, show, season, episode, add_string=''): search_string = {'Episode': []} @@ -200,11 +198,17 @@ class ThePirateBayProvider(generic.TorrentProvider): self.show = show - if abd: + if show.air_by_date: for show_name in set(allPossibleShowNames(show)): ep_string = sanitizeSceneName(show_name) + ' ' + \ str(episode).replace('-', '|') + '|' + \ - helpers.custom_strftime('%b', str(episode)) + episode.strftime('%b') + search_string['Episode'].append(ep_string) + elif show.sports: + for show_name in set(allPossibleShowNames(show)): + ep_string = sanitizeSceneName(show_name) + ' ' + \ + str(episode).replace('-', '|') + '|' + \ + episode.strftime('%b') search_string['Episode'].append(ep_string) else: for show_name in set(allPossibleShowNames(show)): @@ -382,7 +386,13 @@ class ThePirateBayProvider(generic.TorrentProvider): for sqlShow in sqlResults: curShow = helpers.findCertainShow(sickbeard.showList, int(sqlShow["showid"])) curEp = curShow.getEpisode(int(sqlShow["season"]), int(sqlShow["episode"])) - searchString = self._get_episode_search_strings(curShow, curEp.scene_season, curEp.scene_episode, curShow.air_by_date, add_string='PROPER|REPACK') + + season = curEp.scene_season + episode = curEp.scene_episode + if curShow.air_by_date or curShow.sports: + episode = curEp.airdate + + searchString = self._get_episode_search_strings(curShow, season, episode, add_string='PROPER|REPACK') for item in self._doSearch(searchString[0], show=curShow): title, url = self._get_title_and_url(item) diff --git a/sickbeard/providers/torrentday.py b/sickbeard/providers/torrentday.py index d6b6ca02..bb9e4b53 100644 --- a/sickbeard/providers/torrentday.py +++ b/sickbeard/providers/torrentday.py @@ -56,8 +56,6 @@ class TorrentDayProvider(generic.TorrentProvider): self.url = self.urls['base_url'] - self.session = requests.Session() - self.cookies = None self.categories = {'Season': {'c14': 1}, 'Episode': {'c2': 1, 'c26': 1, 'c7': 1, 'c24': 1}, @@ -114,7 +112,7 @@ class TorrentDayProvider(generic.TorrentProvider): return True - def _get_season_search_strings(self, show, season, episode, abd=False): + def _get_season_search_strings(self, show, season, episode): if not show: return [] @@ -124,22 +122,28 @@ class TorrentDayProvider(generic.TorrentProvider): ep_string = show_name + ' S%02d' % int(season) #1) ShowName SXX search_string['Season'].append(ep_string) - search_string['Episode'] = self._get_episode_search_strings(show, season, episode, abd)[0]['Episode'] + search_string['Episode'] = self._get_episode_search_strings(show, season, episode)[0]['Episode'] return [search_string] - def _get_episode_search_strings(self, show, season, episode, abd=False, add_string=''): + def _get_episode_search_strings(self, show, season, episode, add_string=''): search_string = {'Episode': []} if not episode: return [] - if abd: + if show.air_by_date: for show_name in set(show_name_helpers.allPossibleShowNames(show)): ep_string = sanitizeSceneName(show_name) + ' ' + \ str(episode).replace('-', '|') + '|' + \ - helpers.custom_strftime('%b', str(episode)) + episode.strftime('%b') + search_string['Episode'].append(ep_string) + if show.sports: + for show_name in set(show_name_helpers.allPossibleShowNames(show)): + ep_string = sanitizeSceneName(show_name) + ' ' + \ + str(episode).replace('-', '|') + '|' + \ + episode.strftime('%b') search_string['Episode'].append(ep_string) else: for show_name in set(show_name_helpers.allPossibleShowNames(show)): @@ -250,7 +254,13 @@ class TorrentDayProvider(generic.TorrentProvider): for sqlShow in sqlResults: curShow = helpers.findCertainShow(sickbeard.showList, int(sqlShow["showid"])) curEp = curShow.getEpisode(int(sqlShow["season"]), int(sqlShow["episode"])) - searchString = self._get_episode_search_strings(curShow, curEp.scene_season, curEp.scene_episode, curShow.air_by_date, add_string='PROPER|REPACK') + + season = curEp.scene_season + episode = curEp.scene_episode + if curShow.air_by_date or curShow.sports: + episode = curEp.airdate + + searchString = self._get_episode_search_strings(curShow, season, episode, add_string='PROPER|REPACK') for item in self._doSearch(searchString[0], show=curShow): title, url = self._get_title_and_url(item) diff --git a/sickbeard/providers/torrentleech.py b/sickbeard/providers/torrentleech.py index af6d26b9..9ba1d4f5 100644 --- a/sickbeard/providers/torrentleech.py +++ b/sickbeard/providers/torrentleech.py @@ -59,8 +59,6 @@ class TorrentLeechProvider(generic.TorrentProvider): self.categories = "2,26,27,32" - self.session = None - def isEnabled(self): return sickbeard.TORRENTLEECH @@ -96,7 +94,7 @@ class TorrentLeechProvider(generic.TorrentProvider): return True - def _get_season_search_strings(self, show, season, episode, abd=False): + def _get_season_search_strings(self, show, season, episode): if not show: return [] @@ -106,22 +104,28 @@ class TorrentLeechProvider(generic.TorrentProvider): ep_string = show_name + ' S%02d' % int(season) #1) ShowName SXX search_string['Season'].append(ep_string) - search_string['Episode'] = self._get_episode_search_strings(show, season, episode, abd)[0]['Episode'] + search_string['Episode'] = self._get_episode_search_strings(show, season, episode)[0]['Episode'] return [search_string] - def _get_episode_search_strings(self, show, season, episode, abd=False, add_string=''): + def _get_episode_search_strings(self, show, season, episode, add_string=''): search_string = {'Episode': []} if not episode: return [] - if abd: + if show.air_by_date: for show_name in set(show_name_helpers.allPossibleShowNames(show)): ep_string = sanitizeSceneName(show_name) + ' ' + \ str(episode).replace('-', '|') + '|' + \ - helpers.custom_strftime('%b', str(episode)) + episode.strftime('%b') + search_string['Episode'].append(ep_string) + if show.sports: + for show_name in set(show_name_helpers.allPossibleShowNames(show)): + ep_string = sanitizeSceneName(show_name) + ' ' + \ + str(episode).replace('-', '|') + '|' + \ + episode.strftime('%b') search_string['Episode'].append(ep_string) else: for show_name in set(show_name_helpers.allPossibleShowNames(show)): @@ -254,7 +258,13 @@ class TorrentLeechProvider(generic.TorrentProvider): for sqlShow in sqlResults: curShow = helpers.findCertainShow(sickbeard.showList, int(sqlShow["showid"])) curEp = curShow.getEpisode(int(sqlShow["season"]), int(sqlShow["episode"])) - searchString = self._get_episode_search_strings(curShow, curEp.scene_season, curEp.scene_episode, curShow.air_by_date, add_string='PROPER|REPACK') + + season = curEp.scene_season + episode = curEp.scene_episode + if curShow.air_by_date or curShow.sports: + episode = curEp.airdate + + searchString = self._get_episode_search_strings(curShow, season, episode, add_string='PROPER|REPACK') for item in self._doSearch(searchString[0], show=curShow): title, url = self._get_title_and_url(item) diff --git a/sickbeard/search.py b/sickbeard/search.py index 00375c86..307fd0ec 100644 --- a/sickbeard/search.py +++ b/sickbeard/search.py @@ -380,9 +380,7 @@ def searchProviders(show, season, episode=None, manualSearch=False): # skip non-tv crap curResults[curEp] = filter( - lambda x: show_name_helpers.filterBadReleases(x.name) and show_name_helpers.isGoodResult(x.name, - show), - curResults[curEp]) + lambda x: show_name_helpers.filterBadReleases(x.name) and show_name_helpers.isGoodResult(x.name,show),curResults[curEp]) if curEp in foundResults: foundResults[curEp] += curResults[curEp] diff --git a/sickbeard/searchBacklog.py b/sickbeard/searchBacklog.py index 6a1f75da..e4725190 100644 --- a/sickbeard/searchBacklog.py +++ b/sickbeard/searchBacklog.py @@ -96,6 +96,7 @@ class BacklogSearcher: # get separate lists of the season/date shows #season_shows = [x for x in show_list if not x.air_by_date] air_by_date_shows = [x for x in show_list if x.air_by_date] + sports_shows = [x for x in show_list if x.sports] # figure out how many segments of air by date shows we're going to do air_by_date_segments = [] @@ -104,6 +105,12 @@ class BacklogSearcher: logger.log(u"Air-by-date segments: " + str(air_by_date_segments), logger.DEBUG) + sports_segments = [] + for cur_id in [x.indexerid for x in sports_shows]: + sports_segments += self._get_sports_segments(cur_id, fromDate) + + logger.log(u"Sports segments: " + str(sports_segments), logger.DEBUG) + #totalSeasons = float(len(numSeasonResults) + len(air_by_date_segments)) #numSeasonsDone = 0.0 @@ -115,6 +122,8 @@ class BacklogSearcher: if curShow.air_by_date: segments = [x[1] for x in self._get_air_by_date_segments(curShow.indexerid, fromDate)] + elif curShow.sports: + segments = [x[1] for x in self._get_sports_segments(curShow.indexerid, fromDate)] else: segments = self._get_season_segments(curShow.indexerid, fromDate) @@ -169,7 +178,7 @@ class BacklogSearcher: # query the DB for all dates for this show myDB = db.DBConnection() num_air_by_date_results = myDB.select( - "SELECT airdate, showid FROM tv_episodes ep, tv_shows show WHERE season != 0 AND ep.showid = show.indexer_id AND show.paused = 0 ANd ep.airdate > ? AND ep.showid = ?", + "SELECT airdate, showid FROM tv_episodes ep, tv_shows show WHERE season != 0 AND ep.showid = show.indexer_id AND show.paused = 0 ANd ep.airdate > ? AND ep.showid = ? AND show.air_by_date = 1", [fromDate.toordinal(), indexer_id]) # break them apart into month/year strings @@ -185,6 +194,26 @@ class BacklogSearcher: return air_by_date_segments + def _get_sports_segments(self, indexer_id, fromDate): + # query the DB for all dates for this show + myDB = db.DBConnection() + num_sports_results = myDB.select( + "SELECT airdate, showid FROM tv_episodes ep, tv_shows show WHERE season != 0 AND ep.showid = show.indexer_id AND show.paused = 0 ANd ep.airdate > ? AND ep.showid = ? AND show.sports = 1", + [fromDate.toordinal(), indexer_id]) + + # break them apart into month/year strings + sports_segments = [] + for cur_result in num_sports_results: + cur_date = datetime.date.fromordinal(int(cur_result["airdate"])) + cur_date_str = str(cur_date)[:7] + cur_indexer_id = int(cur_result["showid"]) + + cur_result_tuple = (cur_indexer_id, cur_date_str) + if cur_result_tuple not in sports_segments: + sports_segments.append(cur_result_tuple) + + return sports_segments + def _set_lastBacklog(self, when): logger.log(u"Setting the last backlog in the DB to " + str(when), logger.DEBUG) diff --git a/sickbeard/search_queue.py b/sickbeard/search_queue.py index 79be7ec4..7f871ed7 100644 --- a/sickbeard/search_queue.py +++ b/sickbeard/search_queue.py @@ -192,7 +192,7 @@ class BacklogQueueItem(generic_queue.QueueItem): myDB = db.DBConnection() # see if there is anything in this season worth searching for - if not self.show.air_by_date: + if not self.show.air_by_date and not self.show.sports: statusResults = myDB.select("SELECT status FROM tv_episodes WHERE showid = ? AND season = ?", [self.show.indexerid, self.segment]) else: diff --git a/sickbeard/show_name_helpers.py b/sickbeard/show_name_helpers.py index 13182755..c12a802d 100644 --- a/sickbeard/show_name_helpers.py +++ b/sickbeard/show_name_helpers.py @@ -119,7 +119,7 @@ def makeSceneShowSearchStrings(show): return map(sanitizeSceneName, showNames) -def makeSceneSeasonSearchString(show, season, episode, abd=False, extraSearchType=None): +def makeSceneSeasonSearchString(show, season, episode, extraSearchType=None): myDB = db.DBConnection() if show.air_by_date: @@ -127,7 +127,11 @@ def makeSceneSeasonSearchString(show, season, episode, abd=False, extraSearchTyp # the search string for air by date shows is just seasonStrings = [season] + elif show.sports: + numseasons = 0 + # the search string for air by date shows is just + seasonStrings = [season] else: numseasonsSQlResult = myDB.select( "SELECT COUNT(DISTINCT season) as numseasons FROM tv_episodes WHERE showid = ? and season != 0", @@ -153,12 +157,12 @@ def makeSceneSeasonSearchString(show, season, episode, abd=False, extraSearchTyp toReturn.append(curShow + "." + cur_season) # episode - toReturn.extend(makeSceneSearchString(show, season, episode, abd)) + toReturn.extend(makeSceneSearchString(show, season, episode)) return toReturn -def makeSceneSearchString(show, season, episode, abd=False): +def makeSceneSearchString(show, season, episode): myDB = db.DBConnection() numseasonsSQlResult = myDB.select( "SELECT COUNT(DISTINCT season) as numseasons FROM tv_episodes WHERE showid = ? and season != 0", @@ -170,8 +174,10 @@ def makeSceneSearchString(show, season, episode, abd=False): numepisodes = int(numepisodesSQlResult[0][0]) # see if we should use dates instead of episodes - if abd and episode != datetime.date.fromordinal(1): - epStrings = [str(episode.airdate)] + if show.air_by_date and episode != datetime.date.fromordinal(1): + epStrings = [str(episode)] + if show.sports and episode != datetime.date.fromordinal(1): + epStrings = [str(episode)] else: epStrings = ["S%02iE%02i" % (int(season), int(episode)), "%ix%02i" % (int(season), int(episode))] diff --git a/sickbeard/show_queue.py b/sickbeard/show_queue.py index 8b49ac82..a836efca 100644 --- a/sickbeard/show_queue.py +++ b/sickbeard/show_queue.py @@ -294,8 +294,11 @@ class QueueItemAdd(ShowQueueItem): self.show.paused = False # be smartish about this - if self.show.genre and "talk show" in self.show.genre.lower() or "sports" in self.show.classification.lower(): + if self.show.genre and "talk show" in self.show.genre.lower(): self.show.air_by_date = 1 + elif self.show.genre and "sports" in self.show.genre.lower(): + self.show.sports = 1 + except sickbeard.indexer_exception, e: logger.log( diff --git a/sickbeard/traktWatchListChecker.py b/sickbeard/traktWatchListChecker.py index 74d105be..76edf273 100644 --- a/sickbeard/traktWatchListChecker.py +++ b/sickbeard/traktWatchListChecker.py @@ -118,7 +118,7 @@ class TraktChecker(): return logger.log(u"Setting episode s" + str(s) + "e" + str(e) + " of show " + show.name + " to wanted") # figure out what segment the episode is in and remember it so we can backlog it - if epObj.show.air_by_date: + if epObj.show.air_by_date or epObj.show.sports: ep_segment = str(epObj.airdate)[:7] else: ep_segment = epObj.season diff --git a/sickbeard/tv.py b/sickbeard/tv.py index 962183b8..36171b6b 100644 --- a/sickbeard/tv.py +++ b/sickbeard/tv.py @@ -76,6 +76,7 @@ class TVShow(object): self.startyear = 0 self.paused = 0 self.air_by_date = 0 + self.sports = 0 self.subtitles = int(sickbeard.SUBTITLES_DEFAULT if sickbeard.SUBTITLES_DEFAULT else 0) self.dvdorder = 0 self.archive_firstmatch = 0 @@ -138,7 +139,7 @@ class TVShow(object): sql_selection = sql_selection + " FROM tv_episodes tve WHERE showid = " + str(self.indexerid) if season is not None: - if not self.air_by_date: + if not self.air_by_date and not self.sports: sql_selection = sql_selection + " AND season = " + str(season) else: segment_year, segment_month = map(int, str(season).split('-')) @@ -552,7 +553,7 @@ class TVShow(object): logger.log(u"Unable to parse the filename " + file + " into a valid episode", logger.ERROR) return None - if len(parse_result.episode_numbers) == 0 and not parse_result.air_by_date: + if len(parse_result.episode_numbers) == 0 and not (parse_result.air_by_date or parse_result.sports): logger.log("parse_result: " + str(parse_result)) logger.log(u"No episode number found in " + file + ", ignoring it", logger.ERROR) return None @@ -563,7 +564,7 @@ class TVShow(object): rootEp = None # if we have an air-by-date show then get the real season/episode numbers - if parse_result.air_by_date: + if parse_result.air_by_date or parse_result.sports: try: lINDEXER_API_PARMS = sickbeard.indexerApi(self.indexer).api_params.copy() @@ -575,7 +576,12 @@ class TVShow(object): t = sickbeard.indexerApi(self.indexer).indexer(**lINDEXER_API_PARMS) - epObj = t[self.indexerid].airedOn(parse_result.air_date)[0] + epObj = None + if parse_result.air_by_date: + epObj = t[self.indexerid].airedOn(parse_result.air_date)[0] + elif parse_result.sports: + epObj = t[self.indexerid].airedOn(parse_result.sports_date)[0] + season = int(epObj["seasonnumber"]) episodes = [int(epObj["episodenumber"])] except sickbeard.indexer_episodenotfound: @@ -730,6 +736,10 @@ class TVShow(object): if not self.air_by_date: self.air_by_date = 0 + self.sports = sqlResults[0]["sports"] + if not self.sports: + self.sports = 0 + self.subtitles = sqlResults[0]["subtitles"] if self.subtitles: self.subtitles = 1 @@ -1023,6 +1033,7 @@ class TVShow(object): "flatten_folders": self.flatten_folders, "paused": self.paused, "air_by_date": self.air_by_date, + "sports": self.sports, "subtitles": self.subtitles, "dvdorder": self.dvdorder, "archive_firstmatch": self.archive_firstmatch, @@ -1935,7 +1946,7 @@ class TVEpisode(object): # if there's no release group then replace it with a reasonable facsimile if not replace_map['%RN']: - if self.show.air_by_date: + if self.show.air_by_date or self.show.sports: result_name = result_name.replace('%RN', '%S.N.%A.D.%E.N-SiCKBEARD') result_name = result_name.replace('%rn', '%s.n.%A.D.%e.n-sickbeard') else: @@ -2066,6 +2077,8 @@ class TVEpisode(object): # we only use ABD if it's enabled, this is an ABD show, AND this is not a multi-ep if self.show.air_by_date and sickbeard.NAMING_CUSTOM_ABD and not self.relatedEps: pattern = sickbeard.NAMING_ABD_PATTERN + elif self.show.sports and sickbeard.NAMING_CUSTOM_SPORTS and not self.relatedEps: + pattern = sickbeard.NAMING_SPORTS_PATTERN else: pattern = sickbeard.NAMING_PATTERN @@ -2086,6 +2099,8 @@ class TVEpisode(object): # we only use ABD if it's enabled, this is an ABD show, AND this is not a multi-ep if self.show.air_by_date and sickbeard.NAMING_CUSTOM_ABD and not self.relatedEps: pattern = sickbeard.NAMING_ABD_PATTERN + elif self.show.sports and sickbeard.NAMING_CUSTOM_SPORTS and not self.relatedEps: + pattern = sickbeard.NAMING_CUSTOM_SPORTS else: pattern = sickbeard.NAMING_PATTERN diff --git a/sickbeard/tvcache.py b/sickbeard/tvcache.py index 60cb4c77..8adc91f3 100644 --- a/sickbeard/tvcache.py +++ b/sickbeard/tvcache.py @@ -281,7 +281,7 @@ class TVCache(): episodes = parse_result.episode_numbers # if we have an air-by-date show then get the real season/episode numbers - if parse_result.air_by_date and indexer_id: + if (parse_result.air_by_date or parse_result.sports) and indexer_id: try: lINDEXER_API_PARMS = sickbeard.indexerApi(self.indexer).api_params.copy() if not (indexer_lang == "" or indexer_lang == "en" or indexer_lang == None): @@ -289,7 +289,15 @@ class TVCache(): t = sickbeard.indexerApi(self.indexer).indexer(**lINDEXER_API_PARMS) - epObj = t[indexer_id].airedOn(parse_result.air_date)[0] + epObj = None + if parse_result.air_by_date: + epObj = t[indexer_id].airedOn(parse_result.air_date)[0] + elif parse_result.sports: + epObj = t[indexer_id].airedOn(parse_result.sports_date)[0] + + if epObj is None: + return None + season = int(epObj["seasonnumber"]) episodes = [int(epObj["episodenumber"])] except sickbeard.indexer_episodenotfound: diff --git a/sickbeard/webapi.py b/sickbeard/webapi.py index 9d749a05..bc2dc3af 100644 --- a/sickbeard/webapi.py +++ b/sickbeard/webapi.py @@ -975,7 +975,7 @@ class CMD_EpisodeSetStatus(ApiCall): for epObj in ep_list: if ep_segment == None and self.status == WANTED: # figure out what segment the episode is in and remember it so we can backlog it - if showObj.air_by_date: + if showObj.air_by_date or showObj.sports: ep_segment = str(epObj.airdate)[:7] else: ep_segment = epObj.season @@ -1764,6 +1764,7 @@ class CMD_Show(ApiCall): showDict["show_name"] = showObj.name showDict["paused"] = showObj.paused showDict["air_by_date"] = showObj.air_by_date + showDict["sports"] = showObj.sports showDict["flatten_folders"] = showObj.flatten_folders #clean up tvdb horrible airs field showDict["airs"] = str(showObj.airs).replace('am', ' AM').replace('pm', ' PM').replace(' ', ' ') @@ -2526,6 +2527,7 @@ class CMD_Shows(ApiCall): "quality": _get_quality_string(curShow.quality), "language": curShow.lang, "air_by_date": curShow.air_by_date, + "sports": curShow.sports, "indexerid": curShow.indexerid, "network": curShow.network, "show_name": curShow.name, diff --git a/sickbeard/webserve.py b/sickbeard/webserve.py index bed3aaa9..0d6a567c 100644 --- a/sickbeard/webserve.py +++ b/sickbeard/webserve.py @@ -1134,7 +1134,8 @@ class ConfigPostProcessing: rename_episodes=None, unpack=None, move_associated_files=None, tv_download_dir=None, naming_custom_abd=None, naming_abd_pattern=None, naming_strip_year=None, use_failed_downloads=None, - delete_failed=None, extra_scripts=None): + delete_failed=None, extra_scripts=None, + naming_custom_sports=None, naming_sports_pattern=None): results = [] @@ -1163,17 +1164,11 @@ class ConfigPostProcessing: sickbeard.RENAME_EPISODES = config.checkbox_to_value(rename_episodes) sickbeard.MOVE_ASSOCIATED_FILES = config.checkbox_to_value(move_associated_files) sickbeard.NAMING_CUSTOM_ABD = config.checkbox_to_value(naming_custom_abd) + sickbeard.NAMING_CUSTOM_SPORTS = config.checkbox_to_value(naming_custom_sports) sickbeard.NAMING_STRIP_YEAR = config.checkbox_to_value(naming_strip_year) sickbeard.USE_FAILED_DOWNLOADS = config.checkbox_to_value(use_failed_downloads) sickbeard.DELETE_FAILED = config.checkbox_to_value(delete_failed) - sickbeard.METADATA_XBMC = xbmc_data - sickbeard.METADATA_XBMC_12PLUS = xbmc_12plus_data - sickbeard.METADATA_MEDIABROWSER = mediabrowser_data - sickbeard.METADATA_PS3 = sony_ps3_data - sickbeard.METADATA_WDTV = wdtv_data - sickbeard.METADATA_TIVO = tivo_data - sickbeard.metadata_provider_dict['XBMC'].set_config(sickbeard.METADATA_XBMC) sickbeard.metadata_provider_dict['XBMC 12+'].set_config(sickbeard.METADATA_XBMC_12PLUS) sickbeard.metadata_provider_dict['MediaBrowser'].set_config(sickbeard.METADATA_MEDIABROWSER) @@ -1188,12 +1183,18 @@ class ConfigPostProcessing: else: results.append("You tried saving an invalid naming config, not saving your naming settings") - if self.isNamingValid(naming_abd_pattern, None, True) != "invalid": + if self.isNamingValid(naming_abd_pattern, None, abd=True) != "invalid": sickbeard.NAMING_ABD_PATTERN = naming_abd_pattern else: results.append( "You tried saving an invalid air-by-date naming config, not saving your air-by-date settings") + if self.isNamingValid(naming_sports_pattern, None, sports=True) != "invalid": + sickbeard.NAMING_SPORTS_PATTERN = naming_sports_pattern + else: + results.append( + "You tried saving an invalid sports naming config, not saving your sports settings") + sickbeard.save_config() if len(results) > 0: @@ -1207,19 +1208,19 @@ class ConfigPostProcessing: redirect("/config/postProcessing/") @cherrypy.expose - def testNaming(self, pattern=None, multi=None, abd=False): + def testNaming(self, pattern=None, multi=None, abd=False, sports=False): if multi is not None: multi = int(multi) - result = naming.test_name(pattern, multi, abd) + result = naming.test_name(pattern, multi, abd, sports) result = ek.ek(os.path.join, result['dir'], result['name']) return result @cherrypy.expose - def isNamingValid(self, pattern=None, multi=None, abd=False): + def isNamingValid(self, pattern=None, multi=None, abd=False, sports=False): if pattern is None: return "invalid" @@ -1228,6 +1229,11 @@ class ConfigPostProcessing: is_valid = naming.check_valid_abd_naming(pattern) require_season_folders = False + # sport shows just need one check, we don't need to worry about season folders + elif sports: + is_valid = naming.check_valid_sports_naming(pattern) + require_season_folders = False + else: # check validity of single and multi ep cases for the whole path is_valid = naming.check_valid_naming(pattern, multi) @@ -2829,13 +2835,13 @@ class Home: def plotDetails(self, show, season, episode): result = db.DBConnection().action( "SELECT description FROM tv_episodes WHERE showid = ? AND season = ? AND episode = ?", - (show, season, episode)).fetchone() + (int(show), int(season), int(episode))).fetchone() return result['description'] if result else 'Episode not found.' @cherrypy.expose def editShow(self, show=None, location=None, anyQualities=[], bestQualities=[], exceptions_list=[], - flatten_folders=None, paused=None, directCall=False, air_by_date=None, dvdorder=None, indexerLang=None, - subtitles=None, archive_firstmatch=None, rls_ignore_words=None, rls_require_words=None): + flatten_folders=None, paused=None, directCall=False, air_by_date=None, sports=None, dvdorder=None, + indexerLang=None,subtitles=None, archive_firstmatch=None, rls_ignore_words=None, rls_require_words=None): if show is None: errString = "Invalid show ID: " + str(show) @@ -2872,6 +2878,7 @@ class Home: archive_firstmatch = config.checkbox_to_value(archive_firstmatch) paused = config.checkbox_to_value(paused) air_by_date = config.checkbox_to_value(air_by_date) + sports = config.checkbox_to_value(sports) subtitles = config.checkbox_to_value(subtitles) indexer_lang = indexerLang @@ -2915,6 +2922,7 @@ class Home: showObj.paused = paused showObj.air_by_date = air_by_date + showObj.sports = sports showObj.subtitles = subtitles showObj.lang = indexer_lang showObj.dvdorder = dvdorder @@ -3129,7 +3137,7 @@ class Home: if int(status) == WANTED: # figure out what episodes are wanted so we can backlog them - if epObj.show.air_by_date: + if epObj.show.air_by_date or epObj.show.sports: segment = str(epObj.airdate)[:7] else: segment = epObj.season @@ -3406,7 +3414,7 @@ class Home: return json.dumps({'result': 'failure'}) # figure out what segment the episode is in and remember it so we can backlog it - if ep_obj.show.air_by_date: + if ep_obj.show.air_by_date or ep_obj.show.sports: segment = str(ep_obj.airdate)[:7] else: segment = ep_obj.season diff --git a/tests/name_parser_tests.py b/tests/name_parser_tests.py index c535fb29..60b2e182 100644 --- a/tests/name_parser_tests.py +++ b/tests/name_parser_tests.py @@ -238,6 +238,7 @@ class BasicTests(unittest.TestCase): if DEBUG or verbose: print 'air_by_date:', test_result.air_by_date, 'air_date:', test_result.air_date + print 'sports:', test_result.sports, 'air_date:', test_result.air_date print test_result print result self.assertEqual(test_result.which_regex, [section]) diff --git a/tests/test_lib.py b/tests/test_lib.py index dd9b36da..d7509c30 100644 --- a/tests/test_lib.py +++ b/tests/test_lib.py @@ -76,6 +76,7 @@ sickbeard.FLATTEN_FOLDERS_DEFAULT = 0 sickbeard.NAMING_PATTERN = '' sickbeard.NAMING_ABD_PATTERN = '' +sickbeard.NAMING_SPORTS_PATTERN = '' sickbeard.NAMING_MULTI_EP = 1 diff --git a/tests/xem_tests.py b/tests/xem_tests.py index 52b32af1..96744132 100644 --- a/tests/xem_tests.py +++ b/tests/xem_tests.py @@ -28,8 +28,9 @@ sys.path.append(os.path.abspath('../lib')) import test_lib as test import sickbeard -from sickbeard.helpers import sanitizeSceneName, custom_strftime +from sickbeard.helpers import sanitizeSceneName from sickbeard.tv import TVShow +from sickbeard.name_parser.parser import NameParser, InvalidNameException class XEMBasicTests(test.SickbeardTestDBCase): def loadFromDB(self): @@ -53,12 +54,31 @@ class XEMBasicTests(test.SickbeardTestDBCase): ep = show.getEpisode(21, 17) ep.airdate = datetime.datetime.now() + ep_date_formated = ep.airdate.strftime('%b') + + show_name = 'UFC' + if show_name.lower() in sickbeard.showList: + print 'good' + else: + print 'bad' + + # parse the file name + parse_result = None + title = u'UFC 155 Dos Santos vs Velasquez 29th Dec 2012 HDTV x264-Sir Paul' + try: + myParser = NameParser(False, 1) + parse_result = myParser.parse(title, True) + except InvalidNameException: + print(u"Unable to parse the filename " + title + " into a valid episode") + + print parse_result + search_string = {'Episode':[]} episode = ep.airdate str(episode).replace('-', '|') ep_string = sanitizeSceneName(show.name) + ' ' + \ str(episode).replace('-', '|') + '|' + \ - sickbeard.helpers.custom_strftime('%b', episode) + episode.strftime('%b') search_string['Episode'].append(ep_string)