mirror of
https://github.com/moparisthebest/SickRage
synced 2024-12-13 11:32:20 -05:00
Merge branch 'dev'
This commit is contained in:
commit
fc9e451f15
@ -26,6 +26,7 @@
|
|||||||
#end if
|
#end if
|
||||||
|
|
||||||
<script type="text/javascript" src="$sbRoot/js/config.js?$sbPID"></script>
|
<script type="text/javascript" src="$sbRoot/js/config.js?$sbPID"></script>
|
||||||
|
<script type="text/javascript" src="$sbRoot/js/rootDirs.js?$sbPID"></script>
|
||||||
|
|
||||||
<div id="config">
|
<div id="config">
|
||||||
<div id="config-content">
|
<div id="config-content">
|
||||||
@ -167,6 +168,14 @@
|
|||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="field-pair">
|
||||||
|
<label class="clearfix">
|
||||||
|
<span class="component-title">Show Root Directories</span>
|
||||||
|
<span class="component-desc">Set root directories for where you want your shows to be.</span>
|
||||||
|
#include $os.path.join($sickbeard.PROG_DIR, "gui/slick/interfaces/default/inc_rootDirs.tmpl")
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
<input type="submit" class="btn config_submitter" value="Save Changes" />
|
<input type="submit" class="btn config_submitter" value="Save Changes" />
|
||||||
</fieldset>
|
</fieldset>
|
||||||
</div><!-- /component-group1 //-->
|
</div><!-- /component-group1 //-->
|
||||||
|
@ -156,14 +156,24 @@ var show_nzb_providers = #if $sickbeard.USE_NZBS then "true" else "false"#;
|
|||||||
</div>
|
</div>
|
||||||
#end if
|
#end if
|
||||||
|
|
||||||
#if $hasattr($curNewznabProvider, 'backlog_only'):
|
#if $hasattr($curNewznabProvider, 'enable_daily'):
|
||||||
<div class="field-pair">
|
<div class="field-pair">
|
||||||
<input type="checkbox" name="${curNewznabProvider.getID()}_backlog_only" id="${curNewznabProvider.getID()}_backlog_only" #if $curNewznabProvider.backlog_only then "checked=\"checked\"" else ""#/>
|
<input type="checkbox" name="${curNewznabProvider.getID()}_enable_daily" id="${curNewznabProvider.getID()}_enable_daily" #if $curNewznabProvider.enable_daily then "checked=\"checked\"" else ""#/>
|
||||||
<label class="clearfix" for="${curNewznabProvider.getID()}_backlog_only">
|
<label class="clearfix" for="${curNewznabProvider.getID()}_enable_daily">
|
||||||
<span class="component-title">Backlog Only</span>
|
<span class="component-title">Enable Daily Searches</span>
|
||||||
<span class="component-desc">
|
<span class="component-desc">
|
||||||
Sets the provider to only be used for<br>
|
Enables daily searches</span>
|
||||||
backlog searches.</span>
|
</label>
|
||||||
|
</div>
|
||||||
|
#end if
|
||||||
|
|
||||||
|
#if $hasattr($curNewznabProvider, 'enable_backlog'):
|
||||||
|
<div class="field-pair">
|
||||||
|
<input type="checkbox" name="${curNewznabProvider.getID()}_enable_backlog" id="${curNewznabProvider.getID()}_enable_backlog" #if $curNewznabProvider.enable_backlog then "checked=\"checked\"" else ""#/>
|
||||||
|
<label class="clearfix" for="${curNewznabProvider.getID()}_enable_backlog">
|
||||||
|
<span class="component-title">Enable Backlog Searches</span>
|
||||||
|
<span class="component-desc">
|
||||||
|
Enables backlog searches</span>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
#end if
|
#end if
|
||||||
@ -190,12 +200,12 @@ var show_nzb_providers = #if $sickbeard.USE_NZBS then "true" else "false"#;
|
|||||||
When searching for complete seasons<br>
|
When searching for complete seasons<br>
|
||||||
you can choose to have it look for season<br>
|
you can choose to have it look for season<br>
|
||||||
packs ONLY or choose to have it build a<br>
|
packs ONLY or choose to have it build a<br>
|
||||||
complete season from just single episodes.</span>
|
complete season from just single episodes.<br></span>
|
||||||
|
|
||||||
<span class="component-title"></span>
|
<span class="component-title"></span>
|
||||||
<input type="radio" name="${curNewznabProvider.getID()}_search_mode" id="${curNewznabProvider.getID()}_search_mode_sponly" value="sponly" class="radio" #if $curNewznabProvider.search_mode=="sponly" then "checked=\"checked\"" else ""# />Season Packs ONLY!<br />
|
<input type="radio" name="${curNewznabProvider.getID()}_search_mode" id="${curNewznabProvider.getID()}_search_mode_sponly" value="sponly" class="radio" #if $curNewznabProvider.search_mode=="sponly" then "checked=\"checked\"" else ""# />Season Packs ONLY!<br />
|
||||||
<span class="component-title"></span>
|
<span class="component-title"></span>
|
||||||
<input type="radio" name="${curNewznabProvider.getID()}_search_mode" id="${curNewznabProvider.getID()}_search_mode_eponly" value="eponly" class="radio" #if $curNewznabProvider.search_mode=="eponly" then "checked=\"checked\"" else ""# />Episodes ONLY!<br />
|
<input type="radio" name="${curNewznabProvider.getID()}_search_mode" id="${curNewznabProvider.getID()}_search_mode_eponly" value="eponly" class="radio" #if $curNewznabProvider.search_mode=="eponly" then "checked=\"checked\"" else ""# />Episodes ONLY!<br />
|
||||||
</span>
|
</span>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
@ -224,14 +234,24 @@ var show_nzb_providers = #if $sickbeard.USE_NZBS then "true" else "false"#;
|
|||||||
</div>
|
</div>
|
||||||
#end if
|
#end if
|
||||||
|
|
||||||
#if $hasattr($curNzbProvider, 'backlog_only'):
|
#if $hasattr($curNzbProvider, 'enable_daily'):
|
||||||
<div class="field-pair">
|
<div class="field-pair">
|
||||||
<input type="checkbox" name="${curNzbProvider.getID()}_backlog_only" id="${curNzbProvider.getID()}_backlog_only" #if $curNzbProvider.backlog_only then "checked=\"checked\"" else ""#/>
|
<input type="checkbox" name="${curNzbProvider.getID()}_enable_daily" id="${curNzbProvider.getID()}_enable_daily" #if $curNzbProvider.enable_daily then "checked=\"checked\"" else ""#/>
|
||||||
<label class="clearfix" for="${curNzbProvider.getID()}_backlog_only">
|
<label class="clearfix" for="${curNzbProvider.getID()}_enable_daily">
|
||||||
<span class="component-title">Backlog Only</span>
|
<span class="component-title">Enable Daily Searches</span>
|
||||||
<span class="component-desc">
|
<span class="component-desc">
|
||||||
Sets the provider to only be used for<br>
|
Enables daily searches</span>
|
||||||
backlog searches.</span>
|
</label>
|
||||||
|
</div>
|
||||||
|
#end if
|
||||||
|
|
||||||
|
#if $hasattr($curNzbProvider, 'enable_backlog'):
|
||||||
|
<div class="field-pair">
|
||||||
|
<input type="checkbox" name="${curNzbProvider.getID()}_enable_backlog" id="${curNzbProvider.getID()}_enable_backlog" #if $curNzbProvider.enable_backlog then "checked=\"checked\"" else ""#/>
|
||||||
|
<label class="clearfix" for="${curNzbProvider.getID()}_enable_backlog">
|
||||||
|
<span class="component-title">Enable Backlog Searches</span>
|
||||||
|
<span class="component-desc">
|
||||||
|
Enables backlog searches</span>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
#end if
|
#end if
|
||||||
@ -440,14 +460,24 @@ var show_nzb_providers = #if $sickbeard.USE_NZBS then "true" else "false"#;
|
|||||||
</div>
|
</div>
|
||||||
#end if
|
#end if
|
||||||
|
|
||||||
#if $hasattr($curTorrentProvider, 'backlog_only'):
|
#if $hasattr($curTorrentProvider, 'enable_daily'):
|
||||||
<div class="field-pair">
|
<div class="field-pair">
|
||||||
<input type="checkbox" name="${curTorrentProvider.getID()}_backlog_only" id="${curTorrentProvider.getID()}_backlog_only" #if $curTorrentProvider.backlog_only then "checked=\"checked\"" else ""#/>
|
<input type="checkbox" name="${curTorrentProvider.getID()}_enable_daily" id="${curTorrentProvider.getID()}_enable_daily" #if $curTorrentProvider.enable_daily then "checked=\"checked\"" else ""#/>
|
||||||
<label class="clearfix" for="${curTorrentProvider.getID()}_backlog_only">
|
<label class="clearfix" for="${curTorrentProvider.getID()}_enable_daily">
|
||||||
<span class="component-title">Backlog Only</span>
|
<span class="component-title">Enable Daily Searches</span>
|
||||||
<span class="component-desc">
|
<span class="component-desc">
|
||||||
Sets the provider to only be used for<br>
|
Enables daily searches</span>
|
||||||
backlog searches.</span>
|
</label>
|
||||||
|
</div>
|
||||||
|
#end if
|
||||||
|
|
||||||
|
#if $hasattr($curTorrentProvider, 'enable_backlog'):
|
||||||
|
<div class="field-pair">
|
||||||
|
<input type="checkbox" name="${curTorrentProvider.getID()}_enable_backlog" id="${curTorrentProvider.getID()}_enable_backlog" #if $curTorrentProvider.enable_backlog then "checked=\"checked\"" else ""#/>
|
||||||
|
<label class="clearfix" for="${curTorrentProvider.getID()}_enable_backlog">
|
||||||
|
<span class="component-title">Enable Backlog Searches</span>
|
||||||
|
<span class="component-desc">
|
||||||
|
Enables backlog searches</span>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
#end if
|
#end if
|
||||||
|
@ -147,6 +147,7 @@ a > i.icon-question-sign { background-image: url("$sbRoot/images/glyphicons-half
|
|||||||
\$("#SubMenu a[href*='/home/logout/']").addClass('btn').html('<span class="ui-icon ui-icon-power pull-left"></span> Logout');
|
\$("#SubMenu a[href*='/home/logout/']").addClass('btn').html('<span class="ui-icon ui-icon-power pull-left"></span> Logout');
|
||||||
\$("#SubMenu a:contains('Edit')").addClass('btn').html('<span class="ui-icon ui-icon-pencil pull-left"></span> Edit');
|
\$("#SubMenu a:contains('Edit')").addClass('btn').html('<span class="ui-icon ui-icon-pencil pull-left"></span> Edit');
|
||||||
\$("#SubMenu a:contains('Delete')").addClass('btn').html('<span class="ui-icon ui-icon-trash pull-left"></span> Delete');
|
\$("#SubMenu a:contains('Delete')").addClass('btn').html('<span class="ui-icon ui-icon-trash pull-left"></span> Delete');
|
||||||
|
\$("#SubMenu a:contains('Remove')").addClass('btn').html('<span class="ui-icon ui-icon-trash pull-left"></span> Remove');
|
||||||
\$("#SubMenu a:contains('Clear History')").addClass('btn confirm').html('<span class="ui-icon ui-icon-trash pull-left"></span> Clear History');
|
\$("#SubMenu a:contains('Clear History')").addClass('btn confirm').html('<span class="ui-icon ui-icon-trash pull-left"></span> Clear History');
|
||||||
\$("#SubMenu a:contains('Trim History')").addClass('btn confirm').html('<span class="ui-icon ui-icon-trash pull-left"></span> Trim History');
|
\$("#SubMenu a:contains('Trim History')").addClass('btn confirm').html('<span class="ui-icon ui-icon-trash pull-left"></span> Trim History');
|
||||||
\$("#SubMenu a[href$='/errorlogs/clearerrors/']").addClass('btn').html('<span class="ui-icon ui-icon-trash pull-left"></span> Clear Errors');
|
\$("#SubMenu a[href$='/errorlogs/clearerrors/']").addClass('btn').html('<span class="ui-icon ui-icon-trash pull-left"></span> Clear Errors');
|
||||||
|
@ -102,6 +102,7 @@
|
|||||||
#end if
|
#end if
|
||||||
<!-- <th>Force Metadata Regen <input type="checkbox" class="bulkCheck" id="metadataCheck" /></th>//-->
|
<!-- <th>Force Metadata Regen <input type="checkbox" class="bulkCheck" id="metadataCheck" /></th>//-->
|
||||||
<th width="1%">Delete<br/><input type="checkbox" class="bulkCheck" id="deleteCheck" /></th>
|
<th width="1%">Delete<br/><input type="checkbox" class="bulkCheck" id="deleteCheck" /></th>
|
||||||
|
<th width="1%">Remove<br/><input type="checkbox" class="bulkCheck" id="removeCheck" /></th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tfoot>
|
<tfoot>
|
||||||
@ -120,6 +121,7 @@ $myShowList.sort(lambda x, y: cmp(x.name, y.name))
|
|||||||
#set $curRename_disabled = ""
|
#set $curRename_disabled = ""
|
||||||
#set $curSubtitle_disabled = ""
|
#set $curSubtitle_disabled = ""
|
||||||
#set $curDelete_disabled = ""
|
#set $curDelete_disabled = ""
|
||||||
|
#set $curRemove_disabled = ""
|
||||||
|
|
||||||
#if $sickbeard.showQueueScheduler.action.isBeingUpdated($curShow) or $sickbeard.showQueueScheduler.action.isInUpdateQueue($curShow):
|
#if $sickbeard.showQueueScheduler.action.isBeingUpdated($curShow) or $sickbeard.showQueueScheduler.action.isInUpdateQueue($curShow):
|
||||||
#set $curUpdate_disabled = "disabled=\"disabled\" "
|
#set $curUpdate_disabled = "disabled=\"disabled\" "
|
||||||
@ -141,6 +143,10 @@ $myShowList.sort(lambda x, y: cmp(x.name, y.name))
|
|||||||
#set $curDelete = "disabled=\"disabled\" "
|
#set $curDelete = "disabled=\"disabled\" "
|
||||||
#end if
|
#end if
|
||||||
#set $curDelete = "<input type=\"checkbox\" class=\"deleteCheck\" id=\"delete-"+str($curShow.indexerid)+"\" "+$curDelete_disabled+"/>"
|
#set $curDelete = "<input type=\"checkbox\" class=\"deleteCheck\" id=\"delete-"+str($curShow.indexerid)+"\" "+$curDelete_disabled+"/>"
|
||||||
|
#if $sickbeard.showQueueScheduler.action.isBeingRenamed($curShow) or $sickbeard.showQueueScheduler.action.isInRenameQueue($curShow) or $sickbeard.showQueueScheduler.action.isInRefreshQueue($curShow):
|
||||||
|
#set $curRemove = "disabled=\"disabled\" "
|
||||||
|
#end if
|
||||||
|
#set $curRemove = "<input type=\"checkbox\" class=\"removeCheck\" id=\"remove-"+str($curShow.indexerid)+"\" "+$curRemove_disabled+"/>"
|
||||||
|
|
||||||
<tr>
|
<tr>
|
||||||
<td align="center"><input type="checkbox" class="editCheck" id="edit-$curShow.indexerid" /></td>
|
<td align="center"><input type="checkbox" class="editCheck" id="edit-$curShow.indexerid" /></td>
|
||||||
@ -163,6 +169,7 @@ $myShowList.sort(lambda x, y: cmp(x.name, y.name))
|
|||||||
<td align="center">$curSubtitle</td>
|
<td align="center">$curSubtitle</td>
|
||||||
#end if
|
#end if
|
||||||
<td align="center">$curDelete</td>
|
<td align="center">$curDelete</td>
|
||||||
|
<td align="center">$curRemove</td>
|
||||||
</tr>
|
</tr>
|
||||||
#end for
|
#end for
|
||||||
</tbody>
|
</tbody>
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
#set $cur_index = $root_dir_list.index($cur_dir)
|
#set $cur_index = $root_dir_list.index($cur_dir)
|
||||||
<div style="padding: 6px 0 3px 25px;">
|
<div style="padding: 6px 0 3px 25px;">
|
||||||
<input class="btn edit_root_dir" type="button" class="edit_root_dir" id="edit_root_dir_$cur_index" value="Edit" />
|
<input class="btn edit_root_dir" type="button" class="edit_root_dir" id="edit_root_dir_$cur_index" value="Edit" />
|
||||||
|
<input class="btn delete_root_dir" type="button" class="delete_root_dir" id="delete_root_dir_$cur_index" value="Delete" />
|
||||||
$cur_dir => <span id="display_new_root_dir_$cur_index">$cur_dir</span>
|
$cur_dir => <span id="display_new_root_dir_$cur_index">$cur_dir</span>
|
||||||
</div>
|
</div>
|
||||||
<input type="hidden" name="orig_root_dir_$cur_index" value="$cur_dir" />
|
<input type="hidden" name="orig_root_dir_$cur_index" value="$cur_dir" />
|
||||||
|
@ -63,7 +63,7 @@ $(document).ready(function(){
|
|||||||
$('#Torrent_username').show();
|
$('#Torrent_username').show();
|
||||||
$('#Torrent_Path').show();
|
$('#Torrent_Path').show();
|
||||||
$('#Torrent_Ratio').show();
|
$('#Torrent_Ratio').show();
|
||||||
$('#Torrent_Seed_Time').hide();
|
$('#Torrent_Seed_Time').show();
|
||||||
$('#Torrent_High_Bandwidth').show();
|
$('#Torrent_High_Bandwidth').show();
|
||||||
$('#Torrent_Label').hide();
|
$('#Torrent_Label').hide();
|
||||||
$('#host_desc').html('Transmission Host');
|
$('#host_desc').html('Transmission Host');
|
||||||
|
@ -22,4 +22,10 @@ $(document).ready(function(){
|
|||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$('.delete_root_dir').click(function(){
|
||||||
|
var cur_id = find_dir_index($(this).attr('id'));
|
||||||
|
|
||||||
|
$('#new_root_dir_'+cur_id).val(null);
|
||||||
|
$('#display_new_root_dir_'+cur_id).html('<b>DELETED</b>');
|
||||||
|
});
|
||||||
});
|
});
|
@ -24,6 +24,7 @@ $(document).ready(function(){
|
|||||||
var renameArr = new Array()
|
var renameArr = new Array()
|
||||||
var subtitleArr = new Array()
|
var subtitleArr = new Array()
|
||||||
var deleteArr = new Array()
|
var deleteArr = new Array()
|
||||||
|
var removeArr = new Array()
|
||||||
var metadataArr = new Array()
|
var metadataArr = new Array()
|
||||||
|
|
||||||
$('.updateCheck').each(function() {
|
$('.updateCheck').each(function() {
|
||||||
@ -56,6 +57,12 @@ $(document).ready(function(){
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$('.removeCheck').each(function() {
|
||||||
|
if (this.checked == true) {
|
||||||
|
removeArr.push($(this).attr('id').split('-')[1])
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
/*
|
/*
|
||||||
$('.metadataCheck').each(function() {
|
$('.metadataCheck').each(function() {
|
||||||
if (this.checked == true) {
|
if (this.checked == true) {
|
||||||
@ -63,10 +70,10 @@ $(document).ready(function(){
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
*/
|
*/
|
||||||
if (updateArr.length+refreshArr.length+renameArr.length+subtitleArr.length+deleteArr.length+metadataArr.length == 0)
|
if (updateArr.length+refreshArr.length+renameArr.length+subtitleArr.length+deleteArr.length+removeArr.length+metadataArr.length == 0)
|
||||||
return false
|
return false
|
||||||
|
|
||||||
url = 'massUpdate?toUpdate='+updateArr.join('|')+'&toRefresh='+refreshArr.join('|')+'&toRename='+renameArr.join('|')+'&toSubtitle='+subtitleArr.join('|')+'&toDelete='+deleteArr.join('|')+'&toMetadata='+metadataArr.join('|')
|
url = 'massUpdate?toUpdate='+updateArr.join('|')+'&toRefresh='+refreshArr.join('|')+'&toRename='+renameArr.join('|')+'&toSubtitle='+subtitleArr.join('|')+'&toDelete='+deleteArr.join('|')+'&toRemove='+removeArr.join('|')+'&toMetadata='+metadataArr.join('|')
|
||||||
|
|
||||||
window.location.href = url
|
window.location.href = url
|
||||||
|
|
||||||
@ -83,7 +90,7 @@ $(document).ready(function(){
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
['.editCheck', '.updateCheck', '.refreshCheck', '.renameCheck', '.deleteCheck'].forEach(function(name) {
|
['.editCheck', '.updateCheck', '.refreshCheck', '.renameCheck', '.deleteCheck', '.removeCheck'].forEach(function(name) {
|
||||||
var lastCheck = null;
|
var lastCheck = null;
|
||||||
|
|
||||||
$(name).click(function(event) {
|
$(name).click(function(event) {
|
||||||
|
@ -244,23 +244,56 @@ class Connection(threading.Thread):
|
|||||||
"""
|
"""
|
||||||
return self.handle(PushAckCommand(nid), callback)
|
return self.handle(PushAckCommand(nid), callback)
|
||||||
|
|
||||||
def notifyadd(self, aid=None, gid=None, type=None, priority=None, callback=None):
|
def notification(self, aid=None, gid=None, type=None, priority=None, callback=None):
|
||||||
"""
|
"""
|
||||||
Add a notification
|
Add a notification
|
||||||
|
|
||||||
parameters:
|
parameters:
|
||||||
aid - Anime id
|
aid - Anime id
|
||||||
gid - Group id
|
gid - Group id
|
||||||
type - Type of notification: type=> 0=all, 1=new, 2=group, 3=complete
|
type - Type of notification: type=> 0=all, 1=new, 2=group, 3=complete
|
||||||
priority - low = 0, medium = 1, high = 2 (unconfirmed)
|
priority - low = 0, medium = 1, high = 2 (unconfirmed)
|
||||||
|
|
||||||
structure of parameters:
|
structure of parameters:
|
||||||
[aid={int}|gid={int}]&type={int}&priority={int}
|
[aid={int}|gid={int}]&type={int}&priority={int}
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
return self.handle(Notification(aid, gid, type, priority), callback)
|
||||||
|
|
||||||
|
def notifyadd(self, aid=None, gid=None, type=None, priority=None, callback=None):
|
||||||
|
"""
|
||||||
|
Add a notification
|
||||||
|
|
||||||
|
parameters:
|
||||||
|
aid - Anime id
|
||||||
|
gid - Group id
|
||||||
|
type - Type of notification: type=> 0=all, 1=new, 2=group, 3=complete
|
||||||
|
priority - low = 0, medium = 1, high = 2 (unconfirmed)
|
||||||
|
|
||||||
|
structure of parameters:
|
||||||
|
[aid={int}|gid={int}]&type={int}&priority={int}
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
return self.handle(NotifyAddCommand(aid, gid, type, priority), callback)
|
return self.handle(NotifyAddCommand(aid, gid, type, priority), callback)
|
||||||
|
|
||||||
|
def notifydel(self, aid=None, gid=None, type=None, priority=None, callback=None):
|
||||||
|
"""
|
||||||
|
Add a notification
|
||||||
|
|
||||||
|
parameters:
|
||||||
|
aid - Anime id
|
||||||
|
gid - Group id
|
||||||
|
type - Type of notification: type=> 0=all, 1=new, 2=group, 3=complete
|
||||||
|
priority - low = 0, medium = 1, high = 2 (unconfirmed)
|
||||||
|
|
||||||
|
structure of parameters:
|
||||||
|
[aid={int}|gid={int}]&type={int}&priority={int}
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
return self.handle(NotifyDelCommand(aid, gid, type, priority), callback)
|
||||||
|
|
||||||
def notify(self, buddy=None, callback=None):
|
def notify(self, buddy=None, callback=None):
|
||||||
"""
|
"""
|
||||||
|
@ -99,9 +99,18 @@ class aniDBabstractObject(object):
|
|||||||
priority - low = 0, medium = 1, high = 2 (unconfirmed)
|
priority - low = 0, medium = 1, high = 2 (unconfirmed)
|
||||||
|
|
||||||
"""
|
"""
|
||||||
if (self.aid):
|
if self.aid:
|
||||||
self.aniDB.notifyadd(aid=self.aid, type=1, priority=1)
|
self.aniDB.notifyadd(aid=self.aid, type=1, priority=1)
|
||||||
|
|
||||||
|
def del_notification(self):
|
||||||
|
"""
|
||||||
|
type - Type of notification: type=> 0=all, 1=new, 2=group, 3=complete
|
||||||
|
priority - low = 0, medium = 1, high = 2 (unconfirmed)
|
||||||
|
|
||||||
|
"""
|
||||||
|
if self.aid:
|
||||||
|
self.aniDB.notifydel(aid=self.aid, type=1, priority=1)
|
||||||
|
|
||||||
|
|
||||||
class Anime(aniDBabstractObject):
|
class Anime(aniDBabstractObject):
|
||||||
def __init__(self, aniDB, name=None, aid=None, tvdbid=None, paramsA=None, autoCorrectName=False, load=False):
|
def __init__(self, aniDB, name=None, aid=None, tvdbid=None, paramsA=None, autoCorrectName=False, load=False):
|
||||||
|
@ -103,6 +103,14 @@ class PushAckCommand(Command):
|
|||||||
Command.__init__(self, 'PUSHACK', **parameters)
|
Command.__init__(self, 'PUSHACK', **parameters)
|
||||||
|
|
||||||
|
|
||||||
|
class Notification(Command):
|
||||||
|
def __init__(self, aid=None, gid=None, type=None, priority=None):
|
||||||
|
if not (aid or gid) or (aid and gid):
|
||||||
|
raise AniDBIncorrectParameterError, "You must provide aid OR gid for NOTIFICATION command"
|
||||||
|
parameters = {'aid': aid, "gid": gid, "type": type, "priority": priority}
|
||||||
|
Command.__init__(self, 'NOTIFICATION', **parameters)
|
||||||
|
|
||||||
|
|
||||||
class NotifyAddCommand(Command):
|
class NotifyAddCommand(Command):
|
||||||
def __init__(self, aid=None, gid=None, type=None, priority=None):
|
def __init__(self, aid=None, gid=None, type=None, priority=None):
|
||||||
if not (aid or gid) or (aid and gid):
|
if not (aid or gid) or (aid and gid):
|
||||||
@ -111,6 +119,14 @@ class NotifyAddCommand(Command):
|
|||||||
Command.__init__(self, 'NOTIFICATIONADD', **parameters)
|
Command.__init__(self, 'NOTIFICATIONADD', **parameters)
|
||||||
|
|
||||||
|
|
||||||
|
class NotifyDelCommand(Command):
|
||||||
|
def __init__(self, aid=None, gid=None, type=None, priority=None):
|
||||||
|
if not (aid or gid) or (aid and gid):
|
||||||
|
raise AniDBIncorrectParameterError, "You must provide aid OR gid for NOTIFICATIONDEL command"
|
||||||
|
parameters = {'aid': aid, "gid": gid, "type": type, "priority": priority}
|
||||||
|
Command.__init__(self, 'NOTIFICATIONDEL', **parameters)
|
||||||
|
|
||||||
|
|
||||||
class NotifyCommand(Command):
|
class NotifyCommand(Command):
|
||||||
def __init__(self, buddy=None):
|
def __init__(self, buddy=None):
|
||||||
parameters = {'buddy': buddy}
|
parameters = {'buddy': buddy}
|
||||||
|
@ -15,23 +15,30 @@
|
|||||||
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with aDBa. If not, see <http://www.gnu.org/licenses/>.
|
# along with aDBa. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
|
||||||
class AniDBError(Exception):
|
class AniDBError(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class AniDBIncorrectParameterError(AniDBError):
|
class AniDBIncorrectParameterError(AniDBError):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class AniDBCommandTimeoutError(AniDBError):
|
class AniDBCommandTimeoutError(AniDBError):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class AniDBMustAuthError(AniDBError):
|
class AniDBMustAuthError(AniDBError):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class AniDBPacketCorruptedError(AniDBError):
|
class AniDBPacketCorruptedError(AniDBError):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class AniDBBannedError(AniDBError):
|
class AniDBBannedError(AniDBError):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class AniDBInternalError(AniDBError):
|
class AniDBInternalError(AniDBError):
|
||||||
pass
|
pass
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -628,21 +628,10 @@ class Tvdb:
|
|||||||
"""Loads a URL using caching, returns an ElementTree of the source
|
"""Loads a URL using caching, returns an ElementTree of the source
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
src = self._loadUrl(url, params=params, language=language)
|
src = self._loadUrl(url, params=params, language=language).values()[0]
|
||||||
src = [src[item] for item in src][0] if src else []
|
return src
|
||||||
except:
|
except:
|
||||||
errormsg = "There was an error with the XML retrieved from thetvdb.com:"
|
return []
|
||||||
|
|
||||||
if self.config['cache_enabled']:
|
|
||||||
errormsg += "\nFirst try emptying the cache folder at..\n%s" % (
|
|
||||||
self.config['cache_location']
|
|
||||||
)
|
|
||||||
|
|
||||||
errormsg += "\nIf this does not resolve the issue, please try again later. If the error persists, report a bug on"
|
|
||||||
errormsg += "\nhttp://dbr.lighthouseapp.com/projects/13342-tvdb_api/overview\n"
|
|
||||||
raise tvdb_error(errormsg)
|
|
||||||
|
|
||||||
return src
|
|
||||||
|
|
||||||
def _setItem(self, sid, seas, ep, attrib, value):
|
def _setItem(self, sid, seas, ep, attrib, value):
|
||||||
"""Creates a new episode, creating Show(), Season() and
|
"""Creates a new episode, creating Show(), Season() and
|
||||||
@ -692,8 +681,12 @@ class Tvdb:
|
|||||||
series = series.encode("utf-8")
|
series = series.encode("utf-8")
|
||||||
log().debug("Searching for show %s" % series)
|
log().debug("Searching for show %s" % series)
|
||||||
self.config['params_getSeries']['seriesname'] = series
|
self.config['params_getSeries']['seriesname'] = series
|
||||||
seriesEt = self._getetsrc(self.config['url_getSeries'], self.config['params_getSeries'])
|
|
||||||
return [seriesEt[item] for item in seriesEt][0] if seriesEt else []
|
try:
|
||||||
|
seriesFound = self._getetsrc(self.config['url_getSeries'], self.config['params_getSeries']).values()[0]
|
||||||
|
return seriesFound
|
||||||
|
except:
|
||||||
|
return []
|
||||||
|
|
||||||
def _getSeries(self, series):
|
def _getSeries(self, series):
|
||||||
"""This searches TheTVDB.com for the series name,
|
"""This searches TheTVDB.com for the series name,
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
# !/usr/bin/env python2
|
# !/usr/bin/env python2
|
||||||
#encoding:utf-8
|
# encoding:utf-8
|
||||||
#author:echel0n
|
#author:echel0n
|
||||||
#project:tvrage_api
|
#project:tvrage_api
|
||||||
#repository:http://github.com/echel0n/tvrage_api
|
#repository:http://github.com/echel0n/tvrage_api
|
||||||
@ -393,7 +393,6 @@ class TVRage:
|
|||||||
except ImportError:
|
except ImportError:
|
||||||
return os.path.join(tempfile.gettempdir(), "tvrage_api")
|
return os.path.join(tempfile.gettempdir(), "tvrage_api")
|
||||||
|
|
||||||
|
|
||||||
return os.path.join(tempfile.gettempdir(), "tvrage_api-%s" % (uid))
|
return os.path.join(tempfile.gettempdir(), "tvrage_api-%s" % (uid))
|
||||||
|
|
||||||
#@retry(tvrage_error)
|
#@retry(tvrage_error)
|
||||||
@ -455,7 +454,7 @@ class TVRage:
|
|||||||
if key == 'genre':
|
if key == 'genre':
|
||||||
value = value['genre']
|
value = value['genre']
|
||||||
if not value:
|
if not value:
|
||||||
value=[]
|
value = []
|
||||||
if not isinstance(value, list):
|
if not isinstance(value, list):
|
||||||
value = [value]
|
value = [value]
|
||||||
value = filter(None, value)
|
value = filter(None, value)
|
||||||
@ -470,9 +469,9 @@ class TVRage:
|
|||||||
value = parse(value, fuzzy=True).date()
|
value = parse(value, fuzzy=True).date()
|
||||||
value = value.strftime("%Y-%m-%d")
|
value = value.strftime("%Y-%m-%d")
|
||||||
|
|
||||||
#if key == 'airs_time':
|
#if key == 'airs_time':
|
||||||
# value = parse(value).time()
|
# value = parse(value).time()
|
||||||
# value = value.strftime("%I:%M %p")
|
# value = value.strftime("%I:%M %p")
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@ -489,20 +488,10 @@ class TVRage:
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
try:
|
try:
|
||||||
src = self._loadUrl(url, params)
|
src = self._loadUrl(url, params).values()[0]
|
||||||
src = [src[item] for item in src][0] if src else []
|
return src
|
||||||
except:
|
except:
|
||||||
errormsg = "There was an error with the XML retrieved from tvrage.com"
|
return []
|
||||||
|
|
||||||
if self.config['cache_enabled']:
|
|
||||||
errormsg += "\nFirst try emptying the cache folder at..\n%s" % (
|
|
||||||
self.config['cache_location']
|
|
||||||
)
|
|
||||||
|
|
||||||
errormsg += "\nIf this does not resolve the issue, please try again later. If the error persists, report a bug on\n"
|
|
||||||
raise tvrage_error(errormsg)
|
|
||||||
|
|
||||||
return src
|
|
||||||
|
|
||||||
def _setItem(self, sid, seas, ep, attrib, value):
|
def _setItem(self, sid, seas, ep, attrib, value):
|
||||||
"""Creates a new episode, creating Show(), Season() and
|
"""Creates a new episode, creating Show(), Season() and
|
||||||
@ -557,8 +546,12 @@ class TVRage:
|
|||||||
series = series.encode("utf-8")
|
series = series.encode("utf-8")
|
||||||
log().debug("Searching for show %s" % series)
|
log().debug("Searching for show %s" % series)
|
||||||
self.config['params_getSeries']['show'] = series
|
self.config['params_getSeries']['show'] = series
|
||||||
seriesEt = self._getetsrc(self.config['url_getSeries'], self.config['params_getSeries'])
|
|
||||||
return [seriesEt[item] for item in seriesEt][0] if seriesEt else []
|
try:
|
||||||
|
seriesFound = self._getetsrc(self.config['url_getSeries'], self.config['params_getSeries']).values()[0]
|
||||||
|
return seriesFound
|
||||||
|
except:
|
||||||
|
return []
|
||||||
|
|
||||||
def _getSeries(self, series):
|
def _getSeries(self, series):
|
||||||
"""This searches tvrage.com for the series name,
|
"""This searches tvrage.com for the series name,
|
||||||
@ -632,7 +625,7 @@ class TVRage:
|
|||||||
ep_no = int(episode['episodenumber'])
|
ep_no = int(episode['episodenumber'])
|
||||||
self._setItem(sid, seas_no, ep_no, 'seasonnumber', seas_no)
|
self._setItem(sid, seas_no, ep_no, 'seasonnumber', seas_no)
|
||||||
|
|
||||||
for k,v in episode.items():
|
for k, v in episode.items():
|
||||||
try:
|
try:
|
||||||
k = k.lower()
|
k = k.lower()
|
||||||
if v is not None:
|
if v is not None:
|
||||||
|
@ -981,10 +981,16 @@ def initialize(consoleLogging=True):
|
|||||||
curTorrentProvider.search_fallback = bool(check_setting_int(CFG, curTorrentProvider.getID().upper(),
|
curTorrentProvider.search_fallback = bool(check_setting_int(CFG, curTorrentProvider.getID().upper(),
|
||||||
curTorrentProvider.getID() + '_search_fallback',
|
curTorrentProvider.getID() + '_search_fallback',
|
||||||
0))
|
0))
|
||||||
if hasattr(curTorrentProvider, 'backlog_only'):
|
|
||||||
curTorrentProvider.backlog_only = bool(check_setting_int(CFG, curTorrentProvider.getID().upper(),
|
if hasattr(curTorrentProvider, 'enable_daily'):
|
||||||
curTorrentProvider.getID() + '_backlog_only',
|
curTorrentProvider.enable_daily = bool(check_setting_int(CFG, curTorrentProvider.getID().upper(),
|
||||||
0))
|
curTorrentProvider.getID() + '_enable_daily',
|
||||||
|
1))
|
||||||
|
|
||||||
|
if hasattr(curTorrentProvider, 'enable_backlog'):
|
||||||
|
curTorrentProvider.enable_backlog = bool(check_setting_int(CFG, curTorrentProvider.getID().upper(),
|
||||||
|
curTorrentProvider.getID() + '_enable_backlog',
|
||||||
|
1))
|
||||||
|
|
||||||
for curNzbProvider in [curProvider for curProvider in providers.sortedProviderList() if
|
for curNzbProvider in [curProvider for curProvider in providers.sortedProviderList() if
|
||||||
curProvider.providerType == GenericProvider.NZB]:
|
curProvider.providerType == GenericProvider.NZB]:
|
||||||
@ -1004,10 +1010,15 @@ def initialize(consoleLogging=True):
|
|||||||
curNzbProvider.search_fallback = bool(check_setting_int(CFG, curNzbProvider.getID().upper(),
|
curNzbProvider.search_fallback = bool(check_setting_int(CFG, curNzbProvider.getID().upper(),
|
||||||
curNzbProvider.getID() + '_search_fallback',
|
curNzbProvider.getID() + '_search_fallback',
|
||||||
0))
|
0))
|
||||||
if hasattr(curNzbProvider, 'backlog_only'):
|
if hasattr(curNzbProvider, 'enable_daily'):
|
||||||
curNzbProvider.backlog_only = bool(check_setting_int(CFG, curNzbProvider.getID().upper(),
|
curNzbProvider.enable_daily = bool(check_setting_int(CFG, curNzbProvider.getID().upper(),
|
||||||
curNzbProvider.getID() + '_backlog_only',
|
curNzbProvider.getID() + '_enable_daily',
|
||||||
0))
|
1))
|
||||||
|
|
||||||
|
if hasattr(curNzbProvider, 'enable_backlog'):
|
||||||
|
curNzbProvider.enable_backlog = bool(check_setting_int(CFG, curNzbProvider.getID().upper(),
|
||||||
|
curNzbProvider.getID() + '_enable_backlog',
|
||||||
|
1))
|
||||||
|
|
||||||
if not os.path.isfile(CONFIG_FILE):
|
if not os.path.isfile(CONFIG_FILE):
|
||||||
logger.log(u"Unable to find '" + CONFIG_FILE + "', all settings will be default!", logger.DEBUG)
|
logger.log(u"Unable to find '" + CONFIG_FILE + "', all settings will be default!", logger.DEBUG)
|
||||||
@ -1124,6 +1135,7 @@ def initialize(consoleLogging=True):
|
|||||||
__INITIALIZED__ = True
|
__INITIALIZED__ = True
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
def start():
|
def start():
|
||||||
global __INITIALIZED__, backlogSearchScheduler, \
|
global __INITIALIZED__, backlogSearchScheduler, \
|
||||||
showUpdateScheduler, versionCheckScheduler, showQueueScheduler, \
|
showUpdateScheduler, versionCheckScheduler, showQueueScheduler, \
|
||||||
@ -1278,6 +1290,7 @@ def halt():
|
|||||||
__INITIALIZED__ = False
|
__INITIALIZED__ = False
|
||||||
started = False
|
started = False
|
||||||
|
|
||||||
|
|
||||||
def sig_handler(signum=None, frame=None):
|
def sig_handler(signum=None, frame=None):
|
||||||
if type(signum) != type(None):
|
if type(signum) != type(None):
|
||||||
logger.log(u"Signal %i caught, saving and exiting..." % int(signum))
|
logger.log(u"Signal %i caught, saving and exiting..." % int(signum))
|
||||||
@ -1462,9 +1475,12 @@ def save_config():
|
|||||||
if hasattr(curTorrentProvider, 'search_fallback'):
|
if hasattr(curTorrentProvider, 'search_fallback'):
|
||||||
new_config[curTorrentProvider.getID().upper()][curTorrentProvider.getID() + '_search_fallback'] = int(
|
new_config[curTorrentProvider.getID().upper()][curTorrentProvider.getID() + '_search_fallback'] = int(
|
||||||
curTorrentProvider.search_fallback)
|
curTorrentProvider.search_fallback)
|
||||||
if hasattr(curTorrentProvider, 'backlog_only'):
|
if hasattr(curTorrentProvider, 'enable_daily'):
|
||||||
new_config[curTorrentProvider.getID().upper()][curTorrentProvider.getID() + '_backlog_only'] = int(
|
new_config[curTorrentProvider.getID().upper()][curTorrentProvider.getID() + '_enable_daily'] = int(
|
||||||
curTorrentProvider.backlog_only)
|
curTorrentProvider.enable_daily)
|
||||||
|
if hasattr(curTorrentProvider, 'enable_backlog'):
|
||||||
|
new_config[curTorrentProvider.getID().upper()][curTorrentProvider.getID() + '_enable_backlog'] = int(
|
||||||
|
curTorrentProvider.enable_backlog)
|
||||||
|
|
||||||
for curNzbProvider in [curProvider for curProvider in providers.sortedProviderList() if
|
for curNzbProvider in [curProvider for curProvider in providers.sortedProviderList() if
|
||||||
curProvider.providerType == GenericProvider.NZB]:
|
curProvider.providerType == GenericProvider.NZB]:
|
||||||
@ -1483,9 +1499,12 @@ def save_config():
|
|||||||
if hasattr(curNzbProvider, 'search_fallback'):
|
if hasattr(curNzbProvider, 'search_fallback'):
|
||||||
new_config[curNzbProvider.getID().upper()][curNzbProvider.getID() + '_search_fallback'] = int(
|
new_config[curNzbProvider.getID().upper()][curNzbProvider.getID() + '_search_fallback'] = int(
|
||||||
curNzbProvider.search_fallback)
|
curNzbProvider.search_fallback)
|
||||||
if hasattr(curNzbProvider, 'backlog_only'):
|
if hasattr(curNzbProvider, 'enable_daily'):
|
||||||
new_config[curNzbProvider.getID().upper()][curNzbProvider.getID() + '_backlog_only'] = int(
|
new_config[curNzbProvider.getID().upper()][curNzbProvider.getID() + '_enable_daily'] = int(
|
||||||
curNzbProvider.backlog_only)
|
curNzbProvider.enable_daily)
|
||||||
|
if hasattr(curNzbProvider, 'enable_backlog'):
|
||||||
|
new_config[curNzbProvider.getID().upper()][curNzbProvider.getID() + '_enable_backlog'] = int(
|
||||||
|
curNzbProvider.enable_backlog)
|
||||||
|
|
||||||
new_config['NZBs'] = {}
|
new_config['NZBs'] = {}
|
||||||
new_config['NZBs']['nzbs'] = int(NZBS)
|
new_config['NZBs']['nzbs'] = int(NZBS)
|
||||||
|
@ -22,6 +22,7 @@ import string
|
|||||||
from tornado.httputil import HTTPHeaders
|
from tornado.httputil import HTTPHeaders
|
||||||
from tornado.web import RequestHandler
|
from tornado.web import RequestHandler
|
||||||
from sickbeard import encodingKludge as ek
|
from sickbeard import encodingKludge as ek
|
||||||
|
from sickbeard import logger
|
||||||
|
|
||||||
# use the built-in if it's available (python 2.6), if not use the included library
|
# use the built-in if it's available (python 2.6), if not use the included library
|
||||||
try:
|
try:
|
||||||
@ -80,7 +81,12 @@ def foldersAtPath(path, includeParent=False, includeFiles=False):
|
|||||||
if path == parentPath and os.name == 'nt':
|
if path == parentPath and os.name == 'nt':
|
||||||
parentPath = ""
|
parentPath = ""
|
||||||
|
|
||||||
fileList = [{'name': filename, 'path': ek.ek(os.path.join, path, filename)} for filename in ek.ek(os.listdir, path)]
|
try:
|
||||||
|
fileList = [{'name': filename, 'path': ek.ek(os.path.join, path, filename)} for filename in ek.ek(os.listdir, path)]
|
||||||
|
except OSError, e:
|
||||||
|
logger.log(u"Unable to open " + path + ": " + repr(e) + " / " + str(e), logger.WARNING)
|
||||||
|
fileList = [{'name': filename, 'path': ek.ek(os.path.join, parentPath, filename)} for filename in ek.ek(os.listdir, parentPath)]
|
||||||
|
|
||||||
if not includeFiles:
|
if not includeFiles:
|
||||||
fileList = filter(lambda entry: ek.ek(os.path.isdir, entry['path']), fileList)
|
fileList = filter(lambda entry: ek.ek(os.path.isdir, entry['path']), fileList)
|
||||||
|
|
||||||
|
@ -148,8 +148,10 @@ class TorrentSearchResult(SearchResult):
|
|||||||
resultType = "torrent"
|
resultType = "torrent"
|
||||||
|
|
||||||
# torrent hash
|
# torrent hash
|
||||||
|
content = None
|
||||||
hash = None
|
hash = None
|
||||||
|
|
||||||
|
|
||||||
class AllShowsListUI:
|
class AllShowsListUI:
|
||||||
"""
|
"""
|
||||||
This class is for indexer api. Instead of prompting with a UI to pick the
|
This class is for indexer api. Instead of prompting with a UI to pick the
|
||||||
@ -178,7 +180,7 @@ class AllShowsListUI:
|
|||||||
seriesnames.append(curShow['seriesname'])
|
seriesnames.append(curShow['seriesname'])
|
||||||
if 'aliasnames' in curShow:
|
if 'aliasnames' in curShow:
|
||||||
seriesnames.extend(curShow['aliasnames'].split('|'))
|
seriesnames.extend(curShow['aliasnames'].split('|'))
|
||||||
|
|
||||||
for name in seriesnames:
|
for name in seriesnames:
|
||||||
if searchterm.lower() in name.lower():
|
if searchterm.lower() in name.lower():
|
||||||
if 'firstaired' not in curShow:
|
if 'firstaired' not in curShow:
|
||||||
@ -192,6 +194,7 @@ class AllShowsListUI:
|
|||||||
|
|
||||||
return searchResults
|
return searchResults
|
||||||
|
|
||||||
|
|
||||||
class ShowListUI:
|
class ShowListUI:
|
||||||
"""
|
"""
|
||||||
This class is for tvdb-api. Instead of prompting with a UI to pick the
|
This class is for tvdb-api. Instead of prompting with a UI to pick the
|
||||||
@ -225,7 +228,7 @@ class Proper:
|
|||||||
self.quality = Quality.UNKNOWN
|
self.quality = Quality.UNKNOWN
|
||||||
self.release_group = None
|
self.release_group = None
|
||||||
self.version = -1
|
self.version = -1
|
||||||
|
|
||||||
self.show = show
|
self.show = show
|
||||||
self.indexer = None
|
self.indexer = None
|
||||||
self.indexerid = -1
|
self.indexerid = -1
|
||||||
|
@ -104,6 +104,24 @@ class TransmissionAPI(GenericClient):
|
|||||||
|
|
||||||
return self.response.json()['result'] == "success"
|
return self.response.json()['result'] == "success"
|
||||||
|
|
||||||
|
def _set_torrent_seed_time(self, result):
|
||||||
|
|
||||||
|
if sickbeard.TORRENT_SEED_TIME:
|
||||||
|
time = 60 * float(sickbeard.TORRENT_SEED_TIME)
|
||||||
|
arguments = {'ids': [result.hash],
|
||||||
|
'seedIdleLimit': time,
|
||||||
|
'seedIdleMode': 1
|
||||||
|
}
|
||||||
|
|
||||||
|
post_data = json.dumps({'arguments': arguments,
|
||||||
|
'method': 'torrent-set',
|
||||||
|
})
|
||||||
|
self._request(method='post', data=post_data)
|
||||||
|
|
||||||
|
return self.response.json()['result'] == "success"
|
||||||
|
else:
|
||||||
|
return True
|
||||||
|
|
||||||
def _set_torrent_priority(self, result):
|
def _set_torrent_priority(self, result):
|
||||||
|
|
||||||
arguments = {'ids': [result.hash]}
|
arguments = {'ids': [result.hash]}
|
||||||
|
@ -40,67 +40,37 @@ class DailySearcher():
|
|||||||
|
|
||||||
self.amActive = True
|
self.amActive = True
|
||||||
|
|
||||||
didSearch = False
|
logger.log(u"Searching for coming episodes and 1 weeks worth of previously WANTED episodes ...")
|
||||||
|
|
||||||
providers = [x for x in sickbeard.providers.sortedProviderList() if x.isActive() and not x.backlog_only]
|
curDate = datetime.date.today().toordinal()
|
||||||
for curProviderCount, curProvider in enumerate(providers):
|
|
||||||
|
|
||||||
logger.log(u"Updating [" + curProvider.name + "] RSS cache ...")
|
myDB = db.DBConnection()
|
||||||
|
sqlResults = myDB.select("SELECT * FROM tv_episodes WHERE status = ? AND season > 0 AND airdate <= ?",
|
||||||
|
[common.UNAIRED, curDate])
|
||||||
|
|
||||||
|
sql_l = []
|
||||||
|
for sqlEp in sqlResults:
|
||||||
try:
|
try:
|
||||||
curProvider.cache.updateCache()
|
show = helpers.findCertainShow(sickbeard.showList, int(sqlEp["showid"]))
|
||||||
except exceptions.AuthException, e:
|
except exceptions.MultipleShowObjectsException:
|
||||||
logger.log(u"Authentication error: " + ex(e), logger.ERROR)
|
logger.log(u"ERROR: expected to find a single show matching " + sqlEp["showid"])
|
||||||
continue
|
|
||||||
except Exception, e:
|
|
||||||
logger.log(u"Error while updating cache for " + curProvider.name + ", skipping: " + ex(e), logger.ERROR)
|
|
||||||
logger.log(traceback.format_exc(), logger.DEBUG)
|
|
||||||
continue
|
continue
|
||||||
|
|
||||||
didSearch = True
|
ep = show.getEpisode(int(sqlEp["season"]), int(sqlEp["episode"]))
|
||||||
|
with ep.lock:
|
||||||
|
if ep.show.paused:
|
||||||
|
ep.status = common.SKIPPED
|
||||||
|
else:
|
||||||
|
ep.status = common.WANTED
|
||||||
|
|
||||||
if didSearch:
|
sql_l.append(ep.get_sql())
|
||||||
logger.log(u"Searching for coming episodes and 1 weeks worth of previously WANTED episodes ...")
|
|
||||||
|
|
||||||
fromDate = datetime.date.today() - datetime.timedelta(weeks=1)
|
|
||||||
curDate = datetime.date.today()
|
|
||||||
|
|
||||||
|
if len(sql_l) > 0:
|
||||||
myDB = db.DBConnection()
|
myDB = db.DBConnection()
|
||||||
sqlResults = myDB.select("SELECT * FROM tv_episodes WHERE status in (?,?) AND airdate >= ? AND airdate <= ?",
|
myDB.mass_action(sql_l)
|
||||||
[common.UNAIRED, common.WANTED, fromDate.toordinal(), curDate.toordinal()])
|
|
||||||
|
|
||||||
sql_l = []
|
# queue episode for daily search
|
||||||
for sqlEp in sqlResults:
|
dailysearch_queue_item = sickbeard.search_queue.DailySearchQueueItem()
|
||||||
try:
|
sickbeard.searchQueueScheduler.action.add_item(dailysearch_queue_item)
|
||||||
show = helpers.findCertainShow(sickbeard.showList, int(sqlEp["showid"]))
|
|
||||||
except exceptions.MultipleShowObjectsException:
|
|
||||||
logger.log(u"ERROR: expected to find a single show matching " + sqlEp["showid"])
|
|
||||||
continue
|
|
||||||
|
|
||||||
ep = show.getEpisode(int(sqlEp["season"]), int(sqlEp["episode"]))
|
|
||||||
with ep.lock:
|
|
||||||
if ep.show.paused:
|
|
||||||
ep.status = common.SKIPPED
|
|
||||||
|
|
||||||
if ep.status == common.UNAIRED:
|
|
||||||
logger.log(u"New episode " + ep.prettyName() + " airs today, setting status to WANTED")
|
|
||||||
ep.status = common.WANTED
|
|
||||||
|
|
||||||
sql_l.append(ep.get_sql())
|
|
||||||
|
|
||||||
if ep.status == common.WANTED:
|
|
||||||
dailysearch_queue_item = sickbeard.search_queue.DailySearchQueueItem(show, [ep])
|
|
||||||
sickbeard.searchQueueScheduler.action.add_item(dailysearch_queue_item)
|
|
||||||
else:
|
|
||||||
logger.log(u"Could not find any wanted episodes for the last 7 days to search for")
|
|
||||||
|
|
||||||
if len(sql_l) > 0:
|
|
||||||
myDB = db.DBConnection()
|
|
||||||
myDB.mass_action(sql_l)
|
|
||||||
|
|
||||||
else:
|
|
||||||
logger.log(
|
|
||||||
u"No NZB/Torrent providers found or enabled in the sickrage config. Please check your settings.",
|
|
||||||
logger.ERROR)
|
|
||||||
|
|
||||||
self.amActive = False
|
self.amActive = False
|
@ -210,21 +210,17 @@ def _remove_file_failed(file):
|
|||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
def findCertainShow(showList, indexerid):
|
def findCertainShow(showList, indexerid):
|
||||||
if not showList:
|
|
||||||
return None
|
|
||||||
|
|
||||||
results = []
|
results = []
|
||||||
if indexerid:
|
if showList and indexerid:
|
||||||
results = filter(lambda x: int(x.indexerid) == int(indexerid), showList)
|
results = filter(lambda x: int(x.indexerid) == int(indexerid), showList)
|
||||||
|
|
||||||
if len(results):
|
if len(results) == 1:
|
||||||
return results[0]
|
return results[0]
|
||||||
elif len(results) > 1:
|
elif len(results) > 1:
|
||||||
raise MultipleShowObjectsException()
|
raise MultipleShowObjectsException()
|
||||||
|
|
||||||
|
|
||||||
def makeDir(path):
|
def makeDir(path):
|
||||||
if not ek.ek(os.path.isdir, path):
|
if not ek.ek(os.path.isdir, path):
|
||||||
try:
|
try:
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
# SickRage is distributed in the hope that it will be useful,
|
# SickRage is distributed in the hope that it will be useful,
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
# GNU General Public License for more details.
|
# GNU General Public License for more details.
|
||||||
#
|
#
|
||||||
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with SickRage. If not, see <http://www.gnu.org/licenses/>.
|
# along with SickRage. If not, see <http://www.gnu.org/licenses/>.
|
||||||
@ -63,6 +63,7 @@ def sortedProviderList():
|
|||||||
|
|
||||||
return newList
|
return newList
|
||||||
|
|
||||||
|
|
||||||
def makeProviderList():
|
def makeProviderList():
|
||||||
return [x.provider for x in [getProviderModule(y) for y in __all__] if x]
|
return [x.provider for x in [getProviderModule(y) for y in __all__] if x]
|
||||||
|
|
||||||
@ -96,6 +97,8 @@ def getNewznabProviderList(data):
|
|||||||
providerDict[curDefault.name].needs_auth = curDefault.needs_auth
|
providerDict[curDefault.name].needs_auth = curDefault.needs_auth
|
||||||
providerDict[curDefault.name].search_mode = curDefault.search_mode
|
providerDict[curDefault.name].search_mode = curDefault.search_mode
|
||||||
providerDict[curDefault.name].search_fallback = curDefault.search_fallback
|
providerDict[curDefault.name].search_fallback = curDefault.search_fallback
|
||||||
|
providerDict[curDefault.name].enable_daily = curDefault.enable_daily
|
||||||
|
providerDict[curDefault.name].enable_backlog = curDefault.enable_backlog
|
||||||
|
|
||||||
return filter(lambda x: x, providerList)
|
return filter(lambda x: x, providerList)
|
||||||
|
|
||||||
@ -106,20 +109,28 @@ def makeNewznabProvider(configString):
|
|||||||
|
|
||||||
search_mode = 'eponly'
|
search_mode = 'eponly'
|
||||||
search_fallback = 0
|
search_fallback = 0
|
||||||
|
enable_daily = 0
|
||||||
|
enable_backlog = 0
|
||||||
|
|
||||||
try:
|
try:
|
||||||
name, url, key, catIDs, enabled, search_mode, search_fallback = configString.split('|')
|
values = configString.split('|')
|
||||||
|
if len(values) == 9:
|
||||||
|
name, url, key, catIDs, enabled, search_mode, search_fallback, enable_daily, enable_backlog = values
|
||||||
|
else:
|
||||||
|
name = values[0]
|
||||||
|
url = values[1]
|
||||||
|
key = values[2]
|
||||||
|
catIDs = values[3]
|
||||||
|
enabled = values[4]
|
||||||
except ValueError:
|
except ValueError:
|
||||||
try:
|
logger.log(u"Skipping Newznab provider string: '" + configString + "', incorrect format", logger.ERROR)
|
||||||
name, url, key, catIDs, enabled = configString.split('|')
|
return None
|
||||||
except ValueError:
|
|
||||||
logger.log(u"Skipping Newznab provider string: '" + configString + "', incorrect format", logger.ERROR)
|
|
||||||
return None
|
|
||||||
|
|
||||||
newznab = sys.modules['sickbeard.providers.newznab']
|
newznab = sys.modules['sickbeard.providers.newznab']
|
||||||
|
|
||||||
newProvider = newznab.NewznabProvider(name, url, key=key, catIDs=catIDs, search_mode=search_mode,
|
newProvider = newznab.NewznabProvider(name, url, key=key, catIDs=catIDs, search_mode=search_mode,
|
||||||
search_fallback=search_fallback)
|
search_fallback=search_fallback, enable_daily=enable_daily,
|
||||||
|
enable_backlog=enable_backlog)
|
||||||
newProvider.enabled = enabled == '1'
|
newProvider.enabled = enabled == '1'
|
||||||
|
|
||||||
return newProvider
|
return newProvider
|
||||||
@ -146,33 +157,36 @@ def makeTorrentRssProvider(configString):
|
|||||||
cookies = None
|
cookies = None
|
||||||
search_mode = 'eponly'
|
search_mode = 'eponly'
|
||||||
search_fallback = 0
|
search_fallback = 0
|
||||||
backlog_only = 0
|
enable_daily = 0
|
||||||
|
enable_backlog = 0
|
||||||
|
|
||||||
try:
|
try:
|
||||||
name, url, cookies, enabled, search_mode, search_fallback, backlog_only = configString.split('|')
|
values = configString.split('|')
|
||||||
|
if len(values) == 8:
|
||||||
|
name, url, cookies, enabled, search_mode, search_fallback, enable_daily, enable_backlog = values
|
||||||
|
else:
|
||||||
|
name = values[0]
|
||||||
|
url = values[1]
|
||||||
|
enabled = values[3]
|
||||||
except ValueError:
|
except ValueError:
|
||||||
try:
|
logger.log(u"Skipping RSS Torrent provider string: '" + configString + "', incorrect format",
|
||||||
name, url, enabled, search_mode, search_fallback, backlog_only = configString.split('|')
|
logger.ERROR)
|
||||||
except ValueError:
|
return None
|
||||||
try:
|
|
||||||
name, url, enabled = configString.split('|')
|
|
||||||
except ValueError:
|
|
||||||
logger.log(u"Skipping RSS Torrent provider string: '" + configString + "', incorrect format", logger.ERROR)
|
|
||||||
return None
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
torrentRss = sys.modules['sickbeard.providers.rsstorrent']
|
torrentRss = sys.modules['sickbeard.providers.rsstorrent']
|
||||||
except:
|
except:
|
||||||
return
|
return
|
||||||
|
|
||||||
newProvider = torrentRss.TorrentRssProvider(name, url, cookies, search_mode, search_fallback, backlog_only)
|
newProvider = torrentRss.TorrentRssProvider(name, url, cookies, search_mode, search_fallback, enable_daily,
|
||||||
|
enable_backlog)
|
||||||
newProvider.enabled = enabled == '1'
|
newProvider.enabled = enabled == '1'
|
||||||
|
|
||||||
return newProvider
|
return newProvider
|
||||||
|
|
||||||
|
|
||||||
def getDefaultNewznabProviders():
|
def getDefaultNewznabProviders():
|
||||||
return 'Sick Beard Index|http://lolo.sickbeard.com/|0|5030,5040|0|eponly|0!!!NZBs.org|https://nzbs.org/||5030,5040|0|eponly|0!!!Usenet-Crawler|https://www.usenet-crawler.com/||5030,5040|0|eponly|0'
|
return 'Sick Beard Index|http://lolo.sickbeard.com/|0|5030,5040|0|eponly|0|0|0!!!NZBs.org|https://nzbs.org/|0|5030,5040|0|eponly|0|0|0!!!Usenet-Crawler|https://www.usenet-crawler.com/|0|5030,5040|0|eponly|0|0|0'
|
||||||
|
|
||||||
|
|
||||||
def getProviderModule(name):
|
def getProviderModule(name):
|
||||||
|
@ -133,7 +133,7 @@ class AnimezbCache(tvcache.TVCache):
|
|||||||
# only poll Animezb every 20 minutes max
|
# only poll Animezb every 20 minutes max
|
||||||
self.minTime = 20
|
self.minTime = 20
|
||||||
|
|
||||||
def _getDailyData(self):
|
def _getRSSData(self):
|
||||||
|
|
||||||
params = {
|
params = {
|
||||||
"cat": "anime".encode('utf-8'),
|
"cat": "anime".encode('utf-8'),
|
||||||
|
@ -274,7 +274,7 @@ class BitSoupCache(tvcache.TVCache):
|
|||||||
# only poll TorrentBytes every 20 minutes max
|
# only poll TorrentBytes every 20 minutes max
|
||||||
self.minTime = 20
|
self.minTime = 20
|
||||||
|
|
||||||
def _getDailyData(self):
|
def _getRSSData(self):
|
||||||
search_params = {'RSS': ['']}
|
search_params = {'RSS': ['']}
|
||||||
return self.provider._doSearch(search_params)
|
return self.provider._doSearch(search_params)
|
||||||
|
|
||||||
|
@ -297,7 +297,7 @@ class BTNCache(tvcache.TVCache):
|
|||||||
# At least 15 minutes between queries
|
# At least 15 minutes between queries
|
||||||
self.minTime = 15
|
self.minTime = 15
|
||||||
|
|
||||||
def _getDailyData(self):
|
def _getRSSData(self):
|
||||||
# Get the torrents uploaded since last check.
|
# Get the torrents uploaded since last check.
|
||||||
seconds_since_last_update = math.ceil(time.time() - time.mktime(self._getLastUpdate().timetuple()))
|
seconds_since_last_update = math.ceil(time.time() - time.mktime(self._getLastUpdate().timetuple()))
|
||||||
|
|
||||||
|
@ -174,7 +174,7 @@ class EZRSSCache(tvcache.TVCache):
|
|||||||
# only poll EZRSS every 15 minutes max
|
# only poll EZRSS every 15 minutes max
|
||||||
self.minTime = 15
|
self.minTime = 15
|
||||||
|
|
||||||
def _getDailyData(self):
|
def _getRSSData(self):
|
||||||
|
|
||||||
rss_url = self.provider.url + 'feed/'
|
rss_url = self.provider.url + 'feed/'
|
||||||
logger.log(self.provider.name + " cache update URL: " + rss_url, logger.DEBUG)
|
logger.log(self.provider.name + " cache update URL: " + rss_url, logger.DEBUG)
|
||||||
|
@ -128,7 +128,7 @@ class FanzubCache(tvcache.TVCache):
|
|||||||
# only poll Fanzub every 20 minutes max
|
# only poll Fanzub every 20 minutes max
|
||||||
self.minTime = 20
|
self.minTime = 20
|
||||||
|
|
||||||
def _getDailyData(self):
|
def _getRSSData(self):
|
||||||
|
|
||||||
params = {
|
params = {
|
||||||
"cat": "anime".encode('utf-8'),
|
"cat": "anime".encode('utf-8'),
|
||||||
|
@ -306,7 +306,7 @@ class FreshOnTVCache(tvcache.TVCache):
|
|||||||
# poll delay in minutes
|
# poll delay in minutes
|
||||||
self.minTime = 20
|
self.minTime = 20
|
||||||
|
|
||||||
def _getDailyData(self):
|
def _getRSSData(self):
|
||||||
search_params = {'RSS': ['']}
|
search_params = {'RSS': ['']}
|
||||||
return self.provider._doSearch(search_params)
|
return self.provider._doSearch(search_params)
|
||||||
|
|
||||||
|
@ -55,7 +55,8 @@ class GenericProvider:
|
|||||||
|
|
||||||
self.search_mode = None
|
self.search_mode = None
|
||||||
self.search_fallback = False
|
self.search_fallback = False
|
||||||
self.backlog_only = False
|
self.enable_daily = False
|
||||||
|
self.enable_backlog = False
|
||||||
|
|
||||||
self.cache = tvcache.TVCache(self)
|
self.cache = tvcache.TVCache(self)
|
||||||
|
|
||||||
@ -194,8 +195,8 @@ class GenericProvider:
|
|||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def searchRSS(self, episodes):
|
def searchRSS(self):
|
||||||
return self.cache.findNeededEpisodes(episodes)
|
return self.cache.findNeededEpisodes()
|
||||||
|
|
||||||
def getQuality(self, item, anime=False):
|
def getQuality(self, item, anime=False):
|
||||||
"""
|
"""
|
||||||
@ -254,10 +255,15 @@ class GenericProvider:
|
|||||||
|
|
||||||
searched_scene_season = None
|
searched_scene_season = None
|
||||||
for epObj in episodes:
|
for epObj in episodes:
|
||||||
# check cache for results
|
# search cache for episode result
|
||||||
cacheResult = self.cache.searchCache([epObj], manualSearch)
|
cacheResult = self.cache.searchCache(epObj, manualSearch)
|
||||||
if len(cacheResult):
|
if cacheResult:
|
||||||
results.update({epObj.episode: cacheResult[epObj]})
|
if epObj not in results:
|
||||||
|
results = [cacheResult]
|
||||||
|
else:
|
||||||
|
results.append(cacheResult)
|
||||||
|
|
||||||
|
# found result, search next episode
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# skip if season already searched
|
# skip if season already searched
|
||||||
|
@ -204,7 +204,7 @@ class HDBitsCache(tvcache.TVCache):
|
|||||||
# only poll HDBits every 15 minutes max
|
# only poll HDBits every 15 minutes max
|
||||||
self.minTime = 15
|
self.minTime = 15
|
||||||
|
|
||||||
def _getDailyData(self):
|
def _getRSSData(self):
|
||||||
parsedJSON = self.provider.getURL(self.provider.rss_url, post_data=self.provider._make_post_data_JSON(), json=True)
|
parsedJSON = self.provider.getURL(self.provider.rss_url, post_data=self.provider._make_post_data_JSON(), json=True)
|
||||||
|
|
||||||
if not self.provider._checkAuthFromData(parsedJSON):
|
if not self.provider._checkAuthFromData(parsedJSON):
|
||||||
|
@ -336,7 +336,7 @@ class HDTorrentsCache(tvcache.TVCache):
|
|||||||
# only poll HDTorrents every 10 minutes max
|
# only poll HDTorrents every 10 minutes max
|
||||||
self.minTime = 20
|
self.minTime = 20
|
||||||
|
|
||||||
def _getDailyData(self):
|
def _getRSSData(self):
|
||||||
search_params = {'RSS': []}
|
search_params = {'RSS': []}
|
||||||
return self.provider._doSearch(search_params)
|
return self.provider._doSearch(search_params)
|
||||||
|
|
||||||
|
@ -276,7 +276,7 @@ class IPTorrentsCache(tvcache.TVCache):
|
|||||||
# Only poll IPTorrents every 10 minutes max
|
# Only poll IPTorrents every 10 minutes max
|
||||||
self.minTime = 10
|
self.minTime = 10
|
||||||
|
|
||||||
def _getDailyData(self):
|
def _getRSSData(self):
|
||||||
search_params = {'RSS': ['']}
|
search_params = {'RSS': ['']}
|
||||||
return self.provider._doSearch(search_params)
|
return self.provider._doSearch(search_params)
|
||||||
|
|
||||||
|
@ -355,7 +355,7 @@ class KATCache(tvcache.TVCache):
|
|||||||
# only poll ThePirateBay every 10 minutes max
|
# only poll ThePirateBay every 10 minutes max
|
||||||
self.minTime = 20
|
self.minTime = 20
|
||||||
|
|
||||||
def _getDailyData(self):
|
def _getRSSData(self):
|
||||||
search_params = {'RSS': ['rss']}
|
search_params = {'RSS': ['rss']}
|
||||||
return self.provider._doSearch(search_params)
|
return self.provider._doSearch(search_params)
|
||||||
|
|
||||||
|
@ -33,14 +33,14 @@ from sickbeard import classes
|
|||||||
from sickbeard import helpers
|
from sickbeard import helpers
|
||||||
from sickbeard import scene_exceptions
|
from sickbeard import scene_exceptions
|
||||||
from sickbeard import encodingKludge as ek
|
from sickbeard import encodingKludge as ek
|
||||||
from sickbeard.common import cpu_presets
|
|
||||||
from sickbeard import logger
|
from sickbeard import logger
|
||||||
from sickbeard import tvcache
|
from sickbeard import tvcache
|
||||||
from sickbeard.exceptions import ex, AuthException
|
from sickbeard.exceptions import ex, AuthException
|
||||||
|
|
||||||
|
|
||||||
class NewznabProvider(generic.NZBProvider):
|
class NewznabProvider(generic.NZBProvider):
|
||||||
def __init__(self, name, url, key='', catIDs='5030,5040', search_mode='eponly', search_fallback=False):
|
def __init__(self, name, url, key='', catIDs='5030,5040', search_mode='eponly', search_fallback=False,
|
||||||
|
enable_daily=False, enable_backlog=False):
|
||||||
|
|
||||||
generic.NZBProvider.__init__(self, name)
|
generic.NZBProvider.__init__(self, name)
|
||||||
|
|
||||||
@ -52,6 +52,8 @@ class NewznabProvider(generic.NZBProvider):
|
|||||||
|
|
||||||
self.search_mode = search_mode
|
self.search_mode = search_mode
|
||||||
self.search_fallback = search_fallback
|
self.search_fallback = search_fallback
|
||||||
|
self.enable_daily = enable_daily
|
||||||
|
self.enable_backlog = enable_backlog
|
||||||
|
|
||||||
# a 0 in the key spot indicates that no key is needed
|
# a 0 in the key spot indicates that no key is needed
|
||||||
if self.key == '0':
|
if self.key == '0':
|
||||||
@ -71,10 +73,13 @@ class NewznabProvider(generic.NZBProvider):
|
|||||||
|
|
||||||
def configStr(self):
|
def configStr(self):
|
||||||
return self.name + '|' + self.url + '|' + self.key + '|' + self.catIDs + '|' + str(
|
return self.name + '|' + self.url + '|' + self.key + '|' + self.catIDs + '|' + str(
|
||||||
int(self.enabled)) + '|' + self.search_mode + '|' + str(int(self.search_fallback))
|
int(self.enabled)) + '|' + self.search_mode + '|' + str(int(self.search_fallback)) + '|' + str(
|
||||||
|
int(self.enable_daily)) + '|' + str(int(self.enable_backlog))
|
||||||
|
|
||||||
def imageName(self):
|
def imageName(self):
|
||||||
if ek.ek(os.path.isfile, ek.ek(os.path.join, sickbeard.PROG_DIR, 'gui', sickbeard.GUI_NAME, 'images', 'providers', self.getID() + '.png')):
|
if ek.ek(os.path.isfile,
|
||||||
|
ek.ek(os.path.join, sickbeard.PROG_DIR, 'gui', sickbeard.GUI_NAME, 'images', 'providers',
|
||||||
|
self.getID() + '.png')):
|
||||||
return self.getID() + '.png'
|
return self.getID() + '.png'
|
||||||
return 'newznab.png'
|
return 'newznab.png'
|
||||||
|
|
||||||
@ -99,16 +104,17 @@ class NewznabProvider(generic.NZBProvider):
|
|||||||
# search
|
# search
|
||||||
rid = helpers.mapIndexersToShow(ep_obj.show)[2]
|
rid = helpers.mapIndexersToShow(ep_obj.show)[2]
|
||||||
if rid:
|
if rid:
|
||||||
cur_params['rid'] = rid
|
cur_return = cur_params.copy()
|
||||||
|
cur_return['rid'] = rid
|
||||||
|
to_return.append(cur_return)
|
||||||
|
|
||||||
|
# add new query strings for exceptions
|
||||||
|
name_exceptions = list(
|
||||||
|
set(scene_exceptions.get_scene_exceptions(ep_obj.show.indexerid) + [ep_obj.show.name]))
|
||||||
|
for cur_exception in name_exceptions:
|
||||||
|
if 'q' in cur_params:
|
||||||
|
cur_params['q'] = helpers.sanitizeSceneName(cur_exception) + '.' + cur_params['q']
|
||||||
to_return.append(cur_params)
|
to_return.append(cur_params)
|
||||||
else:
|
|
||||||
# add new query strings for exceptions
|
|
||||||
name_exceptions = list(
|
|
||||||
set(scene_exceptions.get_scene_exceptions(ep_obj.show.indexerid) + [ep_obj.show.name]))
|
|
||||||
for cur_exception in name_exceptions:
|
|
||||||
if 'q' in cur_params:
|
|
||||||
cur_params['q'] = helpers.sanitizeSceneName(cur_exception) + '.' + cur_params['q']
|
|
||||||
to_return.append(cur_params)
|
|
||||||
|
|
||||||
return to_return
|
return to_return
|
||||||
|
|
||||||
@ -132,14 +138,16 @@ class NewznabProvider(generic.NZBProvider):
|
|||||||
# search
|
# search
|
||||||
rid = helpers.mapIndexersToShow(ep_obj.show)[2]
|
rid = helpers.mapIndexersToShow(ep_obj.show)[2]
|
||||||
if rid:
|
if rid:
|
||||||
params['rid'] = rid
|
cur_return = params.copy()
|
||||||
|
cur_return['rid'] = rid
|
||||||
|
to_return.append(cur_return)
|
||||||
|
|
||||||
|
# add new query strings for exceptions
|
||||||
|
name_exceptions = list(
|
||||||
|
set(scene_exceptions.get_scene_exceptions(ep_obj.show.indexerid) + [ep_obj.show.name]))
|
||||||
|
for cur_exception in name_exceptions:
|
||||||
|
params['q'] = helpers.sanitizeSceneName(cur_exception)
|
||||||
to_return.append(params)
|
to_return.append(params)
|
||||||
else:
|
|
||||||
# add new query strings for exceptions
|
|
||||||
name_exceptions = list(set(scene_exceptions.get_scene_exceptions(ep_obj.show.indexerid) + [ep_obj.show.name]))
|
|
||||||
for cur_exception in name_exceptions:
|
|
||||||
params['q'] = helpers.sanitizeSceneName(cur_exception)
|
|
||||||
to_return.append(params)
|
|
||||||
|
|
||||||
return to_return
|
return to_return
|
||||||
|
|
||||||
@ -234,7 +242,9 @@ class NewznabProvider(generic.NZBProvider):
|
|||||||
# if there are more items available then the amount given in one call, grab some more
|
# if there are more items available then the amount given in one call, grab some more
|
||||||
if (total - params['limit']) > offset == params['offset']:
|
if (total - params['limit']) > offset == params['offset']:
|
||||||
params['offset'] += params['limit']
|
params['offset'] += params['limit']
|
||||||
logger.log(str(total - params['offset']) + " more items to be fetched from provider. Fetching another " + str(params['limit']) + " items.", logger.DEBUG)
|
logger.log(str(
|
||||||
|
total - params['offset']) + " more items to be fetched from provider. Fetching another " + str(
|
||||||
|
params['limit']) + " items.", logger.DEBUG)
|
||||||
else:
|
else:
|
||||||
break
|
break
|
||||||
|
|
||||||
@ -327,21 +337,18 @@ class NewznabCache(tvcache.TVCache):
|
|||||||
|
|
||||||
def updateCache(self):
|
def updateCache(self):
|
||||||
|
|
||||||
# delete anything older then 7 days
|
if self.shouldUpdate() and self._checkAuth(None):
|
||||||
self._clearCache()
|
|
||||||
|
|
||||||
if not self.shouldUpdate():
|
|
||||||
return
|
|
||||||
|
|
||||||
if self._checkAuth(None):
|
|
||||||
data = self._getRSSData()
|
data = self._getRSSData()
|
||||||
|
|
||||||
# as long as the http request worked we count this as an update
|
# as long as the http request worked we count this as an update
|
||||||
if data:
|
if not data:
|
||||||
self.setLastUpdate()
|
|
||||||
else:
|
|
||||||
return []
|
return []
|
||||||
|
|
||||||
|
self.setLastUpdate()
|
||||||
|
|
||||||
|
# clear cache
|
||||||
|
self._clearCache()
|
||||||
|
|
||||||
if self._checkAuth(data):
|
if self._checkAuth(data):
|
||||||
items = data.entries
|
items = data.entries
|
||||||
cl = []
|
cl = []
|
||||||
@ -360,7 +367,6 @@ class NewznabCache(tvcache.TVCache):
|
|||||||
|
|
||||||
return []
|
return []
|
||||||
|
|
||||||
|
|
||||||
# overwrite method with that parses the rageid from the newznab feed
|
# overwrite method with that parses the rageid from the newznab feed
|
||||||
def _parseItem(self, item):
|
def _parseItem(self, item):
|
||||||
title = item.title
|
title = item.title
|
||||||
|
@ -318,7 +318,7 @@ class NextGenCache(tvcache.TVCache):
|
|||||||
# Only poll NextGen every 10 minutes max
|
# Only poll NextGen every 10 minutes max
|
||||||
self.minTime = 10
|
self.minTime = 10
|
||||||
|
|
||||||
def _getDailyData(self):
|
def _getRSSData(self):
|
||||||
search_params = {'RSS': ['']}
|
search_params = {'RSS': ['']}
|
||||||
return self.provider._doSearch(search_params)
|
return self.provider._doSearch(search_params)
|
||||||
|
|
||||||
|
@ -126,7 +126,7 @@ class NyaaCache(tvcache.TVCache):
|
|||||||
# only poll NyaaTorrents every 15 minutes max
|
# only poll NyaaTorrents every 15 minutes max
|
||||||
self.minTime = 15
|
self.minTime = 15
|
||||||
|
|
||||||
def _getDailyData(self):
|
def _getRSSData(self):
|
||||||
params = {
|
params = {
|
||||||
"page": 'rss', # Use RSS page
|
"page": 'rss', # Use RSS page
|
||||||
"order": '1', # Sort Descending By Date
|
"order": '1', # Sort Descending By Date
|
||||||
|
@ -174,7 +174,7 @@ class OmgwtfnzbsCache(tvcache.TVCache):
|
|||||||
|
|
||||||
return (title, url)
|
return (title, url)
|
||||||
|
|
||||||
def _getDailyData(self):
|
def _getRSSData(self):
|
||||||
params = {'user': provider.username,
|
params = {'user': provider.username,
|
||||||
'api': provider.api_key,
|
'api': provider.api_key,
|
||||||
'eng': 1,
|
'eng': 1,
|
||||||
|
@ -34,8 +34,10 @@ from lib import requests
|
|||||||
from lib.requests import exceptions
|
from lib.requests import exceptions
|
||||||
from lib.bencode import bdecode
|
from lib.bencode import bdecode
|
||||||
|
|
||||||
|
|
||||||
class TorrentRssProvider(generic.TorrentProvider):
|
class TorrentRssProvider(generic.TorrentProvider):
|
||||||
def __init__(self, name, url, cookies='', search_mode='eponly', search_fallback=False, backlog_only=False):
|
def __init__(self, name, url, cookies='', search_mode='eponly', search_fallback=False, enable_daily=False,
|
||||||
|
enable_backlog=False):
|
||||||
generic.TorrentProvider.__init__(self, name)
|
generic.TorrentProvider.__init__(self, name)
|
||||||
self.cache = TorrentRssCache(self)
|
self.cache = TorrentRssCache(self)
|
||||||
self.url = re.sub('\/$', '', url)
|
self.url = re.sub('\/$', '', url)
|
||||||
@ -46,14 +48,19 @@ class TorrentRssProvider(generic.TorrentProvider):
|
|||||||
|
|
||||||
self.search_mode = search_mode
|
self.search_mode = search_mode
|
||||||
self.search_fallback = search_fallback
|
self.search_fallback = search_fallback
|
||||||
self.backlog_only = backlog_only
|
self.enable_daily = enable_daily
|
||||||
|
self.enable_backlog = enable_backlog
|
||||||
self.cookies = cookies
|
self.cookies = cookies
|
||||||
|
|
||||||
def configStr(self):
|
def configStr(self):
|
||||||
return self.name + '|' + self.url + '|' + self.cookies + '|' + str(int(self.enabled)) + '|' + self.search_mode + '|' + str(int(self.search_fallback)) + '|' + str(int(self.backlog_only))
|
return self.name + '|' + self.url + '|' + self.cookies + '|' + str(
|
||||||
|
int(self.enabled)) + '|' + self.search_mode + '|' + str(int(self.search_fallback)) + '|' + str(
|
||||||
|
int(self.enable_daily)) + '|' + str(int(self.enable_backlog))
|
||||||
|
|
||||||
def imageName(self):
|
def imageName(self):
|
||||||
if ek.ek(os.path.isfile, ek.ek(os.path.join, sickbeard.PROG_DIR, 'gui', sickbeard.GUI_NAME, 'images', 'providers', self.getID() + '.png')):
|
if ek.ek(os.path.isfile,
|
||||||
|
ek.ek(os.path.join, sickbeard.PROG_DIR, 'gui', sickbeard.GUI_NAME, 'images', 'providers',
|
||||||
|
self.getID() + '.png')):
|
||||||
return self.getID() + '.png'
|
return self.getID() + '.png'
|
||||||
return 'torrentrss.png'
|
return 'torrentrss.png'
|
||||||
|
|
||||||
@ -91,12 +98,12 @@ class TorrentRssProvider(generic.TorrentProvider):
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
if self.cookies:
|
if self.cookies:
|
||||||
cookie_validator=re.compile("^(\w+=\w+)(;\w+=\w+)*$")
|
cookie_validator = re.compile("^(\w+=\w+)(;\w+=\w+)*$")
|
||||||
if not cookie_validator.match(self.cookies):
|
if not cookie_validator.match(self.cookies):
|
||||||
return (False, 'Cookie is not correctly formatted: ' + self.cookies)
|
return (False, 'Cookie is not correctly formatted: ' + self.cookies)
|
||||||
|
|
||||||
items = self.cache._getDailyData()
|
items = self.cache._getRSSData()
|
||||||
|
|
||||||
if not len(items) > 0:
|
if not len(items) > 0:
|
||||||
return (False, 'No items found in the RSS feed ' + self.url)
|
return (False, 'No items found in the RSS feed ' + self.url)
|
||||||
|
|
||||||
@ -144,17 +151,18 @@ class TorrentRssProvider(generic.TorrentProvider):
|
|||||||
def seedRatio(self):
|
def seedRatio(self):
|
||||||
return self.ratio
|
return self.ratio
|
||||||
|
|
||||||
|
|
||||||
class TorrentRssCache(tvcache.TVCache):
|
class TorrentRssCache(tvcache.TVCache):
|
||||||
def __init__(self, provider):
|
def __init__(self, provider):
|
||||||
tvcache.TVCache.__init__(self, provider)
|
tvcache.TVCache.__init__(self, provider)
|
||||||
self.minTime = 15
|
self.minTime = 15
|
||||||
|
|
||||||
def _getDailyData(self):
|
def _getRSSData(self):
|
||||||
logger.log(u"TorrentRssCache cache update URL: " + self.provider.url, logger.DEBUG)
|
logger.log(u"TorrentRssCache cache update URL: " + self.provider.url, logger.DEBUG)
|
||||||
|
|
||||||
request_headers = None
|
request_headers = None
|
||||||
if self.provider.cookies:
|
if self.provider.cookies:
|
||||||
request_headers = { 'Cookie': self.provider.cookies }
|
request_headers = {'Cookie': self.provider.cookies}
|
||||||
|
|
||||||
data = self.getRSSFeed(self.provider.url, request_headers=request_headers)
|
data = self.getRSSFeed(self.provider.url, request_headers=request_headers)
|
||||||
|
|
||||||
|
@ -312,7 +312,7 @@ class SCCCache(tvcache.TVCache):
|
|||||||
# only poll SCC every 10 minutes max
|
# only poll SCC every 10 minutes max
|
||||||
self.minTime = 20
|
self.minTime = 20
|
||||||
|
|
||||||
def _getDailyData(self):
|
def _getRSSData(self):
|
||||||
search_params = {'RSS': ['']}
|
search_params = {'RSS': ['']}
|
||||||
return self.provider._doSearch(search_params)
|
return self.provider._doSearch(search_params)
|
||||||
|
|
||||||
|
@ -252,7 +252,7 @@ class SpeedCDCache(tvcache.TVCache):
|
|||||||
# only poll Speedcd every 20 minutes max
|
# only poll Speedcd every 20 minutes max
|
||||||
self.minTime = 20
|
self.minTime = 20
|
||||||
|
|
||||||
def _getDailyData(self):
|
def _getRSSData(self):
|
||||||
search_params = {'RSS': ['']}
|
search_params = {'RSS': ['']}
|
||||||
return self.provider._doSearch(search_params)
|
return self.provider._doSearch(search_params)
|
||||||
|
|
||||||
|
@ -338,7 +338,7 @@ class ThePirateBayCache(tvcache.TVCache):
|
|||||||
# only poll ThePirateBay every 10 minutes max
|
# only poll ThePirateBay every 10 minutes max
|
||||||
self.minTime = 20
|
self.minTime = 20
|
||||||
|
|
||||||
def _getDailyData(self):
|
def _getRSSData(self):
|
||||||
search_params = {'RSS': ['rss']}
|
search_params = {'RSS': ['rss']}
|
||||||
return self.provider._doSearch(search_params)
|
return self.provider._doSearch(search_params)
|
||||||
|
|
||||||
|
@ -274,7 +274,7 @@ class TorrentBytesCache(tvcache.TVCache):
|
|||||||
# only poll TorrentBytes every 20 minutes max
|
# only poll TorrentBytes every 20 minutes max
|
||||||
self.minTime = 20
|
self.minTime = 20
|
||||||
|
|
||||||
def _getDailyData(self):
|
def _getRSSData(self):
|
||||||
search_params = {'RSS': ['']}
|
search_params = {'RSS': ['']}
|
||||||
return self.provider._doSearch(search_params)
|
return self.provider._doSearch(search_params)
|
||||||
|
|
||||||
|
@ -277,7 +277,7 @@ class TorrentDayCache(tvcache.TVCache):
|
|||||||
# Only poll IPTorrents every 10 minutes max
|
# Only poll IPTorrents every 10 minutes max
|
||||||
self.minTime = 10
|
self.minTime = 10
|
||||||
|
|
||||||
def _getDailyData(self):
|
def _getRSSData(self):
|
||||||
search_params = {'RSS': ['']}
|
search_params = {'RSS': ['']}
|
||||||
return self.provider._doSearch(search_params)
|
return self.provider._doSearch(search_params)
|
||||||
|
|
||||||
|
@ -275,7 +275,7 @@ class TorrentLeechCache(tvcache.TVCache):
|
|||||||
# only poll TorrentLeech every 20 minutes max
|
# only poll TorrentLeech every 20 minutes max
|
||||||
self.minTime = 20
|
self.minTime = 20
|
||||||
|
|
||||||
def _getDailyData(self):
|
def _getRSSData(self):
|
||||||
search_params = {'RSS': ['']}
|
search_params = {'RSS': ['']}
|
||||||
return self.provider._doSearch(search_params)
|
return self.provider._doSearch(search_params)
|
||||||
|
|
||||||
|
@ -83,7 +83,7 @@ class TvTorrentsCache(tvcache.TVCache):
|
|||||||
# only poll TvTorrents every 15 minutes max
|
# only poll TvTorrents every 15 minutes max
|
||||||
self.minTime = 15
|
self.minTime = 15
|
||||||
|
|
||||||
def _getDailyData(self):
|
def _getRSSData(self):
|
||||||
# These will be ignored on the serverside.
|
# These will be ignored on the serverside.
|
||||||
ignore_regex = "all.month|month.of|season[\s\d]*complete"
|
ignore_regex = "all.month|month.of|season[\s\d]*complete"
|
||||||
|
|
||||||
|
@ -40,17 +40,17 @@ class RSSFeeds:
|
|||||||
fc = cache.Cache(fs)
|
fc = cache.Cache(fs)
|
||||||
feed = fc.fetch(url, False, False, request_headers)
|
feed = fc.fetch(url, False, False, request_headers)
|
||||||
|
|
||||||
if not feed or not feed.entries:
|
if feed:
|
||||||
logger.log(u"RSS error loading url: " + url, logger.DEBUG)
|
if 'entries' in feed:
|
||||||
return
|
return feed
|
||||||
elif 'error' in feed.feed:
|
elif 'error' in feed.feed:
|
||||||
err_code = feed.feed['error']['code']
|
err_code = feed.feed['error']['code']
|
||||||
err_desc = feed.feed['error']['description']
|
err_desc = feed.feed['error']['description']
|
||||||
|
|
||||||
logger.log(
|
logger.log(
|
||||||
u"RSS ERROR:[%s] CODE:[%s]" % (err_desc, err_code), logger.DEBUG)
|
u"RSS ERROR:[%s] CODE:[%s]" % (err_desc, err_code), logger.DEBUG)
|
||||||
return
|
|
||||||
else:
|
else:
|
||||||
return feed
|
logger.log(u"RSS error loading url: " + url, logger.DEBUG)
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.log(u"RSS error: " + ex(e), logger.DEBUG)
|
logger.log(u"RSS error: " + ex(e), logger.DEBUG)
|
@ -53,7 +53,7 @@ def get_scene_numbering(indexer_id, indexer, season, episode, fallback_to_xem=Tr
|
|||||||
return (season, episode)
|
return (season, episode)
|
||||||
|
|
||||||
showObj = sickbeard.helpers.findCertainShow(sickbeard.showList, int(indexer_id))
|
showObj = sickbeard.helpers.findCertainShow(sickbeard.showList, int(indexer_id))
|
||||||
if not showObj.is_scene:
|
if showObj and not showObj.is_scene:
|
||||||
return (season, episode)
|
return (season, episode)
|
||||||
|
|
||||||
result = find_scene_numbering(int(indexer_id), int(indexer), season, episode)
|
result = find_scene_numbering(int(indexer_id), int(indexer), season, episode)
|
||||||
@ -105,7 +105,7 @@ def get_scene_absolute_numbering(indexer_id, indexer, absolute_number, fallback_
|
|||||||
indexer = int(indexer)
|
indexer = int(indexer)
|
||||||
|
|
||||||
showObj = sickbeard.helpers.findCertainShow(sickbeard.showList, indexer_id)
|
showObj = sickbeard.helpers.findCertainShow(sickbeard.showList, indexer_id)
|
||||||
if not showObj.is_scene:
|
if showObj and not showObj.is_scene:
|
||||||
return absolute_number
|
return absolute_number
|
||||||
|
|
||||||
result = find_scene_absolute_numbering(indexer_id, indexer, absolute_number)
|
result = find_scene_absolute_numbering(indexer_id, indexer, absolute_number)
|
||||||
|
@ -336,23 +336,21 @@ def filterSearchResults(show, season, results):
|
|||||||
|
|
||||||
return foundResults
|
return foundResults
|
||||||
|
|
||||||
def searchForNeededEpisodes(show, episodes):
|
def searchForNeededEpisodes():
|
||||||
foundResults = {}
|
foundResults = {}
|
||||||
|
|
||||||
didSearch = False
|
didSearch = False
|
||||||
|
|
||||||
origThreadName = threading.currentThread().name
|
origThreadName = threading.currentThread().name
|
||||||
|
|
||||||
providers = [x for x in sickbeard.providers.sortedProviderList() if x.isActive() and not x.backlog_only]
|
providers = [x for x in sickbeard.providers.sortedProviderList() if x.isActive() and x.enable_daily]
|
||||||
for curProviderCount, curProvider in enumerate(providers):
|
for curProvider in providers:
|
||||||
if curProvider.anime_only and not show.is_anime:
|
|
||||||
logger.log(u"" + str(show.name) + " is not an anime, skiping", logger.DEBUG)
|
|
||||||
continue
|
|
||||||
|
|
||||||
threading.currentThread().name = origThreadName + " :: [" + curProvider.name + "]"
|
threading.currentThread().name = origThreadName + " :: [" + curProvider.name + "]"
|
||||||
|
|
||||||
try:
|
try:
|
||||||
curFoundResults = curProvider.searchRSS(episodes)
|
curProvider.cache.updateCache()
|
||||||
|
curFoundResults = curProvider.searchRSS()
|
||||||
except exceptions.AuthException, e:
|
except exceptions.AuthException, e:
|
||||||
logger.log(u"Authentication error: " + ex(e), logger.ERROR)
|
logger.log(u"Authentication error: " + ex(e), logger.ERROR)
|
||||||
continue
|
continue
|
||||||
@ -374,6 +372,12 @@ def searchForNeededEpisodes(show, episodes):
|
|||||||
logger.DEBUG)
|
logger.DEBUG)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
# find the best result for the current episode
|
||||||
|
bestResult = None
|
||||||
|
for curResult in curFoundResults[curEp]:
|
||||||
|
if not bestResult or bestResult.quality < curResult.quality:
|
||||||
|
bestResult = curResult
|
||||||
|
|
||||||
bestResult = pickBestResult(curFoundResults[curEp], curEp.show)
|
bestResult = pickBestResult(curFoundResults[curEp], curEp.show)
|
||||||
|
|
||||||
# if all results were rejected move on to the next episode
|
# if all results were rejected move on to the next episode
|
||||||
@ -400,7 +404,7 @@ def searchForNeededEpisodes(show, episodes):
|
|||||||
u"No NZB/Torrent providers found or enabled in the sickrage config for daily searches. Please check your settings.",
|
u"No NZB/Torrent providers found or enabled in the sickrage config for daily searches. Please check your settings.",
|
||||||
logger.ERROR)
|
logger.ERROR)
|
||||||
|
|
||||||
return foundResults.values() if len(foundResults) else {}
|
return foundResults.values()
|
||||||
|
|
||||||
|
|
||||||
def searchProviders(show, season, episodes, manualSearch=False):
|
def searchProviders(show, season, episodes, manualSearch=False):
|
||||||
@ -409,6 +413,9 @@ def searchProviders(show, season, episodes, manualSearch=False):
|
|||||||
|
|
||||||
didSearch = False
|
didSearch = False
|
||||||
|
|
||||||
|
# build name cache for show
|
||||||
|
sickbeard.name_cache.buildNameCache(show)
|
||||||
|
|
||||||
# check if we want to search for season packs instead of just season/episode
|
# check if we want to search for season packs instead of just season/episode
|
||||||
seasonSearch = False
|
seasonSearch = False
|
||||||
if not manualSearch:
|
if not manualSearch:
|
||||||
@ -418,7 +425,7 @@ def searchProviders(show, season, episodes, manualSearch=False):
|
|||||||
|
|
||||||
origThreadName = threading.currentThread().name
|
origThreadName = threading.currentThread().name
|
||||||
|
|
||||||
providers = [x for x in sickbeard.providers.sortedProviderList() if x.isActive()]
|
providers = [x for x in sickbeard.providers.sortedProviderList() if x.isActive() and x.enable_backlog]
|
||||||
for providerNum, curProvider in enumerate(providers):
|
for providerNum, curProvider in enumerate(providers):
|
||||||
if curProvider.anime_only and not show.is_anime:
|
if curProvider.anime_only and not show.is_anime:
|
||||||
logger.log(u"" + str(show.name) + " is not an anime, skiping", logger.DEBUG)
|
logger.log(u"" + str(show.name) + " is not an anime, skiping", logger.DEBUG)
|
||||||
@ -442,6 +449,7 @@ def searchProviders(show, season, episodes, manualSearch=False):
|
|||||||
logger.log(u"Searching for episodes we need from " + show.name + " Season " + str(season))
|
logger.log(u"Searching for episodes we need from " + show.name + " Season " + str(season))
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
curProvider.cache.updateCache()
|
||||||
searchResults = curProvider.findSearchResults(show, season, episodes, search_mode, manualSearch)
|
searchResults = curProvider.findSearchResults(show, season, episodes, search_mode, manualSearch)
|
||||||
except exceptions.AuthException, e:
|
except exceptions.AuthException, e:
|
||||||
logger.log(u"Authentication error: " + ex(e), logger.ERROR)
|
logger.log(u"Authentication error: " + ex(e), logger.ERROR)
|
||||||
|
@ -29,6 +29,7 @@ from sickbeard import logger
|
|||||||
from sickbeard import ui
|
from sickbeard import ui
|
||||||
from sickbeard import common
|
from sickbeard import common
|
||||||
|
|
||||||
|
|
||||||
class BacklogSearchScheduler(scheduler.Scheduler):
|
class BacklogSearchScheduler(scheduler.Scheduler):
|
||||||
def forceSearch(self):
|
def forceSearch(self):
|
||||||
self.action._set_lastBacklog(1)
|
self.action._set_lastBacklog(1)
|
||||||
@ -40,11 +41,12 @@ class BacklogSearchScheduler(scheduler.Scheduler):
|
|||||||
else:
|
else:
|
||||||
return datetime.date.fromordinal(self.action._lastBacklog + self.action.cycleTime)
|
return datetime.date.fromordinal(self.action._lastBacklog + self.action.cycleTime)
|
||||||
|
|
||||||
|
|
||||||
class BacklogSearcher:
|
class BacklogSearcher:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
|
||||||
self._lastBacklog = self._get_lastBacklog()
|
self._lastBacklog = self._get_lastBacklog()
|
||||||
self.cycleTime = sickbeard.BACKLOG_FREQUENCY/60/24
|
self.cycleTime = sickbeard.BACKLOG_FREQUENCY / 60 / 24
|
||||||
self.lock = threading.Lock()
|
self.lock = threading.Lock()
|
||||||
self.amActive = False
|
self.amActive = False
|
||||||
self.amPaused = False
|
self.amPaused = False
|
||||||
@ -99,7 +101,7 @@ class BacklogSearcher:
|
|||||||
|
|
||||||
if len(segments):
|
if len(segments):
|
||||||
backlog_queue_item = search_queue.BacklogQueueItem(curShow, segments)
|
backlog_queue_item = search_queue.BacklogQueueItem(curShow, segments)
|
||||||
sickbeard.searchQueueScheduler.action.add_item(backlog_queue_item) #@UndefinedVariable
|
sickbeard.searchQueueScheduler.action.add_item(backlog_queue_item) # @UndefinedVariable
|
||||||
else:
|
else:
|
||||||
logger.log(u"Nothing needs to be downloaded for " + str(curShow.name) + ", skipping this season",
|
logger.log(u"Nothing needs to be downloaded for " + str(curShow.name) + ", skipping this season",
|
||||||
logger.DEBUG)
|
logger.DEBUG)
|
||||||
@ -132,14 +134,14 @@ class BacklogSearcher:
|
|||||||
return self._lastBacklog
|
return self._lastBacklog
|
||||||
|
|
||||||
def _get_segments(self, show, fromDate):
|
def _get_segments(self, show, fromDate):
|
||||||
anyQualities, bestQualities = common.Quality.splitQuality(show.quality) #@UnusedVariable
|
anyQualities, bestQualities = common.Quality.splitQuality(show.quality) # @UnusedVariable
|
||||||
|
|
||||||
logger.log(u"Seeing if we need anything from " + show.name)
|
logger.log(u"Seeing if we need anything from " + show.name)
|
||||||
|
|
||||||
myDB = db.DBConnection()
|
myDB = db.DBConnection()
|
||||||
if show.air_by_date:
|
if show.air_by_date:
|
||||||
sqlResults = myDB.select(
|
sqlResults = myDB.select(
|
||||||
"SELECT ep.status, ep.season, ep.episode 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",
|
"SELECT ep.status, ep.season, ep.episode 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(), show.indexerid])
|
[fromDate.toordinal(), show.indexerid])
|
||||||
else:
|
else:
|
||||||
sqlResults = myDB.select(
|
sqlResults = myDB.select(
|
||||||
|
@ -72,34 +72,27 @@ class SearchQueue(generic_queue.GenericQueue):
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
def add_item(self, item):
|
def add_item(self, item):
|
||||||
|
if isinstance(item, DailySearchQueueItem) or (
|
||||||
if isinstance(item, (DailySearchQueueItem, BacklogQueueItem, ManualSearchQueueItem, FailedQueueItem)) \
|
isinstance(item, (BacklogQueueItem, ManualSearchQueueItem, FailedQueueItem)) and not self.is_in_queue(
|
||||||
and not self.is_in_queue(item.show, item.segment):
|
item.show, item.segment)):
|
||||||
sickbeard.name_cache.buildNameCache(item.show)
|
|
||||||
generic_queue.GenericQueue.add_item(self, item)
|
generic_queue.GenericQueue.add_item(self, item)
|
||||||
else:
|
else:
|
||||||
logger.log(u"Not adding item, it's already in the queue", logger.DEBUG)
|
logger.log(u"Not adding item, it's already in the queue", logger.DEBUG)
|
||||||
|
|
||||||
|
|
||||||
class DailySearchQueueItem(generic_queue.QueueItem):
|
class DailySearchQueueItem(generic_queue.QueueItem):
|
||||||
def __init__(self, show, segment):
|
def __init__(self):
|
||||||
generic_queue.QueueItem.__init__(self, 'Daily Search', DAILY_SEARCH)
|
generic_queue.QueueItem.__init__(self, 'Daily Search', DAILY_SEARCH)
|
||||||
self.priority = generic_queue.QueuePriorities.HIGH
|
|
||||||
self.name = 'DAILYSEARCH-' + str(show.indexerid)
|
|
||||||
self.show = show
|
|
||||||
self.segment = segment
|
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
|
|
||||||
generic_queue.QueueItem.run(self)
|
generic_queue.QueueItem.run(self)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
logger.log("Beginning daily search for new episodes")
|
||||||
logger.log("Beginning daily search for [" + self.show.name + "]")
|
foundResults = search.searchForNeededEpisodes()
|
||||||
foundResults = search.searchForNeededEpisodes(self.show, self.segment)
|
|
||||||
|
|
||||||
if not len(foundResults):
|
if not len(foundResults):
|
||||||
logger.log(u"No needed episodes found during daily search for [" + self.show.name + "]")
|
logger.log(u"No needed episodes found")
|
||||||
else:
|
else:
|
||||||
for result in foundResults:
|
for result in foundResults:
|
||||||
# just use the first result for now
|
# just use the first result for now
|
||||||
@ -115,6 +108,7 @@ class DailySearchQueueItem(generic_queue.QueueItem):
|
|||||||
|
|
||||||
self.finish()
|
self.finish()
|
||||||
|
|
||||||
|
|
||||||
class ManualSearchQueueItem(generic_queue.QueueItem):
|
class ManualSearchQueueItem(generic_queue.QueueItem):
|
||||||
def __init__(self, show, segment):
|
def __init__(self, show, segment):
|
||||||
generic_queue.QueueItem.__init__(self, 'Manual Search', MANUAL_SEARCH)
|
generic_queue.QueueItem.__init__(self, 'Manual Search', MANUAL_SEARCH)
|
||||||
@ -169,7 +163,7 @@ class BacklogQueueItem(generic_queue.QueueItem):
|
|||||||
try:
|
try:
|
||||||
for season in self.segment:
|
for season in self.segment:
|
||||||
sickbeard.searchBacklog.BacklogSearcher.currentSearchInfo = {
|
sickbeard.searchBacklog.BacklogSearcher.currentSearchInfo = {
|
||||||
'title': self.show.name + " Season " + str(season)}
|
'title': self.show.name + " Season " + str(season)}
|
||||||
|
|
||||||
wantedEps = self.segment[season]
|
wantedEps = self.segment[season]
|
||||||
|
|
||||||
|
@ -23,6 +23,7 @@ import datetime
|
|||||||
import threading
|
import threading
|
||||||
import re
|
import re
|
||||||
import glob
|
import glob
|
||||||
|
import stat
|
||||||
import traceback
|
import traceback
|
||||||
|
|
||||||
import sickbeard
|
import sickbeard
|
||||||
@ -962,7 +963,7 @@ class TVShow(object):
|
|||||||
|
|
||||||
return self.nextaired
|
return self.nextaired
|
||||||
|
|
||||||
def deleteShow(self):
|
def deleteShow(self, full=False):
|
||||||
|
|
||||||
sql_l = [["DELETE FROM tv_episodes WHERE showid = ?", [self.indexerid]],
|
sql_l = [["DELETE FROM tv_episodes WHERE showid = ?", [self.indexerid]],
|
||||||
["DELETE FROM tv_shows WHERE indexer_id = ?", [self.indexerid]],
|
["DELETE FROM tv_shows WHERE indexer_id = ?", [self.indexerid]],
|
||||||
@ -973,7 +974,6 @@ class TVShow(object):
|
|||||||
myDB = db.DBConnection()
|
myDB = db.DBConnection()
|
||||||
myDB.mass_action(sql_l)
|
myDB.mass_action(sql_l)
|
||||||
|
|
||||||
|
|
||||||
# remove self from show list
|
# remove self from show list
|
||||||
sickbeard.showList = [x for x in sickbeard.showList if int(x.indexerid) != self.indexerid]
|
sickbeard.showList = [x for x in sickbeard.showList if int(x.indexerid) != self.indexerid]
|
||||||
|
|
||||||
@ -983,6 +983,24 @@ class TVShow(object):
|
|||||||
logger.log(u"Deleting cache file " + cache_file)
|
logger.log(u"Deleting cache file " + cache_file)
|
||||||
os.remove(cache_file)
|
os.remove(cache_file)
|
||||||
|
|
||||||
|
# remove entire show folder
|
||||||
|
if full:
|
||||||
|
try:
|
||||||
|
logger.log(u"Deleting show folder " + self.location)
|
||||||
|
# check first the read-only attribute
|
||||||
|
file_attribute = ek.ek(os.stat, self.location)[0]
|
||||||
|
if (not file_attribute & stat.S_IWRITE):
|
||||||
|
# File is read-only, so make it writeable
|
||||||
|
logger.log('Read only mode on folder ' + self.location + ' Will try to make it writeable', logger.DEBUG)
|
||||||
|
try:
|
||||||
|
ek.ek(os.chmod, self.location, stat.S_IWRITE)
|
||||||
|
except:
|
||||||
|
logger.log(u'Cannot change permissions of ' + self.location, logger.WARNING)
|
||||||
|
|
||||||
|
ek.ek(os.rmdir, self.location)
|
||||||
|
except OSError, e:
|
||||||
|
logger.log(u"Unable to delete " + self.location + ": " + repr(e) + " / " + str(e), logger.WARNING)
|
||||||
|
|
||||||
def populateCache(self):
|
def populateCache(self):
|
||||||
cache_inst = image_cache.ImageCache()
|
cache_inst = image_cache.ImageCache()
|
||||||
|
|
||||||
|
@ -89,26 +89,17 @@ class TVCache():
|
|||||||
|
|
||||||
def _clearCache(self):
|
def _clearCache(self):
|
||||||
if self.shouldClearCache():
|
if self.shouldClearCache():
|
||||||
logger.log(u"Clearing items older than 1 week from " + self.provider.name + " cache")
|
|
||||||
|
|
||||||
curDate = datetime.date.today() - datetime.timedelta(weeks=1)
|
|
||||||
|
|
||||||
myDB = self._getDB()
|
myDB = self._getDB()
|
||||||
myDB.action("DELETE FROM [" + self.providerID + "] WHERE time < ?", [int(time.mktime(curDate.timetuple()))])
|
myDB.action("DELETE FROM [" + self.providerID + "] WHERE 1")
|
||||||
|
|
||||||
def _get_title_and_url(self, item):
|
def _get_title_and_url(self, item):
|
||||||
# override this in the provider if daily search has a different data layout to backlog searches
|
# override this in the provider if daily search has a different data layout to backlog searches
|
||||||
return self.provider._get_title_and_url(item)
|
return self.provider._get_title_and_url(item)
|
||||||
|
|
||||||
def _getRSSData(self):
|
def _getRSSData(self):
|
||||||
|
|
||||||
data = None
|
data = None
|
||||||
|
|
||||||
return data
|
return data
|
||||||
|
|
||||||
def _getDailyData(self):
|
|
||||||
return None
|
|
||||||
|
|
||||||
def _checkAuth(self):
|
def _checkAuth(self):
|
||||||
return self.provider._checkAuth()
|
return self.provider._checkAuth()
|
||||||
|
|
||||||
@ -116,10 +107,9 @@ class TVCache():
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
def updateCache(self):
|
def updateCache(self):
|
||||||
|
|
||||||
if self.shouldUpdate() and self._checkAuth():
|
if self.shouldUpdate() and self._checkAuth():
|
||||||
# as long as the http request worked we count this as an update
|
# as long as the http request worked we count this as an update
|
||||||
data = self._getDailyData()
|
data = self._getRSSData()
|
||||||
if not data:
|
if not data:
|
||||||
return []
|
return []
|
||||||
|
|
||||||
@ -230,8 +220,6 @@ class TVCache():
|
|||||||
def shouldClearCache(self):
|
def shouldClearCache(self):
|
||||||
# if daily search hasn't used our previous results yet then don't clear the cache
|
# if daily search hasn't used our previous results yet then don't clear the cache
|
||||||
if self.lastUpdate > self.lastSearch:
|
if self.lastUpdate > self.lastSearch:
|
||||||
logger.log(
|
|
||||||
u"Daily search has not yet used our last cache results, not clearing cache ...", logger.DEBUG)
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
return True
|
return True
|
||||||
@ -289,9 +277,9 @@ class TVCache():
|
|||||||
[name, season, episodeText, parse_result.show.indexerid, url, curTimestamp, quality, release_group, version]]
|
[name, season, episodeText, parse_result.show.indexerid, url, curTimestamp, quality, release_group, version]]
|
||||||
|
|
||||||
|
|
||||||
def searchCache(self, episodes, manualSearch=False):
|
def searchCache(self, episode, manualSearch=False):
|
||||||
neededEps = self.findNeededEpisodes(episodes, manualSearch)
|
neededEps = self.findNeededEpisodes(episode, manualSearch)
|
||||||
return neededEps
|
return neededEps[episode]
|
||||||
|
|
||||||
def listPropers(self, date=None, delimiter="."):
|
def listPropers(self, date=None, delimiter="."):
|
||||||
myDB = self._getDB()
|
myDB = self._getDB()
|
||||||
@ -303,69 +291,84 @@ class TVCache():
|
|||||||
return filter(lambda x: x['indexerid'] != 0, myDB.select(sql))
|
return filter(lambda x: x['indexerid'] != 0, myDB.select(sql))
|
||||||
|
|
||||||
|
|
||||||
def findNeededEpisodes(self, episodes, manualSearch=False):
|
def findNeededEpisodes(self, episode=None, manualSearch=False):
|
||||||
neededEps = {}
|
neededEps = {}
|
||||||
|
|
||||||
for epObj in episodes:
|
if episode:
|
||||||
myDB = self._getDB()
|
neededEps[episode] = []
|
||||||
|
|
||||||
|
myDB = self._getDB()
|
||||||
|
if not episode:
|
||||||
|
sqlResults = myDB.select("SELECT * FROM [" + self.providerID + "]")
|
||||||
|
else:
|
||||||
sqlResults = myDB.select(
|
sqlResults = myDB.select(
|
||||||
"SELECT * FROM [" + self.providerID + "] WHERE indexerid = ? AND season = ? AND episodes LIKE ?",
|
"SELECT * FROM [" + self.providerID + "] WHERE indexerid = ? AND season = ? AND episodes LIKE ?",
|
||||||
[epObj.show.indexerid, epObj.season, "%|" + str(epObj.episode) + "|%"])
|
[episode.show.indexerid, episode.season, "%|" + str(episode.episode) + "|%"])
|
||||||
|
|
||||||
# for each cache entry
|
# for each cache entry
|
||||||
for curResult in sqlResults:
|
for curResult in sqlResults:
|
||||||
|
|
||||||
# skip non-tv crap (but allow them for Newzbin cause we assume it's filtered well)
|
# skip non-tv crap
|
||||||
if self.providerID != 'newzbin' and not show_name_helpers.filterBadReleases(curResult["name"]):
|
if not show_name_helpers.filterBadReleases(curResult["name"]):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# get the show object, or if it's not one of our shows then ignore it
|
# get the show object, or if it's not one of our shows then ignore it
|
||||||
try:
|
showObj = helpers.findCertainShow(sickbeard.showList, int(curResult["indexerid"]))
|
||||||
showObj = helpers.findCertainShow(sickbeard.showList, int(curResult["indexerid"]))
|
if not showObj:
|
||||||
except MultipleShowObjectsException:
|
continue
|
||||||
showObj = None
|
|
||||||
|
|
||||||
if not showObj:
|
# skip if provider is anime only and show is not anime
|
||||||
continue
|
if self.provider.anime_only and not showObj.is_anime:
|
||||||
|
logger.log(u"" + str(showObj.name) + " is not an anime, skiping", logger.DEBUG)
|
||||||
|
continue
|
||||||
|
|
||||||
# get season and ep data (ignoring multi-eps for now)
|
# get season and ep data (ignoring multi-eps for now)
|
||||||
curSeason = int(curResult["season"])
|
curSeason = int(curResult["season"])
|
||||||
if curSeason == -1:
|
if curSeason == -1:
|
||||||
continue
|
continue
|
||||||
curEp = curResult["episodes"].split("|")[1]
|
curEp = curResult["episodes"].split("|")[1]
|
||||||
if not curEp:
|
if not curEp:
|
||||||
continue
|
continue
|
||||||
curEp = int(curEp)
|
curEp = int(curEp)
|
||||||
curQuality = int(curResult["quality"])
|
|
||||||
curReleaseGroup = curResult["release_group"]
|
|
||||||
curVersion = curResult["version"]
|
|
||||||
|
|
||||||
# if the show says we want that episode then add it to the list
|
curQuality = int(curResult["quality"])
|
||||||
if not showObj.wantEpisode(curSeason, curEp, curQuality, manualSearch):
|
curReleaseGroup = curResult["release_group"]
|
||||||
logger.log(u"Skipping " + curResult["name"] + " because we don't want an episode that's " +
|
curVersion = curResult["version"]
|
||||||
Quality.qualityStrings[curQuality], logger.DEBUG)
|
|
||||||
continue
|
|
||||||
|
|
||||||
# build a result object
|
# if the show says we want that episode then add it to the list
|
||||||
title = curResult["name"]
|
if not showObj.wantEpisode(curSeason, curEp, curQuality, manualSearch):
|
||||||
url = curResult["url"]
|
logger.log(u"Skipping " + curResult["name"] + " because we don't want an episode that's " +
|
||||||
|
Quality.qualityStrings[curQuality], logger.DEBUG)
|
||||||
|
continue
|
||||||
|
|
||||||
logger.log(u"Found result " + title + " at " + url)
|
# build name cache for show
|
||||||
|
sickbeard.name_cache.buildNameCache(showObj)
|
||||||
|
|
||||||
result = self.provider.getResult([epObj])
|
if episode:
|
||||||
result.show = showObj
|
epObj = episode
|
||||||
result.url = url
|
else:
|
||||||
result.name = title
|
epObj = showObj.getEpisode(curSeason, curEp)
|
||||||
result.quality = curQuality
|
|
||||||
result.release_group = curReleaseGroup
|
|
||||||
result.version = curVersion
|
|
||||||
result.content = None
|
|
||||||
|
|
||||||
# add it to the list
|
# build a result object
|
||||||
if epObj not in neededEps:
|
title = curResult["name"]
|
||||||
neededEps[epObj] = [result]
|
url = curResult["url"]
|
||||||
else:
|
|
||||||
neededEps[epObj].append(result)
|
logger.log(u"Found result " + title + " at " + url)
|
||||||
|
|
||||||
|
result = self.provider.getResult([epObj])
|
||||||
|
result.show = showObj
|
||||||
|
result.url = url
|
||||||
|
result.name = title
|
||||||
|
result.quality = curQuality
|
||||||
|
result.release_group = curReleaseGroup
|
||||||
|
result.version = curVersion
|
||||||
|
result.content = None
|
||||||
|
|
||||||
|
# add it to the list
|
||||||
|
if epObj not in neededEps:
|
||||||
|
neededEps[epObj] = [result]
|
||||||
|
else:
|
||||||
|
neededEps[epObj].append(result)
|
||||||
|
|
||||||
# datetime stamp this search so cache gets cleared
|
# datetime stamp this search so cache gets cleared
|
||||||
self.setLastSearch()
|
self.setLastSearch()
|
||||||
|
@ -1036,8 +1036,10 @@ class Manage(MainHandler):
|
|||||||
return _munge(t)
|
return _munge(t)
|
||||||
|
|
||||||
|
|
||||||
def massEditSubmit(self, paused=None, anime=None, sports=None, scene=None, flatten_folders=None, quality_preset=False,
|
def massEditSubmit(self, paused=None, anime=None, sports=None, scene=None, flatten_folders=None,
|
||||||
subtitles=None, air_by_date=None, anyQualities=[], bestQualities=[], toEdit=None, *args, **kwargs):
|
quality_preset=False,
|
||||||
|
subtitles=None, air_by_date=None, anyQualities=[], bestQualities=[], toEdit=None, *args,
|
||||||
|
**kwargs):
|
||||||
|
|
||||||
dir_map = {}
|
dir_map = {}
|
||||||
for cur_arg in kwargs:
|
for cur_arg in kwargs:
|
||||||
@ -1112,7 +1114,8 @@ class Manage(MainHandler):
|
|||||||
|
|
||||||
exceptions_list = []
|
exceptions_list = []
|
||||||
|
|
||||||
curErrors += Home(self.application, self.request).editShow(curShow, new_show_dir, anyQualities, bestQualities, exceptions_list,
|
curErrors += Home(self.application, self.request).editShow(curShow, new_show_dir, anyQualities,
|
||||||
|
bestQualities, exceptions_list,
|
||||||
flatten_folders=new_flatten_folders,
|
flatten_folders=new_flatten_folders,
|
||||||
paused=new_paused, sports=new_sports,
|
paused=new_paused, sports=new_sports,
|
||||||
subtitles=new_subtitles, anime=new_anime,
|
subtitles=new_subtitles, anime=new_anime,
|
||||||
@ -1131,7 +1134,7 @@ class Manage(MainHandler):
|
|||||||
redirect("/manage/")
|
redirect("/manage/")
|
||||||
|
|
||||||
|
|
||||||
def massUpdate(self, toUpdate=None, toRefresh=None, toRename=None, toDelete=None, toMetadata=None, toSubtitle=None):
|
def massUpdate(self, toUpdate=None, toRefresh=None, toRename=None, toDelete=None, toRemove=None, toMetadata=None, toSubtitle=None):
|
||||||
|
|
||||||
if toUpdate is not None:
|
if toUpdate is not None:
|
||||||
toUpdate = toUpdate.split('|')
|
toUpdate = toUpdate.split('|')
|
||||||
@ -1158,6 +1161,11 @@ class Manage(MainHandler):
|
|||||||
else:
|
else:
|
||||||
toDelete = []
|
toDelete = []
|
||||||
|
|
||||||
|
if toRemove is not None:
|
||||||
|
toRemove = toRemove.split('|')
|
||||||
|
else:
|
||||||
|
toRemove = []
|
||||||
|
|
||||||
if toMetadata is not None:
|
if toMetadata is not None:
|
||||||
toMetadata = toMetadata.split('|')
|
toMetadata = toMetadata.split('|')
|
||||||
else:
|
else:
|
||||||
@ -1169,7 +1177,7 @@ class Manage(MainHandler):
|
|||||||
renames = []
|
renames = []
|
||||||
subtitles = []
|
subtitles = []
|
||||||
|
|
||||||
for curShowID in set(toUpdate + toRefresh + toRename + toSubtitle + toDelete + toMetadata):
|
for curShowID in set(toUpdate + toRefresh + toRename + toSubtitle + toDelete + toRemove + toMetadata):
|
||||||
|
|
||||||
if curShowID == '':
|
if curShowID == '':
|
||||||
continue
|
continue
|
||||||
@ -1180,10 +1188,15 @@ class Manage(MainHandler):
|
|||||||
continue
|
continue
|
||||||
|
|
||||||
if curShowID in toDelete:
|
if curShowID in toDelete:
|
||||||
showObj.deleteShow()
|
showObj.deleteShow(True)
|
||||||
# don't do anything else if it's being deleted
|
# don't do anything else if it's being deleted
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
if curShowID in toRemove:
|
||||||
|
showObj.deleteShow()
|
||||||
|
# don't do anything else if it's being remove
|
||||||
|
continue
|
||||||
|
|
||||||
if curShowID in toUpdate:
|
if curShowID in toUpdate:
|
||||||
try:
|
try:
|
||||||
sickbeard.showQueueScheduler.action.updateShow(showObj, True) # @UndefinedVariable
|
sickbeard.showQueueScheduler.action.updateShow(showObj, True) # @UndefinedVariable
|
||||||
@ -1601,7 +1614,8 @@ class ConfigSearch(MainHandler):
|
|||||||
|
|
||||||
def saveSearch(self, use_nzbs=None, use_torrents=None, nzb_dir=None, sab_username=None, sab_password=None,
|
def saveSearch(self, use_nzbs=None, use_torrents=None, nzb_dir=None, sab_username=None, sab_password=None,
|
||||||
sab_apikey=None, sab_category=None, sab_host=None, nzbget_username=None, nzbget_password=None,
|
sab_apikey=None, sab_category=None, sab_host=None, nzbget_username=None, nzbget_password=None,
|
||||||
nzbget_category=None, nzbget_priority=100, nzbget_host=None, nzbget_use_https=None, dailysearch_frequency=None,
|
nzbget_category=None, nzbget_priority=100, nzbget_host=None, nzbget_use_https=None,
|
||||||
|
dailysearch_frequency=None,
|
||||||
nzb_method=None, torrent_method=None, usenet_retention=None, backlog_frequency=None,
|
nzb_method=None, torrent_method=None, usenet_retention=None, backlog_frequency=None,
|
||||||
download_propers=None, check_propers_interval=None, allow_high_priority=None,
|
download_propers=None, check_propers_interval=None, allow_high_priority=None,
|
||||||
backlog_startup=None, dailysearch_startup=None,
|
backlog_startup=None, dailysearch_startup=None,
|
||||||
@ -1992,19 +2006,42 @@ class ConfigProviders(MainHandler):
|
|||||||
cur_url = config.clean_url(cur_url)
|
cur_url = config.clean_url(cur_url)
|
||||||
|
|
||||||
newProvider = newznab.NewznabProvider(cur_name, cur_url, key=cur_key)
|
newProvider = newznab.NewznabProvider(cur_name, cur_url, key=cur_key)
|
||||||
|
|
||||||
cur_id = newProvider.getID()
|
cur_id = newProvider.getID()
|
||||||
|
|
||||||
# if it already exists then update it
|
# if it already exists then update it
|
||||||
if cur_id in newznabProviderDict:
|
if cur_id in newznabProviderDict:
|
||||||
newznabProviderDict[cur_id].name = cur_name
|
newznabProviderDict[cur_id].name = cur_name
|
||||||
newznabProviderDict[cur_id].url = cur_url
|
newznabProviderDict[cur_id].url = cur_url
|
||||||
|
|
||||||
newznabProviderDict[cur_id].key = cur_key
|
newznabProviderDict[cur_id].key = cur_key
|
||||||
# a 0 in the key spot indicates that no key is needed
|
# a 0 in the key spot indicates that no key is needed
|
||||||
if cur_key == '0':
|
if cur_key == '0':
|
||||||
newznabProviderDict[cur_id].needs_auth = False
|
newznabProviderDict[cur_id].needs_auth = False
|
||||||
else:
|
else:
|
||||||
newznabProviderDict[cur_id].needs_auth = True
|
newznabProviderDict[cur_id].needs_auth = True
|
||||||
|
|
||||||
|
try:
|
||||||
|
newznabProviderDict[cur_id].search_mode = str(kwargs[cur_id + '_search_mode']).strip()
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
try:
|
||||||
|
newznabProviderDict[cur_id].search_fallback = config.checkbox_to_value(
|
||||||
|
kwargs[cur_id + '_search_fallback'])
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
try:
|
||||||
|
newznabProviderDict[cur_id].enable_daily = config.checkbox_to_value(
|
||||||
|
kwargs[cur_id + '_enable_daily'])
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
try:
|
||||||
|
newznabProviderDict[cur_id].enable_backlog = config.checkbox_to_value(
|
||||||
|
kwargs[cur_id + '_enable_backlog'])
|
||||||
|
except:
|
||||||
|
pass
|
||||||
else:
|
else:
|
||||||
sickbeard.newznabProviderList.append(newProvider)
|
sickbeard.newznabProviderList.append(newProvider)
|
||||||
|
|
||||||
@ -2161,12 +2198,19 @@ class ConfigProviders(MainHandler):
|
|||||||
except:
|
except:
|
||||||
curTorrentProvider.search_fallback = 0
|
curTorrentProvider.search_fallback = 0
|
||||||
|
|
||||||
if hasattr(curTorrentProvider, 'backlog_only'):
|
if hasattr(curTorrentProvider, 'enable_daily'):
|
||||||
try:
|
try:
|
||||||
curTorrentProvider.backlog_only = config.checkbox_to_value(
|
curTorrentProvider.enable_daily = config.checkbox_to_value(
|
||||||
kwargs[curTorrentProvider.getID() + '_backlog_only'])
|
kwargs[curTorrentProvider.getID() + '_enable_daily'])
|
||||||
except:
|
except:
|
||||||
curTorrentProvider.backlog_only = 0
|
curTorrentProvider.enable_daily = 1
|
||||||
|
|
||||||
|
if hasattr(curTorrentProvider, 'enable_backlog'):
|
||||||
|
try:
|
||||||
|
curTorrentProvider.enable_backlog = config.checkbox_to_value(
|
||||||
|
kwargs[curTorrentProvider.getID() + '_enable_backlog'])
|
||||||
|
except:
|
||||||
|
curTorrentProvider.enable_backlog = 1
|
||||||
|
|
||||||
for curNzbProvider in [curProvider for curProvider in sickbeard.providers.sortedProviderList() if
|
for curNzbProvider in [curProvider for curProvider in sickbeard.providers.sortedProviderList() if
|
||||||
curProvider.providerType == sickbeard.GenericProvider.NZB]:
|
curProvider.providerType == sickbeard.GenericProvider.NZB]:
|
||||||
@ -2196,12 +2240,19 @@ class ConfigProviders(MainHandler):
|
|||||||
except:
|
except:
|
||||||
curNzbProvider.search_fallback = 0
|
curNzbProvider.search_fallback = 0
|
||||||
|
|
||||||
if hasattr(curNzbProvider, 'backlog_only'):
|
if hasattr(curNzbProvider, 'enable_daily'):
|
||||||
try:
|
try:
|
||||||
curNzbProvider.backlog_only = config.checkbox_to_value(
|
curNzbProvider.enable_daily = config.checkbox_to_value(
|
||||||
kwargs[curNzbProvider.getID() + '_backlog_only'])
|
kwargs[curNzbProvider.getID() + '_enable_daily'])
|
||||||
except:
|
except:
|
||||||
curNzbProvider.backlog_only = 0
|
curNzbProvider.enable_daily = 1
|
||||||
|
|
||||||
|
if hasattr(curNzbProvider, 'enable_backlog'):
|
||||||
|
try:
|
||||||
|
curNzbProvider.enable_backlog = config.checkbox_to_value(
|
||||||
|
kwargs[curNzbProvider.getID() + '_enable_backlog'])
|
||||||
|
except:
|
||||||
|
curNzbProvider.enable_backlog = 1
|
||||||
|
|
||||||
sickbeard.NEWZNAB_DATA = '!!!'.join([x.configStr() for x in sickbeard.newznabProviderList])
|
sickbeard.NEWZNAB_DATA = '!!!'.join([x.configStr() for x in sickbeard.newznabProviderList])
|
||||||
sickbeard.PROVIDER_ORDER = provider_list
|
sickbeard.PROVIDER_ORDER = provider_list
|
||||||
@ -2796,8 +2847,9 @@ class NewHomeAddShows(MainHandler):
|
|||||||
final_results = []
|
final_results = []
|
||||||
|
|
||||||
logger.log(u"Getting recommended shows from Trakt.tv", logger.DEBUG)
|
logger.log(u"Getting recommended shows from Trakt.tv", logger.DEBUG)
|
||||||
recommendedlist = TraktCall("recommendations/shows.json/%API%", sickbeard.TRAKT_API, sickbeard.TRAKT_USERNAME, sickbeard.TRAKT_PASSWORD)
|
recommendedlist = TraktCall("recommendations/shows.json/%API%", sickbeard.TRAKT_API, sickbeard.TRAKT_USERNAME,
|
||||||
|
sickbeard.TRAKT_PASSWORD)
|
||||||
|
|
||||||
if recommendedlist == 'NULL':
|
if recommendedlist == 'NULL':
|
||||||
logger.log(u"No shows found in your recommendedlist, aborting recommendedlist update", logger.DEBUG)
|
logger.log(u"No shows found in your recommendedlist, aborting recommendedlist update", logger.DEBUG)
|
||||||
return
|
return
|
||||||
@ -2807,7 +2859,8 @@ class NewHomeAddShows(MainHandler):
|
|||||||
return
|
return
|
||||||
|
|
||||||
map(final_results.append,
|
map(final_results.append,
|
||||||
([int(show['tvdb_id'] or 0) if sickbeard.TRAKT_DEFAULT_INDEXER == 1 else int(show['tvdb_id'] or 0), show['url'], show['title'], show['overview'],
|
([int(show['tvdb_id'] or 0) if sickbeard.TRAKT_DEFAULT_INDEXER == 1 else int(show['tvdb_id'] or 0),
|
||||||
|
show['url'], show['title'], show['overview'],
|
||||||
datetime.date.fromtimestamp(int(show['first_aired']) / 1000.0).strftime('%Y%m%d')] for show in
|
datetime.date.fromtimestamp(int(show['first_aired']) / 1000.0).strftime('%Y%m%d')] for show in
|
||||||
recommendedlist if not helpers.findCertainShow(sickbeard.showList, indexerid=int(show['tvdb_id']))))
|
recommendedlist if not helpers.findCertainShow(sickbeard.showList, indexerid=int(show['tvdb_id']))))
|
||||||
|
|
||||||
@ -3563,7 +3616,10 @@ class Home(MainHandler):
|
|||||||
if not sickbeard.showQueueScheduler.action.isBeingAdded(showObj): # @UndefinedVariable
|
if not sickbeard.showQueueScheduler.action.isBeingAdded(showObj): # @UndefinedVariable
|
||||||
if not sickbeard.showQueueScheduler.action.isBeingUpdated(showObj): # @UndefinedVariable
|
if not sickbeard.showQueueScheduler.action.isBeingUpdated(showObj): # @UndefinedVariable
|
||||||
t.submenu.append(
|
t.submenu.append(
|
||||||
{'title': 'Delete', 'path': 'home/deleteShow?show=%d' % showObj.indexerid, 'confirm': True})
|
{'title': 'Delete', 'path': 'home/deleteShow?show=%d&full=1' % showObj.indexerid,
|
||||||
|
'confirm': True})
|
||||||
|
t.submenu.append(
|
||||||
|
{'title': 'Remove', 'path': 'home/deleteShow?show=%d' % showObj.indexerid, 'confirm': True})
|
||||||
t.submenu.append({'title': 'Re-scan files', 'path': 'home/refreshShow?show=%d' % showObj.indexerid})
|
t.submenu.append({'title': 'Re-scan files', 'path': 'home/refreshShow?show=%d' % showObj.indexerid})
|
||||||
t.submenu.append(
|
t.submenu.append(
|
||||||
{'title': 'Force Full Update', 'path': 'home/updateShow?show=%d&force=1' % showObj.indexerid})
|
{'title': 'Force Full Update', 'path': 'home/updateShow?show=%d&force=1' % showObj.indexerid})
|
||||||
@ -3895,7 +3951,7 @@ class Home(MainHandler):
|
|||||||
redirect("/home/displayShow?show=" + show)
|
redirect("/home/displayShow?show=" + show)
|
||||||
|
|
||||||
|
|
||||||
def deleteShow(self, show=None):
|
def deleteShow(self, show=None, full=0):
|
||||||
|
|
||||||
if show is None:
|
if show is None:
|
||||||
return self._genericMessage("Error", "Invalid show ID")
|
return self._genericMessage("Error", "Invalid show ID")
|
||||||
@ -3913,7 +3969,7 @@ class Home(MainHandler):
|
|||||||
# remove show from trakt.tv library
|
# remove show from trakt.tv library
|
||||||
sickbeard.traktCheckerScheduler.action.removeShowFromTraktLibrary(showObj)
|
sickbeard.traktCheckerScheduler.action.removeShowFromTraktLibrary(showObj)
|
||||||
|
|
||||||
showObj.deleteShow()
|
showObj.deleteShow(bool(full))
|
||||||
|
|
||||||
ui.notifications.message('<b>%s</b> has been deleted' % showObj.name)
|
ui.notifications.message('<b>%s</b> has been deleted' % showObj.name)
|
||||||
redirect("/home/")
|
redirect("/home/")
|
||||||
|
Loading…
Reference in New Issue
Block a user