Added sports feature, acts just like air_by_date except allows us to control the date pattern to match events that air_by_date could not.

Custome sports naming patterns can be set now as well.

Fixed issues with FINDPROPERS.

Fixed issues with session connections.

Cleaned up code.
This commit is contained in:
echel0n 2014-04-28 02:15:29 -07:00
parent d4263e1b03
commit 5e38813a73
49 changed files with 805 additions and 288 deletions

View file

@ -627,6 +627,183 @@
</div><!-- /naming_abd_different --> </div><!-- /naming_abd_different -->
<div class="field-pair clearfix">
<input type="checkbox" class="enabler" id="naming_custom_sports" name="naming_custom_sports" #if $sickbeard.NAMING_CUSTOM_SPORTS then "checked=\"checked\"" else ""#/>
<label class="clearfix" for="naming_custom_sports">
<span class="component-title">Custom Sports</span>
<span class="component-desc">Name Sports shows differently than regular shows?</span>
</label>
</div>
<div id="content_naming_custom_sports">
<div class="field-pair">
<label class="nocheck clearfix" for="name_sports_presets">
<span class="component-title">Name Pattern:</span>
<span class="component-desc">
<select id="name_sports_presets">
#set is_sports_custom = True
#for $cur_preset in $naming.name_sports_presets:
#set $tmp = $naming.test_name($cur_preset)
#if $cur_preset == $sickbeard.NAMING_SPORTS_PATTERN:
#set is_sports_custom = False
#end if
<option id="$cur_preset" #if $cur_preset == $sickbeard.NAMING_SPORTS_PATTERN then "selected=\"selected\"" else ""#>$os.path.join($tmp['dir'], $tmp['name'])</option>
#end for
<option id="$sickbeard.NAMING_SPORTS_PATTERN" #if $is_sports_custom then "selected=\"selected\"" else ""#>Custom...</option>
</select>
</span>
</label>
</div>
<div id="naming_sports_custom">
<div class="field-pair clearfix" style="padding-top: 0;">
<label class="nocheck clearfix">
<span class="component-title">
&nbsp;
</span>
<span class="component-desc">
<input type="text" size="45" name="naming_sports_pattern" id="naming_sports_pattern" class="custom-pattern" value="$sickbeard.NAMING_SPORTS_PATTERN" style="font-size: 13px; height: 18px; margin-top: -8px"/>
<img src="$sbRoot/images/legend16.png" width="16" height="16" alt="[Toggle Key]" id="show_naming_sports_key" title="Toggle sports Naming Legend" style="padding: 0 0 0 3px; margin-top: -2px;" />
</span>
</label>
</div>
<div id="naming_sports_key" class="nocheck clearfix" style="display: none;">
<table class="Key">
<thead>
<tr>
<th class="align-right">Meaning</th>
<th>Pattern</th>
<th width="60%">Result</th>
</tr>
</thead>
<tfoot>
<tr>
<th colspan="3">Use lower case if you want lower case names (eg. %sn, %e.n, %q_n etc)</th>
</tr>
</tfoot>
<tbody>
<tr>
<td class="align-right"><b>Show Name:</b></td>
<td>%SN</td>
<td>Show Name</td>
</tr>
<tr class="even">
<td>&nbsp;</td>
<td>%S.N</td>
<td>Show.Name</td>
</tr>
<tr>
<td>&nbsp;</td>
<td>%S_N</td>
<td>Show_Name</td>
</tr>
<tr class="even">
<td class="align-right"><b>Sports:</b></td>
<td>%AD</td>
<td>9th Mar 2010</td>
</tr>
<tr>
<td>&nbsp;</td>
<td>%A.D</td>
<td>9th.Mar.2010</td>
</tr>
<tr class="even">
<td>&nbsp;</td>
<td>%A_D</td>
<td>9th_Mar_2010</td>
</tr>
<tr>
<td>&nbsp;</td>
<td>%A-D</td>
<td>9th-Mar-2010</td>
</tr>
<tr class="even">
<td class="align-right"><b>Episode Name:</b></td>
<td>%EN</td>
<td>Episode Name</td>
</tr>
<tr>
<td>&nbsp;</td>
<td>%E.N</td>
<td>Episode.Name</td>
</tr>
<tr class="even">
<td>&nbsp;</td>
<td>%E_N</td>
<td>Episode_Name</td>
</tr>
<tr>
<td class="align-right"><b>Quality:</b></td>
<td>%QN</td>
<td>720p BluRay</td>
</tr>
<tr class="even">
<td>&nbsp;</td>
<td>%Q.N</td>
<td>720p.BluRay</td>
</tr>
<tr>
<td>&nbsp;</td>
<td>%Q_N</td>
<td>720p_BluRay</td>
</tr>
<tr class="even">
<td class="align-right"><b>Year:</b></td>
<td>%Y</td>
<td>2010</td>
</tr>
<tr>
<td class="align-right"><b>Month:</b></td>
<td>%M</td>
<td>3</td>
</tr>
<tr class="even">
<td class="align-right">&nbsp;</td>
<td>%0M</td>
<td>03</td>
</tr>
<tr>
<td class="align-right"><b>Day:</b></td>
<td>%D</td>
<td>9</td>
</tr>
<tr class="even">
<td class="align-right">&nbsp;</td>
<td>%0D</td>
<td>09</td>
</tr>
<tr>
<td class="align-right"><i class="icon-info-sign" title="Multi-EP style is ignored"></i> <b>Release Name:</b></td>
<td>%RN</td>
<td>Show.Name.9th.Mar.2010.HDTV.XviD-RLSGROUP</td>
</tr>
<tr class="even">
<td class="align-right"><i class="icon-info-sign" title="'SiCKBEARD' is used in place of RLSGROUP if it could not be properly detected"></i> <b>Release Group:</b></td>
<td>%RG</td>
<td>RLSGROUP</td>
</tr>
<tr>
<td class="align-right"><i class="icon-info-sign" title="If episode is proper/repack add 'proper' to name."></i> <b>Release Type:</b></td>
<td>%RT</td>
<td>PROPER</td>
</tr>
</tbody>
</table>
<br/>
</div>
</div><!-- /naming_sports_custom -->
<div id="naming_sports_example_div">
<h2>Sample:</h2>
<div class="example">
<span class="jumbo" id="naming_sports_example">&nbsp;</span>
</div>
<br/>
</div>
</div><!-- /naming_sports_different -->
<div class="clearfix"></div> <div class="clearfix"></div>
<input type="submit" class="btn config_submitter" value="Save Changes" /><br/> <input type="submit" class="btn config_submitter" value="Save Changes" /><br/>

View file

@ -154,6 +154,7 @@
<tr><td class="showLegend">Flat Folders: </td><td><img src="$sbRoot/images/#if $show.flatten_folders == 1 or $sickbeard.NAMING_FORCE_FOLDERS then "yes16.png\" alt=\"Y" else "no16.png\" alt=\"N"#" width="16" height="16" /></td></tr> <tr><td class="showLegend">Flat Folders: </td><td><img src="$sbRoot/images/#if $show.flatten_folders == 1 or $sickbeard.NAMING_FORCE_FOLDERS then "yes16.png\" alt=\"Y" else "no16.png\" alt=\"N"#" width="16" height="16" /></td></tr>
<tr><td class="showLegend">Paused: </td><td><img src="$sbRoot/images/#if int($show.paused) == 1 then "yes16.png\" alt=\"Y" else "no16.png\" alt=\"N"#" width="16" height="16" /></td></tr> <tr><td class="showLegend">Paused: </td><td><img src="$sbRoot/images/#if int($show.paused) == 1 then "yes16.png\" alt=\"Y" else "no16.png\" alt=\"N"#" width="16" height="16" /></td></tr>
<tr><td class="showLegend">Air-by-Date: </td><td><img src="$sbRoot/images/#if int($show.air_by_date) == 1 then "yes16.png\" alt=\"Y" else "no16.png\" alt=\"N"#" width="16" height="16" /></td></tr> <tr><td class="showLegend">Air-by-Date: </td><td><img src="$sbRoot/images/#if int($show.air_by_date) == 1 then "yes16.png\" alt=\"Y" else "no16.png\" alt=\"N"#" width="16" height="16" /></td></tr>
<tr><td class="showLegend">Sports: </td><td><img src="$sbRoot/images/#if int($show.sports) == 1 then "yes16.png\" alt=\"Y" else "no16.png\" alt=\"N"#" width="16" height="16" /></td></tr>
<tr><td class="showLegend">DVD Order: </td><td><img src="$sbRoot/images/#if int($show.dvdorder) == 1 then "yes16.png\" alt=\"Y" else "no16.png\" alt=\"N"#" width="16" height="16" /></td></tr> <tr><td class="showLegend">DVD Order: </td><td><img src="$sbRoot/images/#if int($show.dvdorder) == 1 then "yes16.png\" alt=\"Y" else "no16.png\" alt=\"N"#" width="16" height="16" /></td></tr>
#if $bestQualities #if $bestQualities
<tr><td class="showLegend">Archive First Match: </td><td><img src="$sbRoot/images/#if int($show.archive_firstmatch) == 1 then "yes16.png\" alt=\"Y" else "no16.png\" alt=\"N"#" width="16" height="16" /></td></tr> <tr><td class="showLegend">Archive First Match: </td><td><img src="$sbRoot/images/#if int($show.archive_firstmatch) == 1 then "yes16.png\" alt=\"Y" else "no16.png\" alt=\"N"#" width="16" height="16" /></td></tr>
@ -239,7 +240,7 @@
<td align="center"><img src="$sbRoot/images/#if $epResult["hastbn"] == 1 then "tbn.gif\" alt=\"Y" else "tbn-no.gif\" alt=\"N"#" width="23" height="11" /></td> <td align="center"><img src="$sbRoot/images/#if $epResult["hastbn"] == 1 then "tbn.gif\" alt=\"Y" else "tbn-no.gif\" alt=\"N"#" width="23" height="11" /></td>
<td align="center">$epResult["episode"]</td> <td align="center">$epResult["episode"]</td>
<td align="center"> <td align="center">
#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: #if (epResult["season"], epResult["episode"]) in $xem_numbering:
#set ($dfltSeas, $dfltEpis) = $xem_numbering[(epResult["season"], epResult["episode"])] #set ($dfltSeas, $dfltEpis) = $xem_numbering[(epResult["season"], epResult["episode"])]
#else #else

View file

@ -108,6 +108,10 @@ This <b>DOES NOT</b> allow Sick Beard to download non-english TV episodes!<br />
<input type="checkbox" name="air_by_date" #if $show.air_by_date == 1 then "checked=\"checked\"" else ""# /><br /> <input type="checkbox" name="air_by_date" #if $show.air_by_date == 1 then "checked=\"checked\"" else ""# /><br />
(check this if the show is released as Show.03.02.2010 rather than Show.S02E03) (check this if the show is released as Show.03.02.2010 rather than Show.S02E03)
<br /><br /> <br /><br />
<b>Sports: </b>
<input type="checkbox" name="sports" #if $show.sports == 1 then "checked=\"checked\"" else ""# /><br />
(check this if the show is a sporting or MMA event)
<br /><br />
<b>DVD Order: </b> <b>DVD Order: </b>
<input type="checkbox" name="dvdorder" #if $show.dvdorder == 1 then "checked=\"checked\"" else ""# /><br/> <input type="checkbox" name="dvdorder" #if $show.dvdorder == 1 then "checked=\"checked\"" else ""# /><br/>
(check this if you wish to use the DVD order instead of the Airing order) (check this if you wish to use the DVD order instead of the Airing order)

View file

@ -23,6 +23,8 @@
<blockquote style="margin-bottom: 0; color: #3A87AD;"> <blockquote style="margin-bottom: 0; color: #3A87AD;">
#if int($show.air_by_date) == 1 and $sickbeard.NAMING_CUSTOM_ABD: #if int($show.air_by_date) == 1 and $sickbeard.NAMING_CUSTOM_ABD:
$sickbeard.NAMING_ABD_PATTERN $sickbeard.NAMING_ABD_PATTERN
#elif int($show.sports) == 1 and $sickbeard.NAMING_CUSTOM_SPORTS:
$sickbeard.NAMING_SPORTS_PATTERN
#else #else
$sickbeard.NAMING_PATTERN $sickbeard.NAMING_PATTERN
#end if #end if

View file

@ -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() { function setup_naming() {
// if it is a custom selection then show the text box // if it is a custom selection then show the text box
if ($('#name_presets :selected').val() == "Custom...") { if ($('#name_presets :selected').val() == "Custom...") {
@ -141,12 +182,23 @@ $(document).ready(function () {
fill_abd_examples(); 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 () { $('#unpack').change(function () {
if(this.checked) { if(this.checked) {
israr_supported(); israr_supported();
} else { } else {
$('#unpack').qtip('toggle', false); $('#unpack').qtip('toggle', false);
} }
}); });
$('#name_presets').change(function () { $('#name_presets').change(function () {
@ -161,6 +213,14 @@ $(document).ready(function () {
setup_abd_naming(); 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_multi_ep').change(fill_examples);
$('#naming_pattern').focusout(fill_examples); $('#naming_pattern').focusout(fill_examples);
$('#naming_pattern').keyup(function () { $('#naming_pattern').keyup(function () {
@ -176,12 +236,22 @@ $(document).ready(function () {
}, 500); }, 500);
}); });
$('#naming_sports_pattern').focusout(fill_examples);
$('#naming_sports_pattern').keyup(function () {
typewatch(function () {
fill_sports_examples();
}, 500);
});
$('#show_naming_key').click(function () { $('#show_naming_key').click(function () {
$('#naming_key').toggle(); $('#naming_key').toggle();
}); });
$('#show_naming_abd_key').click(function () { $('#show_naming_abd_key').click(function () {
$('#naming_abd_key').toggle(); $('#naming_abd_key').toggle();
}); });
$('#show_naming_sports_key').click(function () {
$('#naming_sports_key').toggle();
});
$('#do_custom').click(function () { $('#do_custom').click(function () {
$('#naming_pattern').val($('#name_presets :selected').attr('id')); $('#naming_pattern').val($('#name_presets :selected').attr('id'));
$('#naming_custom').show(); $('#naming_custom').show();
@ -189,6 +259,7 @@ $(document).ready(function () {
}); });
setup_naming(); setup_naming();
setup_abd_naming(); setup_abd_naming();
setup_sports_naming();
// -- start of metadata options div toggle code -- // -- start of metadata options div toggle code --
$('#metadataType').on('change keyup', function () { $('#metadataType').on('change keyup', function () {
@ -295,7 +366,7 @@ $(document).ready(function () {
position: { position: {
viewport: $(window), viewport: $(window),
at: 'top center', at: 'top center',
my: 'bottom center', my: 'bottom center'
}, },
style: { style: {
tip: { tip: {
@ -315,7 +386,7 @@ $(document).ready(function () {
position: { position: {
viewport: $(window), viewport: $(window),
at: 'center left', at: 'center left',
my: 'center right', my: 'center right'
}, },
style: { style: {
tip: { tip: {

View file

@ -151,6 +151,8 @@ NAMING_MULTI_EP = None
NAMING_PATTERN = None NAMING_PATTERN = None
NAMING_ABD_PATTERN = None NAMING_ABD_PATTERN = None
NAMING_CUSTOM_ABD = None NAMING_CUSTOM_ABD = None
NAMING_SPORTS_PATTERN = None
NAMING_CUSTOM_SPORTS = None
NAMING_FORCE_FOLDERS = False NAMING_FORCE_FOLDERS = False
NAMING_STRIP_YEAR = None NAMING_STRIP_YEAR = None
@ -480,7 +482,7 @@ def initialize(consoleLogging=True):
versionCheckScheduler, VERSION_NOTIFY, AUTO_UPDATE, PROCESS_AUTOMATICALLY, UNPACK, \ 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,\ 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, \ 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, \ RENAME_EPISODES, properFinderScheduler, PROVIDER_ORDER, autoPostProcesserScheduler, \
WOMBLE, OMGWTFNZBS, OMGWTFNZBS_USERNAME, OMGWTFNZBS_APIKEY, providerList, newznabProviderList, torrentRssProviderList, \ WOMBLE, OMGWTFNZBS, OMGWTFNZBS_USERNAME, OMGWTFNZBS_APIKEY, providerList, newznabProviderList, torrentRssProviderList, \
EXTRA_SCRIPTS, USE_TWITTER, TWITTER_USERNAME, TWITTER_PASSWORD, TWITTER_PREFIX, \ 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_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_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_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_MULTI_EP = check_setting_int(CFG, 'General', 'naming_multi_ep', 1)
NAMING_FORCE_FOLDERS = naming.check_force_season_folders() NAMING_FORCE_FOLDERS = naming.check_force_season_folders()
NAMING_STRIP_YEAR = bool(check_setting_int(CFG, 'General', 'naming_strip_year', 0)) 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_pattern'] = NAMING_PATTERN
new_config['General']['naming_custom_abd'] = int(NAMING_CUSTOM_ABD) new_config['General']['naming_custom_abd'] = int(NAMING_CUSTOM_ABD)
new_config['General']['naming_abd_pattern'] = NAMING_ABD_PATTERN 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']['naming_multi_ep'] = int(NAMING_MULTI_EP)
new_config['General']['launch_browser'] = int(LAUNCH_BROWSER) new_config['General']['launch_browser'] = int(LAUNCH_BROWSER)
new_config['General']['update_shows_on_start'] = int(UPDATE_SHOWS_ON_START) new_config['General']['update_shows_on_start'] = int(UPDATE_SHOWS_ON_START)

View file

@ -27,8 +27,7 @@ from sickbeard import encodingKludge as ek
from sickbeard.name_parser.parser import NameParser, InvalidNameException from sickbeard.name_parser.parser import NameParser, InvalidNameException
MIN_DB_VERSION = 9 # oldest db version we support migrating from MIN_DB_VERSION = 9 # oldest db version we support migrating from
MAX_DB_VERSION = 29 MAX_DB_VERSION = 30
class MainSanityCheck(db.DBSanityCheck): class MainSanityCheck(db.DBSanityCheck):
def check(self): def check(self):
@ -657,7 +656,6 @@ class ConvertInfoToIndexerScheme(ConvertIMDBInfoToIndexerScheme):
self.incDBVersion() self.incDBVersion()
class AddArchiveFirstMatchOption(ConvertInfoToIndexerScheme): class AddArchiveFirstMatchOption(ConvertInfoToIndexerScheme):
def test(self): def test(self):
return self.checkDBVersion() >= 26 return self.checkDBVersion() >= 26
@ -671,7 +669,6 @@ class AddArchiveFirstMatchOption(ConvertInfoToIndexerScheme):
self.incDBVersion() self.incDBVersion()
class AddSceneNumbering(AddArchiveFirstMatchOption): class AddSceneNumbering(AddArchiveFirstMatchOption):
def test(self): def test(self):
return self.checkDBVersion() >= 27 return self.checkDBVersion() >= 27
@ -726,3 +723,26 @@ class AddRequireAndIgnoreWords(ConvertIndexerToInteger):
self.addColumn("tv_shows", "rls_ignore_words", "TEXT", "") self.addColumn("tv_shows", "rls_ignore_words", "TEXT", "")
self.incDBVersion() 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()

View file

@ -974,14 +974,6 @@ def get_show_by_name(name, showList, useIndexer=False):
return None 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): def is_hidden_folder(folder):
""" """
Returns True if folder is hidden. Returns True if folder is hidden.

View file

@ -98,7 +98,7 @@ class SBRotatingLogHandler(object):
# define a Handler which writes INFO messages or higher to the sys.stderr # define a Handler which writes INFO messages or higher to the sys.stderr
console = logging.StreamHandler() console = logging.StreamHandler()
console.setLevel(logging.INFO) console.setLevel(logging.DEBUG)
# set a format which is simpler for console use # set a format which is simpler for console use
console.setFormatter(DispatchingFormatter( console.setFormatter(DispatchingFormatter(

View file

@ -33,11 +33,16 @@ from time import strptime
class NameParser(object): 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.file_name = file_name
self.regexMode = regexMode
self.compiled_regexes = [] self.compiled_regexes = []
self._compile_regexes() self._compile_regexes(regexMode)
def clean_series_name(self, series_name): def clean_series_name(self, series_name):
"""Cleans up series name by removing any . and _ """Cleans up series name by removing any . and _
@ -63,8 +68,24 @@ class NameParser(object):
series_name = re.sub("^\[.*\]", "", series_name) series_name = re.sub("^\[.*\]", "", series_name)
return series_name.strip() return series_name.strip()
def _compile_regexes(self): def _compile_regexes(self, regexMode):
for (cur_pattern_name, cur_pattern) in regexes.ep_regexes: 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: try:
cur_regex = re.compile(cur_pattern, re.VERBOSE | re.IGNORECASE) cur_regex = re.compile(cur_pattern, re.VERBOSE | re.IGNORECASE)
except re.error, errormsg: except re.error, errormsg:
@ -107,18 +128,22 @@ class NameParser(object):
result.episode_numbers = [ep_num] result.episode_numbers = [ep_num]
if 'air_year' in named_groups and 'air_month' in named_groups and 'air_day' in named_groups: 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: if 'sports' in cur_regex_name:
year = match.group('air_year') year = int(match.group('air_year'))
month = strptime(match.group('air_month')[:3], '%b').tm_mon month = match.group('air_month')
day = re.sub("(st|nd|rd|th)", "", match.group('air_day')) day = int(re.sub("(st|nd|rd|th)", "", match.group('air_day')))
else: else:
year = int(match.group('air_year')) year = int(match.group('air_year'))
month = int(match.group('air_month')) month = int(match.group('air_month'))
day = int(match.group('air_day')) day = int(match.group('air_day'))
try: try:
dtStr = '%s-%s-%s' % (year, month, day) if 'sports' in cur_regex_name:
result.air_date = datetime.datetime.strptime(dtStr, "%Y-%m-%d").date() 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: except ValueError, e:
raise InvalidNameException(e.message) raise InvalidNameException(e.message)
@ -220,6 +245,7 @@ class NameParser(object):
# build the ParseResult object # build the ParseResult object
final_result.air_date = self._combine_results(file_name_result, dir_name_result, 'air_date') 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: if not final_result.air_date:
final_result.season_number = self._combine_results(file_name_result, dir_name_result, 'season_number') 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 return final_result
@classmethod @classmethod
def series_name_to_indexer_id(cls, series_name, check_scene_exceptions=True, check_database=True, def series_name_to_indexer_id(cls, series_name):
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
"""
# do a scene reverse-lookup to get a list of all possible names # do a scene reverse-lookup to get a list of all possible names
name_list = sickbeard.show_name_helpers.sceneToNormalShowNames(series_name) name_list = sickbeard.show_name_helpers.sceneToNormalShowNames(series_name)
# for each possible interpretation of that scene name # for each possible interpretation of that scene name
if check_scene_exceptions: for cur_name in name_list:
for cur_name in name_list: logger.log(u"Checking scene exceptions and database for a match on " + cur_name, logger.DEBUG)
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)
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 if scene_id:
return scene_id
# see if we can find the name directly in the DB, if so use it elif db_result:
if check_database: return db_result[1]
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
class ParseResult(object): class ParseResult(object):
def __init__(self, def __init__(self,
@ -329,7 +303,8 @@ class ParseResult(object):
episode_numbers=None, episode_numbers=None,
extra_info=None, extra_info=None,
release_group=None, release_group=None,
air_date=None air_date=None,
sports_date=None
): ):
self.original_name = original_name self.original_name = original_name
@ -345,6 +320,7 @@ class ParseResult(object):
self.release_group = release_group self.release_group = release_group
self.air_date = air_date self.air_date = air_date
self.sports_date = sports_date
self.which_regex = None self.which_regex = None
@ -364,6 +340,8 @@ class ParseResult(object):
return False return False
if self.air_date != other.air_date: if self.air_date != other.air_date:
return False return False
if self.sports_date != other.sports_date:
return False
return True return True
@ -380,6 +358,8 @@ class ParseResult(object):
if self.air_by_date: if self.air_by_date:
to_return += str(self.air_date) to_return += str(self.air_date)
if self.sports:
to_return += str(self.sports_date)
if self.extra_info: if self.extra_info:
to_return += ' - ' + self.extra_info to_return += ' - ' + self.extra_info
@ -387,26 +367,33 @@ class ParseResult(object):
to_return += ' (' + self.release_group + ')' to_return += ' (' + self.release_group + ')'
to_return += ' [ABD: ' + str(self.air_by_date) + ']' 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') return to_return.encode('utf-8')
def _is_air_by_date(self): 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 True
return False return False
air_by_date = property(_is_air_by_date) 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): def fix_scene_numbering(self):
""" """
The changes the parsed result (which is assumed to be scene numbering) to The changes the parsed result (which is assumed to be scene numbering) to
tvdb numbering, if necessary. 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 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 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_episode_numbers = []
new_season_numbers = [] new_season_numbers = []

View file

@ -96,19 +96,6 @@ ep_regexes = [
-(?P<release_group>[^- ]+))?)?$ # Group -(?P<release_group>[^- ]+))?)?$ # Group
'''), '''),
('scene_sports_date_format',
# Show.Name.2010.Nov.23rd.Source.Quality.Etc-Group
# Show Name - 2010-Nov-23rd - Ep Name
'''
^(?P<series_name>.*?(UEFA|MLB|ESPN|WWE|MMA|UFC|TNA|EPL|NASCAR|NBA|NFL|NHL|NRL|PGA|SUPER LEAGUE|FORMULA|FIFA|NETBALL|MOTOGP).*?)[. _-]+
(?P<parts>\d{1,3}\d{1,3}.*?)[. _-]+ # Parts
(?P<air_day>\d{1,2}[a-zA-Z]{2})[. _-]+ # 23rd and seperator
(?P<air_month>[a-zA-Z]{3,})[. _-]+ # Nov and seperator
(?P<air_year>\d{4})[. _-]+ # 2010
(?P<extra_info>.*?(?<![. _-])(?<!WEB))[. _-]+ # Make sure this is really the release group
(?P<release_group>.*?)$ # Group
'''),
('stupid', ('stupid',
# tpz-abc102 # tpz-abc102
''' '''
@ -198,3 +185,30 @@ ep_regexes = [
''' '''
), ),
] ]
sports_regexs = [
('sports_event',
# Show.Name.123.Event.Nov.23rd.2010.Source.Quality.Etc-Group
'''
^(?P<series_name>.*?(UEFA|MLB|ESPN|WWE|MMA|UFC|TNA|EPL|NASCAR|NBA|NFL|NHL|NRL|PGA|SUPER LEAGUE|FORMULA|FIFA|NETBALL|MOTOGP).*?)[. _-]+
(?P<parts>\d{1,3}\d{1,3}.*?)[. _-]+
(?P<event>.*?)[. _-]+
(?P<air_day>\d{1,2}[a-zA-Z]{2})[. _-]+
(?P<air_month>[a-zA-Z]{3,})[. _-]+
(?P<air_year>\d{4})[. _-]+
(?P<extra_info>.*?(?<![. _-])(?<!WEB))[. _-]+
(?P<release_group>.*?)$
'''),
('sports_event_without_parts',
# Show.Name.Event.Nov.23rd.2010.Source.Quality.Etc-Group
'''
^(?P<series_name>.*?(UEFA|MLB|ESPN|WWE|MMA|UFC|TNA|EPL|NASCAR|NBA|NFL|NHL|NRL|PGA|SUPER LEAGUE|FORMULA|FIFA|NETBALL|MOTOGP).*?)[. _-]+
(?P<event>.*?)[. _-]+
(?P<air_day>\d{1,2}[a-zA-Z]{2})[. _-]+
(?P<air_month>[a-zA-Z]{3,})[. _-]+
(?P<air_year>\d{4})[. _-]+
(?P<extra_info>.*?(?<![. _-])(?<!WEB))[. _-]+
(?P<release_group>.*?)$
'''),
]

View file

@ -40,13 +40,17 @@ name_abd_presets = ('%SN - %A-D - %EN',
'%Y/%0M/%S.N.%A.D.%E.N-%RG' '%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(): class TVShow():
def __init__(self): def __init__(self):
self.name = "Show Name" self.name = "Show Name"
self.genre = "Comedy" self.genre = "Comedy"
self.air_by_date = 0 self.air_by_date = 0
self.sports = 0
class TVEpisode(tv.TVEpisode): class TVEpisode(tv.TVEpisode):
def __init__(self, season, episode, name): def __init__(self, season, episode, name):
@ -114,11 +118,28 @@ def check_valid_abd_naming(pattern=None):
return valid 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): Returns true if the naming is valid, false if not.
ep = _generate_sample_ep(multi, abd) """
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_name = ep.formatted_filename(pattern, multi) + '.ext'
new_path = ep.formatted_dir(pattern, multi) 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: if result.air_date != ep.airdate:
logger.log(u"Air date incorrect in parsed episode, pattern isn't valid", logger.DEBUG) logger.log(u"Air date incorrect in parsed episode, pattern isn't valid", logger.DEBUG)
return False 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: else:
if result.season_number != ep.season: if result.season_number != ep.season:
logger.log(u"Season incorrect in parsed episode, pattern isn't valid", logger.DEBUG) 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 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 # make a fake episode object
ep = TVEpisode(2, 3, "Ep Name") ep = TVEpisode(2, 3, "Ep Name")
ep._status = Quality.compositeStatus(DOWNLOADED, Quality.HDTV) ep._status = Quality.compositeStatus(DOWNLOADED, Quality.HDTV)
ep._airdate = datetime.date(2011, 3, 9) ep._airdate = datetime.date(2011, 3, 9)
if abd: if abd:
ep._release_name = 'Show.Name.2011.03.09.HDTV.XviD-RLSGROUP' 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: else:
ep._release_name = 'Show.Name.S02E03.HDTV.XviD-RLSGROUP' ep._release_name = 'Show.Name.S02E03.HDTV.XviD-RLSGROUP'
@ -182,7 +210,7 @@ def _generate_sample_ep(multi=None, abd=False):
return ep return ep
def test_name(pattern, multi=None, abd=False): def test_name(pattern, multi=None, abd=False, sports=False):
ep = _generate_sample_ep(multi, abd) ep = _generate_sample_ep(multi, abd, sports)
return {'name': ep.formatted_filename(pattern, multi), 'dir': ep.formatted_dir(pattern, multi)} return {'name': ep.formatted_filename(pattern, multi), 'dir': ep.formatted_dir(pattern, multi)}

View file

@ -464,6 +464,9 @@ class PostProcessor(object):
if parse_result.air_by_date: if parse_result.air_by_date:
season = -1 season = -1
episodes = [parse_result.air_date] episodes = [parse_result.air_date]
elif parse_result.sports:
season = -1
episodes = [parse_result.sports_date]
else: else:
season = parse_result.season_number season = parse_result.season_number
episodes = parse_result.episode_numbers 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 # for air-by-date shows we need to look up the season/episode from tvdb
if season == -1 and indexer_id and episodes: 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) logger.DEBUG)
# try to get language set for this show # try to get language set for this show

View file

@ -115,6 +115,9 @@ class ProperFinder():
if parse_result.air_by_date: if parse_result.air_by_date:
curProper.season = -1 curProper.season = -1
curProper.episode = parse_result.air_date curProper.episode = parse_result.air_date
elif parse_result.sports:
curProper.season = -1
curProper.episode = parse_result.sports_date
else: else:
curProper.season = parse_result.season_number if parse_result.season_number != None else 1 curProper.season = parse_result.season_number if parse_result.season_number != None else 1
curProper.episode = parse_result.episode_numbers[0] curProper.episode = parse_result.episode_numbers[0]

View file

@ -191,7 +191,7 @@ class BTNProvider(generic.TorrentProvider):
return (title, url) 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: if not show:
return [] return []
@ -215,15 +215,14 @@ class BTNProvider(generic.TorrentProvider):
# Search for entire seasons: no need to do special things for air by date shows # Search for entire seasons: no need to do special things for air by date shows
whole_season_params['category'] = 'Season' whole_season_params['category'] = 'Season'
whole_season_params['name'] = 'Season ' + str(season) whole_season_params['name'] = 'Season ' + str(season)
search_params.append(whole_season_params) search_params.append(whole_season_params)
# Search for episodes in the season # 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 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: if not episode:
return [{}] return [{}]
@ -237,13 +236,18 @@ class BTNProvider(generic.TorrentProvider):
else: else:
search_params['series'] = sanitizeSceneName(show.name) search_params['series'] = sanitizeSceneName(show.name)
if abd: if show.air_by_date:
date_str = str(episode) date_str = str(episode)
# BTN uses dots in dates, we just search for the date since that # BTN uses dots in dates, we just search for the date since that
# combined with the series identifier should result in just one episode # combined with the series identifier should result in just one episode
search_params['name'] = date_str.replace('-', '.') 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: else:
# Do a general name search for the episode, formatted like SXXEYY # Do a general name search for the episode, formatted like SXXEYY
search_params['name'] = "S%02dE%02d" % (season, episode) search_params['name'] = "S%02dE%02d" % (season, episode)

View file

@ -52,7 +52,7 @@ class DTTProvider(generic.TorrentProvider):
def _dtt_show_id(self, show_name): def _dtt_show_id(self, show_name):
return sanitizeSceneName(show_name).replace('.', '-').lower() 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 = [] search_string = []
for show_name in set(show_name_helpers.allPossibleShowNames(show)): for show_name in set(show_name_helpers.allPossibleShowNames(show)):
@ -61,8 +61,8 @@ class DTTProvider(generic.TorrentProvider):
return search_string return search_string
def _get_episode_search_strings(self, show, season, episode, abd=False): def _get_episode_search_strings(self, show, season, episode, add_string=''):
return self._get_season_search_strings(show, season, episode, abd) return self._get_season_search_strings(show, season, episode)
def _doSearch(self, search_params, show=None, age=None): def _doSearch(self, search_params, show=None, age=None):

View file

@ -61,8 +61,8 @@ class EZRSSProvider(generic.TorrentProvider):
results = {} results = {}
if show.air_by_date: if show.air_by_date or show.sports:
logger.log(self.name + u" doesn't support air-by-date backlog because of limitations on their RSS search.", logger.log(self.name + u" doesn't support air-by-date or sports backloging because of limitations on their RSS search.",
logger.WARNING) logger.WARNING)
return results return results
@ -70,7 +70,7 @@ class EZRSSProvider(generic.TorrentProvider):
return results return results
def _get_season_search_strings(self, show, season, episode, abd=False): def _get_season_search_strings(self, show, season, episode):
params = {} params = {}
@ -81,11 +81,11 @@ class EZRSSProvider(generic.TorrentProvider):
params['season'] = season 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] 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 = {} params = {}
@ -94,7 +94,9 @@ class EZRSSProvider(generic.TorrentProvider):
params['show_name'] = helpers.sanitizeSceneName(show.name, ezrss=True).replace('.', ' ').encode('utf-8') 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) params['date'] = str(episode)
else: else:
params['season'] = season params['season'] = season

View file

@ -30,10 +30,11 @@ import itertools
import operator import operator
import collections import collections
import urlparse import urlparse
from lib.feedparser import feedparser
import sickbeard import sickbeard
from lib import requests
from lib.feedparser import feedparser
from sickbeard import helpers, classes, logger, db 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.common import Quality, MULTI_EP_RESULT, SEASON_RESULT #, SEED_POLICY_TIME, SEED_POLICY_RATIO
from sickbeard import tvcache from sickbeard import tvcache
@ -54,11 +55,16 @@ class GenericProvider:
self.providerType = None self.providerType = None
self.name = name self.name = name
self.url = '' self.url = ''
self.session = None
self.supportsBacklog = False self.supportsBacklog = False
self.cache = tvcache.TVCache(self) 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): def getID(self):
return GenericProvider.makeID(self.name) return GenericProvider.makeID(self.name)
@ -214,10 +220,10 @@ class GenericProvider:
def _doSearch(self, search_params, show=None, age=None): def _doSearch(self, search_params, show=None, age=None):
return [] return []
def _get_season_search_strings(self, show, season, episode, abd=False): def _get_season_search_strings(self, show, season, episode):
return [] return []
def _get_episode_search_strings(self, show, season, episode, abd=False): def _get_episode_search_strings(self, show, season, episode, add_string=''):
return [] return []
def _get_title_and_url(self, item): def _get_title_and_url(self, item):
@ -245,11 +251,15 @@ class GenericProvider:
self._checkAuth() self._checkAuth()
regexMethod = 0
if show.sports:
regexMethod = 1
for ep_obj in ep_objs: for ep_obj in ep_objs:
# get scene season/episode info # get scene season/episode info
scene_season = ep_obj.scene_season scene_season = ep_obj.scene_season
scene_episode = ep_obj.scene_episode scene_episode = ep_obj.scene_episode
if show.air_by_date: if show.air_by_date or show.sports:
scene_episode = ep_obj.airdate scene_episode = ep_obj.airdate
if not seasonSearch: if not seasonSearch:
@ -268,10 +278,10 @@ class GenericProvider:
return results return results
if seasonSearch: 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) itemList += self._doSearch(curString, show=show)
else: 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) itemList += self._doSearch(curString, show=show)
for item in itemList: for item in itemList:
@ -282,16 +292,16 @@ class GenericProvider:
# parse the file name # parse the file name
try: try:
myParser = NameParser(False) myParser = NameParser(False, regexMethod)
parse_result = myParser.parse(title, True) parse_result = myParser.parse(title, True)
except InvalidNameException: except InvalidNameException:
logger.log(u"Unable to parse the filename " + title + " into a valid episode", logger.WARNING) logger.log(u"Unable to parse the filename " + title + " into a valid episode", logger.WARNING)
continue 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 # this check is meaningless for non-season searches
if (parse_result.season_number != None and parse_result.season_number != season) or ( 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( logger.log(u"The result " + title + " doesn't seem to be a valid episode for season " + str(
season) + ", ignoring", logger.DEBUG) season) + ", ignoring", logger.DEBUG)
continue continue
@ -301,15 +311,25 @@ class GenericProvider:
actual_episodes = parse_result.episode_numbers actual_episodes = parse_result.episode_numbers
else: else:
if not parse_result.air_by_date: if show.air_by_date and not parse_result.air_by_date:
logger.log( logger.log(
u"This is supposed to be an air-by-date search but the result " + title + " didn't parse as one, skipping it", u"This is supposed to be an air-by-date search but the result " + title + " didn't parse as one, skipping it",
logger.DEBUG) logger.DEBUG)
continue 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() myDB = db.DBConnection()
sql_results = myDB.select("SELECT season, episode FROM tv_episodes WHERE showid = ? AND airdate = ?", if parse_result.air_by_date:
[show.indexerid, parse_result.air_date.toordinal()]) 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: if len(sql_results) != 1:
logger.log( logger.log(

View file

@ -122,7 +122,7 @@ class HDBitsProvider(generic.TorrentProvider):
logger.log(u"Unable to parse the filename " + title + " into a valid episode", logger.WARNING) logger.log(u"Unable to parse the filename " + title + " into a valid episode", logger.WARNING)
continue continue
if episode.show.air_by_date: if episode.show.air_by_date or episode.sports:
if parse_result.air_date != episode.airdate: if parse_result.air_date != episode.airdate:
logger.log(u"Episode " + title + " didn't air on " + str(episode.airdate) + ", skipping it", logger.log(u"Episode " + title + " didn't air on " + str(episode.airdate) + ", skipping it",
logger.DEBUG) logger.DEBUG)

View file

@ -61,8 +61,6 @@ class HDTorrentsProvider(generic.TorrentProvider):
self.categories = "&category[]=59&category[]=60&category[]=30&category[]=38" self.categories = "&category[]=59&category[]=60&category[]=30&category[]=38"
self.session = requests.Session()
self.cookies = None self.cookies = None
def isEnabled(self): def isEnabled(self):
@ -112,7 +110,7 @@ class HDTorrentsProvider(generic.TorrentProvider):
return True 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: if not show:
return [] return []
@ -121,21 +119,27 @@ class HDTorrentsProvider(generic.TorrentProvider):
ep_string = show_name + ' S%02d' % int(season) #1) ShowName SXX ep_string = show_name + ' S%02d' % int(season) #1) ShowName SXX
search_string['Season'].append(ep_string) 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] 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': []} search_string = {'Episode': []}
if not episode: if not episode:
return [] return []
if abd: if show.air_by_date:
for show_name in set(show_name_helpers.allPossibleShowNames(show)): for show_name in set(show_name_helpers.allPossibleShowNames(show)):
ep_string = sanitizeSceneName(show_name) + ' ' + \ ep_string = sanitizeSceneName(show_name) + ' ' + \
str(episode).replace('-', '|') + '|' + \ 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) search_string['Episode'].append(ep_string)
else: else:
for show_name in set(show_name_helpers.allPossibleShowNames(show)): for show_name in set(show_name_helpers.allPossibleShowNames(show)):
@ -273,7 +277,6 @@ class HDTorrentsProvider(generic.TorrentProvider):
if not headers: if not headers:
headers = [] headers = []
try: try:
parsed = list(urlparse.urlparse(url)) parsed = list(urlparse.urlparse(url))
parsed[2] = re.sub("/{2,}", "/", parsed[2]) # replace two or more / with one 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: for sqlShow in sqlResults:
curShow = helpers.findCertainShow(sickbeard.showList, int(sqlShow["showid"])) curShow = helpers.findCertainShow(sickbeard.showList, int(sqlShow["showid"]))
curEp = curShow.getEpisode(int(sqlShow["season"]), int(sqlShow["episode"])) 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): for item in self._doSearch(searchString[0], show=curShow):
title, url = self._get_title_and_url(item) title, url = self._get_title_and_url(item)

View file

@ -37,6 +37,7 @@ from lib.requests import exceptions
from bs4 import BeautifulSoup from bs4 import BeautifulSoup
from lib.unidecode import unidecode from lib.unidecode import unidecode
from sickbeard.helpers import sanitizeSceneName from sickbeard.helpers import sanitizeSceneName
from sickbeard.show_name_helpers import allPossibleShowNames
class IPTorrentsProvider(generic.TorrentProvider): class IPTorrentsProvider(generic.TorrentProvider):
@ -55,8 +56,6 @@ class IPTorrentsProvider(generic.TorrentProvider):
self.url = self.urls['base_url'] 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' self.categorie = 'l73=1&l78=1&l66=1&l65=1&l79=1&l5=1&l4=1'
def isEnabled(self): def isEnabled(self):
@ -93,7 +92,7 @@ class IPTorrentsProvider(generic.TorrentProvider):
return True 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: if not show:
return [] return []
@ -102,22 +101,28 @@ class IPTorrentsProvider(generic.TorrentProvider):
ep_string = show_name + ' S%02d' % int(season) #1) ShowName SXX ep_string = show_name + ' S%02d' % int(season) #1) ShowName SXX
search_string['Season'].append(ep_string) 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] 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': []} search_string = {'Episode': []}
if not episode: if not episode:
return [] return []
if abd: if show.air_by_date:
for show_name in set(show_name_helpers.allPossibleShowNames(show)): for show_name in set(allPossibleShowNames(show)):
ep_string = sanitizeSceneName(show_name) + ' ' + \ ep_string = sanitizeSceneName(show_name) + ' ' + \
str(episode).replace('-', '|') + '|' + \ 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) search_string['Episode'].append(ep_string)
else: else:
for show_name in set(show_name_helpers.allPossibleShowNames(show)): for show_name in set(show_name_helpers.allPossibleShowNames(show)):
@ -254,7 +259,7 @@ class IPTorrentsProvider(generic.TorrentProvider):
for sqlShow in sqlResults: for sqlShow in sqlResults:
curShow = helpers.findCertainShow(sickbeard.showList, int(sqlShow["showid"])) curShow = helpers.findCertainShow(sickbeard.showList, int(sqlShow["showid"]))
curEp = curShow.getEpisode(int(sqlShow["season"]), int(sqlShow["episode"])) 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): for item in self._doSearch(searchString[0], show=curShow):
title, url = self._get_title_and_url(item) title, url = self._get_title_and_url(item)

View file

@ -61,8 +61,6 @@ class KATProvider(generic.TorrentProvider):
self.searchurl = self.url + 'usearch/%s/?field=seeders&sorder=desc' #order by seed self.searchurl = self.url + 'usearch/%s/?field=seeders&sorder=desc' #order by seed
self.session = requests.Session()
def isEnabled(self): def isEnabled(self):
return sickbeard.KAT return sickbeard.KAT
@ -166,7 +164,7 @@ class KATProvider(generic.TorrentProvider):
logger.log(u"Failed parsing " + self.name + " Traceback: " + traceback.format_exc(), logger.ERROR) 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': []} search_string = {'Season': [], 'Episode': []}
if not show: 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 ep_string = show_name + ' Season ' + str(season) + ' -Ep*' + ' category:tv' #2) ShowName Season X
search_string['Season'].append(ep_string) 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': []} search_string = {'Episode': []}
if not show: if not show:
@ -191,12 +189,18 @@ class KATProvider(generic.TorrentProvider):
self.show = show self.show = show
if abd: if show.air_by_date:
for show_name in set(allPossibleShowNames(show)): for show_name in set(allPossibleShowNames(show)):
ep_string = sanitizeSceneName(show_name) + ' ' + \ ep_string = sanitizeSceneName(show_name) + ' ' + \
str(episode).replace('-','|') + '|' + \ 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) search_string['Episode'].append(ep_string)
else: else:
for show_name in set(allPossibleShowNames(show)): for show_name in set(allPossibleShowNames(show)):
@ -388,7 +392,13 @@ class KATProvider(generic.TorrentProvider):
for sqlShow in sqlResults: for sqlShow in sqlResults:
curShow = helpers.findCertainShow(sickbeard.showList, int(sqlShow["showid"])) curShow = helpers.findCertainShow(sickbeard.showList, int(sqlShow["showid"]))
curEp = curShow.getEpisode(int(sqlShow["season"]), int(sqlShow["episode"])) 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): for item in self._doSearch(searchString[0], show=curShow):
title, url = self._get_title_and_url(item) title, url = self._get_title_and_url(item)

View file

@ -251,11 +251,11 @@ class NewzbinProvider(generic.NZBProvider):
return data return data
def _get_season_search_strings(self, show, season, episode, abd=False): def _get_season_search_strings(self, show, season, episode):
return ['^' + x for x in show_name_helpers.makeSceneSeasonSearchString(show, season, episode, abd)] return ['^' + x for x in show_name_helpers.makeSceneSeasonSearchString(show, season, episode)]
def _get_episode_search_strings(self, show, season, episode, abd=False): def _get_episode_search_strings(self, show, season, episode, add_string=''):
return ['^' + x for x in show_name_helpers.makeSceneSearchString(show, season, episode, abd)] return ['^' + x for x in show_name_helpers.makeSceneSearchString(show, season, episode)]
def _doSearch(self, searchStr, show=None, age=None): def _doSearch(self, searchStr, show=None, age=None):

View file

@ -80,7 +80,7 @@ class NewznabProvider(generic.NZBProvider):
def isEnabled(self): def isEnabled(self):
return self.enabled 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: if not show:
return [{}] return [{}]
@ -100,13 +100,13 @@ class NewznabProvider(generic.NZBProvider):
cur_params['season'] = str(season) cur_params['season'] = str(season)
# episode # 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) to_return.append(cur_params)
return to_return 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 = {} params = {}
@ -116,7 +116,12 @@ class NewznabProvider(generic.NZBProvider):
# search # search
params['q'] = helpers.sanitizeSceneName(show.name) 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) date_str = str(episode)
params['season'] = date_str.partition('-')[0] params['season'] = date_str.partition('-')[0]

View file

@ -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.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.last_login_check = None
self.login_opener = None self.login_opener = None
def isEnabled(self): def isEnabled(self):
@ -130,7 +131,7 @@ class NextGenProvider(generic.TorrentProvider):
logger.log(u'Failed to login:' + str(error), logger.ERROR) logger.log(u'Failed to login:' + str(error), logger.ERROR)
return False 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: if not show:
return [] return []
@ -140,22 +141,28 @@ class NextGenProvider(generic.TorrentProvider):
ep_string = show_name + ' S%02d' % int(season) #1) ShowName SXX ep_string = show_name + ' S%02d' % int(season) #1) ShowName SXX
search_string['Season'].append(ep_string) 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] 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': []} search_string = {'Episode': []}
if not episode: if not episode:
return [] return []
if abd: if show.air_by_date:
for show_name in set(show_name_helpers.allPossibleShowNames(show)): for show_name in set(show_name_helpers.allPossibleShowNames(show)):
ep_string = sanitizeSceneName(show_name) + ' ' + \ ep_string = sanitizeSceneName(show_name) + ' ' + \
str(episode).replace('-', '|') + '|' + \ 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) search_string['Episode'].append(ep_string)
else: else:
for show_name in set(show_name_helpers.allPossibleShowNames(show)): for show_name in set(show_name_helpers.allPossibleShowNames(show)):
@ -301,7 +308,7 @@ class NextGenProvider(generic.TorrentProvider):
for sqlShow in sqlResults: for sqlShow in sqlResults:
curShow = helpers.findCertainShow(sickbeard.showList, int(sqlShow["showid"])) curShow = helpers.findCertainShow(sickbeard.showList, int(sqlShow["showid"]))
curEp = curShow.getEpisode(int(sqlShow["season"]), int(sqlShow["episode"])) 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): for item in self._doSearch(searchString[0], show=curShow):
title, url = self._get_title_and_url(item) title, url = self._get_title_and_url(item)

View file

@ -58,13 +58,13 @@ class NyaaProvider(generic.TorrentProvider):
results = generic.TorrentProvider.getSearchResults(self, show, season, ep_objs, seasonSearch, manualSearch) results = generic.TorrentProvider.getSearchResults(self, show, season, ep_objs, seasonSearch, manualSearch)
return results return results
def _get_season_search_strings(self, show, season, episode, abd=False): def _get_season_search_strings(self, show, season, episode):
names = [] names = []
names.extend(show_name_helpers.makeSceneShowSearchStrings(show)) names.extend(show_name_helpers.makeSceneShowSearchStrings(show))
return names return names
def _get_episode_search_strings(self, show, season, episode, abd=False): def _get_episode_search_strings(self, show, season, episode, add_string=''):
return self._get_season_search_strings(show, season, episode, abd) return self._get_season_search_strings(show, season, episode)
def _doSearch(self, search_string, show=None, age=None): def _doSearch(self, search_string, show=None, age=None):

View file

@ -53,11 +53,11 @@ class NZBsProvider(generic.NZBProvider):
if sickbeard.NZBS_UID in (None, "") or sickbeard.NZBS_HASH in (None, ""): if sickbeard.NZBS_UID in (None, "") or sickbeard.NZBS_HASH in (None, ""):
raise exceptions.AuthException("NZBs.org authentication details are empty, check your config") raise exceptions.AuthException("NZBs.org authentication details are empty, check your config")
def _get_season_search_strings(self, show, season, episode, abd=False): def _get_season_search_strings(self, show, season, episode):
return ['^' + x for x in show_name_helpers.makeSceneSeasonSearchString(show, season, episode, abd)] return ['^' + x for x in show_name_helpers.makeSceneSeasonSearchString(show, season, episode)]
def _get_episode_search_strings(self, show, season, episode, abd=False): def _get_episode_search_strings(self, show, season, episode, add_string=''):
return ['^' + x for x in show_name_helpers.makeSceneSearchString(show, season, episode, abd)] return ['^' + x for x in show_name_helpers.makeSceneSearchString(show, season, episode)]
def _doSearch(self, curString, show=None, age=None): def _doSearch(self, curString, show=None, age=None):

View file

@ -42,11 +42,11 @@ class NZBsRUSProvider(generic.NZBProvider):
if sickbeard.NZBSRUS_UID in (None, "") or sickbeard.NZBSRUS_HASH in (None, ""): 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") raise exceptions.AuthException("NZBs'R'US authentication details are empty, check your config")
def _get_season_search_strings(self, show, season, episode, abd=False): def _get_season_search_strings(self, show, season, episode):
return ['^' + x for x in show_name_helpers.makeSceneSeasonSearchString(show, season, episode, abd)] return ['^' + x for x in show_name_helpers.makeSceneSeasonSearchString(show, season, episode)]
def _get_episode_search_strings(self, show, season, episode, abd=False): def _get_episode_search_strings(self, show, season, episode, add_string=''):
return ['^' + x for x in show_name_helpers.makeSceneSearchString(show, season, episode, abd)] return ['^' + x for x in show_name_helpers.makeSceneSearchString(show, season, episode)]
def _doSearch(self, search, show=None, age=None): def _doSearch(self, search, show=None, age=None):
params = {'uid': sickbeard.NZBSRUS_UID, params = {'uid': sickbeard.NZBSRUS_UID,

View file

@ -85,11 +85,11 @@ class OmgwtfnzbsProvider(generic.NZBProvider):
return True return True
def _get_season_search_strings(self, show, season, episode, abd=False): def _get_season_search_strings(self, show, season, episode):
return [x for x in show_name_helpers.makeSceneSeasonSearchString(show, season, episode, abd)] return [x for x in show_name_helpers.makeSceneSeasonSearchString(show, season, episode)]
def _get_episode_search_strings(self, show, season, episode, abd=False): def _get_episode_search_strings(self, show, season, episode, add_string=''):
return [x for x in show_name_helpers.makeSceneSearchString(show, season, episode, abd)] return [x for x in show_name_helpers.makeSceneSearchString(show, season, episode)]
def _get_title_and_url(self, item): def _get_title_and_url(self, item):
return (item['release'], item['getnzb']) return (item['release'], item['getnzb'])

View file

@ -61,8 +61,6 @@ class PublicHDProvider(generic.TorrentProvider):
self.categories = {'Season': ['23'], 'Episode': ['7', '14', '24'], 'RSS': ['7', '14', '23', '24']} self.categories = {'Season': ['23'], 'Episode': ['7', '14', '24'], 'RSS': ['7', '14', '23', '24']}
self.session = requests.Session()
def isEnabled(self): def isEnabled(self):
return sickbeard.PUBLICHD return sickbeard.PUBLICHD
@ -74,7 +72,7 @@ class PublicHDProvider(generic.TorrentProvider):
quality = Quality.sceneQuality(item[0]) quality = Quality.sceneQuality(item[0])
return quality 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: if not show:
return [] return []
@ -87,22 +85,28 @@ class PublicHDProvider(generic.TorrentProvider):
ep_string = show_name + ' Season ' + str(season) #2) ShowName Season X ep_string = show_name + ' Season ' + str(season) #2) ShowName Season X
search_string['Season'].append(ep_string) 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] 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': []} search_string = {'Episode': []}
if not episode: if not episode:
return [] return []
if abd: if show.air_by_date:
for show_name in set(allPossibleShowNames(show)): for show_name in set(allPossibleShowNames(show)):
ep_string = sanitizeSceneName(show_name) + ' ' + \ ep_string = sanitizeSceneName(show_name) + ' ' + \
str(episode).replace('-', '|') + '|' + \ 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) search_string['Episode'].append(ep_string)
else: else:
for show_name in set(allPossibleShowNames(show)): for show_name in set(allPossibleShowNames(show)):
@ -276,7 +280,13 @@ class PublicHDProvider(generic.TorrentProvider):
for sqlShow in sqlResults: for sqlShow in sqlResults:
curShow = helpers.findCertainShow(sickbeard.showList, int(sqlShow["showid"])) curShow = helpers.findCertainShow(sickbeard.showList, int(sqlShow["showid"]))
curEp = curShow.getEpisode(int(sqlShow["season"]), int(sqlShow["episode"])) 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): for item in self._doSearch(searchString[0], show=curShow):
title, url = self._get_title_and_url(item) title, url = self._get_title_and_url(item)

View file

@ -42,7 +42,6 @@ class TorrentRssProvider(generic.TorrentProvider):
self.url = re.sub('\/$', '', url) self.url = re.sub('\/$', '', url)
self.enabled = True self.enabled = True
self.supportsBacklog = False self.supportsBacklog = False
self.session = requests.Session()
def configStr(self): def configStr(self):
return self.name + '|' + self.url + '|' + str(int(self.enabled)) return self.name + '|' + self.url + '|' + str(int(self.enabled))

View file

@ -63,8 +63,6 @@ class SCCProvider(generic.TorrentProvider):
self.categories = "c27=27&c17=17&c11=11" 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'} 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): def isEnabled(self):
@ -101,7 +99,7 @@ class SCCProvider(generic.TorrentProvider):
return True 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: if not show:
return [] return []
@ -111,22 +109,28 @@ class SCCProvider(generic.TorrentProvider):
ep_string = show_name + ' S%02d' % int(season) #1) ShowName SXX ep_string = show_name + ' S%02d' % int(season) #1) ShowName SXX
search_string['Season'].append(ep_string) 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] 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': []} search_string = {'Episode': []}
if not episode: if not episode:
return [] return []
if abd: if show.air_by_date:
for show_name in set(show_name_helpers.allPossibleShowNames(show)): for show_name in set(show_name_helpers.allPossibleShowNames(show)):
ep_string = sanitizeSceneName(show_name) + ' ' + \ ep_string = sanitizeSceneName(show_name) + ' ' + \
str(episode).replace('-', '|') + '|' + \ 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) search_string['Episode'].append(ep_string)
else: else:
for show_name in set(show_name_helpers.allPossibleShowNames(show)): for show_name in set(show_name_helpers.allPossibleShowNames(show)):
@ -278,7 +282,13 @@ class SCCProvider(generic.TorrentProvider):
for sqlShow in sqlResults: for sqlShow in sqlResults:
curShow = helpers.findCertainShow(sickbeard.showList, int(sqlShow["showid"])) curShow = helpers.findCertainShow(sickbeard.showList, int(sqlShow["showid"]))
curEp = curShow.getEpisode(int(sqlShow["season"]), int(sqlShow["episode"])) 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): for item in self._doSearch(searchString[0], show=curShow):
title, url = self._get_title_and_url(item) title, url = self._get_title_and_url(item)

View file

@ -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.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): def isEnabled(self):
return sickbeard.SPEEDCD return sickbeard.SPEEDCD
@ -80,7 +76,6 @@ class SpeedCDProvider(generic.TorrentProvider):
} }
self.session = requests.Session() self.session = requests.Session()
self.session.headers.update(self.headers)
try: try:
response = self.session.post(self.urls['login'], data=login_params, timeout=30, verify=False) response = self.session.post(self.urls['login'], data=login_params, timeout=30, verify=False)
@ -95,7 +90,7 @@ class SpeedCDProvider(generic.TorrentProvider):
return True 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: if not show:
return [] return []
@ -107,22 +102,28 @@ class SpeedCDProvider(generic.TorrentProvider):
search_string['Season'].append(ep_string) search_string['Season'].append(ep_string)
#Building the search string with the episodes we need #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] 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': []} search_string = {'Episode': []}
if not episode: if not episode:
return [] return []
if abd: if show.air_by_date:
for show_name in set(show_name_helpers.allPossibleShowNames(show)): for show_name in set(show_name_helpers.allPossibleShowNames(show)):
ep_string = sanitizeSceneName(show_name) + ' ' + \ ep_string = sanitizeSceneName(show_name) + ' ' + \
str(episode).replace('-', '|') + '|' + \ 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) search_string['Episode'].append(ep_string)
else: else:
for show_name in set(show_name_helpers.allPossibleShowNames(show)): for show_name in set(show_name_helpers.allPossibleShowNames(show)):
@ -237,7 +238,13 @@ class SpeedCDProvider(generic.TorrentProvider):
for sqlShow in sqlResults: for sqlShow in sqlResults:
curShow = helpers.findCertainShow(sickbeard.showList, int(sqlShow["showid"])) curShow = helpers.findCertainShow(sickbeard.showList, int(sqlShow["showid"]))
curEp = curShow.getEpisode(int(sqlShow["season"]), int(sqlShow["episode"])) 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): for item in self._doSearch(searchString[0], show=curShow):
title, url = self._get_title_and_url(item) title, url = self._get_title_and_url(item)

View file

@ -72,8 +72,6 @@ class ThePirateBayProvider(generic.TorrentProvider):
self.re_title_url = '/torrent/(?P<id>\d+)/(?P<title>.*?)//1".+?(?P<url>magnet.*?)//1".+?(?P<seeders>\d+)</td>.+?(?P<leechers>\d+)</td>' self.re_title_url = '/torrent/(?P<id>\d+)/(?P<title>.*?)//1".+?(?P<url>magnet.*?)//1".+?(?P<seeders>\d+)</td>.+?(?P<leechers>\d+)</td>'
self.session = requests.Session()
def isEnabled(self): def isEnabled(self):
return sickbeard.THEPIRATEBAY return sickbeard.THEPIRATEBAY
@ -172,7 +170,7 @@ class ThePirateBayProvider(generic.TorrentProvider):
return title 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: if not show:
return [] return []
@ -187,11 +185,11 @@ class ThePirateBayProvider(generic.TorrentProvider):
ep_string = show_name + ' Season ' + str(season) + ' -Ep*' #2) ShowName Season X ep_string = show_name + ' Season ' + str(season) + ' -Ep*' #2) ShowName Season X
search_string['Season'].append(ep_string) 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] 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': []} search_string = {'Episode': []}
@ -200,11 +198,17 @@ class ThePirateBayProvider(generic.TorrentProvider):
self.show = show self.show = show
if abd: if show.air_by_date:
for show_name in set(allPossibleShowNames(show)): for show_name in set(allPossibleShowNames(show)):
ep_string = sanitizeSceneName(show_name) + ' ' + \ ep_string = sanitizeSceneName(show_name) + ' ' + \
str(episode).replace('-', '|') + '|' + \ 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) search_string['Episode'].append(ep_string)
else: else:
for show_name in set(allPossibleShowNames(show)): for show_name in set(allPossibleShowNames(show)):
@ -382,7 +386,13 @@ class ThePirateBayProvider(generic.TorrentProvider):
for sqlShow in sqlResults: for sqlShow in sqlResults:
curShow = helpers.findCertainShow(sickbeard.showList, int(sqlShow["showid"])) curShow = helpers.findCertainShow(sickbeard.showList, int(sqlShow["showid"]))
curEp = curShow.getEpisode(int(sqlShow["season"]), int(sqlShow["episode"])) 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): for item in self._doSearch(searchString[0], show=curShow):
title, url = self._get_title_and_url(item) title, url = self._get_title_and_url(item)

View file

@ -56,8 +56,6 @@ class TorrentDayProvider(generic.TorrentProvider):
self.url = self.urls['base_url'] self.url = self.urls['base_url']
self.session = requests.Session()
self.cookies = None self.cookies = None
self.categories = {'Season': {'c14': 1}, 'Episode': {'c2': 1, 'c26': 1, 'c7': 1, 'c24': 1}, self.categories = {'Season': {'c14': 1}, 'Episode': {'c2': 1, 'c26': 1, 'c7': 1, 'c24': 1},
@ -114,7 +112,7 @@ class TorrentDayProvider(generic.TorrentProvider):
return True 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: if not show:
return [] return []
@ -124,22 +122,28 @@ class TorrentDayProvider(generic.TorrentProvider):
ep_string = show_name + ' S%02d' % int(season) #1) ShowName SXX ep_string = show_name + ' S%02d' % int(season) #1) ShowName SXX
search_string['Season'].append(ep_string) 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] 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': []} search_string = {'Episode': []}
if not episode: if not episode:
return [] return []
if abd: if show.air_by_date:
for show_name in set(show_name_helpers.allPossibleShowNames(show)): for show_name in set(show_name_helpers.allPossibleShowNames(show)):
ep_string = sanitizeSceneName(show_name) + ' ' + \ ep_string = sanitizeSceneName(show_name) + ' ' + \
str(episode).replace('-', '|') + '|' + \ 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) search_string['Episode'].append(ep_string)
else: else:
for show_name in set(show_name_helpers.allPossibleShowNames(show)): for show_name in set(show_name_helpers.allPossibleShowNames(show)):
@ -250,7 +254,13 @@ class TorrentDayProvider(generic.TorrentProvider):
for sqlShow in sqlResults: for sqlShow in sqlResults:
curShow = helpers.findCertainShow(sickbeard.showList, int(sqlShow["showid"])) curShow = helpers.findCertainShow(sickbeard.showList, int(sqlShow["showid"]))
curEp = curShow.getEpisode(int(sqlShow["season"]), int(sqlShow["episode"])) 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): for item in self._doSearch(searchString[0], show=curShow):
title, url = self._get_title_and_url(item) title, url = self._get_title_and_url(item)

View file

@ -59,8 +59,6 @@ class TorrentLeechProvider(generic.TorrentProvider):
self.categories = "2,26,27,32" self.categories = "2,26,27,32"
self.session = None
def isEnabled(self): def isEnabled(self):
return sickbeard.TORRENTLEECH return sickbeard.TORRENTLEECH
@ -96,7 +94,7 @@ class TorrentLeechProvider(generic.TorrentProvider):
return True 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: if not show:
return [] return []
@ -106,22 +104,28 @@ class TorrentLeechProvider(generic.TorrentProvider):
ep_string = show_name + ' S%02d' % int(season) #1) ShowName SXX ep_string = show_name + ' S%02d' % int(season) #1) ShowName SXX
search_string['Season'].append(ep_string) 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] 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': []} search_string = {'Episode': []}
if not episode: if not episode:
return [] return []
if abd: if show.air_by_date:
for show_name in set(show_name_helpers.allPossibleShowNames(show)): for show_name in set(show_name_helpers.allPossibleShowNames(show)):
ep_string = sanitizeSceneName(show_name) + ' ' + \ ep_string = sanitizeSceneName(show_name) + ' ' + \
str(episode).replace('-', '|') + '|' + \ 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) search_string['Episode'].append(ep_string)
else: else:
for show_name in set(show_name_helpers.allPossibleShowNames(show)): for show_name in set(show_name_helpers.allPossibleShowNames(show)):
@ -254,7 +258,13 @@ class TorrentLeechProvider(generic.TorrentProvider):
for sqlShow in sqlResults: for sqlShow in sqlResults:
curShow = helpers.findCertainShow(sickbeard.showList, int(sqlShow["showid"])) curShow = helpers.findCertainShow(sickbeard.showList, int(sqlShow["showid"]))
curEp = curShow.getEpisode(int(sqlShow["season"]), int(sqlShow["episode"])) 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): for item in self._doSearch(searchString[0], show=curShow):
title, url = self._get_title_and_url(item) title, url = self._get_title_and_url(item)

View file

@ -380,9 +380,7 @@ def searchProviders(show, season, episode=None, manualSearch=False):
# skip non-tv crap # skip non-tv crap
curResults[curEp] = filter( curResults[curEp] = filter(
lambda x: show_name_helpers.filterBadReleases(x.name) and show_name_helpers.isGoodResult(x.name, lambda x: show_name_helpers.filterBadReleases(x.name) and show_name_helpers.isGoodResult(x.name,show),curResults[curEp])
show),
curResults[curEp])
if curEp in foundResults: if curEp in foundResults:
foundResults[curEp] += curResults[curEp] foundResults[curEp] += curResults[curEp]

View file

@ -96,6 +96,7 @@ class BacklogSearcher:
# get separate lists of the season/date shows # get separate lists of the season/date shows
#season_shows = [x for x in show_list if not x.air_by_date] #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] 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 # figure out how many segments of air by date shows we're going to do
air_by_date_segments = [] air_by_date_segments = []
@ -104,6 +105,12 @@ class BacklogSearcher:
logger.log(u"Air-by-date segments: " + str(air_by_date_segments), logger.DEBUG) 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)) #totalSeasons = float(len(numSeasonResults) + len(air_by_date_segments))
#numSeasonsDone = 0.0 #numSeasonsDone = 0.0
@ -115,6 +122,8 @@ class BacklogSearcher:
if curShow.air_by_date: if curShow.air_by_date:
segments = [x[1] for x in self._get_air_by_date_segments(curShow.indexerid, fromDate)] 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: else:
segments = self._get_season_segments(curShow.indexerid, fromDate) segments = self._get_season_segments(curShow.indexerid, fromDate)
@ -169,7 +178,7 @@ class BacklogSearcher:
# query the DB for all dates for this show # query the DB for all dates for this show
myDB = db.DBConnection() myDB = db.DBConnection()
num_air_by_date_results = myDB.select( 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]) [fromDate.toordinal(), indexer_id])
# break them apart into month/year strings # break them apart into month/year strings
@ -185,6 +194,26 @@ class BacklogSearcher:
return air_by_date_segments 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): def _set_lastBacklog(self, when):
logger.log(u"Setting the last backlog in the DB to " + str(when), logger.DEBUG) logger.log(u"Setting the last backlog in the DB to " + str(when), logger.DEBUG)

View file

@ -192,7 +192,7 @@ class BacklogQueueItem(generic_queue.QueueItem):
myDB = db.DBConnection() myDB = db.DBConnection()
# see if there is anything in this season worth searching for # 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 = ?", statusResults = myDB.select("SELECT status FROM tv_episodes WHERE showid = ? AND season = ?",
[self.show.indexerid, self.segment]) [self.show.indexerid, self.segment])
else: else:

View file

@ -119,7 +119,7 @@ def makeSceneShowSearchStrings(show):
return map(sanitizeSceneName, showNames) return map(sanitizeSceneName, showNames)
def makeSceneSeasonSearchString(show, season, episode, abd=False, extraSearchType=None): def makeSceneSeasonSearchString(show, season, episode, extraSearchType=None):
myDB = db.DBConnection() myDB = db.DBConnection()
if show.air_by_date: 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 # the search string for air by date shows is just
seasonStrings = [season] seasonStrings = [season]
elif show.sports:
numseasons = 0
# the search string for air by date shows is just
seasonStrings = [season]
else: else:
numseasonsSQlResult = myDB.select( numseasonsSQlResult = myDB.select(
"SELECT COUNT(DISTINCT season) as numseasons FROM tv_episodes WHERE showid = ? and season != 0", "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) toReturn.append(curShow + "." + cur_season)
# episode # episode
toReturn.extend(makeSceneSearchString(show, season, episode, abd)) toReturn.extend(makeSceneSearchString(show, season, episode))
return toReturn return toReturn
def makeSceneSearchString(show, season, episode, abd=False): def makeSceneSearchString(show, season, episode):
myDB = db.DBConnection() myDB = db.DBConnection()
numseasonsSQlResult = myDB.select( numseasonsSQlResult = myDB.select(
"SELECT COUNT(DISTINCT season) as numseasons FROM tv_episodes WHERE showid = ? and season != 0", "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]) numepisodes = int(numepisodesSQlResult[0][0])
# see if we should use dates instead of episodes # see if we should use dates instead of episodes
if abd and episode != datetime.date.fromordinal(1): if show.air_by_date and episode != datetime.date.fromordinal(1):
epStrings = [str(episode.airdate)] epStrings = [str(episode)]
if show.sports and episode != datetime.date.fromordinal(1):
epStrings = [str(episode)]
else: else:
epStrings = ["S%02iE%02i" % (int(season), int(episode)), epStrings = ["S%02iE%02i" % (int(season), int(episode)),
"%ix%02i" % (int(season), int(episode))] "%ix%02i" % (int(season), int(episode))]

View file

@ -294,8 +294,11 @@ class QueueItemAdd(ShowQueueItem):
self.show.paused = False self.show.paused = False
# be smartish about this # 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 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: except sickbeard.indexer_exception, e:
logger.log( logger.log(

View file

@ -118,7 +118,7 @@ class TraktChecker():
return return
logger.log(u"Setting episode s" + str(s) + "e" + str(e) + " of show " + show.name + " to wanted") 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 # 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] ep_segment = str(epObj.airdate)[:7]
else: else:
ep_segment = epObj.season ep_segment = epObj.season

View file

@ -76,6 +76,7 @@ class TVShow(object):
self.startyear = 0 self.startyear = 0
self.paused = 0 self.paused = 0
self.air_by_date = 0 self.air_by_date = 0
self.sports = 0
self.subtitles = int(sickbeard.SUBTITLES_DEFAULT if sickbeard.SUBTITLES_DEFAULT else 0) self.subtitles = int(sickbeard.SUBTITLES_DEFAULT if sickbeard.SUBTITLES_DEFAULT else 0)
self.dvdorder = 0 self.dvdorder = 0
self.archive_firstmatch = 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) sql_selection = sql_selection + " FROM tv_episodes tve WHERE showid = " + str(self.indexerid)
if season is not None: 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) sql_selection = sql_selection + " AND season = " + str(season)
else: else:
segment_year, segment_month = map(int, str(season).split('-')) 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) logger.log(u"Unable to parse the filename " + file + " into a valid episode", logger.ERROR)
return None 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("parse_result: " + str(parse_result))
logger.log(u"No episode number found in " + file + ", ignoring it", logger.ERROR) logger.log(u"No episode number found in " + file + ", ignoring it", logger.ERROR)
return None return None
@ -563,7 +564,7 @@ class TVShow(object):
rootEp = None rootEp = None
# if we have an air-by-date show then get the real season/episode numbers # 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: try:
lINDEXER_API_PARMS = sickbeard.indexerApi(self.indexer).api_params.copy() 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) 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"]) season = int(epObj["seasonnumber"])
episodes = [int(epObj["episodenumber"])] episodes = [int(epObj["episodenumber"])]
except sickbeard.indexer_episodenotfound: except sickbeard.indexer_episodenotfound:
@ -730,6 +736,10 @@ class TVShow(object):
if not self.air_by_date: if not self.air_by_date:
self.air_by_date = 0 self.air_by_date = 0
self.sports = sqlResults[0]["sports"]
if not self.sports:
self.sports = 0
self.subtitles = sqlResults[0]["subtitles"] self.subtitles = sqlResults[0]["subtitles"]
if self.subtitles: if self.subtitles:
self.subtitles = 1 self.subtitles = 1
@ -1023,6 +1033,7 @@ class TVShow(object):
"flatten_folders": self.flatten_folders, "flatten_folders": self.flatten_folders,
"paused": self.paused, "paused": self.paused,
"air_by_date": self.air_by_date, "air_by_date": self.air_by_date,
"sports": self.sports,
"subtitles": self.subtitles, "subtitles": self.subtitles,
"dvdorder": self.dvdorder, "dvdorder": self.dvdorder,
"archive_firstmatch": self.archive_firstmatch, "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 there's no release group then replace it with a reasonable facsimile
if not replace_map['%RN']: 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')
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: 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 # 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: if self.show.air_by_date and sickbeard.NAMING_CUSTOM_ABD and not self.relatedEps:
pattern = sickbeard.NAMING_ABD_PATTERN pattern = sickbeard.NAMING_ABD_PATTERN
elif self.show.sports and sickbeard.NAMING_CUSTOM_SPORTS and not self.relatedEps:
pattern = sickbeard.NAMING_SPORTS_PATTERN
else: else:
pattern = sickbeard.NAMING_PATTERN 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 # 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: if self.show.air_by_date and sickbeard.NAMING_CUSTOM_ABD and not self.relatedEps:
pattern = sickbeard.NAMING_ABD_PATTERN pattern = sickbeard.NAMING_ABD_PATTERN
elif self.show.sports and sickbeard.NAMING_CUSTOM_SPORTS and not self.relatedEps:
pattern = sickbeard.NAMING_CUSTOM_SPORTS
else: else:
pattern = sickbeard.NAMING_PATTERN pattern = sickbeard.NAMING_PATTERN

View file

@ -281,7 +281,7 @@ class TVCache():
episodes = parse_result.episode_numbers episodes = parse_result.episode_numbers
# if we have an air-by-date show then get the real season/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: try:
lINDEXER_API_PARMS = sickbeard.indexerApi(self.indexer).api_params.copy() lINDEXER_API_PARMS = sickbeard.indexerApi(self.indexer).api_params.copy()
if not (indexer_lang == "" or indexer_lang == "en" or indexer_lang == None): 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) 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"]) season = int(epObj["seasonnumber"])
episodes = [int(epObj["episodenumber"])] episodes = [int(epObj["episodenumber"])]
except sickbeard.indexer_episodenotfound: except sickbeard.indexer_episodenotfound:

View file

@ -975,7 +975,7 @@ class CMD_EpisodeSetStatus(ApiCall):
for epObj in ep_list: for epObj in ep_list:
if ep_segment == None and self.status == WANTED: if ep_segment == None and self.status == WANTED:
# figure out what segment the episode is in and remember it so we can backlog it # 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] ep_segment = str(epObj.airdate)[:7]
else: else:
ep_segment = epObj.season ep_segment = epObj.season
@ -1764,6 +1764,7 @@ class CMD_Show(ApiCall):
showDict["show_name"] = showObj.name showDict["show_name"] = showObj.name
showDict["paused"] = showObj.paused showDict["paused"] = showObj.paused
showDict["air_by_date"] = showObj.air_by_date showDict["air_by_date"] = showObj.air_by_date
showDict["sports"] = showObj.sports
showDict["flatten_folders"] = showObj.flatten_folders showDict["flatten_folders"] = showObj.flatten_folders
#clean up tvdb horrible airs field #clean up tvdb horrible airs field
showDict["airs"] = str(showObj.airs).replace('am', ' AM').replace('pm', ' PM').replace(' ', ' ') 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), "quality": _get_quality_string(curShow.quality),
"language": curShow.lang, "language": curShow.lang,
"air_by_date": curShow.air_by_date, "air_by_date": curShow.air_by_date,
"sports": curShow.sports,
"indexerid": curShow.indexerid, "indexerid": curShow.indexerid,
"network": curShow.network, "network": curShow.network,
"show_name": curShow.name, "show_name": curShow.name,

View file

@ -1134,7 +1134,8 @@ class ConfigPostProcessing:
rename_episodes=None, unpack=None, rename_episodes=None, unpack=None,
move_associated_files=None, tv_download_dir=None, naming_custom_abd=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, 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 = [] results = []
@ -1163,17 +1164,11 @@ class ConfigPostProcessing:
sickbeard.RENAME_EPISODES = config.checkbox_to_value(rename_episodes) sickbeard.RENAME_EPISODES = config.checkbox_to_value(rename_episodes)
sickbeard.MOVE_ASSOCIATED_FILES = config.checkbox_to_value(move_associated_files) 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_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.NAMING_STRIP_YEAR = config.checkbox_to_value(naming_strip_year)
sickbeard.USE_FAILED_DOWNLOADS = config.checkbox_to_value(use_failed_downloads) sickbeard.USE_FAILED_DOWNLOADS = config.checkbox_to_value(use_failed_downloads)
sickbeard.DELETE_FAILED = config.checkbox_to_value(delete_failed) 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'].set_config(sickbeard.METADATA_XBMC)
sickbeard.metadata_provider_dict['XBMC 12+'].set_config(sickbeard.METADATA_XBMC_12PLUS) sickbeard.metadata_provider_dict['XBMC 12+'].set_config(sickbeard.METADATA_XBMC_12PLUS)
sickbeard.metadata_provider_dict['MediaBrowser'].set_config(sickbeard.METADATA_MEDIABROWSER) sickbeard.metadata_provider_dict['MediaBrowser'].set_config(sickbeard.METADATA_MEDIABROWSER)
@ -1188,12 +1183,18 @@ class ConfigPostProcessing:
else: else:
results.append("You tried saving an invalid naming config, not saving your naming settings") 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 sickbeard.NAMING_ABD_PATTERN = naming_abd_pattern
else: else:
results.append( results.append(
"You tried saving an invalid air-by-date naming config, not saving your air-by-date settings") "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() sickbeard.save_config()
if len(results) > 0: if len(results) > 0:
@ -1207,19 +1208,19 @@ class ConfigPostProcessing:
redirect("/config/postProcessing/") redirect("/config/postProcessing/")
@cherrypy.expose @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: if multi is not None:
multi = int(multi) 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']) result = ek.ek(os.path.join, result['dir'], result['name'])
return result return result
@cherrypy.expose @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: if pattern is None:
return "invalid" return "invalid"
@ -1228,6 +1229,11 @@ class ConfigPostProcessing:
is_valid = naming.check_valid_abd_naming(pattern) is_valid = naming.check_valid_abd_naming(pattern)
require_season_folders = False 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: else:
# check validity of single and multi ep cases for the whole path # check validity of single and multi ep cases for the whole path
is_valid = naming.check_valid_naming(pattern, multi) is_valid = naming.check_valid_naming(pattern, multi)
@ -2829,13 +2835,13 @@ class Home:
def plotDetails(self, show, season, episode): def plotDetails(self, show, season, episode):
result = db.DBConnection().action( result = db.DBConnection().action(
"SELECT description FROM tv_episodes WHERE showid = ? AND season = ? AND episode = ?", "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.' return result['description'] if result else 'Episode not found.'
@cherrypy.expose @cherrypy.expose
def editShow(self, show=None, location=None, anyQualities=[], bestQualities=[], exceptions_list=[], 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, flatten_folders=None, paused=None, directCall=False, air_by_date=None, sports=None, dvdorder=None,
subtitles=None, archive_firstmatch=None, rls_ignore_words=None, rls_require_words=None): indexerLang=None,subtitles=None, archive_firstmatch=None, rls_ignore_words=None, rls_require_words=None):
if show is None: if show is None:
errString = "Invalid show ID: " + str(show) errString = "Invalid show ID: " + str(show)
@ -2872,6 +2878,7 @@ class Home:
archive_firstmatch = config.checkbox_to_value(archive_firstmatch) archive_firstmatch = config.checkbox_to_value(archive_firstmatch)
paused = config.checkbox_to_value(paused) paused = config.checkbox_to_value(paused)
air_by_date = config.checkbox_to_value(air_by_date) air_by_date = config.checkbox_to_value(air_by_date)
sports = config.checkbox_to_value(sports)
subtitles = config.checkbox_to_value(subtitles) subtitles = config.checkbox_to_value(subtitles)
indexer_lang = indexerLang indexer_lang = indexerLang
@ -2915,6 +2922,7 @@ class Home:
showObj.paused = paused showObj.paused = paused
showObj.air_by_date = air_by_date showObj.air_by_date = air_by_date
showObj.sports = sports
showObj.subtitles = subtitles showObj.subtitles = subtitles
showObj.lang = indexer_lang showObj.lang = indexer_lang
showObj.dvdorder = dvdorder showObj.dvdorder = dvdorder
@ -3129,7 +3137,7 @@ class Home:
if int(status) == WANTED: if int(status) == WANTED:
# figure out what episodes are wanted so we can backlog them # 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] segment = str(epObj.airdate)[:7]
else: else:
segment = epObj.season segment = epObj.season
@ -3406,7 +3414,7 @@ class Home:
return json.dumps({'result': 'failure'}) return json.dumps({'result': 'failure'})
# figure out what segment the episode is in and remember it so we can backlog it # 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] segment = str(ep_obj.airdate)[:7]
else: else:
segment = ep_obj.season segment = ep_obj.season

View file

@ -238,6 +238,7 @@ class BasicTests(unittest.TestCase):
if DEBUG or verbose: if DEBUG or verbose:
print 'air_by_date:', test_result.air_by_date, 'air_date:', test_result.air_date 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 test_result
print result print result
self.assertEqual(test_result.which_regex, [section]) self.assertEqual(test_result.which_regex, [section])

View file

@ -76,6 +76,7 @@ sickbeard.FLATTEN_FOLDERS_DEFAULT = 0
sickbeard.NAMING_PATTERN = '' sickbeard.NAMING_PATTERN = ''
sickbeard.NAMING_ABD_PATTERN = '' sickbeard.NAMING_ABD_PATTERN = ''
sickbeard.NAMING_SPORTS_PATTERN = ''
sickbeard.NAMING_MULTI_EP = 1 sickbeard.NAMING_MULTI_EP = 1

View file

@ -28,8 +28,9 @@ sys.path.append(os.path.abspath('../lib'))
import test_lib as test import test_lib as test
import sickbeard import sickbeard
from sickbeard.helpers import sanitizeSceneName, custom_strftime from sickbeard.helpers import sanitizeSceneName
from sickbeard.tv import TVShow from sickbeard.tv import TVShow
from sickbeard.name_parser.parser import NameParser, InvalidNameException
class XEMBasicTests(test.SickbeardTestDBCase): class XEMBasicTests(test.SickbeardTestDBCase):
def loadFromDB(self): def loadFromDB(self):
@ -53,12 +54,31 @@ class XEMBasicTests(test.SickbeardTestDBCase):
ep = show.getEpisode(21, 17) ep = show.getEpisode(21, 17)
ep.airdate = datetime.datetime.now() 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':[]} search_string = {'Episode':[]}
episode = ep.airdate episode = ep.airdate
str(episode).replace('-', '|') str(episode).replace('-', '|')
ep_string = sanitizeSceneName(show.name) + ' ' + \ ep_string = sanitizeSceneName(show.name) + ' ' + \
str(episode).replace('-', '|') + '|' + \ str(episode).replace('-', '|') + '|' + \
sickbeard.helpers.custom_strftime('%b', episode) episode.strftime('%b')
search_string['Episode'].append(ep_string) search_string['Episode'].append(ep_string)