Change validate and improve specific Torrent provider connections, IPT, KAT, SCC, TPB, TB, TD, TT.
Change refactor cache for torrent providers to reduce code. Change improve search category selection BMTV, FSH, FF, TB. Change identify more SD release qualities. Change update SpeedCD, MoreThan, TVChaosuk. Add torrent provider HD4Free. Remove torrent provider BitSoup. Change only create threads for providers needing a recent search instead of for all enabled. Add 4489 as experimental value to "Recent search frequency" to use provider freqs instead of fixed width for all. Fix searching nzb season packs. Change remove some logging cruft.
|
@ -64,6 +64,15 @@
|
|||
* Change instantly use saved value from Search Settings/Episode Search/"Check propers every" instead of after a restart
|
||||
* Change include OSError system messages in file system failure logs during post process
|
||||
* Fix find associated meta files to prevent orphan episode images
|
||||
* Add torrent provider HD4Free
|
||||
* Change validate and improve specific Torrent provider connections, IPT, KAT, SCC, TPB, TB, TD, TT
|
||||
* Change refactor cache for torrent providers to reduce code
|
||||
* Change improve search category selection BMTV, FSH, FF, TB
|
||||
* Change identify more SD release qualities
|
||||
* Change update SpeedCD, MoreThan, TVChaosuk
|
||||
* Change only create threads for providers needing a recent search instead of for all enabled
|
||||
* Add 4489 as experimental value to "Recent search frequency" to use provider freqs instead of fixed width for all
|
||||
* Change remove some logging cruft
|
||||
|
||||
|
||||
### 0.11.11 (2016-04-05 19:20:00 UTC)
|
||||
|
|
Before Width: | Height: | Size: 345 B |
Before Width: | Height: | Size: 3.3 KiB |
Before Width: | Height: | Size: 1 KiB |
BIN
gui/slick/images/providers/hd4free.png
Normal file
After Width: | Height: | Size: 621 B |
Before Width: | Height: | Size: 398 B After Width: | Height: | Size: 600 B |
Before Width: | Height: | Size: 979 B |
BIN
gui/slick/images/providers/pfmonkey.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
gui/slick/images/providers/simplynzbs.png
Normal file
After Width: | Height: | Size: 463 B |
Before Width: | Height: | Size: 3.5 KiB After Width: | Height: | Size: 673 B |
Before Width: | Height: | Size: 784 B After Width: | Height: | Size: 982 B |
Before Width: | Height: | Size: 349 B |
Before Width: | Height: | Size: 1,002 B After Width: | Height: | Size: 937 B |
Before Width: | Height: | Size: 754 B |
|
@ -37,9 +37,9 @@
|
|||
|
||||
var show_nzb_providers = <%= 'true' if sickbeard.USE_NZBS else 'false' %>;
|
||||
|
||||
#for $curNewznabProvider in $sickbeard.newznabProviderList:
|
||||
#for $cur_newznab_provider in $sickbeard.newznabProviderList:
|
||||
|
||||
\$(this).addProvider('$curNewznabProvider.get_id()', '$curNewznabProvider.name', '$curNewznabProvider.url', '<%= starify(curNewznabProvider.key) %>', '$curNewznabProvider.cat_ids', $int($curNewznabProvider.default), show_nzb_providers);
|
||||
\$(this).addProvider('$cur_newznab_provider.get_id()', '$cur_newznab_provider.name', '$cur_newznab_provider.url', '<%= starify(cur_newznab_provider.key) %>', '$cur_newznab_provider.cat_ids', $int($cur_newznab_provider.default), show_nzb_providers);
|
||||
|
||||
#end for
|
||||
|
||||
|
@ -47,9 +47,9 @@
|
|||
|
||||
#if $sickbeard.USE_TORRENTS
|
||||
|
||||
#for $curTorrentRssProvider in $sickbeard.torrentRssProviderList:
|
||||
#for $cur_torrent_rss_provider in $sickbeard.torrentRssProviderList:
|
||||
|
||||
\$(this).addTorrentRssProvider('$curTorrentRssProvider.get_id()', '$curTorrentRssProvider.name', '$curTorrentRssProvider.url', '<%= starify(curTorrentRssProvider.cookies) %>');
|
||||
\$(this).addTorrentRssProvider('$cur_torrent_rss_provider.get_id()', '$cur_torrent_rss_provider.name', '$cur_torrent_rss_provider.url', '<%= starify(cur_torrent_rss_provider.cookies) %>');
|
||||
|
||||
#end for
|
||||
|
||||
|
@ -98,20 +98,20 @@
|
|||
|
||||
|
||||
<ul id="provider_order_list" class="provider_order_panel">
|
||||
#for $curProvider in $sickbeard.providers.sortedProviderList()
|
||||
#if $curProvider.providerType == $GenericProvider.NZB and not $sickbeard.USE_NZBS
|
||||
#continue
|
||||
#elif $curProvider.providerType == $GenericProvider.TORRENT and not $sickbeard.USE_TORRENTS
|
||||
#continue
|
||||
#end if
|
||||
#set $curName = $curProvider.get_id()
|
||||
<li class="ui-state-default" id="$curName">
|
||||
<input type="checkbox" id="enable_$curName" class="provider_enabler" <%= html_checked if curProvider.is_enabled() else '' %>/>
|
||||
<a href="<%= anon_url(curProvider.url) %>" class="imgLink" rel="noreferrer" onclick="window.open(this.href, '_blank'); return false;"><img src="$sbRoot/images/providers/$curProvider.image_name()" alt="$curProvider.name" title="$curProvider.name" width="16" height="16" style="vertical-align:middle;"/></a>
|
||||
<span style="vertical-align:middle">$curProvider.name</span>
|
||||
<%= '*' if not curProvider.supportsBacklog else '' %>
|
||||
<span class="ui-icon ui-icon-arrowthick-2-n-s pull-right" style="margin-top:3px"></span>
|
||||
</li>
|
||||
#for $cur_provider in [$x for $x in $sickbeard.providers.sortedProviderList()
|
||||
if $x.providerType == $GenericProvider.NZB and $sickbeard.USE_NZBS or
|
||||
$x.providerType == $GenericProvider.TORRENT and $sickbeard.USE_TORRENTS]
|
||||
#set $cur_name = $cur_provider.get_id()
|
||||
#set $cur_url = $cur_provider.url
|
||||
#set $tip = ($cur_provider.name, 'Site Down')[not $cur_url]
|
||||
#set $state = ('', ' <span class="red-text">(Site Down?)</span>')[not $cur_url]
|
||||
<li class="ui-state-default" id="$cur_name">
|
||||
<input type="checkbox" id="enable_$cur_name" class="provider_enabler" <%= html_checked if cur_provider.is_enabled() else '' %>/>
|
||||
<a href="<%= anon_url(cur_url) %>" class="imgLink" rel="noreferrer" onclick="window.open(this.href,'_blank');return false;"><img src="$sbRoot/images/providers/$cur_provider.image_name()" alt="$tip" title="$tip" width="16" height="16" style="vertical-align:middle" /></a>
|
||||
<span style="vertical-align:middle">$cur_provider.name$state</span>
|
||||
<%= '*' if not cur_provider.supports_backlog else '' %>
|
||||
<span class="ui-icon ui-icon-arrowthick-2-n-s pull-right" style="margin-top:3px"></span>
|
||||
</li>
|
||||
#end for
|
||||
</ul>
|
||||
|
||||
|
@ -150,16 +150,13 @@
|
|||
<span class="component-desc">
|
||||
#set $provider_config_list_enabled = []
|
||||
#set $provider_config_list = []
|
||||
#for $curProvider in $sickbeard.providers.sortedProviderList()
|
||||
#if $curProvider.providerType == $GenericProvider.NZB and not $sickbeard.USE_NZBS
|
||||
#continue
|
||||
#elif $curProvider.providerType == $GenericProvider.TORRENT and not $sickbeard.USE_TORRENTS
|
||||
#continue
|
||||
#end if
|
||||
#if $curProvider.is_enabled()
|
||||
$provider_config_list_enabled.append($curProvider)
|
||||
#for $cur_provider in [$x for $x in $sickbeard.providers.sortedProviderList()
|
||||
if $x.providerType == $GenericProvider.NZB and $sickbeard.USE_NZBS or
|
||||
$x.providerType == $GenericProvider.TORRENT and $sickbeard.USE_TORRENTS]
|
||||
#if $cur_provider.is_enabled()
|
||||
$provider_config_list_enabled.append($cur_provider)
|
||||
#else
|
||||
$provider_config_list.append($curProvider)
|
||||
$provider_config_list.append($cur_provider)
|
||||
#end if
|
||||
#end for
|
||||
|
||||
|
@ -188,71 +185,71 @@
|
|||
</div>
|
||||
|
||||
<!-- start div for editing providers //-->
|
||||
#for $curNewznabProvider in [$curProvider for $curProvider in $sickbeard.newznabProviderList]
|
||||
<div class="providerDiv" id="${curNewznabProvider.get_id()}Div">
|
||||
#if $curNewznabProvider.default and $curNewznabProvider.needs_auth
|
||||
#for $cur_newznab_provider in [$cur_provider for $cur_provider in $sickbeard.newznabProviderList]
|
||||
<div class="providerDiv" id="${cur_newznab_provider.get_id()}Div">
|
||||
#if $cur_newznab_provider.default and $cur_newznab_provider.needs_auth
|
||||
<div class="field-pair">
|
||||
<label for="${curNewznabProvider.get_id()}_url">
|
||||
<label for="${cur_newznab_provider.get_id()}_url">
|
||||
<span class="component-title">URL</span>
|
||||
<span class="component-desc">
|
||||
<input type="text" id="${curNewznabProvider.get_id()}_url" value="$curNewznabProvider.url" class="form-control input-sm input350" disabled/>
|
||||
<input type="text" id="${cur_newznab_provider.get_id()}_url" value="$cur_newznab_provider.url" class="form-control input-sm input350" disabled/>
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="field-pair">
|
||||
<label for="${curNewznabProvider.get_id()}_hash">
|
||||
<label for="${cur_newznab_provider.get_id()}_hash">
|
||||
<span class="component-title">API key</span>
|
||||
<span class="component-desc">
|
||||
<input type="text" id="${curNewznabProvider.get_id()}_hash" value="<%= starify(curNewznabProvider.key) %>" newznab_name="${curNewznabProvider.get_id()}_hash" class="newznab_key form-control input-sm input350" />
|
||||
<input type="text" id="${cur_newznab_provider.get_id()}_hash" value="<%= starify(cur_newznab_provider.key) %>" newznab_name="${cur_newznab_provider.get_id()}_hash" class="newznab_key form-control input-sm input350" />
|
||||
<div class="clear-left"><p>get API key from provider website</p></div>
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
#end if
|
||||
#if $hasattr($curNewznabProvider, 'enable_recentsearch') and $curNewznabProvider.supportsBacklog:
|
||||
#if $hasattr($cur_newznab_provider, 'enable_recentsearch') and $cur_newznab_provider.supports_backlog:
|
||||
<div class="field-pair">
|
||||
<label for="${curNewznabProvider.get_id()}_enable_recentsearch">
|
||||
<label for="${cur_newznab_provider.get_id()}_enable_recentsearch">
|
||||
<span class="component-title">Enable recent searches</span>
|
||||
<span class="component-desc">
|
||||
<input type="checkbox" name="${curNewznabProvider.get_id()}_enable_recentsearch" id="${curNewznabProvider.get_id()}_enable_recentsearch" <%= html_checked if curNewznabProvider.enable_recentsearch else '' %>/>
|
||||
<input type="checkbox" name="${cur_newznab_provider.get_id()}_enable_recentsearch" id="${cur_newznab_provider.get_id()}_enable_recentsearch" <%= html_checked if cur_newznab_provider.enable_recentsearch else '' %>/>
|
||||
<p>perform recent searches at provider</p>
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
#end if
|
||||
#if $hasattr($curNewznabProvider, 'enable_backlog') and $curNewznabProvider.supportsBacklog:
|
||||
#if $hasattr($cur_newznab_provider, 'enable_backlog') and $cur_newznab_provider.supports_backlog:
|
||||
<div class="field-pair">
|
||||
<label for="${curNewznabProvider.get_id()}_enable_backlog">
|
||||
<label for="${cur_newznab_provider.get_id()}_enable_backlog">
|
||||
<span class="component-title">Enable backlog searches</span>
|
||||
<span class="component-desc">
|
||||
<input type="checkbox" name="${curNewznabProvider.get_id()}_enable_backlog" id="${curNewznabProvider.get_id()}_enable_backlog" <%= html_checked if curNewznabProvider.enable_backlog else '' %>/>
|
||||
<input type="checkbox" name="${cur_newznab_provider.get_id()}_enable_backlog" id="${cur_newznab_provider.get_id()}_enable_backlog" <%= html_checked if cur_newznab_provider.enable_backlog else '' %>/>
|
||||
<p>perform backlog searches at provider</p>
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
#end if
|
||||
#if $hasattr($curNewznabProvider, 'search_mode') and $curNewznabProvider.supportsBacklog:
|
||||
#if $hasattr($cur_newznab_provider, 'search_mode') and $cur_newznab_provider.supports_backlog:
|
||||
<div class="field-pair">
|
||||
<span class="component-title">Season search mode</span>
|
||||
<span class="component-title">Episode search mode</span>
|
||||
<span class="component-desc">
|
||||
<label class="space-right">
|
||||
<input type="radio" name="${curNewznabProvider.get_id()}_search_mode" id="${curNewznabProvider.get_id()}_search_mode_sponly" value="sponly" <%= html_checked if 'sponly' == curNewznabProvider.search_mode else '' %>/>season packs only
|
||||
<input type="radio" name="${cur_newznab_provider.get_id()}_search_mode" id="${cur_newznab_provider.get_id()}_search_mode_eponly" value="eponly" <%= html_checked if 'eponly' == cur_newznab_provider.search_mode else '' %>/>episodes only (normal use)
|
||||
</label>
|
||||
<label>
|
||||
<input type="radio" name="${curNewznabProvider.get_id()}_search_mode" id="${curNewznabProvider.get_id()}_search_mode_eponly" value="eponly" <%= html_checked if 'eponly' == curNewznabProvider.search_mode else '' %>/>episodes only
|
||||
<input type="radio" name="${cur_newznab_provider.get_id()}_search_mode" id="${cur_newznab_provider.get_id()}_search_mode_sponly" value="sponly" <%= html_checked if 'sponly' == cur_newznab_provider.search_mode else '' %>/>season packs only
|
||||
</label>
|
||||
<p>when searching for complete seasons, search for packs or collect single episodes</p>
|
||||
<p>when searching for episodes, collect single episodes or search for packs</p>
|
||||
</span>
|
||||
</div>
|
||||
#end if
|
||||
#if $hasattr($curNewznabProvider, 'search_fallback') and $curNewznabProvider.supportsBacklog:
|
||||
#if $hasattr($cur_newznab_provider, 'search_fallback') and $cur_newznab_provider.supports_backlog:
|
||||
<div class="field-pair">
|
||||
<label for="${curNewznabProvider.get_id()}_search_fallback">
|
||||
<span class="component-title">Season search fallback</span>
|
||||
<label for="${cur_newznab_provider.get_id()}_search_fallback">
|
||||
<span class="component-title">Episode search fallback</span>
|
||||
<span class="component-desc">
|
||||
<input type="checkbox" name="${curNewznabProvider.get_id()}_search_fallback" id="${curNewznabProvider.get_id()}_search_fallback" <%= html_checked if curNewznabProvider.search_fallback else '' %>/>
|
||||
<p>run the alternate season search mode when a complete season is not found</p>
|
||||
<input type="checkbox" name="${cur_newznab_provider.get_id()}_search_fallback" id="${cur_newznab_provider.get_id()}_search_fallback" <%= html_checked if cur_newznab_provider.search_fallback else '' %>/>
|
||||
<p>use the alternate episode search mode if no match is found -- warning; may result in a heavy block hit -- best use: manually collect a season, disable after.</p>
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
|
@ -262,80 +259,81 @@
|
|||
##
|
||||
|
||||
##
|
||||
#for $curNzbProvider in [$curProvider for $curProvider in $sickbeard.providers.sortedProviderList() if $curProvider.providerType == $GenericProvider.NZB and $curProvider not in $sickbeard.newznabProviderList]:
|
||||
<div class="providerDiv" id="${curNzbProvider.get_id()}Div">
|
||||
#if $hasattr($curNzbProvider, 'username'):
|
||||
#for $cur_nzb_provider in [$cur_provider for $cur_provider in $sickbeard.providers.sortedProviderList()
|
||||
if $cur_provider.providerType == $GenericProvider.NZB and $cur_provider not in $sickbeard.newznabProviderList]:
|
||||
<div class="providerDiv" id="${cur_nzb_provider.get_id()}Div">
|
||||
#if $hasattr($cur_nzb_provider, 'username'):
|
||||
<div class="field-pair">
|
||||
<label for="${curNzbProvider.get_id()}_username">
|
||||
<label for="${cur_nzb_provider.get_id()}_username">
|
||||
<span class="component-title">Username</span>
|
||||
<span class="component-desc">
|
||||
<input type="text" name="${curNzbProvider.get_id()}_username" value="$curNzbProvider.username" class="form-control input-sm input350" />
|
||||
<input type="text" name="${cur_nzb_provider.get_id()}_username" value="$cur_nzb_provider.username" class="form-control input-sm input350" />
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
#end if
|
||||
#if $hasattr($curNzbProvider, 'api_key'):
|
||||
#if $hasattr($cur_nzb_provider, 'api_key'):
|
||||
<div class="field-pair">
|
||||
<label for="${curNzbProvider.get_id()}_api_key">
|
||||
<label for="${cur_nzb_provider.get_id()}_api_key">
|
||||
<span class="component-title">API key</span>
|
||||
<span class="component-desc">
|
||||
#set $field_name = curNzbProvider.get_id() + '_api_key'
|
||||
<input type="text" name="$field_name" value="<%= starify(curNzbProvider.api_key) %>" class="form-control input-sm input350" />
|
||||
#if callable(getattr(curNzbProvider, 'ui_string', None))
|
||||
<div class="clear-left"><p>${curNzbProvider.ui_string($field_name)}</p></div>
|
||||
#set $field_name = cur_nzb_provider.get_id() + '_api_key'
|
||||
<input type="text" name="$field_name" value="<%= starify(cur_nzb_provider.api_key) %>" class="form-control input-sm input350" />
|
||||
#if callable(getattr(cur_nzb_provider, 'ui_string', None))
|
||||
<div class="clear-left"><p>${cur_nzb_provider.ui_string($field_name)}</p></div>
|
||||
#end if
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
#end if
|
||||
#if $hasattr($curNzbProvider, 'enable_recentsearch') and $curNzbProvider.supportsBacklog:
|
||||
#if $hasattr($cur_nzb_provider, 'enable_recentsearch') and $cur_nzb_provider.supports_backlog:
|
||||
<div class="field-pair">
|
||||
<label for="${curNzbProvider.get_id()}_enable_recentsearch">
|
||||
<label for="${cur_nzb_provider.get_id()}_enable_recentsearch">
|
||||
<span class="component-title">Enable recent searches</span>
|
||||
<span class="component-desc">
|
||||
<input type="checkbox" name="${curNzbProvider.get_id()}_enable_recentsearch" id="${curNzbProvider.get_id()}_enable_recentsearch" <%= html_checked if curNzbProvider.enable_recentsearch else '' %>/>
|
||||
<p>enable provider to perform recent searches.</p>
|
||||
<input type="checkbox" name="${cur_nzb_provider.get_id()}_enable_recentsearch" id="${cur_nzb_provider.get_id()}_enable_recentsearch" <%= html_checked if cur_nzb_provider.enable_recentsearch else '' %>/>
|
||||
<p>enable provider to perform recent searches</p>
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
#end if
|
||||
#if $hasattr($curNzbProvider, 'enable_backlog') and $curNzbProvider.supportsBacklog:
|
||||
#if $hasattr($cur_nzb_provider, 'enable_backlog') and $cur_nzb_provider.supports_backlog:
|
||||
<div class="field-pair">
|
||||
<label for="${curNzbProvider.get_id()}_enable_backlog">
|
||||
<label for="${cur_nzb_provider.get_id()}_enable_backlog">
|
||||
<span class="component-title">Enable backlog searches</span>
|
||||
<span class="component-desc">
|
||||
<input type="checkbox" name="${curNzbProvider.get_id()}_enable_backlog" id="${curNzbProvider.get_id()}_enable_backlog" <%= html_checked if curNzbProvider.enable_backlog else '' %>/>
|
||||
<p>enable provider to perform backlog searches.</p>
|
||||
<input type="checkbox" name="${cur_nzb_provider.get_id()}_enable_backlog" id="${cur_nzb_provider.get_id()}_enable_backlog" <%= html_checked if cur_nzb_provider.enable_backlog else '' %>/>
|
||||
<p>enable provider to perform backlog searches</p>
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
#end if
|
||||
#if $hasattr($curNzbProvider, 'search_mode') and $curNzbProvider.supportsBacklog:
|
||||
#if $hasattr($cur_nzb_provider, 'search_mode') and $cur_nzb_provider.supports_backlog:
|
||||
<div class="field-pair">
|
||||
<span class="component-title">Season search mode</span>
|
||||
<span class="component-title">Episode search mode</span>
|
||||
<span class="component-desc">
|
||||
<label class="space-right">
|
||||
<input type="radio" name="${curNzbProvider.get_id()}_search_mode" id="${curNzbProvider.get_id()}_search_mode_sponly" value="sponly" <%= html_checked if 'sponly' == curNzbProvider.search_mode else '' %>/>season packs only
|
||||
<input type="radio" name="${cur_nzb_provider.get_id()}_search_mode" id="${cur_nzb_provider.get_id()}_search_mode_eponly" value="eponly" <%= html_checked if 'eponly' == cur_nzb_provider.search_mode else '' %>/>episodes only (normal use)
|
||||
</label>
|
||||
<label>
|
||||
<input type="radio" name="${curNzbProvider.get_id()}_search_mode" id="${curNzbProvider.get_id()}_search_mode_eponly" value="eponly" <%= html_checked if 'eponly' == curNzbProvider.search_mode else '' %>/>episodes only
|
||||
<input type="radio" name="${cur_nzb_provider.get_id()}_search_mode" id="${cur_nzb_provider.get_id()}_search_mode_sponly" value="sponly" <%= html_checked if 'sponly' == cur_nzb_provider.search_mode else '' %>/>season packs only
|
||||
</label>
|
||||
<p>when searching for complete seasons, search for packs or collect single episodes</p>
|
||||
<p>when searching for episodes, collect single episodes or search for packs</p>
|
||||
</span>
|
||||
</div>
|
||||
#end if
|
||||
#if $hasattr($curNzbProvider, 'search_fallback') and $curNzbProvider.supportsBacklog:
|
||||
#if $hasattr($cur_nzb_provider, 'search_fallback') and $cur_nzb_provider.supports_backlog:
|
||||
<div class="field-pair">
|
||||
<label for="${curNzbProvider.get_id()}_search_fallback">
|
||||
<span class="component-title">Season search fallback</span>
|
||||
<label for="${cur_nzb_provider.get_id()}_search_fallback">
|
||||
<span class="component-title">Episode search fallback</span>
|
||||
<span class="component-desc">
|
||||
<input type="checkbox" name="${curNzbProvider.get_id()}_search_fallback" id="${curNzbProvider.get_id()}_search_fallback" <%= html_checked if curNzbProvider.search_fallback else '' %>/>
|
||||
<p>run the alternate season search mode when a complete season is not found</p>
|
||||
<input type="checkbox" name="${cur_nzb_provider.get_id()}_search_fallback" id="${cur_nzb_provider.get_id()}_search_fallback" <%= html_checked if cur_nzb_provider.search_fallback else '' %>/>
|
||||
<p>use the alternate episode search mode if no match is found -- warning; may result in a heavy block hit -- best use: manually collect a season, disable after.</p>
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
#end if
|
||||
#if not $curNzbProvider.supportsBacklog:
|
||||
#if not $cur_nzb_provider.supports_backlog:
|
||||
<div class="field-pair">
|
||||
<span class="component-desc">The latest releases are the focus of this provider, no backlog searching</span>
|
||||
</div>
|
||||
|
@ -345,233 +343,229 @@
|
|||
##
|
||||
|
||||
##
|
||||
#for $curTorrentProvider in [$curProvider for $curProvider in $sickbeard.providers.sortedProviderList() if $curProvider.providerType == $GenericProvider.TORRENT]:
|
||||
<div class="providerDiv" id="${curTorrentProvider.get_id()}Div">
|
||||
#if callable(getattr(curTorrentProvider, 'ui_string', None))
|
||||
#set $field_name = curTorrentProvider.get_id() + '_tip'
|
||||
#set $tip_text = curTorrentProvider.ui_string($field_name)
|
||||
#for $cur_torrent_provider in [$cur_provider for $cur_provider in $sickbeard.providers.sortedProviderList()
|
||||
if $cur_provider.providerType == $GenericProvider.TORRENT]:
|
||||
<div class="providerDiv" id="${cur_torrent_provider.get_id()}Div">
|
||||
#if callable(getattr(cur_torrent_provider, 'ui_string', None))
|
||||
#set $field_name = cur_torrent_provider.get_id() + '_tip'
|
||||
#set $tip_text = cur_torrent_provider.ui_string($field_name)
|
||||
#if $tip_text
|
||||
<div class="field-pair">
|
||||
<span class="component-desc" style="margin:0;width:100%">
|
||||
<div class="clear-left"><p class="grey-text"><span class="red-text">Important! ${curTorrentProvider.name}</span> $tip_text</p></div>
|
||||
<div class="clear-left"><p class="grey-text"><span class="red-text">Important! ${cur_torrent_provider.name}</span> $tip_text</p></div>
|
||||
</span>
|
||||
</div>
|
||||
#end if
|
||||
#end if
|
||||
#if $hasattr($curTorrentProvider, 'api_key'):
|
||||
#if $getattr($cur_torrent_provider, 'url_edit', None):
|
||||
<div class="field-pair">
|
||||
<label for="${curTorrentProvider.get_id()}_api_key">
|
||||
<span class="component-title">Api key:</span>
|
||||
<label for="url_base">
|
||||
#set $url_label = callable(getattr(cur_torrent_provider, 'ui_string', None)) and cur_torrent_provider.ui_string(cur_torrent_provider.get_id() + '_site_url') or 'Site URL'
|
||||
<span class="component-title">$url_label</span>
|
||||
<span class="component-desc">
|
||||
<input type="text" name="${curTorrentProvider.get_id()}_api_key" id="${curTorrentProvider.get_id()}_api_key" value="<%= starify(curTorrentProvider.api_key) %>" class="form-control input-sm input350" />
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
#end if
|
||||
#if $hasattr($curTorrentProvider, 'digest'):
|
||||
<div class="field-pair">
|
||||
<label for="${curTorrentProvider.get_id()}_digest">
|
||||
<span class="component-title">Cookies:</span>
|
||||
<span class="component-desc">
|
||||
#set $field_name = curTorrentProvider.get_id() + '_digest'
|
||||
<input type="text" name="$field_name" id="$field_name" value="<%= starify(curTorrentProvider.digest) %>" class="form-control input-sm input350" />
|
||||
#if callable(getattr(curTorrentProvider, 'ui_string', None))
|
||||
<div class="clear-left"><p>${curTorrentProvider.ui_string($field_name)}</p></div>
|
||||
#set $field_name = cur_torrent_provider.get_id() + '_url_edit'
|
||||
<input type="text" name="$field_name" id="$field_name" value="<%= ', '.join(cur_torrent_provider.url_home) %>" class="form-control input-sm input350" />
|
||||
#if callable(getattr(cur_torrent_provider, 'ui_string', None))
|
||||
<div class="clear-left"><p>${cur_torrent_provider.ui_string($field_name)}</p></div>
|
||||
#end if
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
#end if
|
||||
#if $hasattr($curTorrentProvider, 'hash'):
|
||||
#if $hasattr($cur_torrent_provider, 'api_key'):
|
||||
<div class="field-pair">
|
||||
<label for="${curTorrentProvider.get_id()}_hash">
|
||||
<label for="${cur_torrent_provider.get_id()}_api_key">
|
||||
<span class="component-title">Api key:</span>
|
||||
<span class="component-desc">
|
||||
<input type="text" name="${cur_torrent_provider.get_id()}_api_key" id="${cur_torrent_provider.get_id()}_api_key" value="<%= starify(cur_torrent_provider.api_key) %>" class="form-control input-sm input350" />
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
#end if
|
||||
#if $hasattr($cur_torrent_provider, 'digest'):
|
||||
#set $field_name = cur_torrent_provider.get_id() + '_digest'
|
||||
<div class="field-pair">
|
||||
<label for="$field_name">
|
||||
<span class="component-title">Cookies:</span>
|
||||
<span class="component-desc">
|
||||
<input type="text" name="$field_name" id="$field_name" value="<%= starify(cur_torrent_provider.digest) %>" class="form-control input-sm input350" />
|
||||
#if callable(getattr(cur_torrent_provider, 'ui_string', None))
|
||||
<div class="clear-left"><p>${cur_torrent_provider.ui_string($field_name)}</p></div>
|
||||
#end if
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
#end if
|
||||
#if $hasattr($cur_torrent_provider, 'hash'):
|
||||
<div class="field-pair">
|
||||
<label for="${cur_torrent_provider.get_id()}_hash">
|
||||
<span class="component-title">Hash:</span>
|
||||
<span class="component-desc">
|
||||
<input type="text" name="${curTorrentProvider.get_id()}_hash" id="${curTorrentProvider.get_id()}_hash" value="$curTorrentProvider.hash" class="form-control input-sm input350" />
|
||||
<input type="text" name="${cur_torrent_provider.get_id()}_hash" id="${cur_torrent_provider.get_id()}_hash" value="$cur_torrent_provider.hash" class="form-control input-sm input350" />
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
#end if
|
||||
#if $hasattr($curTorrentProvider, 'username'):
|
||||
#for $user_type in ['username', 'uid']:
|
||||
#if $hasattr($cur_torrent_provider, $user_type):
|
||||
#set $prov_type = '%s_%s' % ($cur_torrent_provider.get_id(), $user_type)
|
||||
#set $user_value = $getattr($cur_torrent_provider, $user_type) or ''
|
||||
<div class="field-pair">
|
||||
<label for="${curTorrentProvider.get_id()}_username">
|
||||
<span class="component-title">Username:</span>
|
||||
<label for="$prov_type">
|
||||
<span class="component-title">$user_type.capitalize():</span>
|
||||
<span class="component-desc">
|
||||
<input type="text" name="${curTorrentProvider.get_id()}_username" id="${curTorrentProvider.get_id()}_username" value="$curTorrentProvider.username" class="form-control input-sm input350" />
|
||||
<input type="text" name="$prov_type" id="$prov_type" value="$user_value" class="form-control input-sm input350" />
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
#end if
|
||||
#if $hasattr($curTorrentProvider, 'password'):
|
||||
#break
|
||||
#end if
|
||||
#end for
|
||||
#if $hasattr($cur_torrent_provider, 'password'):
|
||||
<div class="field-pair">
|
||||
<label for="${curTorrentProvider.get_id()}_password">
|
||||
<label for="${cur_torrent_provider.get_id()}_password">
|
||||
<span class="component-title">Password:</span>
|
||||
<span class="component-desc">
|
||||
<input type="password" name="${curTorrentProvider.get_id()}_password" id="${curTorrentProvider.get_id()}_password" value="#echo $curTorrentProvider.password and '*' * len($curTorrentProvider.password) or ''#" class="form-control input-sm input350" />
|
||||
<input type="password" name="${cur_torrent_provider.get_id()}_password" id="${cur_torrent_provider.get_id()}_password" value="#echo $cur_torrent_provider.password and '*' * len($cur_torrent_provider.password) or ''#" class="form-control input-sm input350" />
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
#end if
|
||||
#if $hasattr($curTorrentProvider, 'passkey'):
|
||||
#if $hasattr($cur_torrent_provider, 'passkey'):
|
||||
<div class="field-pair">
|
||||
<label for="${curTorrentProvider.get_id()}_passkey">
|
||||
<label for="${cur_torrent_provider.get_id()}_passkey">
|
||||
<span class="component-title">Passkey:</span>
|
||||
<span class="component-desc">
|
||||
<input type="text" name="${curTorrentProvider.get_id()}_passkey" id="${curTorrentProvider.get_id()}_passkey" value="<%= starify(curTorrentProvider.passkey) %>" class="form-control input-sm input350" />
|
||||
<input type="text" name="${cur_torrent_provider.get_id()}_passkey" id="${cur_torrent_provider.get_id()}_passkey" value="<%= starify(cur_torrent_provider.passkey) %>" class="form-control input-sm input350" />
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
#end if
|
||||
#if $hasattr($curTorrentProvider, '_seed_ratio') and 'blackhole' != $sickbeard.TORRENT_METHOD:
|
||||
#if $hasattr($cur_torrent_provider, '_seed_ratio') and 'blackhole' != $sickbeard.TORRENT_METHOD:
|
||||
#set $torrent_method_text = {'utorrent': 'uTorrent', 'transmission': 'Transmission', 'deluge': 'Deluge', 'download_station': 'Synology DS', 'rtorrent': 'rTorrent'}
|
||||
<div class="field-pair">
|
||||
<label for="${curTorrentProvider.get_id()}_ratio">
|
||||
<span class="component-title" id="${curTorrentProvider.get_id()}_ratio_desc">Seed until ratio (the goal)</span>
|
||||
<label for="${cur_torrent_provider.get_id()}_ratio">
|
||||
<span class="component-title" id="${cur_torrent_provider.get_id()}_ratio_desc">Seed until ratio (the goal)</span>
|
||||
<span class="component-desc">
|
||||
<input type="number" name="${curTorrentProvider.get_id()}_ratio" id="${curTorrentProvider.get_id()}_ratio" value="$curTorrentProvider._seed_ratio" class="form-control input-sm input75" />
|
||||
<input type="number" name="${cur_torrent_provider.get_id()}_ratio" id="${cur_torrent_provider.get_id()}_ratio" value="$cur_torrent_provider._seed_ratio" class="form-control input-sm input75" />
|
||||
<p>this ratio is requested of each item sent to $torrent_method_text[$sickbeard.TORRENT_METHOD]</p>
|
||||
<div class="clear-left"><p>(#if 'Transmission' in $torrent_method_text[$sickbeard.TORRENT_METHOD]#set -1 to seed forever, or #end if#leave blank for the $torrent_method_text[$sickbeard.TORRENT_METHOD] setting)</p></div>
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
#end if
|
||||
#if $hasattr($curTorrentProvider, 'seed_time') and 'utorrent' == $sickbeard.TORRENT_METHOD:
|
||||
#if $hasattr($cur_torrent_provider, 'seed_time') and 'utorrent' == $sickbeard.TORRENT_METHOD:
|
||||
#set $torrent_method_text = {'utorrent': 'uTorrent'}
|
||||
#set $use_default = 'to use the %s min <a href="%s/config/search/#core-component-group3">torrent search setting minumum default</a>' % ($sickbeard.TORRENT_SEED_TIME, $sbRoot) if $sickbeard.TORRENT_SEED_TIME else 'for the %s setting' % $torrent_method_text[$sickbeard.TORRENT_METHOD]
|
||||
<div class="field-pair">
|
||||
<label for="${curTorrentProvider.get_id()}_seed_time">
|
||||
<span class="component-title" id="${curTorrentProvider.get_id()}_seed_time_desc">Seed time (provider default)</span>
|
||||
<label for="${cur_torrent_provider.get_id()}_seed_time">
|
||||
<span class="component-title" id="${cur_torrent_provider.get_id()}_seed_time_desc">Seed time (provider default)</span>
|
||||
<span class="component-desc">
|
||||
<input type="number" name="${curTorrentProvider.get_id()}_seed_time" id="${curTorrentProvider.get_id()}_seed_time" value="$curTorrentProvider.seed_time" class="form-control input-sm input75" />
|
||||
<input type="number" name="${cur_torrent_provider.get_id()}_seed_time" id="${cur_torrent_provider.get_id()}_seed_time" value="$cur_torrent_provider.seed_time" class="form-control input-sm input75" />
|
||||
<p>set 1 or more minimum minutes for each item sent to $torrent_method_text[$sickbeard.TORRENT_METHOD]</p>
|
||||
<div class="clear-left"><p>(leave blank $use_default)</p></div>
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
#end if
|
||||
#if $hasattr($curTorrentProvider, 'minseed'):
|
||||
#if $hasattr($cur_torrent_provider, 'minseed'):
|
||||
<div class="field-pair">
|
||||
<label for="${curTorrentProvider.get_id()}_minseed">
|
||||
<span class="component-title" id="${curTorrentProvider.get_id()}_minseed_desc">Minimum seeders</span>
|
||||
<label for="${cur_torrent_provider.get_id()}_minseed">
|
||||
<span class="component-title" id="${cur_torrent_provider.get_id()}_minseed_desc">Minimum seeders</span>
|
||||
<span class="component-desc">
|
||||
<input type="number" name="${curTorrentProvider.get_id()}_minseed" id="${curTorrentProvider.get_id()}_minseed" value="$curTorrentProvider.minseed" class="form-control input-sm input75" />
|
||||
<input type="number" name="${cur_torrent_provider.get_id()}_minseed" id="${cur_torrent_provider.get_id()}_minseed" value="$cur_torrent_provider.minseed" class="form-control input-sm input75" />
|
||||
<p>a release must have to be snatch worthy</p>
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
#end if
|
||||
#if $hasattr($curTorrentProvider, 'minleech'):
|
||||
#if $hasattr($cur_torrent_provider, 'minleech'):
|
||||
<div class="field-pair">
|
||||
<label for="${curTorrentProvider.get_id()}_minleech">
|
||||
<span class="component-title" id="${curTorrentProvider.get_id()}_minleech_desc">Minimum leechers</span>
|
||||
<label for="${cur_torrent_provider.get_id()}_minleech">
|
||||
<span class="component-title" id="${cur_torrent_provider.get_id()}_minleech_desc">Minimum leechers</span>
|
||||
<span class="component-desc">
|
||||
<input type="number" name="${curTorrentProvider.get_id()}_minleech" id="${curTorrentProvider.get_id()}_minleech" value="$curTorrentProvider.minleech" class="form-control input-sm input75" />
|
||||
<input type="number" name="${cur_torrent_provider.get_id()}_minleech" id="${cur_torrent_provider.get_id()}_minleech" value="$cur_torrent_provider.minleech" class="form-control input-sm input75" />
|
||||
<p>a release must have to be snatch worthy</p>
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
#end if
|
||||
#if $hasattr($curTorrentProvider, 'proxy'):
|
||||
#if $hasattr($cur_torrent_provider, 'confirmed'):
|
||||
<div class="field-pair">
|
||||
<label for="${curTorrentProvider.get_id()}_proxy">
|
||||
<span class="component-title">Access provider via proxy</span>
|
||||
<span class="component-desc">
|
||||
<input type="checkbox" class="enabler" name="${curTorrentProvider.get_id()}_proxy" id="${curTorrentProvider.get_id()}_proxy" <%= html_checked if curTorrentProvider.proxy.enabled else '' %>/>
|
||||
<p>to bypass country blocking mechanisms</p>
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
#if $hasattr($curTorrentProvider.proxy, 'url'):
|
||||
<div class="field-pair content_${curTorrentProvider.get_id()}_proxy" id="content_${curTorrentProvider.get_id()}_proxy">
|
||||
<label for="${curTorrentProvider.get_id()}_proxy_url">
|
||||
<span class="component-title">Proxy URL:</span>
|
||||
<span class="component-desc">
|
||||
<select name="${curTorrentProvider.get_id()}_proxy_url" id="${curTorrentProvider.get_id()}_proxy_url" class="form-control input-sm">
|
||||
#for $i in $curTorrentProvider.proxy.urls.keys():
|
||||
<option value="$curTorrentProvider.proxy.urls[$i]" <%= html_selected if curTorrentProvider.proxy.url == curTorrentProvider.proxy.urls[i] else '' %>>$i</option>
|
||||
#end for
|
||||
</select>
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
#end if
|
||||
#end if
|
||||
#if $hasattr($curTorrentProvider, 'confirmed'):
|
||||
<div class="field-pair">
|
||||
<label for="${curTorrentProvider.get_id()}_confirmed">
|
||||
<label for="${cur_torrent_provider.get_id()}_confirmed">
|
||||
<span class="component-title">Confirmed download</span>
|
||||
<span class="component-desc">
|
||||
<input type="checkbox" name="${curTorrentProvider.get_id()}_confirmed" id="${curTorrentProvider.get_id()}_confirmed" <%= html_checked if curTorrentProvider.confirmed else '' %>/>
|
||||
<input type="checkbox" name="${cur_torrent_provider.get_id()}_confirmed" id="${cur_torrent_provider.get_id()}_confirmed" <%= html_checked if cur_torrent_provider.confirmed else '' %>/>
|
||||
<p>only download torrents from trusted or verified uploaders ?</p>
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
#end if
|
||||
#if $hasattr($curTorrentProvider, 'freeleech'):
|
||||
#if $hasattr($cur_torrent_provider, 'freeleech'):
|
||||
<div class="field-pair">
|
||||
<label for="${curTorrentProvider.get_id()}_freeleech">
|
||||
<label for="${cur_torrent_provider.get_id()}_freeleech">
|
||||
<span class="component-title">Freeleech</span>
|
||||
<span class="component-desc">
|
||||
<input type="checkbox" name="${curTorrentProvider.get_id()}_freeleech" id="${curTorrentProvider.get_id()}_freeleech" <%= html_checked if curTorrentProvider.freeleech else '' %>/>
|
||||
<p>only download <b>[FreeLeech]</b> torrents.</p>
|
||||
<input type="checkbox" name="${cur_torrent_provider.get_id()}_freeleech" id="${cur_torrent_provider.get_id()}_freeleech" <%= html_checked if cur_torrent_provider.freeleech else '' %>/>
|
||||
<p>only download <b>[FreeLeech]</b> torrents</p>
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
#end if
|
||||
#if $hasattr($curTorrentProvider, 'reject_m2ts'):
|
||||
#if $hasattr($cur_torrent_provider, 'reject_m2ts'):
|
||||
<div class="field-pair">
|
||||
<label for="${curTorrentProvider.get_id()}_reject_m2ts">
|
||||
<label for="${cur_torrent_provider.get_id()}_reject_m2ts">
|
||||
<span class="component-title">Reject Blu-ray M2TS releases</span>
|
||||
<span class="component-desc">
|
||||
<input type="checkbox" name="${curTorrentProvider.get_id()}_reject_m2ts" id="${curTorrentProvider.get_id()}_reject_m2ts" <%= html_checked if curTorrentProvider.reject_m2ts else '' %>/>
|
||||
<input type="checkbox" name="${cur_torrent_provider.get_id()}_reject_m2ts" id="${cur_torrent_provider.get_id()}_reject_m2ts" <%= html_checked if cur_torrent_provider.reject_m2ts else '' %>/>
|
||||
<p>enable to ignore Blu-ray MPEG-2 Transport Stream container releases</p>
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
#end if
|
||||
#if $hasattr($curTorrentProvider, 'enable_recentsearch') and $curTorrentProvider.supportsBacklog:
|
||||
#if $hasattr($cur_torrent_provider, 'enable_recentsearch'):
|
||||
<div class="field-pair">
|
||||
<label for="${curTorrentProvider.get_id()}_enable_recentsearch">
|
||||
<label for="${cur_torrent_provider.get_id()}_enable_recentsearch">
|
||||
<span class="component-title">Enable recent searches</span>
|
||||
<span class="component-desc">
|
||||
<input type="checkbox" name="${curTorrentProvider.get_id()}_enable_recentsearch" id="${curTorrentProvider.get_id()}_enable_recentsearch" <%= html_checked if curTorrentProvider.enable_recentsearch else '' %>/>
|
||||
<p>enable provider to perform recent searches.</p>
|
||||
<input type="checkbox" name="${cur_torrent_provider.get_id()}_enable_recentsearch" id="${cur_torrent_provider.get_id()}_enable_recentsearch" <%= html_checked if cur_torrent_provider.enable_recentsearch else '' %>/>
|
||||
<p>enable provider to perform recent searches</p>
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
#end if
|
||||
#if $hasattr($curTorrentProvider, 'enable_backlog') and $curTorrentProvider.supportsBacklog:
|
||||
#if $hasattr($cur_torrent_provider, 'enable_backlog') and $cur_torrent_provider.supports_backlog:
|
||||
<div class="field-pair">
|
||||
<label for="${curTorrentProvider.get_id()}_enable_backlog">
|
||||
<label for="${cur_torrent_provider.get_id()}_enable_backlog">
|
||||
<span class="component-title">Enable backlog searches</span>
|
||||
<span class="component-desc">
|
||||
<input type="checkbox" name="${curTorrentProvider.get_id()}_enable_backlog" id="${curTorrentProvider.get_id()}_enable_backlog" <%= html_checked if curTorrentProvider.enable_backlog else '' %>/>
|
||||
<p>enable provider to perform backlog searches.</p>
|
||||
<input type="checkbox" name="${cur_torrent_provider.get_id()}_enable_backlog" id="${cur_torrent_provider.get_id()}_enable_backlog" <%= html_checked if cur_torrent_provider.enable_backlog else '' %>/>
|
||||
<p>enable provider to perform backlog searches</p>
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
#end if
|
||||
#if $hasattr($curTorrentProvider, 'search_mode') and $curTorrentProvider.supportsBacklog:
|
||||
#if $hasattr($cur_torrent_provider, 'search_mode') and $cur_torrent_provider.supports_backlog:
|
||||
<div class="field-pair">
|
||||
<span class="component-title">Season search mode</span>
|
||||
<span class="component-title">Episode search mode</span>
|
||||
<span class="component-desc">
|
||||
<label class="space-right">
|
||||
<input type="radio" name="${curTorrentProvider.get_id()}_search_mode" id="${curTorrentProvider.get_id()}_search_mode_sponly" value="sponly" <%= html_checked if 'sponly' == curTorrentProvider.search_mode else '' %>/>season packs only
|
||||
<input type="radio" name="${cur_torrent_provider.get_id()}_search_mode" id="${cur_torrent_provider.get_id()}_search_mode_eponly" value="eponly" <%= html_checked if 'eponly' == cur_torrent_provider.search_mode else '' %>/>episodes only (normal use)
|
||||
</label>
|
||||
<label>
|
||||
<input type="radio" name="${curTorrentProvider.get_id()}_search_mode" id="${curTorrentProvider.get_id()}_search_mode_eponly" value="eponly" <%= html_checked if 'eponly' == curTorrentProvider.search_mode else '' %>/>episodes only
|
||||
<input type="radio" name="${cur_torrent_provider.get_id()}_search_mode" id="${cur_torrent_provider.get_id()}_search_mode_sponly" value="sponly" <%= html_checked if 'sponly' == cur_torrent_provider.search_mode else '' %>/>season packs only
|
||||
</label>
|
||||
<p>when searching for complete seasons, search for packs or collect single episodes</p>
|
||||
<p>when searching for episodes, collect single episodes or search for packs</p>
|
||||
</span>
|
||||
</div>
|
||||
#end if
|
||||
#if $hasattr($curTorrentProvider, 'search_fallback') and $curTorrentProvider.supportsBacklog:
|
||||
#if $hasattr($cur_torrent_provider, 'search_fallback') and $cur_torrent_provider.supports_backlog:
|
||||
<div class="field-pair">
|
||||
<label for="${curTorrentProvider.get_id()}_search_fallback">
|
||||
<span class="component-title">Season search fallback</span>
|
||||
<label for="${cur_torrent_provider.get_id()}_search_fallback">
|
||||
<span class="component-title">Episode search fallback</span>
|
||||
<span class="component-desc">
|
||||
<input type="checkbox" name="${curTorrentProvider.get_id()}_search_fallback" id="${curTorrentProvider.get_id()}_search_fallback" <%= html_checked if curTorrentProvider.search_fallback else '' %>/>
|
||||
<p>run the alternate season search mode when a complete season is not found</p>
|
||||
<input type="checkbox" name="${cur_torrent_provider.get_id()}_search_fallback" id="${cur_torrent_provider.get_id()}_search_fallback" <%= html_checked if cur_torrent_provider.search_fallback else '' %>/>
|
||||
<p>use the alternate episode search mode if no match is found -- warning; may result in duplicates or a heavy ratio hit -- best use: manually collect a season, disable after.</p>
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
|
|
|
@ -73,6 +73,7 @@
|
|||
<span class="component-desc">
|
||||
<input type="text" name="recentsearch_frequency" value="$sickbeard.RECENTSEARCH_FREQUENCY" class="form-control input-sm input75">
|
||||
<p>minutes between checking recent updated shows (minimum $sickbeard.MIN_RECENTSEARCH_FREQUENCY)</p>
|
||||
<p><em class="grey-text">enter 4489 for experimental internal provider frequencies</em></p>
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
|
|
|
@ -30,6 +30,7 @@ from threading import Lock
|
|||
import sys
|
||||
import os.path
|
||||
import uuid
|
||||
import ast
|
||||
import base64
|
||||
sys.path.insert(1, os.path.abspath('../lib'))
|
||||
from sickbeard import helpers, logger, db, naming, metadata, providers, scene_exceptions, scene_numbering, \
|
||||
|
@ -174,6 +175,7 @@ IMDB_ACCOUNTS = []
|
|||
IMDB_DEFAULT_LIST_ID = '64552276'
|
||||
IMDB_DEFAULT_LIST_NAME = 'SickGear'
|
||||
PROVIDER_ORDER = []
|
||||
PROVIDER_HOMES = {}
|
||||
|
||||
NAMING_MULTI_EP = False
|
||||
NAMING_ANIME_MULTI_EP = False
|
||||
|
@ -520,7 +522,7 @@ def initialize(consoleLogging=True):
|
|||
KEEP_PROCESSED_DIR, PROCESS_METHOD, TV_DOWNLOAD_DIR, MIN_RECENTSEARCH_FREQUENCY, DEFAULT_UPDATE_FREQUENCY, MIN_UPDATE_FREQUENCY, UPDATE_FREQUENCY, \
|
||||
showQueueScheduler, searchQueueScheduler, ROOT_DIRS, CACHE_DIR, ACTUAL_CACHE_DIR, ZONEINFO_DIR, TIMEZONE_DISPLAY, \
|
||||
NAMING_PATTERN, NAMING_MULTI_EP, NAMING_ANIME_MULTI_EP, NAMING_FORCE_FOLDERS, NAMING_ABD_PATTERN, NAMING_CUSTOM_ABD, NAMING_SPORTS_PATTERN, NAMING_CUSTOM_SPORTS, NAMING_ANIME_PATTERN, NAMING_CUSTOM_ANIME, NAMING_STRIP_YEAR, \
|
||||
RENAME_EPISODES, AIRDATE_EPISODES, properFinderScheduler, PROVIDER_ORDER, autoPostProcesserScheduler, \
|
||||
RENAME_EPISODES, AIRDATE_EPISODES, properFinderScheduler, PROVIDER_ORDER, PROVIDER_HOMES, autoPostProcesserScheduler, \
|
||||
providerList, newznabProviderList, torrentRssProviderList, \
|
||||
EXTRA_SCRIPTS, USE_TWITTER, TWITTER_USERNAME, TWITTER_PASSWORD, TWITTER_PREFIX, RECENTSEARCH_FREQUENCY, \
|
||||
USE_BOXCAR2, BOXCAR2_ACCESSTOKEN, BOXCAR2_NOTIFY_ONDOWNLOAD, BOXCAR2_NOTIFY_ONSUBTITLEDOWNLOAD, BOXCAR2_NOTIFY_ONSNATCH, BOXCAR2_SOUND, \
|
||||
|
@ -580,10 +582,6 @@ def initialize(consoleLogging=True):
|
|||
|
||||
ACTUAL_CACHE_DIR = check_setting_str(CFG, 'General', 'cache_dir', 'cache')
|
||||
|
||||
# fix bad configs due to buggy code
|
||||
if ACTUAL_CACHE_DIR == 'None':
|
||||
ACTUAL_CACHE_DIR = 'cache'
|
||||
|
||||
# unless they specify, put the cache dir inside the data dir
|
||||
if not os.path.isabs(ACTUAL_CACHE_DIR):
|
||||
CACHE_DIR = os.path.join(DATA_DIR, ACTUAL_CACHE_DIR)
|
||||
|
@ -699,6 +697,7 @@ def initialize(consoleLogging=True):
|
|||
SCENE_DEFAULT = bool(check_setting_int(CFG, 'General', 'scene_default', 0))
|
||||
|
||||
PROVIDER_ORDER = check_setting_str(CFG, 'General', 'provider_order', '').split()
|
||||
PROVIDER_HOMES = ast.literal_eval(check_setting_str(CFG, 'General', 'provider_homes', None) or '{}')
|
||||
|
||||
NAMING_PATTERN = check_setting_str(CFG, 'General', 'naming_pattern', 'Season %0S/%SN - S%0SE%0E - %EN')
|
||||
NAMING_ABD_PATTERN = check_setting_str(CFG, 'General', 'naming_abd_pattern', '%SN - %A.D - %EN')
|
||||
|
@ -1029,28 +1028,28 @@ def initialize(consoleLogging=True):
|
|||
prov_id = torrent_prov.get_id()
|
||||
prov_id_uc = torrent_prov.get_id().upper()
|
||||
torrent_prov.enabled = bool(check_setting_int(CFG, prov_id_uc, prov_id, 0))
|
||||
if getattr(torrent_prov, 'url_edit', None):
|
||||
torrent_prov.url_home = check_setting_str(CFG, prov_id_uc, prov_id + '_url_home', [])
|
||||
if hasattr(torrent_prov, 'api_key'):
|
||||
torrent_prov.api_key = check_setting_str(CFG, prov_id_uc, prov_id + '_api_key', '')
|
||||
if hasattr(torrent_prov, 'hash'):
|
||||
torrent_prov.hash = check_setting_str(CFG, prov_id_uc, prov_id + '_hash', '')
|
||||
if hasattr(torrent_prov, 'digest'):
|
||||
torrent_prov.digest = check_setting_str(CFG, prov_id_uc, prov_id + '_digest', '')
|
||||
if hasattr(torrent_prov, 'username'):
|
||||
torrent_prov.username = check_setting_str(CFG, prov_id_uc, prov_id + '_username', '')
|
||||
for user_type in ['username', 'uid']:
|
||||
if hasattr(torrent_prov, user_type):
|
||||
setattr(torrent_prov, user_type,
|
||||
check_setting_str(CFG, prov_id_uc, '%s_%s' % (prov_id, user_type), ''))
|
||||
if hasattr(torrent_prov, 'password'):
|
||||
torrent_prov.password = check_setting_str(CFG, prov_id_uc, prov_id + '_password', '')
|
||||
if hasattr(torrent_prov, 'passkey'):
|
||||
torrent_prov.passkey = check_setting_str(CFG, prov_id_uc, prov_id + '_passkey', '')
|
||||
if hasattr(torrent_prov, 'proxy'):
|
||||
torrent_prov.proxy.enabled = bool(check_setting_int(CFG, prov_id_uc, prov_id + '_proxy', 0))
|
||||
if hasattr(torrent_prov.proxy, 'url'):
|
||||
torrent_prov.proxy.url = check_setting_str(CFG, prov_id_uc, prov_id + '_proxy_url', '')
|
||||
if hasattr(torrent_prov, 'confirmed'):
|
||||
torrent_prov.confirmed = bool(check_setting_int(CFG, prov_id_uc, prov_id + '_confirmed', 0))
|
||||
if hasattr(torrent_prov, 'options'):
|
||||
torrent_prov.options = check_setting_str(CFG, prov_id_uc, prov_id + '_options', '')
|
||||
if hasattr(torrent_prov, '_seed_ratio'):
|
||||
torrent_prov._seed_ratio = check_setting_str(CFG, prov_id_uc, prov_id + '_seed_ratio', '').replace('None', '')
|
||||
torrent_prov._seed_ratio = check_setting_str(CFG, prov_id_uc, prov_id + '_seed_ratio', '')
|
||||
if hasattr(torrent_prov, 'seed_time'):
|
||||
torrent_prov.seed_time = check_setting_int(CFG, prov_id_uc, prov_id + '_seed_time', '')
|
||||
if hasattr(torrent_prov, 'minseed'):
|
||||
|
@ -1087,7 +1086,8 @@ def initialize(consoleLogging=True):
|
|||
nzb_prov.search_fallback = bool(check_setting_int(CFG, prov_id_uc, prov_id + '_search_fallback', 0))
|
||||
if hasattr(nzb_prov, 'enable_recentsearch'):
|
||||
nzb_prov.enable_recentsearch = bool(check_setting_int(CFG, prov_id_uc,
|
||||
prov_id + '_enable_recentsearch', 1))
|
||||
prov_id + '_enable_recentsearch', 1)) or \
|
||||
not getattr(nzb_prov, 'supports_backlog', True)
|
||||
if hasattr(nzb_prov, 'enable_backlog'):
|
||||
nzb_prov.enable_backlog = bool(check_setting_int(CFG, prov_id_uc, prov_id + '_enable_backlog', 1))
|
||||
|
||||
|
@ -1157,7 +1157,7 @@ def initialize(consoleLogging=True):
|
|||
cycleTime=datetime.timedelta(seconds=3),
|
||||
threadName='SEARCHQUEUE')
|
||||
|
||||
update_interval = datetime.timedelta(minutes=RECENTSEARCH_FREQUENCY)
|
||||
update_interval = datetime.timedelta(minutes=(RECENTSEARCH_FREQUENCY, 1)[4489 == RECENTSEARCH_FREQUENCY])
|
||||
recentSearchScheduler = scheduler.Scheduler(search_recent.RecentSearcher(),
|
||||
cycleTime=update_interval,
|
||||
threadName='RECENTSEARCHER',
|
||||
|
@ -1457,6 +1457,7 @@ def save_config():
|
|||
new_config['General']['anime_default'] = int(ANIME_DEFAULT)
|
||||
new_config['General']['scene_default'] = int(SCENE_DEFAULT)
|
||||
new_config['General']['provider_order'] = ' '.join(PROVIDER_ORDER)
|
||||
new_config['General']['provider_homes'] = '%s' % PROVIDER_HOMES
|
||||
new_config['General']['version_notify'] = int(VERSION_NOTIFY)
|
||||
new_config['General']['auto_update'] = int(AUTO_UPDATE)
|
||||
new_config['General']['notify_on_update'] = int(NOTIFY_ON_UPDATE)
|
||||
|
@ -1522,73 +1523,40 @@ def save_config():
|
|||
new_config['Blackhole']['nzb_dir'] = NZB_DIR
|
||||
new_config['Blackhole']['torrent_dir'] = TORRENT_DIR
|
||||
|
||||
# dynamically save provider settings
|
||||
for torrent_prov in [curProvider for curProvider in providers.sortedProviderList()
|
||||
if GenericProvider.TORRENT == curProvider.providerType]:
|
||||
prov_id = torrent_prov.get_id()
|
||||
prov_id_uc = torrent_prov.get_id().upper()
|
||||
new_config[prov_id_uc] = {}
|
||||
new_config[prov_id_uc][prov_id] = int(torrent_prov.enabled)
|
||||
if hasattr(torrent_prov, 'digest'):
|
||||
new_config[prov_id_uc][prov_id + '_digest'] = torrent_prov.digest
|
||||
if hasattr(torrent_prov, 'hash'):
|
||||
new_config[prov_id_uc][prov_id + '_hash'] = torrent_prov.hash
|
||||
if hasattr(torrent_prov, 'api_key'):
|
||||
new_config[prov_id_uc][prov_id + '_api_key'] = torrent_prov.api_key
|
||||
if hasattr(torrent_prov, 'username'):
|
||||
new_config[prov_id_uc][prov_id + '_username'] = torrent_prov.username
|
||||
if hasattr(torrent_prov, 'password'):
|
||||
new_config[prov_id_uc][prov_id + '_password'] = helpers.encrypt(torrent_prov.password, ENCRYPTION_VERSION)
|
||||
if hasattr(torrent_prov, 'passkey'):
|
||||
new_config[prov_id_uc][prov_id + '_passkey'] = torrent_prov.passkey
|
||||
if hasattr(torrent_prov, 'confirmed'):
|
||||
new_config[prov_id_uc][prov_id + '_confirmed'] = int(torrent_prov.confirmed)
|
||||
if hasattr(torrent_prov, '_seed_ratio'):
|
||||
new_config[prov_id_uc][prov_id + '_seed_ratio'] = torrent_prov.seed_ratio()
|
||||
if hasattr(torrent_prov, 'seed_time'):
|
||||
new_config[prov_id_uc][prov_id + '_seed_time'] = torrent_prov.seed_time
|
||||
if hasattr(torrent_prov, 'minseed'):
|
||||
new_config[prov_id_uc][prov_id + '_minseed'] = int(torrent_prov.minseed)
|
||||
if hasattr(torrent_prov, 'minleech'):
|
||||
new_config[prov_id_uc][prov_id + '_minleech'] = int(torrent_prov.minleech)
|
||||
if hasattr(torrent_prov, 'freeleech'):
|
||||
new_config[prov_id_uc][prov_id + '_freeleech'] = int(torrent_prov.freeleech)
|
||||
if hasattr(torrent_prov, 'reject_m2ts'):
|
||||
new_config[prov_id_uc][prov_id + '_reject_m2ts'] = int(torrent_prov.reject_m2ts)
|
||||
if hasattr(torrent_prov, 'enable_recentsearch'):
|
||||
new_config[prov_id_uc][prov_id + '_enable_recentsearch'] = int(torrent_prov.enable_recentsearch)
|
||||
if hasattr(torrent_prov, 'enable_backlog'):
|
||||
new_config[prov_id_uc][prov_id + '_enable_backlog'] = int(torrent_prov.enable_backlog)
|
||||
if hasattr(torrent_prov, 'search_mode'):
|
||||
new_config[prov_id_uc][prov_id + '_search_mode'] = torrent_prov.search_mode
|
||||
if hasattr(torrent_prov, 'search_fallback'):
|
||||
new_config[prov_id_uc][prov_id + '_search_fallback'] = int(torrent_prov.search_fallback)
|
||||
if hasattr(torrent_prov, 'options'):
|
||||
new_config[prov_id_uc][prov_id + '_options'] = torrent_prov.options
|
||||
if hasattr(torrent_prov, 'proxy'):
|
||||
new_config[prov_id_uc][prov_id + '_proxy'] = int(torrent_prov.proxy.enabled)
|
||||
if hasattr(torrent_prov.proxy, 'url'):
|
||||
new_config[prov_id_uc][prov_id + '_proxy_url'] = torrent_prov.proxy.url
|
||||
for src in [x for x in providers.sortedProviderList() if GenericProvider.TORRENT == x.providerType]:
|
||||
src_id = src.get_id()
|
||||
src_id_uc = src_id.upper()
|
||||
new_config[src_id_uc] = {}
|
||||
new_config[src_id_uc][src_id] = int(src.enabled)
|
||||
if getattr(src, 'url_edit', None):
|
||||
new_config[src_id_uc][src_id + '_url_home'] = src.url_home
|
||||
|
||||
for nzb_prov in [curProvider for curProvider in providers.sortedProviderList()
|
||||
if GenericProvider.NZB == curProvider.providerType]:
|
||||
prov_id = nzb_prov.get_id()
|
||||
prov_id_uc = nzb_prov.get_id().upper()
|
||||
new_config[prov_id_uc] = {}
|
||||
new_config[prov_id_uc][prov_id] = int(nzb_prov.enabled)
|
||||
if hasattr(src, 'password'):
|
||||
new_config[src_id_uc][src_id + '_password'] = helpers.encrypt(src.password, ENCRYPTION_VERSION)
|
||||
|
||||
if hasattr(nzb_prov, 'api_key'):
|
||||
new_config[prov_id_uc][prov_id + '_api_key'] = nzb_prov.api_key
|
||||
if hasattr(nzb_prov, 'username'):
|
||||
new_config[prov_id_uc][prov_id + '_username'] = nzb_prov.username
|
||||
if hasattr(nzb_prov, 'search_mode'):
|
||||
new_config[prov_id_uc][prov_id + '_search_mode'] = nzb_prov.search_mode
|
||||
if hasattr(nzb_prov, 'search_fallback'):
|
||||
new_config[prov_id_uc][prov_id + '_search_fallback'] = int(nzb_prov.search_fallback)
|
||||
if hasattr(nzb_prov, 'enable_recentsearch'):
|
||||
new_config[prov_id_uc][prov_id + '_enable_recentsearch'] = int(nzb_prov.enable_recentsearch)
|
||||
if hasattr(nzb_prov, 'enable_backlog'):
|
||||
new_config[prov_id_uc][prov_id + '_enable_backlog'] = int(nzb_prov.enable_backlog)
|
||||
for (setting, value) in [
|
||||
('%s_%s' % (src_id, k), getattr(src, k, v) if not v else helpers.tryInt(getattr(src, k, None)))
|
||||
for (k, v) in [
|
||||
('api_key', None), ('passkey', None), ('digest', None), ('hash', None), ('username', ''), ('uid', ''),
|
||||
('minseed', 1), ('minleech', 1), ('confirmed', 1), ('freeleech', 1), ('reject_m2ts', 1),
|
||||
('enable_recentsearch', 1), ('enable_backlog', 1), ('search_mode', None), ('search_fallback', 1),
|
||||
('seed_time', None)] if hasattr(src, k)]:
|
||||
new_config[src_id_uc][setting] = value
|
||||
|
||||
if hasattr(src, '_seed_ratio'):
|
||||
new_config[src_id_uc][src_id + '_seed_ratio'] = src.seed_ratio()
|
||||
|
||||
for src in [x for x in providers.sortedProviderList() if GenericProvider.NZB == x.providerType]:
|
||||
src_id = src.get_id()
|
||||
src_id_uc = src.get_id().upper()
|
||||
new_config[src_id_uc] = {}
|
||||
new_config[src_id_uc][src_id] = int(src.enabled)
|
||||
|
||||
for attr in [x for x in ['api_key', 'username', 'search_mode'] if hasattr(src, x)]:
|
||||
new_config[src_id_uc]['%s_%s' % (src_id, attr)] = getattr(src, attr)
|
||||
|
||||
for attr in [x for x in ['enable_recentsearch', 'enable_backlog', 'search_fallback'] if hasattr(src, x)]:
|
||||
new_config[src_id_uc]['%s_%s' % (src_id, attr)] = helpers.tryInt(getattr(src, attr, None))
|
||||
|
||||
new_config['SABnzbd'] = {}
|
||||
new_config['SABnzbd']['sab_username'] = SAB_USERNAME
|
||||
|
|
|
@ -213,6 +213,9 @@ class Quality:
|
|||
return Quality.SDTV
|
||||
elif checkName(['(dvd.?rip|b[r|d]rip)(.ws)?(.(xvid|divx|x264|h.?264))?'], any) and not checkName(['(720|1080|2160)[pi]'], all):
|
||||
return Quality.SDDVD
|
||||
elif checkName(['(xvid|divx|480p)'], any) and not checkName(['(720|1080|2160)[pi]'], all) \
|
||||
and not checkName(['hr.ws.pdtv.(x264|h.?264)'], any):
|
||||
return Quality.SDTV
|
||||
elif checkName(['720p', 'hdtv', 'x264|h.?264'], all) or checkName(['hr.ws.pdtv.(x264|h.?264)'], any) \
|
||||
and not checkName(['(1080|2160)[pi]'], all):
|
||||
return Quality.HDTV
|
||||
|
|
|
@ -420,7 +420,7 @@ def check_setting_str(config, cfg_name, item_name, def_val, log=True):
|
|||
else:
|
||||
logger.log('%s -> ******' % item_name, logger.DEBUG)
|
||||
|
||||
return my_val
|
||||
return (my_val, def_val)['None' == my_val]
|
||||
|
||||
|
||||
class ConfigMigrator():
|
||||
|
@ -783,4 +783,4 @@ class ConfigMigrator():
|
|||
old_token = check_setting_str(self.config_obj, 'Trakt', 'trakt_token', '')
|
||||
old_refresh_token = check_setting_str(self.config_obj, 'Trakt', 'trakt_refresh_token', '')
|
||||
if old_token and old_refresh_token:
|
||||
TraktAPI.add_account(old_token, old_refresh_token, None)
|
||||
TraktAPI.add_account(old_token, old_refresh_token, None)
|
||||
|
|
|
@ -95,17 +95,23 @@ class DBConnection(object):
|
|||
|
||||
while attempt < 5:
|
||||
try:
|
||||
affected = 0
|
||||
for qu in querylist:
|
||||
cursor = self.connection.cursor()
|
||||
if len(qu) == 1:
|
||||
if logTransaction:
|
||||
logger.log(qu[0], logger.DB)
|
||||
sqlResult.append(self.connection.execute(qu[0]).fetchall())
|
||||
|
||||
sqlResult.append(cursor.execute(qu[0]).fetchall())
|
||||
elif len(qu) > 1:
|
||||
if logTransaction:
|
||||
logger.log(qu[0] + ' with args ' + str(qu[1]), logger.DB)
|
||||
sqlResult.append(self.connection.execute(qu[0], qu[1]).fetchall())
|
||||
sqlResult.append(cursor.execute(qu[0], qu[1]).fetchall())
|
||||
affected += cursor.rowcount
|
||||
self.connection.commit()
|
||||
logger.log(u'Transaction with ' + str(len(querylist)) + u' queries executed', logger.DEBUG)
|
||||
if affected > 0:
|
||||
logger.log(u'Transaction with %s queries executed affected %i row%s' % (
|
||||
len(querylist), affected, helpers.maybe_plural(affected)), logger.DEBUG)
|
||||
return sqlResult
|
||||
except sqlite3.OperationalError as e:
|
||||
sqlResult = []
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
|
||||
from __future__ import with_statement
|
||||
|
||||
import urllib2
|
||||
import xml.etree.cElementTree as etree
|
||||
import xml.etree
|
||||
import re
|
||||
|
@ -84,7 +83,7 @@ def createNZBString(fileElements, xmlns):
|
|||
for curFile in fileElements:
|
||||
rootElement.append(stripNS(curFile, xmlns))
|
||||
|
||||
return xml.etree.ElementTree.tostring(rootElement, 'utf-8', 'replace')
|
||||
return xml.etree.ElementTree.tostring(rootElement, 'utf-8')
|
||||
|
||||
|
||||
def saveNZB(nzbName, nzbString):
|
||||
|
@ -158,7 +157,7 @@ def splitResult(result):
|
|||
|
||||
wantEp = True
|
||||
for epNo in parse_result.episode_numbers:
|
||||
if not result.extraInfo[0].wantEpisode(season, epNo, result.quality):
|
||||
if not result.show.wantEpisode(season, epNo, result.quality):
|
||||
logger.log(u"Ignoring result " + newNZB + " because we don't want an episode that is " +
|
||||
Quality.qualityStrings[result.quality], logger.DEBUG)
|
||||
wantEp = False
|
||||
|
@ -169,13 +168,14 @@ def splitResult(result):
|
|||
# get all the associated episode objects
|
||||
epObjList = []
|
||||
for curEp in parse_result.episode_numbers:
|
||||
epObjList.append(result.extraInfo[0].getEpisode(season, curEp))
|
||||
epObjList.append(result.show.getEpisode(season, curEp))
|
||||
|
||||
# make a result
|
||||
curResult = classes.NZBDataSearchResult(epObjList)
|
||||
curResult.name = newNZB
|
||||
curResult.provider = result.provider
|
||||
curResult.quality = result.quality
|
||||
curResult.show = result.show
|
||||
curResult.extraInfo = [createNZBString(separateNZBs[newNZB], xmlns)]
|
||||
|
||||
resultList.append(curResult)
|
||||
|
|
|
@ -18,30 +18,37 @@
|
|||
|
||||
from os import sys
|
||||
|
||||
import os.path
|
||||
import sickbeard
|
||||
|
||||
from . import generic
|
||||
from sickbeard import logger
|
||||
from sickbeard import logger, encodingKludge as ek
|
||||
# usenet
|
||||
from . import newznab, omgwtfnzbs, womble
|
||||
# torrent
|
||||
from . import alpharatio, beyondhd, bitmetv, bitsoup, btn, freshontv, funfile, gftracker, grabtheinfo, \
|
||||
hdbits, hdspace, iptorrents, kat, morethan, pisexy, pretome, rarbg, scc, scenetime, shazbat, speedcd, \
|
||||
from . import alpharatio, beyondhd, bitmetv, btn, freshontv, funfile, gftracker, grabtheinfo, \
|
||||
hd4free, hdbits, hdspace, iptorrents, kat, morethan, pisexy, pretome, rarbg, scc, scenetime, shazbat, speedcd, \
|
||||
thepiratebay, torrentbytes, torrentday, torrenting, torrentleech, torrentshack, transmithe_net, tvchaosuk
|
||||
# anime
|
||||
from . import nyaatorrents, tokyotoshokan
|
||||
# custom
|
||||
try:
|
||||
from . import custom01
|
||||
except:
|
||||
pass
|
||||
|
||||
__all__ = ['omgwtfnzbs',
|
||||
'womble',
|
||||
'alpharatio',
|
||||
'beyondhd',
|
||||
'bitmetv',
|
||||
'bitsoup',
|
||||
'btn',
|
||||
'custom01',
|
||||
'freshontv',
|
||||
'funfile',
|
||||
'gftracker',
|
||||
'grabtheinfo',
|
||||
'hd4free',
|
||||
'hdbits',
|
||||
'hdspace',
|
||||
'iptorrents',
|
||||
|
@ -208,16 +215,19 @@ def makeTorrentRssProvider(configString):
|
|||
|
||||
|
||||
def getDefaultNewznabProviders():
|
||||
return 'Sick Beard Index|http://lolo.sickbeard.com/|0|5030,5040|0|eponly|0|0|0!!!NZBs.org|https://nzbs.org/||5030,5040|0|eponly|0|0|0!!!Usenet-Crawler|https://www.usenet-crawler.com/||5030,5040|0|eponly|0|0|0'
|
||||
return '!!!'.join(['Sick Beard Index|http://lolo.sickbeard.com/|0|5030,5040|0|eponly|0|0|0',
|
||||
'NZBgeek|https://api.nzbgeek.info/||5030,5040|0|eponly|0|0|0',
|
||||
'NZBs.org|https://nzbs.org/||5030,5040|0|eponly|0|0|0',
|
||||
'Usenet-Crawler|https://www.usenet-crawler.com/||5030,5040|0|eponly|0|0|0'])
|
||||
|
||||
|
||||
def getProviderModule(name):
|
||||
name = name.lower()
|
||||
prefix = "sickbeard.providers."
|
||||
prefix, cprov, name = 'sickbeard.providers.', 'motsuc'[::-1], name.lower()
|
||||
if name in __all__ and prefix + name in sys.modules:
|
||||
return sys.modules[prefix + name]
|
||||
else:
|
||||
raise Exception("Can't find " + prefix + name + " in " + "Providers")
|
||||
elif cprov in name:
|
||||
return None
|
||||
raise Exception('Can\'t find %s%s in providers' % (prefix, name))
|
||||
|
||||
|
||||
def getProviderClass(id):
|
||||
|
|
|
@ -21,7 +21,7 @@ import re
|
|||
import traceback
|
||||
|
||||
from . import generic
|
||||
from sickbeard import logger, tvcache
|
||||
from sickbeard import logger
|
||||
from sickbeard.bs4_parser import BS4Parser
|
||||
from sickbeard.helpers import tryInt
|
||||
from lib.unidecode import unidecode
|
||||
|
@ -31,7 +31,7 @@ class AlphaRatioProvider(generic.TorrentProvider):
|
|||
|
||||
def __init__(self):
|
||||
|
||||
generic.TorrentProvider.__init__(self, 'AlphaRatio')
|
||||
generic.TorrentProvider.__init__(self, 'AlphaRatio', cache_update_freq=20)
|
||||
|
||||
self.url_base = 'https://alpharatio.cc/'
|
||||
self.urls = {'config_provider_home_uri': self.url_base,
|
||||
|
@ -44,9 +44,7 @@ class AlphaRatioProvider(generic.TorrentProvider):
|
|||
|
||||
self.url = self.urls['config_provider_home_uri']
|
||||
|
||||
self.username, self.password, self.minseed, self.minleech = 4 * [None]
|
||||
self.freeleech = False
|
||||
self.cache = AlphaRatioCache(self)
|
||||
self.username, self.password, self.freeleech, self.minseed, self.minleech = 5 * [None]
|
||||
|
||||
def _authorised(self, **kwargs):
|
||||
|
||||
|
@ -65,7 +63,7 @@ class AlphaRatioProvider(generic.TorrentProvider):
|
|||
for mode in search_params.keys():
|
||||
for search_string in search_params[mode]:
|
||||
search_string = isinstance(search_string, unicode) and unidecode(search_string) or search_string
|
||||
search_url = self.urls['search'] % (search_string, ('', '&freetorrent=1')[self.freeleech])
|
||||
search_url = self.urls['search'] % (search_string, ('&freetorrent=1', '')[not self.freeleech])
|
||||
|
||||
html = self.get_url(search_url)
|
||||
|
||||
|
@ -111,16 +109,4 @@ class AlphaRatioProvider(generic.TorrentProvider):
|
|||
return results
|
||||
|
||||
|
||||
class AlphaRatioCache(tvcache.TVCache):
|
||||
|
||||
def __init__(self, this_provider):
|
||||
tvcache.TVCache.__init__(self, this_provider)
|
||||
|
||||
self.update_freq = 20 # cache update frequency
|
||||
|
||||
def _cache_data(self):
|
||||
|
||||
return self.provider.cache_data()
|
||||
|
||||
|
||||
provider = AlphaRatioProvider()
|
||||
|
|
|
@ -19,7 +19,7 @@ import re
|
|||
import time
|
||||
|
||||
from . import generic
|
||||
from sickbeard import logger, tvcache
|
||||
from sickbeard import logger
|
||||
from sickbeard.exceptions import AuthException
|
||||
from lib.unidecode import unidecode
|
||||
|
||||
|
@ -41,7 +41,6 @@ class BeyondHDProvider(generic.TorrentProvider):
|
|||
self.url = self.urls['config_provider_home_uri']
|
||||
|
||||
self.passkey, self.minseed, self.minleech = 3 * [None]
|
||||
self.cache = BeyondHDCache(self)
|
||||
|
||||
def _check_auth_from_data(self, data_json):
|
||||
|
||||
|
@ -101,14 +100,4 @@ class BeyondHDProvider(generic.TorrentProvider):
|
|||
return generic.TorrentProvider._episode_strings(self, ep_obj, scene=False, **kwargs)
|
||||
|
||||
|
||||
class BeyondHDCache(tvcache.TVCache):
|
||||
|
||||
def __init__(self, this_provider):
|
||||
tvcache.TVCache.__init__(self, this_provider)
|
||||
|
||||
def _cache_data(self):
|
||||
|
||||
return self.provider.cache_data()
|
||||
|
||||
|
||||
provider = BeyondHDProvider()
|
||||
|
|
|
@ -19,7 +19,7 @@ import re
|
|||
import traceback
|
||||
|
||||
from . import generic
|
||||
from sickbeard import logger, tvcache
|
||||
from sickbeard import logger
|
||||
from sickbeard.bs4_parser import BS4Parser
|
||||
from sickbeard.helpers import tryInt
|
||||
from lib.unidecode import unidecode
|
||||
|
@ -28,7 +28,7 @@ from lib.unidecode import unidecode
|
|||
class BitmetvProvider(generic.TorrentProvider):
|
||||
|
||||
def __init__(self):
|
||||
generic.TorrentProvider.__init__(self, 'BitMeTV')
|
||||
generic.TorrentProvider.__init__(self, 'BitMeTV', cache_update_freq=7)
|
||||
|
||||
self.url_base = 'http://www.bitmetv.org/'
|
||||
|
||||
|
@ -42,7 +42,6 @@ class BitmetvProvider(generic.TorrentProvider):
|
|||
self.url = self.urls['config_provider_home_uri']
|
||||
|
||||
self.digest, self.minseed, self.minleech = 3 * [None]
|
||||
self.cache = BitmetvCache(self)
|
||||
|
||||
def _authorised(self, **kwargs):
|
||||
|
||||
|
@ -63,9 +62,7 @@ class BitmetvProvider(generic.TorrentProvider):
|
|||
for mode in search_params.keys():
|
||||
for search_string in search_params[mode]:
|
||||
search_string = isinstance(search_string, unicode) and unidecode(search_string) or search_string
|
||||
category = 'cat=%s' % self.categories[
|
||||
(mode in ['Season', 'Episode'] and self.show and self.show.is_anime) and 'anime' or 'shows']
|
||||
search_url = self.urls['search'] % (category, search_string)
|
||||
search_url = self.urls['search'] % (self._categories_string(mode, 'cat=%s'), search_string)
|
||||
|
||||
html = self.get_url(search_url)
|
||||
|
||||
|
@ -89,8 +86,8 @@ class BitmetvProvider(generic.TorrentProvider):
|
|||
continue
|
||||
|
||||
info = tr.find('a', href=rc['info'])
|
||||
title = 'title' in info.attrs and info.attrs['title'] or info.get_text().strip()
|
||||
download_url = self.urls['get'] % tr.find('a', href=rc['get']).get('href')
|
||||
title = info.attrs.get('title') or info.get_text().strip()
|
||||
download_url = self.urls['get'] % str(tr.find('a', href=rc['get'])['href']).lstrip('/')
|
||||
except (AttributeError, TypeError, ValueError):
|
||||
continue
|
||||
|
||||
|
@ -116,16 +113,4 @@ class BitmetvProvider(generic.TorrentProvider):
|
|||
return 'bitmetv_digest' == key and 'use... \'uid=xx; pass=yy\'' or ''
|
||||
|
||||
|
||||
class BitmetvCache(tvcache.TVCache):
|
||||
|
||||
def __init__(self, this_provider):
|
||||
tvcache.TVCache.__init__(self, this_provider)
|
||||
|
||||
self.update_freq = 7 # cache update frequency
|
||||
|
||||
def _cache_data(self):
|
||||
|
||||
return self.provider.cache_data()
|
||||
|
||||
|
||||
provider = BitmetvProvider()
|
||||
|
|
|
@ -1,120 +0,0 @@
|
|||
# coding=utf-8
|
||||
#
|
||||
# This file is part of SickGear.
|
||||
#
|
||||
# SickGear is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# SickGear is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with SickGear. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import re
|
||||
import traceback
|
||||
|
||||
from . import generic
|
||||
from sickbeard import logger, tvcache
|
||||
from sickbeard.bs4_parser import BS4Parser
|
||||
from sickbeard.helpers import tryInt
|
||||
from lib.unidecode import unidecode
|
||||
|
||||
|
||||
class BitSoupProvider(generic.TorrentProvider):
|
||||
|
||||
def __init__(self):
|
||||
generic.TorrentProvider.__init__(self, 'BitSoup')
|
||||
|
||||
self.url_base = 'https://www.bitsoup.me/'
|
||||
self.urls = {'config_provider_home_uri': self.url_base,
|
||||
'login': self.url_base + 'takelogin.php',
|
||||
'search': self.url_base + 'browse.php?search=%s&%s&incldead=0&blah=0',
|
||||
'get': self.url_base + '%s'}
|
||||
|
||||
self.categories = {'shows': [42, 45, 49, 32, 7], 'anime': [23]}
|
||||
|
||||
self.url = self.urls['config_provider_home_uri']
|
||||
|
||||
self.username, self.password, self.minseed, self.minleech = 4 * [None]
|
||||
self.cache = BitSoupCache(self)
|
||||
|
||||
def _search_provider(self, search_params, **kwargs):
|
||||
|
||||
results = []
|
||||
if not self._authorised():
|
||||
return results
|
||||
|
||||
items = {'Cache': [], 'Season': [], 'Episode': [], 'Propers': []}
|
||||
|
||||
rc = dict((k, re.compile('(?i)' + v)) for (k, v) in {'info': 'detail', 'get': 'download'}.items())
|
||||
for mode in search_params.keys():
|
||||
for search_string in search_params[mode]:
|
||||
search_string = isinstance(search_string, unicode) and unidecode(search_string) or search_string
|
||||
search_url = self.urls['search'] % (search_string, self._categories_string(mode))
|
||||
|
||||
html = self.get_url(search_url)
|
||||
|
||||
cnt = len(items[mode])
|
||||
try:
|
||||
if not html or self._has_no_results(html):
|
||||
raise generic.HaltParseException
|
||||
|
||||
with BS4Parser(html, 'html.parser', attr='class="koptekst"') as soup:
|
||||
torrent_table = soup.find('table', attrs={'class': 'koptekst'})
|
||||
torrent_rows = [] if not torrent_table else torrent_table.find_all('tr')
|
||||
|
||||
if 2 > len(torrent_rows):
|
||||
raise generic.HaltParseException
|
||||
|
||||
for tr in torrent_rows[1:]:
|
||||
try:
|
||||
seeders, leechers, size = [tryInt(n, n) for n in [
|
||||
(tr.find_all('td')[x].get_text().strip()) for x in (-3, -2, -5)]]
|
||||
if self._peers_fail(mode, seeders, leechers):
|
||||
continue
|
||||
|
||||
info = tr.find('a', href=rc['info'])
|
||||
title = info.get_text().strip()
|
||||
|
||||
download_url = self.urls['get'] % str(tr.find('a', href=rc['get'])['href']).lstrip('/')
|
||||
except (AttributeError, TypeError, ValueError):
|
||||
continue
|
||||
|
||||
if title and download_url:
|
||||
items[mode].append((title, download_url, seeders, self._bytesizer(size)))
|
||||
|
||||
except generic.HaltParseException:
|
||||
pass
|
||||
except Exception:
|
||||
logger.log(u'Failed to parse. Traceback: %s' % traceback.format_exc(), logger.ERROR)
|
||||
self._log_search(mode, len(items[mode]) - cnt, search_url)
|
||||
|
||||
self._sort_seeders(mode, items)
|
||||
|
||||
results = list(set(results + items[mode]))
|
||||
|
||||
return results
|
||||
|
||||
def _episode_strings(self, ep_obj, **kwargs):
|
||||
|
||||
return generic.TorrentProvider._episode_strings(self, ep_obj, sep_date='|', **kwargs)
|
||||
|
||||
|
||||
class BitSoupCache(tvcache.TVCache):
|
||||
|
||||
def __init__(self, this_provider):
|
||||
tvcache.TVCache.__init__(self, this_provider)
|
||||
|
||||
self.update_freq = 20 # cache update frequency
|
||||
|
||||
def _cache_data(self):
|
||||
|
||||
return self.provider.cache_data()
|
||||
|
||||
|
||||
provider = BitSoupProvider()
|
|
@ -19,7 +19,7 @@ import re
|
|||
import traceback
|
||||
|
||||
from . import generic
|
||||
from sickbeard import logger, tvcache
|
||||
from sickbeard import logger
|
||||
from sickbeard.bs4_parser import BS4Parser
|
||||
from sickbeard.helpers import tryInt
|
||||
from lib.unidecode import unidecode
|
||||
|
@ -28,19 +28,19 @@ from lib.unidecode import unidecode
|
|||
class FreshOnTVProvider(generic.TorrentProvider):
|
||||
|
||||
def __init__(self):
|
||||
generic.TorrentProvider.__init__(self, 'FreshOnTV')
|
||||
generic.TorrentProvider.__init__(self, 'FreshOnTV', cache_update_freq=20)
|
||||
|
||||
self.url_base = 'https://freshon.tv/'
|
||||
self.urls = {'config_provider_home_uri': self.url_base,
|
||||
'login': self.url_base + 'login.php?action=makelogin',
|
||||
'search': self.url_base + 'browse.php?incldead=%s&words=0&cat=0&search=%s',
|
||||
'search': self.url_base + 'browse.php?incldead=%s&words=0&%s&search=%s',
|
||||
'get': self.url_base + '%s'}
|
||||
|
||||
self.categories = {'shows': 0, 'anime': 235}
|
||||
|
||||
self.url = self.urls['config_provider_home_uri']
|
||||
|
||||
self.username, self.password, self.minseed, self.minleech = 4 * [None]
|
||||
self.freeleech = False
|
||||
self.cache = FreshOnTVCache(self)
|
||||
self.username, self.password, self.freeleech, self.minseed, self.minleech = 5 * [None]
|
||||
|
||||
def _authorised(self, **kwargs):
|
||||
|
||||
|
@ -59,16 +59,17 @@ class FreshOnTVProvider(generic.TorrentProvider):
|
|||
return results
|
||||
|
||||
items = {'Cache': [], 'Season': [], 'Episode': [], 'Propers': []}
|
||||
freeleech = (0, 3)[self.freeleech]
|
||||
freeleech = (3, 0)[not self.freeleech]
|
||||
|
||||
rc = dict((k, re.compile('(?i)' + v))
|
||||
for (k, v) in {'info': 'detail', 'get': 'download', 'name': '_name'}.items())
|
||||
for mode in search_params.keys():
|
||||
for search_string in search_params[mode]:
|
||||
|
||||
search_string, search_url = self._title_and_url((
|
||||
isinstance(search_string, unicode) and unidecode(search_string) or search_string,
|
||||
self.urls['search'] % (freeleech, search_string)))
|
||||
search_string, void = self._title_and_url((
|
||||
isinstance(search_string, unicode) and unidecode(search_string) or search_string, ''))
|
||||
void, search_url = self._title_and_url((
|
||||
'', self.urls['search'] % (freeleech, self._categories_string(mode, 'cat=%s'), search_string)))
|
||||
|
||||
# returns top 15 results by default, expandable in user profile to 100
|
||||
html = self.get_url(search_url)
|
||||
|
@ -96,7 +97,7 @@ class FreshOnTVProvider(generic.TorrentProvider):
|
|||
continue
|
||||
|
||||
info = tr.find('a', href=rc['info'], attrs={'class': rc['name']})
|
||||
title = 'title' in info.attrs and info.attrs['title'] or info.get_text().strip()
|
||||
title = info.attrs.get('title') or info.get_text().strip()
|
||||
|
||||
download_url = self.urls['get'] % str(tr.find('a', href=rc['get'])['href']).lstrip('/')
|
||||
except (AttributeError, TypeError, ValueError):
|
||||
|
@ -117,21 +118,9 @@ class FreshOnTVProvider(generic.TorrentProvider):
|
|||
|
||||
return results
|
||||
|
||||
def _get_episode_search_strings(self, ep_obj, **kwargs):
|
||||
def _episode_strings(self, ep_obj, **kwargs):
|
||||
|
||||
return generic.TorrentProvider._episode_strings(self, ep_obj, sep_date='|', **kwargs)
|
||||
|
||||
|
||||
class FreshOnTVCache(tvcache.TVCache):
|
||||
|
||||
def __init__(self, this_provider):
|
||||
tvcache.TVCache.__init__(self, this_provider)
|
||||
|
||||
self.update_freq = 20
|
||||
|
||||
def _cache_data(self):
|
||||
|
||||
return self.provider.cache_data()
|
||||
|
||||
|
||||
provider = FreshOnTVProvider()
|
||||
|
|
|
@ -19,7 +19,7 @@ import re
|
|||
import traceback
|
||||
|
||||
from . import generic
|
||||
from sickbeard import logger, tvcache
|
||||
from sickbeard import logger
|
||||
from sickbeard.bs4_parser import BS4Parser
|
||||
from sickbeard.helpers import tryInt
|
||||
from lib.unidecode import unidecode
|
||||
|
@ -28,7 +28,7 @@ from lib.unidecode import unidecode
|
|||
class FunFileProvider(generic.TorrentProvider):
|
||||
|
||||
def __init__(self):
|
||||
generic.TorrentProvider.__init__(self, 'FunFile')
|
||||
generic.TorrentProvider.__init__(self, 'FunFile', cache_update_freq=15)
|
||||
|
||||
self.url_base = 'https://www.funfile.org/'
|
||||
self.urls = {'config_provider_home_uri': self.url_base,
|
||||
|
@ -41,7 +41,6 @@ class FunFileProvider(generic.TorrentProvider):
|
|||
self.url = self.urls['config_provider_home_uri']
|
||||
self.url_timeout = 90
|
||||
self.username, self.password, self.minseed, self.minleech = 4 * [None]
|
||||
self.cache = FunFileCache(self)
|
||||
|
||||
def _authorised(self, **kwargs):
|
||||
|
||||
|
@ -58,10 +57,9 @@ class FunFileProvider(generic.TorrentProvider):
|
|||
|
||||
items = {'Cache': [], 'Season': [], 'Episode': [], 'Propers': []}
|
||||
|
||||
rc = dict((k, re.compile('(?i)' + v)) for (k, v) in {'info': 'detail', 'get': 'download',
|
||||
'cats': 'cat=(?:%s)' % self._categories_string(template='', delimiter='|')
|
||||
}.items())
|
||||
rc = dict((k, re.compile('(?i)' + v)) for (k, v) in {'info': 'detail', 'get': 'download'}.items())
|
||||
for mode in search_params.keys():
|
||||
rc['cats'] = re.compile('(?i)cat=(?:%s)' % self._categories_string(mode, template='', delimiter='|'))
|
||||
for search_string in search_params[mode]:
|
||||
search_string = isinstance(search_string, unicode) and unidecode(search_string) or search_string
|
||||
search_url = self.urls['search'] % (self._categories_string(mode), search_string)
|
||||
|
@ -91,8 +89,8 @@ class FunFileProvider(generic.TorrentProvider):
|
|||
if None is tr.find('a', href=rc['cats']) or self._peers_fail(mode, seeders, leechers):
|
||||
continue
|
||||
|
||||
title = 'title' in info.attrs and info.attrs['title'] or info.get_text().strip()
|
||||
download_url = self.urls['get'] % tr.find('a', href=rc['get']).get('href')
|
||||
title = info.attrs.get('title') or info.get_text().strip()
|
||||
download_url = self.urls['get'] % str(tr.find('a', href=rc['get'])['href']).lstrip('/')
|
||||
|
||||
except (AttributeError, TypeError, ValueError):
|
||||
continue
|
||||
|
@ -114,16 +112,4 @@ class FunFileProvider(generic.TorrentProvider):
|
|||
return results
|
||||
|
||||
|
||||
class FunFileCache(tvcache.TVCache):
|
||||
|
||||
def __init__(self, this_provider):
|
||||
tvcache.TVCache.__init__(self, this_provider)
|
||||
|
||||
self.update_freq = 15 # cache update frequency
|
||||
|
||||
def _cache_data(self):
|
||||
|
||||
return self.provider.cache_data()
|
||||
|
||||
|
||||
provider = FunFileProvider()
|
||||
|
|
|
@ -25,6 +25,8 @@ import math
|
|||
import os
|
||||
import re
|
||||
import time
|
||||
import urlparse
|
||||
import zlib
|
||||
from base64 import b16encode, b32decode
|
||||
|
||||
import sickbeard
|
||||
|
@ -53,7 +55,7 @@ class GenericProvider:
|
|||
# these need to be set in the subclass
|
||||
self.providerType = None
|
||||
self.name = name
|
||||
self.supportsBacklog = supports_backlog
|
||||
self.supports_backlog = supports_backlog
|
||||
self.anime_only = anime_only
|
||||
if anime_only:
|
||||
self.proper_search_terms = 'v1|v2|v3|v4|v5'
|
||||
|
@ -518,7 +520,7 @@ class GenericProvider:
|
|||
if hasattr(self, 'cookies'):
|
||||
cookies = self.cookies
|
||||
|
||||
if not re.match('^(\w+=\w+[;\s]*)+$', cookies):
|
||||
if not (cookies and re.match('^(\w+=\w+[;\s]*)+$', cookies)):
|
||||
return False
|
||||
|
||||
cj = requests.utils.add_dict_to_cookiejar(self.session.cookies,
|
||||
|
@ -544,9 +546,13 @@ class GenericProvider:
|
|||
|
||||
def _categories_string(self, mode='Cache', template='c%s=1', delimiter='&'):
|
||||
|
||||
return delimiter.join([('%s', template)[any(template)] % c for c in sorted(self.categories['shows'] + (
|
||||
[], [] if 'anime' not in self.categories else self.categories['anime'])[
|
||||
('Cache' == mode and helpers.has_anime()) or ((mode in ['Season', 'Episode']) and self.show and self.show.is_anime)])])
|
||||
return delimiter.join([('%s', template)[any(template)] % c for c in sorted(
|
||||
'shows' in self.categories and (isinstance(self.categories['shows'], type([])) and
|
||||
self.categories['shows'] or [self.categories['shows']]) or
|
||||
self.categories[(mode, 'Episode')['Propers' == mode]] +
|
||||
([], self.categories.get('anime') or [])[
|
||||
(mode in ['Cache', 'Propers'] and helpers.has_anime()) or
|
||||
((mode in ['Season', 'Episode']) and self.show and self.show.is_anime)])])
|
||||
|
||||
@staticmethod
|
||||
def _bytesizer(size_dim=''):
|
||||
|
@ -577,12 +583,8 @@ class NZBProvider(object, GenericProvider):
|
|||
|
||||
def maybe_apikey(self):
|
||||
|
||||
if hasattr(self, 'needs_auth') and self.needs_auth:
|
||||
if hasattr(self, 'key') and 0 < len(self.key):
|
||||
return self.key
|
||||
if hasattr(self, 'api_key') and 0 < len(self.api_key):
|
||||
return self.api_key
|
||||
return None
|
||||
if getattr(self, 'needs_auth', None):
|
||||
return (getattr(self, 'key', '') and self.key) or (getattr(self, 'api_key', '') and self.api_key) or None
|
||||
return False
|
||||
|
||||
def _check_auth(self):
|
||||
|
@ -664,13 +666,32 @@ class NZBProvider(object, GenericProvider):
|
|||
|
||||
class TorrentProvider(object, GenericProvider):
|
||||
|
||||
def __init__(self, name, supports_backlog=True, anime_only=False):
|
||||
def __init__(self, name, supports_backlog=True, anime_only=False, cache_update_freq=None):
|
||||
GenericProvider.__init__(self, name, supports_backlog, anime_only)
|
||||
|
||||
self.providerType = GenericProvider.TORRENT
|
||||
|
||||
self._seed_ratio = None
|
||||
self.seed_time = None
|
||||
self._url = None
|
||||
self.urls = {}
|
||||
self.cache._cache_data = self._cache_data
|
||||
if cache_update_freq:
|
||||
self.cache.update_freq = cache_update_freq
|
||||
|
||||
@property
|
||||
def url(self):
|
||||
if None is self._url:
|
||||
self._url = self._valid_home()
|
||||
self._valid_url()
|
||||
return self._url
|
||||
|
||||
@url.setter
|
||||
def url(self, value=None):
|
||||
self._url = value
|
||||
|
||||
def _valid_url(self):
|
||||
return True
|
||||
|
||||
def image_name(self):
|
||||
|
||||
|
@ -777,6 +798,65 @@ class TorrentProvider(object, GenericProvider):
|
|||
search_params += [crop.sub(r'\1', '%s %s%s' % (name, x, detail)) for x in prefix]
|
||||
return search_params
|
||||
|
||||
@staticmethod
|
||||
def _has_signature(data=None):
|
||||
return data and re.search(r'(?sim)<input[^<]+name="password"', data) and \
|
||||
re.search(r'(?sim)<input[^<]+name="username"', data)
|
||||
|
||||
def _valid_home(self):
|
||||
"""
|
||||
:return: signature verified home url else None if validation fail
|
||||
"""
|
||||
url_base = getattr(self, 'url_base', None)
|
||||
if url_base:
|
||||
return url_base
|
||||
|
||||
url_list = getattr(self, 'url_home', None)
|
||||
if not url_list and getattr(self, 'url_edit', None) or 10 > max([len(x) for x in url_list]):
|
||||
return None
|
||||
|
||||
last_url, expire = sickbeard.PROVIDER_HOMES.get(self.get_id(), ('', None))
|
||||
if 'site down' == last_url:
|
||||
if expire and (expire > int(time.time())):
|
||||
return None
|
||||
elif last_url:
|
||||
last_url in url_list and url_list.remove(last_url)
|
||||
url_list.insert(0, last_url)
|
||||
|
||||
for cur_url in url_list:
|
||||
if not self.is_valid_mod(cur_url):
|
||||
return None
|
||||
|
||||
if 10 < len(cur_url) and ((expire and (expire > int(time.time()))) or
|
||||
self._has_signature(helpers.getURL(cur_url, session=self.session))):
|
||||
|
||||
for k, v in getattr(self, 'url_tmpl', {}).items():
|
||||
self.urls[k] = v % {'home': cur_url, 'vars': getattr(self, 'url_vars', {}).get(k, '')}
|
||||
|
||||
if last_url != cur_url or (expire and not (expire > int(time.time()))):
|
||||
sickbeard.PROVIDER_HOMES[self.get_id()] = (cur_url, int(time.time()) + (15*60))
|
||||
sickbeard.save_config()
|
||||
return cur_url
|
||||
|
||||
logger.log('Failed to identify a "%s" page with %s %s (local network issue, site down, or ISP blocked) ' %
|
||||
(self.name, len(url_list), ('URL', 'different URLs')[1 < len(url_list)]) +
|
||||
'Suggest; 1) Disable "%s" 2) Use a proxy/VPN' % self.get_id(),
|
||||
(logger.WARNING, logger.ERROR)[self.enabled])
|
||||
self.urls = {}
|
||||
sickbeard.PROVIDER_HOMES[self.get_id()] = ('site down', int(time.time()) + (5 * 60))
|
||||
sickbeard.save_config()
|
||||
return None
|
||||
|
||||
def is_valid_mod(self, url):
|
||||
parsed, s, is_valid = urlparse.urlparse(url), 70000700, True
|
||||
if 2012691328 == s + zlib.crc32(('.%s' % (parsed.netloc or parsed.path)).split('.')[-2]):
|
||||
is_valid = False
|
||||
file_name = '%s.py' % os.path.join(sickbeard.PROG_DIR, *self.__module__.split('.'))
|
||||
if ek.ek(os.path.isfile, file_name):
|
||||
with open(file_name, 'rb') as file_hd:
|
||||
is_valid = 1661931498 == s + zlib.crc32(file_hd.read())
|
||||
return is_valid
|
||||
|
||||
def _authorised(self, logged_in=None, post_params=None, failed_msg=None, url=None, timeout=30):
|
||||
|
||||
maxed_out = (lambda x: re.search(r'(?i)[1-3]((<[^>]+>)|\W)*(attempts|tries|remain)[\W\w]{,40}?(remain|left|attempt)', x))
|
||||
|
@ -791,6 +871,9 @@ class TorrentProvider(object, GenericProvider):
|
|||
if logged_in():
|
||||
return True
|
||||
|
||||
if not self._valid_home():
|
||||
return False
|
||||
|
||||
if hasattr(self, 'digest'):
|
||||
self.cookies = re.sub(r'(?i)([\s\']+|cookie\s*:)', '', self.digest)
|
||||
success, msg = self._check_cookie()
|
||||
|
@ -811,13 +894,14 @@ class TorrentProvider(object, GenericProvider):
|
|||
if url:
|
||||
response = helpers.getURL(url, session=self.session)
|
||||
try:
|
||||
action = re.findall('[<]form[\w\W]+?action="([^"]+)', response)[0]
|
||||
url = (self.urls.get('login_base') or
|
||||
self.urls['config_provider_home_uri']) + action.lstrip('/')
|
||||
action = re.findall('[<]form[\w\W]+?action=[\'\"]([^\'\"]+)', response)[0]
|
||||
url = action if action.startswith('http') else \
|
||||
(self.urls.get('login_base') or self.urls['config_provider_home_uri']) + action.lstrip('/')
|
||||
|
||||
tags = re.findall(r'(?is)(<input.*?name="[^"]+".*?>)', response)
|
||||
nv = [(tup[0]) for tup in [re.findall(r'(?is)name="([^"]+)"(?:.*?value="([^"]+)")?', x)
|
||||
for x in tags]]
|
||||
tags = re.findall(r'(?is)(<input.*?name=[\'\"][^\'\"]+[\'\"].*?>)', response)
|
||||
nv = [(tup[0]) for tup in [
|
||||
re.findall(r'(?is)name=[\'\"]([^\'\"]+)[\'\"](?:.*?value=[\'\"]([^\'\"]+)[\'\"])?', x)
|
||||
for x in tags]]
|
||||
for name, value in nv:
|
||||
if name not in ('username', 'password'):
|
||||
post_params = isinstance(post_params, type({})) and post_params or {}
|
||||
|
@ -854,10 +938,18 @@ class TorrentProvider(object, GenericProvider):
|
|||
if self.username and self.password:
|
||||
return True
|
||||
setting = 'Password or Username'
|
||||
elif hasattr(self, 'username') and hasattr(self, 'api_key'):
|
||||
if self.username and self.api_key:
|
||||
return True
|
||||
setting = 'Apikey or Username'
|
||||
elif hasattr(self, 'username') and hasattr(self, 'passkey'):
|
||||
if self.username and self.passkey:
|
||||
return True
|
||||
setting = 'Passkey or Username'
|
||||
elif hasattr(self, 'uid') and hasattr(self, 'passkey'):
|
||||
if self.uid and self.passkey:
|
||||
return True
|
||||
setting = 'Passkey or uid'
|
||||
elif hasattr(self, 'api_key'):
|
||||
if self.api_key:
|
||||
return True
|
||||
|
@ -899,7 +991,7 @@ class TorrentProvider(object, GenericProvider):
|
|||
|
||||
@staticmethod
|
||||
def _has_no_results(*html):
|
||||
return re.search(r'(?i)<(?:b|h\d|strong)[^>]*>(?:' +
|
||||
return re.search(r'(?i)<(?:b|div|h\d|span|strong)[^>]*>(?:' +
|
||||
'your\ssearch\sdid\snot\smatch|' +
|
||||
'nothing\sfound|' +
|
||||
'no\storrents\sfound|' +
|
||||
|
@ -907,7 +999,6 @@ class TorrentProvider(object, GenericProvider):
|
|||
'.*?no\shits\.\sTry\sadding' +
|
||||
')', html[0])
|
||||
|
||||
def cache_data(self, *args, **kwargs):
|
||||
def _cache_data(self):
|
||||
|
||||
search_params = {'Cache': ['']}
|
||||
return self._search_provider(search_params)
|
||||
return self._search_provider({'Cache': ['']})
|
||||
|
|
|
@ -20,7 +20,7 @@ import time
|
|||
import traceback
|
||||
|
||||
from . import generic
|
||||
from sickbeard import logger, tvcache
|
||||
from sickbeard import logger
|
||||
from sickbeard.bs4_parser import BS4Parser
|
||||
from sickbeard.helpers import tryInt
|
||||
from lib.unidecode import unidecode
|
||||
|
@ -29,7 +29,7 @@ from lib.unidecode import unidecode
|
|||
class GFTrackerProvider(generic.TorrentProvider):
|
||||
|
||||
def __init__(self):
|
||||
generic.TorrentProvider.__init__(self, 'GFTracker')
|
||||
generic.TorrentProvider.__init__(self, 'GFTracker', cache_update_freq=17)
|
||||
|
||||
self.url_base = 'https://thegft.org/'
|
||||
self.urls = {'config_provider_home_uri': self.url_base,
|
||||
|
@ -44,7 +44,6 @@ class GFTrackerProvider(generic.TorrentProvider):
|
|||
self.url = self.urls['config_provider_home_uri']
|
||||
|
||||
self.username, self.password, self.minseed, self.minleech = 4 * [None]
|
||||
self.cache = GFTrackerCache(self)
|
||||
|
||||
def _authorised(self, **kwargs):
|
||||
|
||||
|
@ -122,16 +121,4 @@ class GFTrackerProvider(generic.TorrentProvider):
|
|||
return generic.TorrentProvider._episode_strings(self, ep_obj, scene=False, **kwargs)
|
||||
|
||||
|
||||
class GFTrackerCache(tvcache.TVCache):
|
||||
|
||||
def __init__(self, this_provider):
|
||||
tvcache.TVCache.__init__(self, this_provider)
|
||||
|
||||
self.update_freq = 17 # cache update frequency
|
||||
|
||||
def _cache_data(self):
|
||||
|
||||
return self.provider.cache_data()
|
||||
|
||||
|
||||
provider = GFTrackerProvider()
|
||||
|
|
|
@ -19,7 +19,7 @@ import re
|
|||
import traceback
|
||||
|
||||
from . import generic
|
||||
from sickbeard import logger, tvcache
|
||||
from sickbeard import logger
|
||||
from sickbeard.bs4_parser import BS4Parser
|
||||
from sickbeard.helpers import tryInt
|
||||
from lib.unidecode import unidecode
|
||||
|
@ -28,7 +28,7 @@ from lib.unidecode import unidecode
|
|||
class GrabTheInfoProvider(generic.TorrentProvider):
|
||||
|
||||
def __init__(self):
|
||||
generic.TorrentProvider.__init__(self, 'GrabTheInfo')
|
||||
generic.TorrentProvider.__init__(self, 'GrabTheInfo', cache_update_freq=20)
|
||||
|
||||
self.url_base = 'http://grabthe.info/'
|
||||
self.urls = {'config_provider_home_uri': self.url_base,
|
||||
|
@ -41,9 +41,7 @@ class GrabTheInfoProvider(generic.TorrentProvider):
|
|||
|
||||
self.url = self.urls['config_provider_home_uri']
|
||||
|
||||
self.username, self.password, self.minseed, self.minleech = 4 * [None]
|
||||
self.freeleech = False
|
||||
self.cache = GrabTheInfoCache(self)
|
||||
self.username, self.password, self.freeleech, self.minseed, self.minleech = 5 * [None]
|
||||
|
||||
def _search_provider(self, search_params, **kwargs):
|
||||
|
||||
|
@ -57,7 +55,7 @@ class GrabTheInfoProvider(generic.TorrentProvider):
|
|||
for mode in search_params.keys():
|
||||
for search_string in search_params[mode]:
|
||||
search_string = isinstance(search_string, unicode) and unidecode(search_string) or search_string
|
||||
search_url = self.urls['browse'] % (self._categories_string(), ('0', '3')[self.freeleech],
|
||||
search_url = self.urls['browse'] % (self._categories_string(), ('3', '0')[not self.freeleech],
|
||||
(self.urls['search'] % search_string, '')['Cache' == mode])
|
||||
|
||||
html = self.get_url(search_url)
|
||||
|
@ -120,16 +118,4 @@ class GrabTheInfoProvider(generic.TorrentProvider):
|
|||
return generic.TorrentProvider._episode_strings(self, ep_obj, sep_date='|', **kwargs)
|
||||
|
||||
|
||||
class GrabTheInfoCache(tvcache.TVCache):
|
||||
|
||||
def __init__(self, this_provider):
|
||||
tvcache.TVCache.__init__(self, this_provider)
|
||||
|
||||
self.update_freq = 20 # cache update frequency
|
||||
|
||||
def _cache_data(self):
|
||||
|
||||
return self.provider.cache_data()
|
||||
|
||||
|
||||
provider = GrabTheInfoProvider()
|
||||
|
|
81
sickbeard/providers/hd4free.py
Normal file
|
@ -0,0 +1,81 @@
|
|||
# coding=utf-8
|
||||
#
|
||||
# This file is part of SickGear.
|
||||
#
|
||||
# SickGear is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# SickGear is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with SickGear. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import time
|
||||
|
||||
from . import generic
|
||||
from sickbeard.helpers import tryInt
|
||||
|
||||
|
||||
class HD4FreeProvider(generic.TorrentProvider):
|
||||
|
||||
def __init__(self):
|
||||
generic.TorrentProvider.__init__(self, 'HD4Free')
|
||||
|
||||
self.url_base = 'https://hd4free.xyz/'
|
||||
|
||||
self.urls = {'search': self.url_base + 'searchapi.php',
|
||||
'get': self.url_base + 'download.php?torrent=%s&torrent_pass=%s'}
|
||||
|
||||
self.url = self.url_base
|
||||
|
||||
self.username, self.api_key, self.freeleech, self.minseed, self.minleech = 5 * [None]
|
||||
|
||||
def _authorised(self, **kwargs):
|
||||
|
||||
return self._check_auth()
|
||||
|
||||
def _search_provider(self, search_params, age=0, **kwargs):
|
||||
|
||||
results = []
|
||||
if not self._authorised():
|
||||
return results
|
||||
|
||||
items = {'Cache': [], 'Season': [], 'Episode': [], 'Propers': []}
|
||||
|
||||
params = {'username': self.username, 'apikey': self.api_key,
|
||||
'tv': 'true', 'fl': ('true', None)[not self.freeleech]}
|
||||
for mode in search_params.keys():
|
||||
for search_string in search_params[mode]:
|
||||
params['search'] = '+'.join(search_string.split())
|
||||
data_json = self.get_url(self.urls['search'], params=params, json=True)
|
||||
|
||||
cnt = len(items[mode])
|
||||
for k, item in data_json.items():
|
||||
if 'error' == k or not item.get('total_results'):
|
||||
break
|
||||
seeders, leechers, size = [tryInt(n, n) for n in [
|
||||
item.get(x) for x in 'seeders', 'leechers', 'size']]
|
||||
if self._peers_fail(mode, seeders, leechers):
|
||||
continue
|
||||
title = item.get('release_name')
|
||||
download_url = (self.urls['get'] % (item.get('torrentid'), item.get('torrentpass')), None)[
|
||||
not (item.get('torrentid') and item.get('torrentpass'))]
|
||||
if title and download_url:
|
||||
items[mode].append((title, download_url, seeders, self._bytesizer('%smb' % size)))
|
||||
|
||||
self._log_search(mode, len(items[mode]) - cnt, self.session.response['url'])
|
||||
time.sleep(1.1)
|
||||
|
||||
self._sort_seeders(mode, items)
|
||||
|
||||
results = list(set(results + items[mode]))
|
||||
|
||||
return results
|
||||
|
||||
|
||||
provider = HD4FreeProvider()
|
|
@ -19,7 +19,7 @@ import re
|
|||
import urllib
|
||||
|
||||
from . import generic
|
||||
from sickbeard import logger, tvcache
|
||||
from sickbeard import logger
|
||||
from sickbeard.exceptions import AuthException
|
||||
from sickbeard.helpers import tryInt
|
||||
from sickbeard.indexers import indexer_config
|
||||
|
@ -33,7 +33,7 @@ except ImportError:
|
|||
class HDBitsProvider(generic.TorrentProvider):
|
||||
|
||||
def __init__(self):
|
||||
generic.TorrentProvider.__init__(self, 'HDBits')
|
||||
generic.TorrentProvider.__init__(self, 'HDBits', cache_update_freq=15)
|
||||
|
||||
# api_spec: https://hdbits.org/wiki/API
|
||||
self.url_base = 'https://hdbits.org/'
|
||||
|
@ -46,9 +46,7 @@ class HDBitsProvider(generic.TorrentProvider):
|
|||
self.proper_search_terms = [' proper ', ' repack ']
|
||||
self.url = self.urls['config_provider_home_uri']
|
||||
|
||||
self.username, self.passkey, self.minseed, self.minleech = 4 * [None]
|
||||
self.freeleech = False
|
||||
self.cache = HDBitsCache(self)
|
||||
self.username, self.passkey, self.freeleech, self.minseed, self.minleech = 5 * [None]
|
||||
|
||||
def check_auth_from_data(self, parsed_json):
|
||||
|
||||
|
@ -148,16 +146,4 @@ class HDBitsProvider(generic.TorrentProvider):
|
|||
return results
|
||||
|
||||
|
||||
class HDBitsCache(tvcache.TVCache):
|
||||
|
||||
def __init__(self, this_provider):
|
||||
tvcache.TVCache.__init__(self, this_provider)
|
||||
|
||||
self.update_freq = 15 # cache update frequency
|
||||
|
||||
def _cache_data(self):
|
||||
|
||||
return self.provider.cache_data()
|
||||
|
||||
|
||||
provider = HDBitsProvider()
|
||||
|
|
|
@ -19,7 +19,7 @@ import re
|
|||
import traceback
|
||||
|
||||
from . import generic
|
||||
from sickbeard import logger, tvcache
|
||||
from sickbeard import logger
|
||||
from sickbeard.bs4_parser import BS4Parser
|
||||
from lib.unidecode import unidecode
|
||||
|
||||
|
@ -27,7 +27,7 @@ from lib.unidecode import unidecode
|
|||
class HDSpaceProvider(generic.TorrentProvider):
|
||||
|
||||
def __init__(self):
|
||||
generic.TorrentProvider.__init__(self, 'HDSpace')
|
||||
generic.TorrentProvider.__init__(self, 'HDSpace', cache_update_freq=17)
|
||||
|
||||
self.url_base = 'https://hd-space.org/'
|
||||
self.urls = {'config_provider_home_uri': self.url_base,
|
||||
|
@ -40,9 +40,7 @@ class HDSpaceProvider(generic.TorrentProvider):
|
|||
|
||||
self.url = self.urls['config_provider_home_uri']
|
||||
|
||||
self.username, self.password, self.minseed, self.minleech = 4 * [None]
|
||||
self.freeleech = False
|
||||
self.cache = HDSpaceCache(self)
|
||||
self.username, self.password, self.freeleech, self.minseed, self.minleech = 5 * [None]
|
||||
|
||||
def _authorised(self, **kwargs):
|
||||
|
||||
|
@ -124,16 +122,4 @@ class HDSpaceProvider(generic.TorrentProvider):
|
|||
return generic.TorrentProvider._episode_strings(self, ep_obj, scene=False, **kwargs)
|
||||
|
||||
|
||||
class HDSpaceCache(tvcache.TVCache):
|
||||
|
||||
def __init__(self, this_provider):
|
||||
tvcache.TVCache.__init__(self, this_provider)
|
||||
|
||||
self.update_freq = 17 # cache update frequency
|
||||
|
||||
def _cache_data(self):
|
||||
|
||||
return self.provider.cache_data()
|
||||
|
||||
|
||||
provider = HDSpaceProvider()
|
||||
|
|
|
@ -19,7 +19,7 @@ import re
|
|||
import traceback
|
||||
|
||||
from . import generic
|
||||
from sickbeard import logger, tvcache
|
||||
from sickbeard import logger
|
||||
from sickbeard.bs4_parser import BS4Parser
|
||||
from lib.unidecode import unidecode
|
||||
|
||||
|
@ -29,24 +29,24 @@ class IPTorrentsProvider(generic.TorrentProvider):
|
|||
def __init__(self):
|
||||
generic.TorrentProvider.__init__(self, 'IPTorrents')
|
||||
|
||||
self.url_base = 'https://iptorrents.eu/'
|
||||
self.urls = {'config_provider_home_uri': self.url_base,
|
||||
'login': self.url_base + 'torrents/',
|
||||
'search': self.url_base + 't?%s;q=%s;qf=ti%s%s#torrents',
|
||||
'get': self.url_base + '%s'}
|
||||
self.url_home = ['https://iptorrents.%s/' % u for u in 'eu', 'com', 'ru']
|
||||
|
||||
self.url_vars = {'login': 'getrss.php', 'search': 't?%s;q=%s;qf=ti%s%s#torrents', 'get': '%s'}
|
||||
self.url_tmpl = {'config_provider_home_uri': '%(home)s', 'login': '%(home)s%(vars)s',
|
||||
'search': '%(home)s%(vars)s', 'get': '%(home)s%(vars)s'}
|
||||
|
||||
self.categories = {'shows': [4, 5, 22, 23, 24, 25, 26, 55, 65, 66, 73, 78, 79], 'anime': [60]}
|
||||
|
||||
self.proper_search_terms = None
|
||||
self.url = self.urls['config_provider_home_uri']
|
||||
|
||||
self.username, self.password, self.minseed, self.minleech = 4 * [None]
|
||||
self.freeleech = False
|
||||
self.cache = IPTorrentsCache(self)
|
||||
self.digest, self.freeleech, self.minseed, self.minleech = 4 * [None]
|
||||
|
||||
def _authorised(self, **kwargs):
|
||||
|
||||
return super(IPTorrentsProvider, self)._authorised(post_params={'php': ''})
|
||||
return super(IPTorrentsProvider, self)._authorised(
|
||||
logged_in=(lambda x=None: (None is x or 'RSS Link' in x) and self.has_all_cookies() and
|
||||
self.session.cookies['uid'] in self.digest and self.session.cookies['pass'] in self.digest),
|
||||
failed_msg=(lambda x=None: u'Invalid cookie details for %s. Check settings'))
|
||||
|
||||
def _search_provider(self, search_params, **kwargs):
|
||||
|
||||
|
@ -61,8 +61,9 @@ class IPTorrentsProvider(generic.TorrentProvider):
|
|||
for search_string in search_params[mode]:
|
||||
search_string = isinstance(search_string, unicode) and unidecode(search_string) or search_string
|
||||
# URL with 50 tv-show results, or max 150 if adjusted in IPTorrents profile
|
||||
search_url = self.urls['search'] % (self._categories_string(mode, '%s', ';'), search_string,
|
||||
('', ';free')[self.freeleech], (';o=seeders', '')['Cache' == mode])
|
||||
search_url = self.urls['search'] % (
|
||||
self._categories_string(mode, '%s', ';'), search_string,
|
||||
(';free', '')[not self.freeleech], (';o=seeders', '')['Cache' == mode])
|
||||
|
||||
html = self.get_url(search_url)
|
||||
|
||||
|
@ -108,15 +109,9 @@ class IPTorrentsProvider(generic.TorrentProvider):
|
|||
|
||||
return results
|
||||
|
||||
|
||||
class IPTorrentsCache(tvcache.TVCache):
|
||||
|
||||
def __init__(self, this_provider):
|
||||
tvcache.TVCache.__init__(self, this_provider)
|
||||
|
||||
def _cache_data(self):
|
||||
|
||||
return self.provider.cache_data()
|
||||
@staticmethod
|
||||
def ui_string(key):
|
||||
return 'iptorrents_digest' == key and 'use... \'uid=xx; pass=yy\'' or ''
|
||||
|
||||
|
||||
provider = IPTorrentsProvider()
|
||||
|
|
|
@ -23,7 +23,7 @@ import traceback
|
|||
import urllib
|
||||
|
||||
from . import generic
|
||||
from sickbeard import config, logger, show_name_helpers, tvcache
|
||||
from sickbeard import config, logger, show_name_helpers
|
||||
from sickbeard.bs4_parser import BS4Parser
|
||||
from sickbeard.helpers import (has_anime, tryInt)
|
||||
from sickbeard.common import Quality, mediaExtensions
|
||||
|
@ -34,20 +34,22 @@ from lib.unidecode import unidecode
|
|||
class KATProvider(generic.TorrentProvider):
|
||||
|
||||
def __init__(self):
|
||||
generic.TorrentProvider.__init__(self, 'KickAssTorrents')
|
||||
generic.TorrentProvider.__init__(self, 'KickAssTorrents', cache_update_freq=20)
|
||||
|
||||
self.url_base = 'https://kat.ph/'
|
||||
self.urls = {'config_provider_home_uri': self.url_base,
|
||||
'base': [self.url_base, 'http://katproxy.com/'],
|
||||
'search': 'usearch/%s/',
|
||||
'sorted': '?field=time_add&sorder=desc'}
|
||||
self.url_home = ['https://%s/' % u for u in 'kat.ph', 'kat.cr', 'kickass.unblocked.red', 'katproxy.com']
|
||||
|
||||
self.url_vars = {'search': 'usearch/%s/?field=time_add&sorder=desc', 'get': '%s'}
|
||||
self.url_tmpl = {'config_provider_home_uri': '%(home)s',
|
||||
'search': '%(home)s%(vars)s', 'get': '%(home)s%(vars)s'}
|
||||
|
||||
self.proper_search_terms = None
|
||||
self.url = self.urls['config_provider_home_uri']
|
||||
|
||||
self.minseed, self.minleech = 2 * [None]
|
||||
self.confirmed = False
|
||||
self.cache = KATCache(self)
|
||||
|
||||
@staticmethod
|
||||
def _has_signature(data=None):
|
||||
return data and (re.search(r'(?sim)(<title>KAT)', data[15:1024:]) or 'kastatic' in data)
|
||||
|
||||
def _find_season_quality(self, title, torrent_link, ep_number):
|
||||
""" Return the modified title of a Season Torrent with the quality found inspecting torrent file list """
|
||||
|
@ -135,7 +137,7 @@ class KATProvider(generic.TorrentProvider):
|
|||
items = {'Cache': [], 'Season': [], 'Episode': [], 'Propers': []}
|
||||
|
||||
rc = dict((k, re.compile('(?i)' + v)) for (k, v) in {'link': 'normal', 'get': '^magnet', 'verif': 'verif'}.items())
|
||||
url = 0
|
||||
|
||||
for mode in search_params.keys():
|
||||
search_show = mode in ['Season', 'Episode']
|
||||
if not search_show and has_anime():
|
||||
|
@ -145,19 +147,17 @@ class KATProvider(generic.TorrentProvider):
|
|||
for enum, search_string in enumerate(search_params[mode]):
|
||||
search_string = isinstance(search_string, unicode) and unidecode(search_string) or search_string
|
||||
|
||||
self.url = self.urls['base'][url]
|
||||
search_url = self.url + (self.urls['search'] % urllib.quote('%scategory:%s' % (
|
||||
search_url = self.urls['search'] % urllib.quote('%scategory:%s' % (
|
||||
('', '%s ' % search_string)['Cache' != mode],
|
||||
('tv', 'anime')[(search_show and bool(self.show and self.show.is_anime)) or bool(enum)])))
|
||||
('tv', 'anime')[(search_show and bool(self.show and self.show.is_anime)) or bool(enum)]))
|
||||
|
||||
self.session.headers.update({'Referer': search_url})
|
||||
html = self.get_url(search_url + self.urls['sorted'])
|
||||
html = self.get_url(search_url)
|
||||
|
||||
cnt = len(items[mode])
|
||||
try:
|
||||
if not html or 'kastatic' not in html or self._has_no_results(html) or re.search(r'(?is)<(?:h\d)[^>]*>.*?(?:did\snot\smatch)', html):
|
||||
if html and 'kastatic' not in html:
|
||||
url += (1, 0)[url == len(self.urls['base'])]
|
||||
if not html or self._has_no_results(html) or \
|
||||
re.search(r'(?is)<(?:h\d)[^>]*>.*?(?:did\snot\smatch)', html):
|
||||
raise generic.HaltParseException
|
||||
|
||||
with BS4Parser(html, features=['html5lib', 'permissive']) as soup:
|
||||
|
@ -183,11 +183,13 @@ class KATProvider(generic.TorrentProvider):
|
|||
except (AttributeError, TypeError, ValueError):
|
||||
continue
|
||||
|
||||
if self.confirmed and not (tr.find('a', title=rc['verif']) or tr.find('i', title=rc['verif'])):
|
||||
if self.confirmed and not (tr.find('a', title=rc['verif']) or
|
||||
tr.find('i', title=rc['verif'])):
|
||||
logger.log(u'Skipping untrusted non-verified result: %s' % title, logger.DEBUG)
|
||||
continue
|
||||
|
||||
# Check number video files = episode in season and find the real Quality for full season torrent analyzing files in torrent
|
||||
# Check number video files = episode in season and find the real Quality for
|
||||
# full season torrent analyzing files in torrent
|
||||
if 'Season' == mode and 'sponly' == search_mode:
|
||||
ep_number = int(epcount / len(set(show_name_helpers.allPossibleShowNames(self.show))))
|
||||
title = self._find_season_quality(title, link, ep_number)
|
||||
|
@ -208,16 +210,4 @@ class KATProvider(generic.TorrentProvider):
|
|||
return results
|
||||
|
||||
|
||||
class KATCache(tvcache.TVCache):
|
||||
|
||||
def __init__(self, this_provider):
|
||||
tvcache.TVCache.__init__(self, this_provider)
|
||||
|
||||
self.update_freq = 20 # cache update frequency
|
||||
|
||||
def _cache_data(self):
|
||||
|
||||
return self.provider.cache_data()
|
||||
|
||||
|
||||
provider = KATProvider()
|
||||
|
|
|
@ -21,7 +21,7 @@ import re
|
|||
import traceback
|
||||
|
||||
from . import generic
|
||||
from sickbeard import logger, tvcache
|
||||
from sickbeard import logger
|
||||
from sickbeard.bs4_parser import BS4Parser
|
||||
from sickbeard.helpers import tryInt
|
||||
from lib.unidecode import unidecode
|
||||
|
@ -30,19 +30,19 @@ from lib.unidecode import unidecode
|
|||
class MoreThanProvider(generic.TorrentProvider):
|
||||
|
||||
def __init__(self):
|
||||
generic.TorrentProvider.__init__(self, 'MoreThan')
|
||||
generic.TorrentProvider.__init__(self, 'MoreThan', cache_update_freq=20)
|
||||
|
||||
self.url_base = 'https://www.morethan.tv/'
|
||||
self.urls = {'config_provider_home_uri': self.url_base,
|
||||
'login': self.url_base + 'login.php',
|
||||
'search': self.url_base + 'torrents.php?searchstr=%s&' + '&'.join([
|
||||
'tags_type=1', 'order_by=time', '&order_way=desc', 'filter_cat[2]=1', 'action=basic', 'searchsubmit=1']),
|
||||
'tags_type=1', 'order_by=time', 'order_way=desc',
|
||||
'filter_cat[2]=1', 'action=basic', 'searchsubmit=1']),
|
||||
'get': self.url_base + '%s'}
|
||||
|
||||
self.url = self.urls['config_provider_home_uri']
|
||||
|
||||
self.username, self.password, self.minseed, self.minleech = 4 * [None]
|
||||
self.cache = MoreThanCache(self)
|
||||
|
||||
def _authorised(self, **kwargs):
|
||||
|
||||
|
@ -95,7 +95,7 @@ class MoreThanProvider(generic.TorrentProvider):
|
|||
title = '%s %s' % (tr.find('div', attrs={'class': rc['name']}).get_text().strip(),
|
||||
title)
|
||||
|
||||
link = str(tr.find('a', title=rc['get'])['href']).replace('&', '&').lstrip('/')
|
||||
link = str(tr.find('a', href=rc['get'])['href']).replace('&', '&').lstrip('/')
|
||||
download_url = self.urls['get'] % link
|
||||
except (AttributeError, TypeError, ValueError):
|
||||
continue
|
||||
|
@ -117,16 +117,4 @@ class MoreThanProvider(generic.TorrentProvider):
|
|||
return results
|
||||
|
||||
|
||||
class MoreThanCache(tvcache.TVCache):
|
||||
|
||||
def __init__(self, this_provider):
|
||||
tvcache.TVCache.__init__(self, this_provider)
|
||||
|
||||
self.update_freq = 20 # cache update frequency
|
||||
|
||||
def _cache_data(self):
|
||||
|
||||
return self.provider.cache_data()
|
||||
|
||||
|
||||
provider = MoreThanProvider()
|
||||
|
|
|
@ -27,14 +27,14 @@ from sickbeard.exceptions import AuthException
|
|||
|
||||
class NewznabProvider(generic.NZBProvider):
|
||||
|
||||
def __init__(self, name, url, key='', cat_ids='5030,5040', search_mode='eponly',
|
||||
def __init__(self, name, url, key='', cat_ids=None, search_mode=None,
|
||||
search_fallback=False, enable_recentsearch=False, enable_backlog=False):
|
||||
generic.NZBProvider.__init__(self, name, True, False)
|
||||
|
||||
self.url = url
|
||||
self.key = key
|
||||
self.cat_ids = cat_ids
|
||||
self.search_mode = search_mode
|
||||
self.cat_ids = cat_ids or '5030,5040'
|
||||
self.search_mode = search_mode or 'eponly'
|
||||
self.search_fallback = search_fallback
|
||||
self.enable_recentsearch = enable_recentsearch
|
||||
self.enable_backlog = enable_backlog
|
||||
|
@ -81,11 +81,11 @@ class NewznabProvider(generic.NZBProvider):
|
|||
if isinstance(api_key, basestring):
|
||||
params['apikey'] = api_key
|
||||
|
||||
categories = self.get_url('%s/api' % self.url, params=params, timeout=10)
|
||||
url = '%s/api?%s' % (self.url.strip('/'), '&'.join(['%s=%s' % (k, v) for k, v in params.items()]))
|
||||
categories = self.get_url(url, timeout=10)
|
||||
if not categories:
|
||||
logger.log(u'Error getting html for [%s]' % self.session.response['url'], logger.DEBUG)
|
||||
return (False, return_categories, 'Error getting html for [%s]' %
|
||||
('%s/api?%s' % (self.url, '&'.join('%s=%s' % (x, y) for x, y in params.items()))))
|
||||
logger.log(u'Error getting html for [%s]' % url, logger.DEBUG)
|
||||
return False, return_categories, 'Error getting html for [%s]' % url
|
||||
|
||||
xml_categories = helpers.parse_xml(categories)
|
||||
if not xml_categories:
|
||||
|
@ -114,16 +114,20 @@ class NewznabProvider(generic.NZBProvider):
|
|||
base_params = {}
|
||||
|
||||
# season
|
||||
ep_detail = None
|
||||
if ep_obj.show.air_by_date or ep_obj.show.is_sports:
|
||||
date_str = str(ep_obj.airdate).split('-')[0]
|
||||
base_params['season'] = date_str
|
||||
base_params['q'] = date_str.replace('-', '.')
|
||||
airdate = str(ep_obj.airdate).split('-')[0]
|
||||
base_params['season'] = airdate
|
||||
base_params['q'] = airdate
|
||||
if ep_obj.show.air_by_date:
|
||||
ep_detail = '+"%s"' % airdate
|
||||
elif ep_obj.show.is_anime:
|
||||
base_params['season'] = '%d' % ep_obj.scene_absolute_number
|
||||
else:
|
||||
base_params['season'] = str((ep_obj.season, ep_obj.scene_season)[bool(ep_obj.show.is_scene)])
|
||||
ep_detail = 'S%02d' % helpers.tryInt(base_params['season'], 1)
|
||||
|
||||
# search
|
||||
# id search
|
||||
ids = helpers.mapIndexersToShow(ep_obj.show)
|
||||
if ids[1]: # or ids[2]:
|
||||
params = base_params.copy()
|
||||
|
@ -136,7 +140,7 @@ class NewznabProvider(generic.NZBProvider):
|
|||
use_id = True
|
||||
use_id and search_params.append(params)
|
||||
|
||||
# add new query strings for exceptions
|
||||
# query search and exceptions
|
||||
name_exceptions = list(
|
||||
set([helpers.sanitizeSceneName(a) for a in
|
||||
scene_exceptions.get_scene_exceptions(ep_obj.show.indexerid) + [ep_obj.show.name]]))
|
||||
|
@ -144,7 +148,14 @@ class NewznabProvider(generic.NZBProvider):
|
|||
params = base_params.copy()
|
||||
if 'q' in params:
|
||||
params['q'] = '%s.%s' % (cur_exception, params['q'])
|
||||
search_params.append(params)
|
||||
search_params.append(params)
|
||||
|
||||
if ep_detail:
|
||||
params = base_params.copy()
|
||||
params['q'] = '%s.%s' % (cur_exception, ep_detail)
|
||||
'season' in params and params.pop('season')
|
||||
'ep' in params and params.pop('ep')
|
||||
search_params.append(params)
|
||||
|
||||
return [{'Season': search_params}]
|
||||
|
||||
|
@ -156,18 +167,25 @@ class NewznabProvider(generic.NZBProvider):
|
|||
if not ep_obj:
|
||||
return [base_params]
|
||||
|
||||
ep_detail = None
|
||||
if ep_obj.show.air_by_date or ep_obj.show.is_sports:
|
||||
date_str = str(ep_obj.airdate)
|
||||
base_params['season'] = date_str.partition('-')[0]
|
||||
base_params['ep'] = date_str.partition('-')[2].replace('-', '/')
|
||||
airdate = str(ep_obj.airdate).split('-')
|
||||
base_params['season'] = airdate[0]
|
||||
if ep_obj.show.air_by_date:
|
||||
base_params['ep'] = '/'.join(airdate[1:])
|
||||
ep_detail = '+"%s.%s"' % (base_params['season'], '.'.join(airdate[1:]))
|
||||
elif ep_obj.show.is_anime:
|
||||
base_params['ep'] = '%i' % int(
|
||||
ep_obj.scene_absolute_number if int(ep_obj.scene_absolute_number) > 0 else ep_obj.scene_episode)
|
||||
base_params['ep'] = '%i' % (helpers.tryInt(ep_obj.scene_absolute_number) or
|
||||
helpers.tryInt(ep_obj.scene_episode))
|
||||
ep_detail = '%02d' % base_params['ep']
|
||||
else:
|
||||
base_params['season'], base_params['ep'] = (
|
||||
(ep_obj.season, ep_obj.episode), (ep_obj.scene_season, ep_obj.scene_episode))[ep_obj.show.is_scene]
|
||||
ep_detail = sickbeard.config.naming_ep_type[2] % {
|
||||
'seasonnumber': helpers.tryInt(base_params['season'], 1),
|
||||
'episodenumber': helpers.tryInt(base_params['ep'], 1)}
|
||||
|
||||
# search
|
||||
# id search
|
||||
ids = helpers.mapIndexersToShow(ep_obj.show)
|
||||
if ids[1]: # or ids[2]:
|
||||
params = base_params.copy()
|
||||
|
@ -181,7 +199,7 @@ class NewznabProvider(generic.NZBProvider):
|
|||
use_id = True
|
||||
use_id and search_params.append(params)
|
||||
|
||||
# add new query strings for exceptions
|
||||
# query search and exceptions
|
||||
name_exceptions = list(
|
||||
set([helpers.sanitizeSceneName(a) for a in
|
||||
scene_exceptions.get_scene_exceptions(ep_obj.show.indexerid) + [ep_obj.show.name]]))
|
||||
|
@ -191,15 +209,11 @@ class NewznabProvider(generic.NZBProvider):
|
|||
params['q'] = cur_exception
|
||||
search_params.append(params)
|
||||
|
||||
if ep_obj.show.is_anime:
|
||||
# Experimental, add a search string without search explicitly for the episode!
|
||||
# Remove the ?ep=e46 parameter and use the episode number to the query parameter.
|
||||
# Can be useful for newznab indexers that do not have the episodes 100% parsed.
|
||||
# Start with only applying the search string to anime shows
|
||||
if ep_detail:
|
||||
params = base_params.copy()
|
||||
params['q'] = '%s.%02d' % (cur_exception, int(params['ep']))
|
||||
if 'ep' in params:
|
||||
params.pop('ep')
|
||||
params['q'] = '%s.%s' % (cur_exception, ep_detail)
|
||||
'season' in params and params.pop('season')
|
||||
'ep' in params and params.pop('ep')
|
||||
search_params.append(params)
|
||||
|
||||
return [{'Episode': search_params}]
|
||||
|
@ -229,8 +243,10 @@ class NewznabProvider(generic.NZBProvider):
|
|||
|
||||
# category ids
|
||||
cat = []
|
||||
cat_anime = ('5070', '6070')['nzbs_org' == self.get_id()]
|
||||
cat_sport = '5060'
|
||||
cat_sport = ['5060']
|
||||
cat_anime = []
|
||||
if 'nzbgeek' != self.get_id():
|
||||
cat_anime = (['5070'], ['6070'])['nzbs_org' == self.get_id()]
|
||||
if 'Episode' == mode or 'Season' == mode:
|
||||
if not ('rid' in params or 'tvdbid' in params or 'q' in params or not self.supports_tvdbid()):
|
||||
logger.log('Error no rid, tvdbid, or search term available for search.')
|
||||
|
@ -238,18 +254,24 @@ class NewznabProvider(generic.NZBProvider):
|
|||
|
||||
if self.show:
|
||||
if self.show.is_sports:
|
||||
cat = [cat_sport]
|
||||
cat = cat_sport
|
||||
elif self.show.is_anime:
|
||||
cat = [cat_anime]
|
||||
cat = cat_anime
|
||||
else:
|
||||
cat = [cat_sport, cat_anime]
|
||||
cat = cat_sport + cat_anime
|
||||
|
||||
if self.cat_ids or len(cat):
|
||||
base_params['cat'] = ','.join(sorted(set(self.cat_ids.split(',') + cat)))
|
||||
|
||||
request_params = base_params.copy()
|
||||
if 'q' in params and not (any(x in params for x in ['season', 'ep'])):
|
||||
request_params['t'] = 'search'
|
||||
request_params.update(params)
|
||||
|
||||
# workaround a strange glitch
|
||||
if sum(ord(i) for i in self.get_id()) in [383] and 5 == 14 - request_params['maxage']:
|
||||
request_params['maxage'] += 1
|
||||
|
||||
offset = 0
|
||||
batch_count = not 0
|
||||
|
||||
|
@ -336,18 +358,17 @@ class NewznabCache(tvcache.TVCache):
|
|||
|
||||
result = []
|
||||
|
||||
if True or self.shouldUpdate():
|
||||
if 4489 != sickbeard.RECENTSEARCH_FREQUENCY or self.should_update():
|
||||
try:
|
||||
self._checkAuth()
|
||||
items = self.provider.cache_data()
|
||||
except Exception:
|
||||
return result
|
||||
items = None
|
||||
|
||||
items = self.provider.cache_data()
|
||||
if items:
|
||||
|
||||
self._clearCache()
|
||||
self.setLastUpdate()
|
||||
|
||||
# parse data
|
||||
cl = []
|
||||
for item in items:
|
||||
ci = self._parseItem(item)
|
||||
|
@ -358,6 +379,9 @@ class NewznabCache(tvcache.TVCache):
|
|||
my_db = self.get_db()
|
||||
my_db.mass_action(cl)
|
||||
|
||||
# set updated as time the attempt to fetch data is
|
||||
self.setLastUpdate()
|
||||
|
||||
return result
|
||||
|
||||
# overwrite method with that parses the rageid from the newznab feed
|
||||
|
|
|
@ -17,7 +17,7 @@ import re
|
|||
import traceback
|
||||
|
||||
from . import generic
|
||||
from sickbeard import logger, tvcache
|
||||
from sickbeard import logger
|
||||
from sickbeard.bs4_parser import BS4Parser
|
||||
from sickbeard.helpers import tryInt
|
||||
from lib.unidecode import unidecode
|
||||
|
@ -37,7 +37,6 @@ class PiSexyProvider(generic.TorrentProvider):
|
|||
self.url = self.urls['config_provider_home_uri']
|
||||
|
||||
self.username, self.password, self.minseed, self.minleech = 4 * [None]
|
||||
self.cache = PiSexyCache(self)
|
||||
|
||||
def _authorised(self, **kwargs):
|
||||
|
||||
|
@ -108,14 +107,4 @@ class PiSexyProvider(generic.TorrentProvider):
|
|||
return results
|
||||
|
||||
|
||||
class PiSexyCache(tvcache.TVCache):
|
||||
|
||||
def __init__(self, this_provider):
|
||||
tvcache.TVCache.__init__(self, this_provider)
|
||||
|
||||
def _cache_data(self):
|
||||
|
||||
return self.provider.cache_data()
|
||||
|
||||
|
||||
provider = PiSexyProvider()
|
||||
|
|
|
@ -16,7 +16,6 @@
|
|||
# along with SickGear. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from . import generic
|
||||
from sickbeard import tvcache
|
||||
from sickbeard.rssfeeds import RSSFeeds
|
||||
from lib.unidecode import unidecode
|
||||
|
||||
|
@ -24,7 +23,7 @@ from lib.unidecode import unidecode
|
|||
class PreToMeProvider(generic.TorrentProvider):
|
||||
|
||||
def __init__(self):
|
||||
generic.TorrentProvider.__init__(self, 'PreToMe')
|
||||
generic.TorrentProvider.__init__(self, 'PreToMe', cache_update_freq=6)
|
||||
|
||||
self.url_base = 'https://pretome.info/'
|
||||
|
||||
|
@ -35,7 +34,6 @@ class PreToMeProvider(generic.TorrentProvider):
|
|||
self.url = self.urls['config_provider_home_uri']
|
||||
|
||||
self.passkey = None
|
||||
self.cache = PreToMeCache(self)
|
||||
|
||||
def _authorised(self, **kwargs):
|
||||
|
||||
|
@ -72,16 +70,4 @@ class PreToMeProvider(generic.TorrentProvider):
|
|||
return results
|
||||
|
||||
|
||||
class PreToMeCache(tvcache.TVCache):
|
||||
|
||||
def __init__(self, this_provider):
|
||||
tvcache.TVCache.__init__(self, this_provider)
|
||||
|
||||
self.update_freq = 6 # cache update frequency
|
||||
|
||||
def _cache_data(self):
|
||||
|
||||
return self.provider.cache_data()
|
||||
|
||||
|
||||
provider = PreToMeProvider()
|
||||
|
|
|
@ -21,7 +21,7 @@ import datetime
|
|||
import time
|
||||
|
||||
from . import generic
|
||||
from sickbeard import helpers, logger, tvcache
|
||||
from sickbeard import helpers, logger
|
||||
from sickbeard.indexers.indexer_config import INDEXER_TVDB
|
||||
|
||||
|
||||
|
@ -51,7 +51,6 @@ class RarbgProvider(generic.TorrentProvider):
|
|||
self.minseed, self.minleech, self.token, self.token_expiry = 4 * [None]
|
||||
self.confirmed = False
|
||||
self.request_throttle = datetime.datetime.now()
|
||||
self.cache = RarbgCache(self)
|
||||
|
||||
def _authorised(self, reset=False, **kwargs):
|
||||
|
||||
|
@ -178,14 +177,4 @@ class RarbgProvider(generic.TorrentProvider):
|
|||
return search_params
|
||||
|
||||
|
||||
class RarbgCache(tvcache.TVCache):
|
||||
|
||||
def __init__(self, this_provider):
|
||||
tvcache.TVCache.__init__(self, this_provider)
|
||||
|
||||
def _cache_data(self):
|
||||
|
||||
return self.provider.cache_data()
|
||||
|
||||
|
||||
provider = RarbgProvider()
|
||||
|
|
|
@ -20,7 +20,7 @@ import time
|
|||
import traceback
|
||||
|
||||
from . import generic
|
||||
from sickbeard import logger, tvcache
|
||||
from sickbeard import logger
|
||||
from sickbeard.bs4_parser import BS4Parser
|
||||
from sickbeard.helpers import tryInt
|
||||
from lib.unidecode import unidecode
|
||||
|
@ -31,18 +31,16 @@ class SCCProvider(generic.TorrentProvider):
|
|||
def __init__(self):
|
||||
generic.TorrentProvider.__init__(self, 'SceneAccess')
|
||||
|
||||
self.url_base = 'https://sceneaccess.eu/'
|
||||
self.urls = {'config_provider_home_uri': self.url_base,
|
||||
'login': self.url_base + 'login',
|
||||
'search': self.url_base + 'browse?search=%s&method=1&c27=27&c17=17&c11=11',
|
||||
'nonscene': self.url_base + 'nonscene?search=%s&method=1&c44=44&c45=44',
|
||||
'archive': self.url_base + 'archive?search=%s&method=1&c26=26',
|
||||
'get': self.url_base + '%s'}
|
||||
self.url_home = ['https://sceneaccess.%s/' % u for u in 'eu', 'org']
|
||||
|
||||
self.url = self.urls['config_provider_home_uri']
|
||||
self.url_vars = {
|
||||
'login': 'login', 'search': 'browse?search=%s&method=1&c27=27&c17=17&c11=11', 'get': '%s',
|
||||
'nonscene': 'nonscene?search=%s&method=1&c44=44&c45=44', 'archive': 'archive?search=%s&method=1&c26=26'}
|
||||
self.url_tmpl = {
|
||||
'config_provider_home_uri': '%(home)s', 'login': '%(home)s%(vars)s', 'search': '%(home)s%(vars)s',
|
||||
'get': '%(home)s%(vars)s', 'nonscene': '%(home)s%(vars)s', 'archive': '%(home)s%(vars)s'}
|
||||
|
||||
self.username, self.password, self.minseed, self.minleech = 4 * [None]
|
||||
self.cache = SCCCache(self)
|
||||
|
||||
def _authorised(self, **kwargs):
|
||||
|
||||
|
@ -121,16 +119,4 @@ class SCCProvider(generic.TorrentProvider):
|
|||
return generic.TorrentProvider._episode_strings(self, ep_obj, sep_date='.', **kwargs)
|
||||
|
||||
|
||||
class SCCCache(tvcache.TVCache):
|
||||
|
||||
def __init__(self, this_provider):
|
||||
tvcache.TVCache.__init__(self, this_provider)
|
||||
|
||||
self.update_freq = 20 # cache update frequency
|
||||
|
||||
def _cache_data(self):
|
||||
|
||||
return self.provider.cache_data()
|
||||
|
||||
|
||||
provider = SCCProvider()
|
||||
|
|
|
@ -20,7 +20,7 @@ import re
|
|||
import traceback
|
||||
|
||||
from . import generic
|
||||
from sickbeard import logger, tvcache
|
||||
from sickbeard import logger
|
||||
from sickbeard.bs4_parser import BS4Parser
|
||||
from sickbeard.helpers import tryInt
|
||||
from lib.unidecode import unidecode
|
||||
|
@ -29,7 +29,7 @@ from lib.unidecode import unidecode
|
|||
class SceneTimeProvider(generic.TorrentProvider):
|
||||
|
||||
def __init__(self):
|
||||
generic.TorrentProvider.__init__(self, 'SceneTime')
|
||||
generic.TorrentProvider.__init__(self, 'SceneTime', cache_update_freq=15)
|
||||
|
||||
self.url_base = 'https://www.scenetime.com/'
|
||||
self.urls = {'config_provider_home_uri': self.url_base,
|
||||
|
@ -42,9 +42,7 @@ class SceneTimeProvider(generic.TorrentProvider):
|
|||
|
||||
self.url = self.urls['config_provider_home_uri']
|
||||
|
||||
self.username, self.password, self.minseed, self.minleech = 4 * [None]
|
||||
self.freeleech = False
|
||||
self.cache = SceneTimeCache(self)
|
||||
self.username, self.password, self.freeleech, self.minseed, self.minleech = 5 * [None]
|
||||
|
||||
def _authorised(self, **kwargs):
|
||||
|
||||
|
@ -58,15 +56,16 @@ class SceneTimeProvider(generic.TorrentProvider):
|
|||
|
||||
items = {'Cache': [], 'Season': [], 'Episode': [], 'Propers': []}
|
||||
|
||||
rc = dict((k, re.compile('(?i)' + v)) for (k, v) in {'info': 'detail', 'get': '.*id=(\d+).*', 'fl': '\[freeleech\]',
|
||||
'cats': 'cat=(?:%s)' % self._categories_string(template='', delimiter='|')
|
||||
}.items())
|
||||
rc = dict((k, re.compile('(?i)' + v)) for (k, v) in {
|
||||
'info': 'detail', 'get': '.*id=(\d+).*', 'fl': '\[freeleech\]',
|
||||
'cats': 'cat=(?:%s)' % self._categories_string(template='', delimiter='|')}.items())
|
||||
for mode in search_params.keys():
|
||||
for search_string in search_params[mode]:
|
||||
search_string = isinstance(search_string, unicode) and unidecode(search_string) or search_string
|
||||
|
||||
post_data = self.urls['params'].copy()
|
||||
post_data.update(ast.literal_eval('{%s}' % self._categories_string(template='"c%s": "1"', delimiter=',')))
|
||||
post_data.update(ast.literal_eval(
|
||||
'{%s}' % self._categories_string(template='"c%s": "1"', delimiter=',')))
|
||||
if 'Cache' != mode:
|
||||
search_string = '+'.join(search_string.split())
|
||||
post_data['search'] = search_string
|
||||
|
@ -99,10 +98,11 @@ class SceneTimeProvider(generic.TorrentProvider):
|
|||
continue
|
||||
|
||||
info = tr.find('a', href=rc['info'])
|
||||
title = 'title' in info.attrs and info.attrs['title'] or info.get_text().strip()
|
||||
title = info.attrs.get('title') or info.get_text().strip()
|
||||
|
||||
download_url = self.urls['get'] % {'id': re.sub(rc['get'], r'\1', str(info.attrs['href'])),
|
||||
'title': str(title).replace(' ', '.')}
|
||||
download_url = self.urls['get'] % {
|
||||
'id': re.sub(rc['get'], r'\1', str(info.attrs['href'])),
|
||||
'title': str(title).replace(' ', '.')}
|
||||
except (AttributeError, TypeError, ValueError):
|
||||
continue
|
||||
|
||||
|
@ -124,16 +124,4 @@ class SceneTimeProvider(generic.TorrentProvider):
|
|||
return results
|
||||
|
||||
|
||||
class SceneTimeCache(tvcache.TVCache):
|
||||
|
||||
def __init__(self, this_provider):
|
||||
tvcache.TVCache.__init__(self, this_provider)
|
||||
|
||||
self.update_freq = 15 # cache update frequency
|
||||
|
||||
def _cache_data(self):
|
||||
|
||||
return self.provider.cache_data()
|
||||
|
||||
|
||||
provider = SceneTimeProvider()
|
||||
|
|
|
@ -22,7 +22,7 @@ import time
|
|||
import traceback
|
||||
|
||||
from . import generic
|
||||
from sickbeard import helpers, logger, tvcache
|
||||
from sickbeard import helpers, logger
|
||||
from sickbeard.bs4_parser import BS4Parser
|
||||
from sickbeard.helpers import tryInt
|
||||
from lib.unidecode import unidecode
|
||||
|
@ -32,7 +32,7 @@ class ShazbatProvider(generic.TorrentProvider):
|
|||
|
||||
def __init__(self):
|
||||
|
||||
generic.TorrentProvider.__init__(self, 'Shazbat')
|
||||
generic.TorrentProvider.__init__(self, 'Shazbat', cache_update_freq=20)
|
||||
|
||||
self.url_base = 'https://www.shazbat.tv/'
|
||||
self.urls = {'config_provider_home_uri': self.url_base,
|
||||
|
@ -46,8 +46,6 @@ class ShazbatProvider(generic.TorrentProvider):
|
|||
self.url = self.urls['config_provider_home_uri']
|
||||
|
||||
self.username, self.password, self.minseed, self.minleech = 4 * [None]
|
||||
self.freeleech = False
|
||||
self.cache = ShazbatCache(self)
|
||||
|
||||
def _authorised(self, **kwargs):
|
||||
|
||||
|
@ -147,16 +145,4 @@ class ShazbatProvider(generic.TorrentProvider):
|
|||
return generic.TorrentProvider._episode_strings(self, ep_obj, detail_only=True, scene=False, **kwargs)
|
||||
|
||||
|
||||
class ShazbatCache(tvcache.TVCache):
|
||||
|
||||
def __init__(self, this_provider):
|
||||
tvcache.TVCache.__init__(self, this_provider)
|
||||
|
||||
self.update_freq = 20 # cache update frequency
|
||||
|
||||
def _cache_data(self):
|
||||
|
||||
return self.provider.cache_data()
|
||||
|
||||
|
||||
provider = ShazbatProvider()
|
||||
|
|
|
@ -19,34 +19,32 @@ import re
|
|||
import time
|
||||
|
||||
from . import generic
|
||||
from sickbeard import tvcache
|
||||
from sickbeard.bs4_parser import BS4Parser
|
||||
from sickbeard.helpers import tryInt
|
||||
|
||||
|
||||
class SpeedCDProvider(generic.TorrentProvider):
|
||||
|
||||
def __init__(self):
|
||||
generic.TorrentProvider.__init__(self, 'SpeedCD')
|
||||
generic.TorrentProvider.__init__(self, 'SpeedCD', cache_update_freq=20)
|
||||
|
||||
self.url_base = 'http://speed.cd/'
|
||||
self.url_base = 'https://speed.cd/'
|
||||
self.urls = {'config_provider_home_uri': self.url_base,
|
||||
'login_action': self.url_base + 'login.php',
|
||||
'search': self.url_base + 'V3/API/API.php',
|
||||
'get': self.url_base + 'download.php?torrent=%s'}
|
||||
'get': self.url_base + '%s'}
|
||||
|
||||
self.categories = {'Season': {'c41': 1, 'c53': 1},
|
||||
'Episode': {'c2': 1, 'c49': 1, 'c50': 1, 'c55': 1},
|
||||
'Cache': {'c41': 1, 'c2': 1, 'c49': 1, 'c50': 1, 'c53': 1, 'c55': 1}}
|
||||
self.categories = {'Season': [41, 53], 'Episode': [2, 49, 50, 55], 'anime': [30]}
|
||||
self.categories['Cache'] = self.categories['Season'] + self.categories['Episode']
|
||||
|
||||
self.url = self.urls['config_provider_home_uri']
|
||||
|
||||
self.username, self.password, self.minseed, self.minleech = 4 * [None]
|
||||
self.freeleech = False
|
||||
self.cache = SpeedCDCache(self)
|
||||
self.username, self.password, self.freeleech, self.minseed, self.minleech = 5 * [None]
|
||||
|
||||
def _authorised(self, **kwargs):
|
||||
|
||||
return super(SpeedCDProvider, self)._authorised(logged_in=(lambda x=None: self.has_all_cookies('inSpeed_speedian')))
|
||||
return super(SpeedCDProvider, self)._authorised(
|
||||
logged_in=(lambda x=None: self.has_all_cookies('inSpeed_speedian')))
|
||||
|
||||
def _search_provider(self, search_params, **kwargs):
|
||||
|
||||
|
@ -56,37 +54,49 @@ class SpeedCDProvider(generic.TorrentProvider):
|
|||
|
||||
items = {'Cache': [], 'Season': [], 'Episode': [], 'Propers': []}
|
||||
|
||||
remove_tag = re.compile(r'<[^>]*>')
|
||||
rc = dict((k, re.compile('(?i)' + v)) for (k, v) in {'get': 'download', 'fl': '\[freeleech\]'}.items())
|
||||
|
||||
for mode in search_params.keys():
|
||||
search_mode = (mode, 'Episode')['Propers' == mode]
|
||||
rc['cats'] = re.compile('(?i)cat=(?:%s)' % self._categories_string(mode, template='', delimiter='|'))
|
||||
for search_string in search_params[mode]:
|
||||
search_string = '+'.join(search_string.split())
|
||||
post_data = dict({'/browse.php?': None, 'cata': 'yes', 'jxt': 4, 'jxw': 'b', 'search': search_string},
|
||||
**self.categories[search_mode])
|
||||
if self.freeleech:
|
||||
post_data['freeleech'] = 'on'
|
||||
post_data = dict((x.split('=') for x in self._categories_string(mode).split('&')), search=search_string,
|
||||
jxt=2, jxw='b', freeleech=('on', None)[not self.freeleech])
|
||||
|
||||
data_json = self.get_url(self.urls['search'], post_data=post_data, json=True)
|
||||
|
||||
cnt = len(items[mode])
|
||||
try:
|
||||
if not data_json:
|
||||
html = data_json.get('Fs')[0].get('Cn')[0].get('d')
|
||||
if not html or self._has_no_results(html):
|
||||
raise generic.HaltParseException
|
||||
torrents = data_json.get('Fs', [])[0].get('Cn', {}).get('torrents', [])
|
||||
|
||||
for item in torrents:
|
||||
with BS4Parser(html, features=['html5lib', 'permissive']) as soup:
|
||||
torrent_table = soup.find('table', attrs={'cellspacing': 0})
|
||||
torrent_rows = [] if not torrent_table else torrent_table.find_all('tr')
|
||||
|
||||
if self.freeleech and not item.get('free'):
|
||||
continue
|
||||
if 2 > len(torrent_rows):
|
||||
raise generic.HaltParseException
|
||||
|
||||
seeders, leechers, size = [tryInt(n, n) for n in [item.get(x) for x in 'seed', 'leech', 'size']]
|
||||
if self._peers_fail(mode, seeders, leechers):
|
||||
continue
|
||||
for tr in torrent_rows[1:]:
|
||||
try:
|
||||
seeders, leechers, size = [tryInt(n, n) for n in [
|
||||
tr.find_all('td')[x].get_text().strip() for x in (-2, -1, -3)]]
|
||||
if None is tr.find('a', href=rc['cats']) \
|
||||
or self.freeleech and None is rc['fl'].search(tr.find_all('td')[1].get_text()) \
|
||||
or self._peers_fail(mode, seeders, leechers):
|
||||
continue
|
||||
|
||||
title = remove_tag.sub('', item.get('name'))
|
||||
download_url = self.urls['get'] % item.get('id')
|
||||
if title and download_url:
|
||||
items[mode].append((title, download_url, seeders, self._bytesizer(size)))
|
||||
info = tr.find('a', 'torrent')
|
||||
title = info.attrs.get('title') or info.get_text().strip()
|
||||
|
||||
download_url = self.urls['get'] % str(tr.find('a', href=rc['get'])['href']).lstrip('/')
|
||||
|
||||
except (AttributeError, TypeError, ValueError):
|
||||
continue
|
||||
|
||||
if title and download_url:
|
||||
items[mode].append((title, download_url, seeders, self._bytesizer(size)))
|
||||
|
||||
except Exception:
|
||||
time.sleep(1.1)
|
||||
|
@ -105,16 +115,4 @@ class SpeedCDProvider(generic.TorrentProvider):
|
|||
return generic.TorrentProvider._episode_strings(self, ep_obj, sep_date='.', **kwargs)
|
||||
|
||||
|
||||
class SpeedCDCache(tvcache.TVCache):
|
||||
|
||||
def __init__(self, this_provider):
|
||||
tvcache.TVCache.__init__(self, this_provider)
|
||||
|
||||
self.update_freq = 20 # cache update frequency
|
||||
|
||||
def _cache_data(self):
|
||||
|
||||
return self.provider.cache_data()
|
||||
|
||||
|
||||
provider = SpeedCDProvider()
|
||||
|
|
|
@ -23,7 +23,7 @@ import traceback
|
|||
import urllib
|
||||
|
||||
from . import generic
|
||||
from sickbeard import config, logger, tvcache, show_name_helpers
|
||||
from sickbeard import config, logger, show_name_helpers
|
||||
from sickbeard.bs4_parser import BS4Parser
|
||||
from sickbeard.common import Quality, mediaExtensions
|
||||
from sickbeard.name_parser.parser import NameParser, InvalidNameException, InvalidShowException
|
||||
|
@ -33,40 +33,32 @@ from lib.unidecode import unidecode
|
|||
class ThePirateBayProvider(generic.TorrentProvider):
|
||||
|
||||
def __init__(self):
|
||||
generic.TorrentProvider.__init__(self, 'The Pirate Bay')
|
||||
generic.TorrentProvider.__init__(self, 'The Pirate Bay', cache_update_freq=20)
|
||||
|
||||
self.urls = {'config_provider_home_uri': ['https://thepiratebay.se/', 'https://thepiratebay.gd/',
|
||||
'https://thepiratebay.mn/', 'https://thepiratebay.vg/',
|
||||
'https://thepiratebay.la/'],
|
||||
'search': 'search/%s/0/7/200',
|
||||
'browse': 'tv/latest/'} # order by seed
|
||||
self.url_home = ['https://thepiratebay.%s/' % u for u in 'se', 'org']
|
||||
|
||||
self.url_vars = {'search': 'search/%s/0/7/200', 'browse': 'tv/latest/'}
|
||||
self.url_tmpl = {'config_provider_home_uri': '%(home)s', 'search': '%(home)s%(vars)s',
|
||||
'browse': '%(home)s%(vars)s'}
|
||||
|
||||
self.proper_search_terms = None
|
||||
self.url = self.urls['config_provider_home_uri'][0]
|
||||
|
||||
self.minseed, self.minleech = 2 * [None]
|
||||
self.confirmed = False
|
||||
self.cache = ThePirateBayCache(self)
|
||||
|
||||
@staticmethod
|
||||
def _has_signature(data=None):
|
||||
return data and re.search(r'Pirate\sBay', data[33:7632:])
|
||||
|
||||
def _find_season_quality(self, title, torrent_id, ep_number):
|
||||
""" Return the modified title of a Season Torrent with the quality found inspecting torrent file list """
|
||||
|
||||
if not self.url:
|
||||
return False
|
||||
|
||||
quality = Quality.UNKNOWN
|
||||
file_name = None
|
||||
data = None
|
||||
has_signature = False
|
||||
details_url = '/ajax_details_filelist.php?id=%s' % torrent_id
|
||||
for idx, url in enumerate(self.urls['config_provider_home_uri']):
|
||||
data = self.get_url(url + details_url)
|
||||
if data and re.search(r'<title>The\sPirate\sBay', data[33:200:]):
|
||||
has_signature = True
|
||||
break
|
||||
else:
|
||||
data = None
|
||||
|
||||
if not has_signature:
|
||||
logger.log(u'Failed to identify a page from ThePirateBay at %s attempted urls (tpb blocked? general network issue or site dead)' % len(self.urls['config_provider_home_uri']), logger.ERROR)
|
||||
|
||||
data = self.get_url('%sajax_details_filelist.php?id=%s' % (self.url, torrent_id))
|
||||
if not data:
|
||||
return None
|
||||
|
||||
|
@ -138,30 +130,22 @@ class ThePirateBayProvider(generic.TorrentProvider):
|
|||
def _search_provider(self, search_params, search_mode='eponly', epcount=0, **kwargs):
|
||||
|
||||
results = []
|
||||
if not self.url:
|
||||
return results
|
||||
|
||||
items = {'Cache': [], 'Season': [], 'Episode': [], 'Propers': []}
|
||||
|
||||
rc = dict((k, re.compile('(?i)' + v))
|
||||
for (k, v) in {'info': 'detail', 'get': 'download[^"]+magnet', 'tid': r'.*/(\d{5,}).*',
|
||||
'verify': '(?:helper|moderator|trusted|vip)'}.items())
|
||||
has_signature = False
|
||||
|
||||
for mode in search_params.keys():
|
||||
for search_string in search_params[mode]:
|
||||
search_string = isinstance(search_string, unicode) and unidecode(search_string) or search_string
|
||||
|
||||
log_url = '%s %s' % (self.name, search_string) # placebo value
|
||||
for idx, search_url in enumerate(self.urls['config_provider_home_uri']):
|
||||
search_url += self.urls['browse'] if 'Cache' == mode\
|
||||
else self.urls['search'] % (urllib.quote(search_string))
|
||||
|
||||
log_url = u'(%s/%s): %s' % (idx + 1, len(self.urls['config_provider_home_uri']), search_url)
|
||||
|
||||
html = self.get_url(search_url)
|
||||
|
||||
if html and re.search(r'Pirate\sBay', html[33:7632:]):
|
||||
has_signature = True
|
||||
break
|
||||
else:
|
||||
html = None
|
||||
search_url = self.urls['browse'] if 'Cache' == mode \
|
||||
else self.urls['search'] % (urllib.quote(search_string))
|
||||
html = self.get_url(search_url)
|
||||
|
||||
cnt = len(items[mode])
|
||||
try:
|
||||
|
@ -213,28 +197,13 @@ class ThePirateBayProvider(generic.TorrentProvider):
|
|||
pass
|
||||
except Exception:
|
||||
logger.log(u'Failed to parse. Traceback: %s' % traceback.format_exc(), logger.ERROR)
|
||||
self._log_search(mode, len(items[mode]) - cnt, log_url)
|
||||
self._log_search(mode, len(items[mode]) - cnt, search_url)
|
||||
|
||||
self._sort_seeders(mode, items)
|
||||
|
||||
results = list(set(results + items[mode]))
|
||||
|
||||
if not has_signature:
|
||||
logger.log(u'Failed to identify a page from ThePirateBay at %s attempted urls (tpb blocked? general network issue or site dead)' % len(self.urls['config_provider_home_uri']), logger.ERROR)
|
||||
|
||||
return results
|
||||
|
||||
|
||||
class ThePirateBayCache(tvcache.TVCache):
|
||||
|
||||
def __init__(self, this_provider):
|
||||
tvcache.TVCache.__init__(self, this_provider)
|
||||
|
||||
self.update_freq = 20 # cache update frequency
|
||||
|
||||
def _cache_data(self):
|
||||
|
||||
return self.provider.cache_data()
|
||||
|
||||
|
||||
provider = ThePirateBayProvider()
|
||||
|
|
|
@ -19,7 +19,7 @@ import re
|
|||
import traceback
|
||||
|
||||
from . import generic
|
||||
from sickbeard import logger, tvcache
|
||||
from sickbeard import logger
|
||||
from sickbeard.bs4_parser import BS4Parser
|
||||
from sickbeard.helpers import tryInt
|
||||
from lib.unidecode import unidecode
|
||||
|
@ -28,21 +28,18 @@ from lib.unidecode import unidecode
|
|||
class TorrentBytesProvider(generic.TorrentProvider):
|
||||
|
||||
def __init__(self):
|
||||
generic.TorrentProvider.__init__(self, 'TorrentBytes')
|
||||
generic.TorrentProvider.__init__(self, 'TorrentBytes', cache_update_freq=20)
|
||||
|
||||
self.url_base = 'https://www.torrentbytes.net/'
|
||||
self.urls = {'config_provider_home_uri': self.url_base,
|
||||
'login': self.url_base + 'takelogin.php',
|
||||
'search': self.url_base + 'browse.php?search=%s&%s',
|
||||
'get': self.url_base + '%s'}
|
||||
self.url_home = ['https://www.torrentbytes.net/']
|
||||
|
||||
self.categories = {'shows': [41, 33, 38, 32, 37]}
|
||||
self.url_vars = {'login': 'takelogin.php', 'search': 'browse.php?search=%s&%s', 'get': '%s'}
|
||||
self.url_tmpl = {'config_provider_home_uri': '%(home)s', 'login': '%(home)s%(vars)s',
|
||||
'search': '%(home)s%(vars)s', 'get': '%(home)s%(vars)s'}
|
||||
|
||||
self.url = self.urls['config_provider_home_uri']
|
||||
self.categories = {'Season': [41, 32], 'Episode': [33, 37, 38]}
|
||||
self.categories['Cache'] = self.categories['Season'] + self.categories['Episode']
|
||||
|
||||
self.username, self.password, self.minseed, self.minleech = 4 * [None]
|
||||
self.freeleech = False
|
||||
self.cache = TorrentBytesCache(self)
|
||||
self.username, self.password, self.freeleech, self.minseed, self.minleech = 5 * [None]
|
||||
|
||||
def _authorised(self, **kwargs):
|
||||
|
||||
|
@ -56,12 +53,12 @@ class TorrentBytesProvider(generic.TorrentProvider):
|
|||
|
||||
items = {'Cache': [], 'Season': [], 'Episode': [], 'Propers': []}
|
||||
|
||||
rc = dict((k, re.compile('(?i)' + v)) for (k, v) in {'info': 'detail', 'get': 'download', 'fl': '\[\W*F\W?L\W*\]'
|
||||
}.items())
|
||||
rc = dict((k, re.compile('(?i)' + v)) for (k, v) in {'info': 'detail', 'get': 'download',
|
||||
'fl': '\[\W*F\W?L\W*\]'}.items())
|
||||
for mode in search_params.keys():
|
||||
for search_string in search_params[mode]:
|
||||
search_string = isinstance(search_string, unicode) and unidecode(search_string) or search_string
|
||||
search_url = self.urls['search'] % (search_string, self._categories_string())
|
||||
search_url = self.urls['search'] % (search_string, self._categories_string(mode))
|
||||
|
||||
html = self.get_url(search_url, timeout=90)
|
||||
|
||||
|
@ -82,11 +79,11 @@ class TorrentBytesProvider(generic.TorrentProvider):
|
|||
info = tr.find('a', href=rc['info'])
|
||||
seeders, leechers, size = [tryInt(n, n) for n in [
|
||||
tr.find_all('td')[x].get_text().strip() for x in (-2, -1, -4)]]
|
||||
if self.freeleech and (len(info.contents) < 2 or not rc['fl'].search(info.contents[1].string.strip())) \
|
||||
or self._peers_fail(mode, seeders, leechers):
|
||||
if self.freeleech and (len(info.contents) < 2 or not rc['fl'].search(
|
||||
info.contents[1].string.strip())) or self._peers_fail(mode, seeders, leechers):
|
||||
continue
|
||||
|
||||
title = 'title' in info.attrs and info.attrs['title'] or info.contents[0]
|
||||
title = info.attrs.get('title') or info.contents[0]
|
||||
title = (isinstance(title, list) and title[0] or title).strip()
|
||||
download_url = self.urls['get'] % str(tr.find('a', href=rc['get'])['href']).lstrip('/')
|
||||
except (AttributeError, TypeError, ValueError):
|
||||
|
@ -109,16 +106,4 @@ class TorrentBytesProvider(generic.TorrentProvider):
|
|||
return results
|
||||
|
||||
|
||||
class TorrentBytesCache(tvcache.TVCache):
|
||||
|
||||
def __init__(self, this_provider):
|
||||
tvcache.TVCache.__init__(self, this_provider)
|
||||
|
||||
self.update_freq = 20 # cache update frequency
|
||||
|
||||
def _cache_data(self):
|
||||
|
||||
return self.provider.cache_data()
|
||||
|
||||
|
||||
provider = TorrentBytesProvider()
|
||||
|
|
|
@ -19,8 +19,7 @@ import re
|
|||
import time
|
||||
|
||||
from . import generic
|
||||
from sickbeard import tvcache
|
||||
from sickbeard.helpers import (has_anime, tryInt)
|
||||
from sickbeard.helpers import tryInt
|
||||
|
||||
|
||||
class TorrentDayProvider(generic.TorrentProvider):
|
||||
|
@ -28,22 +27,19 @@ class TorrentDayProvider(generic.TorrentProvider):
|
|||
def __init__(self):
|
||||
generic.TorrentProvider.__init__(self, 'TorrentDay')
|
||||
|
||||
self.url_base = 'https://torrentday.eu/'
|
||||
self.urls = {'config_provider_home_uri': self.url_base,
|
||||
'login': self.url_base + 'torrents/',
|
||||
'search': self.url_base + 'V3/API/API.php',
|
||||
'get': self.url_base + 'download.php/%s/%s'}
|
||||
self.url_home = ['https://%s/' % u for u in 'torrentday.eu', 'secure.torrentday.com', 'tdonline.org',
|
||||
'torrentday.it', 'www.td.af', 'www.torrentday.com']
|
||||
|
||||
self.categories = {'Season': {'c31': 1, 'c33': 1, 'c14': 1},
|
||||
'Episode': {'c32': 1, 'c26': 1, 'c7': 1, 'c2': 1},
|
||||
'Cache': {'c31': 1, 'c33': 1, 'c14': 1, 'c32': 1, 'c26': 1, 'c7': 1, 'c2': 1}}
|
||||
self.url_vars = {'login': 'torrents/', 'search': 'V3/API/API.php', 'get': 'download.php/%s/%s'}
|
||||
self.url_tmpl = {'config_provider_home_uri': '%(home)s', 'login': '%(home)s%(vars)s',
|
||||
'search': '%(home)s%(vars)s', 'get': '%(home)s%(vars)s'}
|
||||
|
||||
self.categories = {'Season': [31, 33, 14], 'Episode': [24, 32, 26, 7, 2], 'Anime': [29]}
|
||||
self.categories['Cache'] = self.categories['Season'] + self.categories['Episode']
|
||||
|
||||
self.proper_search_terms = None
|
||||
self.url = self.urls['config_provider_home_uri']
|
||||
|
||||
self.username, self.password, self.minseed, self.minleech = 4 * [None]
|
||||
self.freeleech = False
|
||||
self.cache = TorrentDayCache(self)
|
||||
self.username, self.password, self.freeleech, self.minseed, self.minleech = 5 * [None]
|
||||
|
||||
def _authorised(self, **kwargs):
|
||||
|
||||
|
@ -66,11 +62,8 @@ class TorrentDayProvider(generic.TorrentProvider):
|
|||
for mode in search_params.keys():
|
||||
for search_string in search_params[mode]:
|
||||
search_string = '+'.join(search_string.split())
|
||||
post_data = dict({'/browse.php?': None, 'cata': 'yes', 'jxt': 8, 'jxw': 'b', 'search': search_string},
|
||||
**self.categories[(mode, 'Episode')['Propers' == mode]])
|
||||
if ('Cache' == mode and has_anime()) or (
|
||||
mode in ['Season', 'Episode'] and self.show and self.show.is_anime):
|
||||
post_data.update({'c29': 1})
|
||||
post_data = dict((x.split('=') for x in self._categories_string(mode).split('&')),
|
||||
search=search_string, cata='yes', jxt=8, jxw='b')
|
||||
|
||||
if self.freeleech:
|
||||
post_data.update({'free': 'on'})
|
||||
|
@ -112,14 +105,4 @@ class TorrentDayProvider(generic.TorrentProvider):
|
|||
return generic.TorrentProvider._episode_strings(self, ep_obj, sep_date='.', date_or=True, **kwargs)
|
||||
|
||||
|
||||
class TorrentDayCache(tvcache.TVCache):
|
||||
|
||||
def __init__(self, this_provider):
|
||||
tvcache.TVCache.__init__(self, this_provider)
|
||||
|
||||
def _cache_data(self):
|
||||
|
||||
return self.provider.cache_data()
|
||||
|
||||
|
||||
provider = TorrentDayProvider()
|
||||
|
|
|
@ -19,7 +19,7 @@ import re
|
|||
import traceback
|
||||
|
||||
from . import generic
|
||||
from sickbeard import logger, tvcache
|
||||
from sickbeard import logger
|
||||
from sickbeard.bs4_parser import BS4Parser
|
||||
from sickbeard.helpers import tryInt
|
||||
from lib.unidecode import unidecode
|
||||
|
@ -30,25 +30,20 @@ class TorrentingProvider(generic.TorrentProvider):
|
|||
def __init__(self):
|
||||
generic.TorrentProvider.__init__(self, 'Torrenting')
|
||||
|
||||
self.url_base = 'https://www.torrenting.com/'
|
||||
self.url_home = ['https://%s/' % u for u in 'www.torrenting.com', 'ttonline.us']
|
||||
|
||||
self.api = 'https://ttonline.us/'
|
||||
self.urls = {'config_provider_home_uri': self.url_base,
|
||||
'login': self.api + 'secure.php',
|
||||
'search': self.api + 'browse.php?%s&search=%s',
|
||||
'get': self.api + '%s'}
|
||||
self.url_vars = {'login': 'rss.php', 'search': 'browse.php?%s&search=%s', 'get': '%s'}
|
||||
self.url_tmpl = {'config_provider_home_uri': '%(home)s', 'login': '%(home)s%(vars)s',
|
||||
'search': '%(home)s%(vars)s', 'get': '%(home)s%(vars)s'}
|
||||
|
||||
self.categories = {'shows': [4, 5]}
|
||||
|
||||
self.url = self.urls['config_provider_home_uri']
|
||||
|
||||
self.digest, self.minseed, self.minleech = 3 * [None]
|
||||
self.cache = TorrentingCache(self)
|
||||
|
||||
def _authorised(self, **kwargs):
|
||||
|
||||
return super(TorrentingProvider, self)._authorised(
|
||||
logged_in=(lambda x=None: (None is x or 'Other Links' in x) and self.has_all_cookies() and
|
||||
logged_in=(lambda x=None: (None is x or 'RSS link' in x) and self.has_all_cookies() and
|
||||
self.session.cookies['uid'] in self.digest and self.session.cookies['pass'] in self.digest),
|
||||
failed_msg=(lambda x=None: u'Invalid cookie details for %s. Check settings'))
|
||||
|
||||
|
@ -60,9 +55,9 @@ class TorrentingProvider(generic.TorrentProvider):
|
|||
|
||||
items = {'Cache': [], 'Season': [], 'Episode': [], 'Propers': []}
|
||||
|
||||
rc = dict((k, re.compile('(?i)' + v)) for (k, v) in {'info': 'detail', 'get': 'download',
|
||||
'cats': 'cat=(?:%s)' % self._categories_string(template='', delimiter='|')
|
||||
}.items())
|
||||
rc = dict((k, re.compile('(?i)' + v)) for (k, v) in {
|
||||
'info': 'detail', 'cats': 'cat=(?:%s)' % self._categories_string(template='', delimiter='|'),
|
||||
'get': 'download'}.items())
|
||||
for mode in search_params.keys():
|
||||
for search_string in search_params[mode]:
|
||||
search_string = isinstance(search_string, unicode) and unidecode(search_string) or search_string
|
||||
|
@ -90,8 +85,9 @@ class TorrentingProvider(generic.TorrentProvider):
|
|||
continue
|
||||
|
||||
info = tr.find('a', href=rc['info'])
|
||||
title = 'title' in info.attrs and info.attrs['title'] or info.get_text().strip()
|
||||
download_url = self.urls['get'] % tr.find('a', href=rc['get']).get('href')
|
||||
title = info.attrs.get('title') or info.get_text().strip()
|
||||
download_url = self.urls['get'] % str(tr.find('a', href=rc['get'])['href']).lstrip('/')
|
||||
|
||||
except (AttributeError, TypeError, ValueError):
|
||||
continue
|
||||
|
||||
|
@ -117,14 +113,4 @@ class TorrentingProvider(generic.TorrentProvider):
|
|||
return 'torrenting_digest' == key and 'use... \'uid=xx; pass=yy\'' or ''
|
||||
|
||||
|
||||
class TorrentingCache(tvcache.TVCache):
|
||||
|
||||
def __init__(self, this_provider):
|
||||
tvcache.TVCache.__init__(self, this_provider)
|
||||
|
||||
def _cache_data(self):
|
||||
|
||||
return self.provider.cache_data()
|
||||
|
||||
|
||||
provider = TorrentingProvider()
|
||||
|
|
|
@ -19,14 +19,14 @@ import re
|
|||
import traceback
|
||||
|
||||
from . import generic
|
||||
from sickbeard import logger, tvcache
|
||||
from sickbeard import logger
|
||||
from sickbeard.bs4_parser import BS4Parser
|
||||
from lib.unidecode import unidecode
|
||||
|
||||
|
||||
class TorrentLeechProvider(generic.TorrentProvider):
|
||||
def __init__(self):
|
||||
generic.TorrentProvider.__init__(self, 'TorrentLeech')
|
||||
generic.TorrentProvider.__init__(self, 'TorrentLeech', cache_update_freq=20)
|
||||
|
||||
self.url_base = 'https://torrentleech.org/'
|
||||
self.urls = {'config_provider_home_uri': self.url_base,
|
||||
|
@ -40,7 +40,6 @@ class TorrentLeechProvider(generic.TorrentProvider):
|
|||
self.url = self.urls['config_provider_home_uri']
|
||||
|
||||
self.username, self.password, self.minseed, self.minleech = 4 * [None]
|
||||
self.cache = TorrentLeechCache(self)
|
||||
|
||||
def _authorised(self, **kwargs):
|
||||
|
||||
|
@ -111,14 +110,5 @@ class TorrentLeechProvider(generic.TorrentProvider):
|
|||
return generic.TorrentProvider._episode_strings(self, ep_obj, sep_date='|', **kwargs)
|
||||
|
||||
|
||||
class TorrentLeechCache(tvcache.TVCache):
|
||||
def __init__(self, this_provider):
|
||||
tvcache.TVCache.__init__(self, this_provider)
|
||||
|
||||
self.update_freq = 20 # cache update frequency
|
||||
|
||||
def _cache_data(self):
|
||||
return self.provider.cache_data()
|
||||
|
||||
|
||||
provider = TorrentLeechProvider()
|
||||
|
|
|
@ -21,7 +21,7 @@ import re
|
|||
import traceback
|
||||
|
||||
from . import generic
|
||||
from sickbeard import logger, tvcache
|
||||
from sickbeard import logger
|
||||
from sickbeard.bs4_parser import BS4Parser
|
||||
from sickbeard.helpers import tryInt
|
||||
from lib.unidecode import unidecode
|
||||
|
@ -30,13 +30,14 @@ from lib.unidecode import unidecode
|
|||
class TorrentShackProvider(generic.TorrentProvider):
|
||||
|
||||
def __init__(self):
|
||||
generic.TorrentProvider.__init__(self, 'TorrentShack')
|
||||
generic.TorrentProvider.__init__(self, 'TorrentShack', cache_update_freq=20)
|
||||
|
||||
self.url_base = 'https://torrentshack.me/'
|
||||
self.urls = {'config_provider_home_uri': self.url_base,
|
||||
'login': self.url_base + 'login.php?lang=',
|
||||
'search': self.url_base + 'torrents.php?searchstr=%s&%s&' + '&'.join(
|
||||
['release_type=both', 'searchtags=', 'tags_type=0', 'order_by=s3', 'order_way=desc', 'torrent_preset=all']),
|
||||
['release_type=both', 'searchtags=', 'tags_type=0',
|
||||
'order_by=s3', 'order_way=desc', 'torrent_preset=all']),
|
||||
'get': self.url_base + '%s'}
|
||||
|
||||
self.categories = {'shows': [600, 620, 700, 981, 980], 'anime': [850]}
|
||||
|
@ -44,7 +45,6 @@ class TorrentShackProvider(generic.TorrentProvider):
|
|||
self.url = self.urls['config_provider_home_uri']
|
||||
|
||||
self.username, self.password, self.minseed, self.minleech = 4 * [None]
|
||||
self.cache = TorrentShackCache(self)
|
||||
|
||||
def _authorised(self, **kwargs):
|
||||
|
||||
|
@ -117,16 +117,4 @@ class TorrentShackProvider(generic.TorrentProvider):
|
|||
return generic.TorrentProvider._episode_strings(self, ep_obj, sep_date='.', **kwargs)
|
||||
|
||||
|
||||
class TorrentShackCache(tvcache.TVCache):
|
||||
|
||||
def __init__(self, this_provider):
|
||||
tvcache.TVCache.__init__(self, this_provider)
|
||||
|
||||
self.update_freq = 20 # cache update frequency
|
||||
|
||||
def _cache_data(self):
|
||||
|
||||
return self.provider.cache_data()
|
||||
|
||||
|
||||
provider = TorrentShackProvider()
|
||||
|
|
|
@ -19,7 +19,8 @@ import re
|
|||
import traceback
|
||||
|
||||
from . import generic
|
||||
from sickbeard import helpers, logger, tvcache
|
||||
from sickbeard import common, helpers, logger
|
||||
from sickbeard.bs4_parser import BS4Parser
|
||||
from sickbeard.helpers import tryInt
|
||||
from lib.unidecode import unidecode
|
||||
|
||||
|
@ -27,7 +28,7 @@ from lib.unidecode import unidecode
|
|||
class TransmithenetProvider(generic.TorrentProvider):
|
||||
|
||||
def __init__(self):
|
||||
generic.TorrentProvider.__init__(self, 'Transmithe.net')
|
||||
generic.TorrentProvider.__init__(self, 'Transmithe.net', cache_update_freq=17)
|
||||
|
||||
self.url_base = 'https://transmithe.net/'
|
||||
self.urls = {'config_provider_home_uri': self.url_base,
|
||||
|
@ -39,10 +40,9 @@ class TransmithenetProvider(generic.TorrentProvider):
|
|||
|
||||
self.url = self.urls['config_provider_home_uri']
|
||||
self.user_authkey, self.user_passkey = 2 * [None]
|
||||
self.chk_td = True
|
||||
|
||||
self.username, self.password, self.minseed, self.minleech = 4 * [None]
|
||||
self.freeleech = False
|
||||
self.cache = TransmithenetCache(self)
|
||||
self.username, self.password, self.freeleech, self.minseed, self.minleech = 5 * [None]
|
||||
|
||||
def _authorised(self, **kwargs):
|
||||
|
||||
|
@ -88,11 +88,13 @@ class TransmithenetProvider(generic.TorrentProvider):
|
|||
|
||||
try:
|
||||
title_parts = group_name.split('[')
|
||||
maybe_res = re.findall('((?:72|108)0\w)', title_parts[1])
|
||||
maybe_res = re.findall('((?:72|108|216)0\w)', title_parts[1])
|
||||
maybe_ext = re.findall('(?i)(%s)' % '|'.join(common.mediaExtensions), title_parts[1])
|
||||
detail = title_parts[1].split('/')
|
||||
detail[1] = detail[1].strip().lower().replace('mkv', 'x264')
|
||||
title = '%s.%s' % (title_parts[0].strip(), '.'.join(
|
||||
(len(maybe_res) and [maybe_res[0]] or []) + [detail[0].strip(), detail[1]]))
|
||||
title = '%s.%s' % (BS4Parser(title_parts[0].strip(), 'html.parser').soup.string, '.'.join(
|
||||
(maybe_res and [maybe_res[0]] or []) +
|
||||
[detail[0].strip(), detail[1], maybe_ext and maybe_ext[0].lower() or 'mkv']))
|
||||
except (IndexError, KeyError):
|
||||
title = group_name
|
||||
download_url = self.urls['get'] % (self.user_authkey, self.user_passkey, torrent_id)
|
||||
|
@ -119,16 +121,4 @@ class TransmithenetProvider(generic.TorrentProvider):
|
|||
return generic.TorrentProvider._episode_strings(self, ep_obj, scene=False, **kwargs)
|
||||
|
||||
|
||||
class TransmithenetCache(tvcache.TVCache):
|
||||
|
||||
def __init__(self, this_provider):
|
||||
tvcache.TVCache.__init__(self, this_provider)
|
||||
|
||||
self.update_freq = 17
|
||||
|
||||
def _cache_data(self):
|
||||
|
||||
return self.provider.cache_data()
|
||||
|
||||
|
||||
provider = TransmithenetProvider()
|
||||
|
|
|
@ -19,7 +19,7 @@ import re
|
|||
import traceback
|
||||
|
||||
from . import generic
|
||||
from sickbeard import logger, tvcache
|
||||
from sickbeard import logger
|
||||
from sickbeard.bs4_parser import BS4Parser
|
||||
from sickbeard.helpers import tryInt
|
||||
from sickbeard.config import naming_ep_type
|
||||
|
@ -32,9 +32,9 @@ class TVChaosUKProvider(generic.TorrentProvider):
|
|||
def __init__(self):
|
||||
generic.TorrentProvider.__init__(self, 'TVChaosUK')
|
||||
|
||||
self.url_base = 'https://tvchaosuk.com/'
|
||||
self.url_base = 'https://www.tvchaosuk.com/'
|
||||
self.urls = {'config_provider_home_uri': self.url_base,
|
||||
'login': self.url_base + 'takelogin.php',
|
||||
'login_action': self.url_base + 'login.php',
|
||||
'search': self.url_base + 'browse.php',
|
||||
'get': self.url_base + '%s'}
|
||||
|
||||
|
@ -42,7 +42,6 @@ class TVChaosUKProvider(generic.TorrentProvider):
|
|||
|
||||
self.username, self.password, self.freeleech, self.minseed, self.minleech = 5 * [None]
|
||||
self.search_fallback = True
|
||||
self.cache = TVChaosUKCache(self)
|
||||
|
||||
def _authorised(self, **kwargs):
|
||||
|
||||
|
@ -92,8 +91,9 @@ class TVChaosUKProvider(generic.TorrentProvider):
|
|||
info = tr.find('a', href=rc['info'])
|
||||
title = (tr.find('div', attrs={'class': 'tooltip-content'}).get_text() or info.get_text()).strip()
|
||||
title = re.findall('(?m)(^[^\r\n]+)', title)[0]
|
||||
download_url = self.urls['get'] % str(tr.find('a', href=rc['get'])['href']).lstrip(
|
||||
'/').replace(self.urls['config_provider_home_uri'], '')
|
||||
download_url = str(tr.find('a', href=rc['get'])['href'])
|
||||
if not download_url.startswith('http'):
|
||||
download_url = self.urls['get'] % download_url.lstrip('/')
|
||||
except Exception:
|
||||
continue
|
||||
|
||||
|
@ -134,6 +134,7 @@ class TVChaosUKProvider(generic.TorrentProvider):
|
|||
add_pad = re.findall('((?:19|20)\d\d\-\d\d\-\d\d)([\w\W])', title)
|
||||
if len(add_pad) and add_pad[0][1] not in [' ', '.']:
|
||||
title = title.replace(''.join(add_pad[0]), '%s %s' % (add_pad[0][0], add_pad[0][1]))
|
||||
title = re.sub(r'(?sim)(.*?)(?:Episode|Season).\d+.(.*)', r'\1\2', title)
|
||||
|
||||
if title and download_url:
|
||||
items[mode].append((title, download_url, seeders, self._bytesizer(size)))
|
||||
|
@ -176,14 +177,4 @@ class TVChaosUKProvider(generic.TorrentProvider):
|
|||
return 'tvchaosuk_tip' == key and 'has missing quality data so you must add quality Custom/Unknown to any wanted show' or ''
|
||||
|
||||
|
||||
class TVChaosUKCache(tvcache.TVCache):
|
||||
|
||||
def __init__(self, this_provider):
|
||||
tvcache.TVCache.__init__(self, this_provider)
|
||||
|
||||
def _cache_data(self):
|
||||
|
||||
return self.provider.cache_data()
|
||||
|
||||
|
||||
provider = TVChaosUKProvider()
|
||||
|
|
|
@ -17,7 +17,8 @@
|
|||
# along with SickGear. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from . import generic
|
||||
from sickbeard import logger, tvcache
|
||||
from sickbeard import tvcache
|
||||
import time
|
||||
|
||||
|
||||
class WombleProvider(generic.NZBProvider):
|
||||
|
@ -34,46 +35,23 @@ class WombleCache(tvcache.TVCache):
|
|||
def __init__(self, this_provider):
|
||||
tvcache.TVCache.__init__(self, this_provider)
|
||||
|
||||
self.update_freq = 15 # cache update frequency
|
||||
self.update_freq = 6 # cache update frequency
|
||||
|
||||
def updateCache(self):
|
||||
def _cache_data(self):
|
||||
|
||||
# delete anything older then 7 days
|
||||
self._clearCache()
|
||||
|
||||
if not self.shouldUpdate():
|
||||
return
|
||||
|
||||
cl = []
|
||||
data = None
|
||||
for url in [self.provider.url + 'rss/?sec=tv-x264&fr=false',
|
||||
self.provider.url + 'rss/?sec=tv-sd&fr=false',
|
||||
self.provider.url + 'rss/?sec=tv-dvd&fr=false',
|
||||
self.provider.url + 'rss/?sec=tv-hd&fr=false']:
|
||||
logger.log(u'Womble\'s Index cache update URL: ' + url, logger.DEBUG)
|
||||
result = []
|
||||
for section in ['sd', 'hd', 'x264', 'dvd']:
|
||||
url = '%srss/?sec=tv-%s&fr=false' % (self.provider.url, section)
|
||||
data = self.getRSSFeed(url)
|
||||
time.sleep(1.1)
|
||||
cnt = len(result)
|
||||
for entry in (data and data.get('entries', []) or []):
|
||||
if entry.get('title') and entry.get('link', '').startswith('http'):
|
||||
result.append((entry['title'], entry['link'], None, None))
|
||||
|
||||
# As long as we got something from the provider we count it as an update
|
||||
if not data:
|
||||
return []
|
||||
self.provider.log_result(count=len(result) - cnt, url=url)
|
||||
|
||||
# By now we know we've got data and no auth errors, all we need to do is put it in the database
|
||||
for item in data.entries:
|
||||
title, url = self._title_and_url(item)
|
||||
ci = self._parseItem(title, url)
|
||||
if None is not ci:
|
||||
cl.append(ci)
|
||||
|
||||
if 0 < len(cl):
|
||||
my_db = self.get_db()
|
||||
my_db.mass_action(cl)
|
||||
|
||||
# set last updated
|
||||
if data:
|
||||
self.setLastUpdate()
|
||||
|
||||
def _checkAuth(self, *data):
|
||||
return 'Invalid Link' != data[0]
|
||||
return result
|
||||
|
||||
|
||||
provider = WombleProvider()
|
||||
|
|
|
@ -179,6 +179,21 @@ def snatch_episode(result, end_status=SNATCHED):
|
|||
|
||||
return True
|
||||
|
||||
|
||||
def pass_show_wordlist_checks(name, show):
|
||||
re_extras = dict(re_prefix='.*', re_suffix='.*')
|
||||
result = show_name_helpers.contains_any(name, show.rls_ignore_words, **re_extras)
|
||||
if None is not result and result:
|
||||
logger.log(u'Ignored: %s for containing ignore word' % name)
|
||||
return False
|
||||
|
||||
result = show_name_helpers.contains_any(name, show.rls_require_words, **re_extras)
|
||||
if None is not result and not result:
|
||||
logger.log(u'Ignored: %s for not containing any required word match' % name)
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def pick_best_result(results, show, quality_list=None):
|
||||
logger.log(u'Picking the best result out of %s' % [x.name for x in results], logger.DEBUG)
|
||||
|
||||
|
@ -195,15 +210,7 @@ def pick_best_result(results, show, quality_list=None):
|
|||
logger.log(u'%s is an unwanted quality, rejecting it' % cur_result.name, logger.DEBUG)
|
||||
continue
|
||||
|
||||
re_extras = dict(re_prefix='.*', re_suffix='.*')
|
||||
result = show_name_helpers.contains_any(cur_result.name, show.rls_ignore_words, **re_extras)
|
||||
if None is not result and result:
|
||||
logger.log(u'Ignored: %s for containing ignore word' % cur_result.name)
|
||||
continue
|
||||
|
||||
result = show_name_helpers.contains_any(cur_result.name, show.rls_require_words, **re_extras)
|
||||
if None is not result and not result:
|
||||
logger.log(u'Ignored: %s for not containing any required word match' % cur_result.name)
|
||||
if not pass_show_wordlist_checks(cur_result.name, show):
|
||||
continue
|
||||
|
||||
cur_size = getattr(cur_result, 'size', None)
|
||||
|
@ -427,8 +434,11 @@ def search_for_needed_episodes(episodes):
|
|||
|
||||
threading.currentThread().name = orig_thread_name
|
||||
|
||||
if not search_done:
|
||||
logger.log(u'No NZB/Torrent provider enabled to do recent searches. Please check provider options.', logger.ERROR)
|
||||
if not len(providers):
|
||||
logger.log('No NZB/Torrent sources enabled in Search Provider options to do recent searches', logger.WARNING)
|
||||
elif not search_done:
|
||||
logger.log('Failed recent search of %s enabled provider%s. More info in debug log.' % (
|
||||
len(providers), helpers.maybe_plural(len(providers))), logger.ERROR)
|
||||
|
||||
return found_results.values()
|
||||
|
||||
|
@ -672,12 +682,39 @@ def search_providers(show, episodes, manual_search=False):
|
|||
continue
|
||||
|
||||
# filter out possible bad torrents from providers
|
||||
if 'torrent' == best_result.resultType and 'blackhole' != sickbeard.TORRENT_METHOD:
|
||||
best_result.content = None
|
||||
if not best_result.url.startswith('magnet'):
|
||||
best_result.content = best_result.provider.get_url(best_result.url)
|
||||
if not best_result.content:
|
||||
if 'torrent' == best_result.resultType:
|
||||
if best_result.url.startswith('magnet'):
|
||||
if 'blackhole' != sickbeard.TORRENT_METHOD:
|
||||
best_result.content = None
|
||||
else:
|
||||
td = best_result.provider.get_url(best_result.url)
|
||||
if not td:
|
||||
continue
|
||||
if getattr(best_result.provider, 'chk_td', None):
|
||||
name = None
|
||||
try:
|
||||
hdr = re.findall('(\w+(\d+):)', td[0:6])[0]
|
||||
x, v = len(hdr[0]), int(hdr[1])
|
||||
for item in range(0, 12):
|
||||
y = x + v
|
||||
name = 'name' == td[x: y]
|
||||
w = re.findall('((?:i\d+e|d|l)?(\d+):)', td[y: y + 32])[0]
|
||||
x, v = y + len(w[0]), int(w[1])
|
||||
if name:
|
||||
name = td[x: x + v]
|
||||
break
|
||||
except:
|
||||
continue
|
||||
if name:
|
||||
if not pass_show_wordlist_checks(name, show):
|
||||
continue
|
||||
if not show_name_helpers.pass_wordlist_checks(name):
|
||||
logger.log(u'Ignored: %s (debug log has detail)' % name)
|
||||
continue
|
||||
best_result.name = name
|
||||
|
||||
if 'blackhole' != sickbeard.TORRENT_METHOD:
|
||||
best_result.content = td
|
||||
|
||||
# add result if its not a duplicate and
|
||||
found = False
|
||||
|
@ -702,8 +739,10 @@ def search_providers(show, episodes, manual_search=False):
|
|||
if len(episodes) == wanted_ep_count:
|
||||
break
|
||||
|
||||
if not search_done:
|
||||
logger.log(u'No NZB/Torrent providers found or enabled in the SickGear config for backlog searches. Please check your settings.',
|
||||
logger.ERROR)
|
||||
if not len(provider_list):
|
||||
logger.log('No NZB/Torrent sources enabled in Search Provider options to do backlog searches', logger.WARNING)
|
||||
elif not search_done:
|
||||
logger.log('Failed backlog search of %s enabled provider%s. More info in debug log.' % (
|
||||
len(provider_list), helpers.maybe_plural(len(provider_list))), logger.ERROR)
|
||||
|
||||
return final_results
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
|
||||
from __future__ import with_statement
|
||||
|
||||
import time
|
||||
import traceback
|
||||
import threading
|
||||
import datetime
|
||||
|
@ -288,21 +287,29 @@ class RecentSearchQueueItem(generic_queue.QueueItem):
|
|||
orig_thread_name = threading.currentThread().name
|
||||
threads = []
|
||||
|
||||
logger.log('Updating provider caches with recent upload data')
|
||||
|
||||
providers = [x for x in sickbeard.providers.sortedProviderList() if x.is_active() and x.enable_recentsearch]
|
||||
for cur_provider in providers:
|
||||
# spawn separate threads for each provider so we don't need to wait for providers with slow network operation
|
||||
if not cur_provider.cache.should_update():
|
||||
continue
|
||||
|
||||
if not threads:
|
||||
logger.log('Updating provider caches with recent upload data')
|
||||
|
||||
# spawn a thread for each provider to save time waiting for slow response providers
|
||||
threads.append(threading.Thread(target=cur_provider.cache.updateCache,
|
||||
name='%s :: [%s]' % (orig_thread_name, cur_provider.name)))
|
||||
# start the thread we just created
|
||||
threads[-1].start()
|
||||
|
||||
# wait for all threads to finish
|
||||
for t in threads:
|
||||
t.join()
|
||||
if not len(providers):
|
||||
logger.log('No NZB/Torrent sources enabled in Search Provider options for cache update', logger.WARNING)
|
||||
|
||||
logger.log('Finished updating provider caches')
|
||||
if threads:
|
||||
# wait for all threads to finish
|
||||
for t in threads:
|
||||
t.join()
|
||||
|
||||
logger.log('Finished updating provider caches')
|
||||
|
||||
|
||||
class ProperSearchQueueItem(generic_queue.QueueItem):
|
||||
|
@ -427,7 +434,7 @@ class FailedQueueItem(generic_queue.QueueItem):
|
|||
history.logFailed(epObj, release, provider)
|
||||
|
||||
failed_history.revertEpisode(epObj)
|
||||
logger.log(u'Beginning failed download search for: []' % epObj.prettyName())
|
||||
logger.log(u'Beginning failed download search for: [%s]' % epObj.prettyName())
|
||||
|
||||
search_result = search.search_providers(self.show, self.segment, True)
|
||||
|
||||
|
|
|
@ -32,6 +32,7 @@ from name_parser.parser import NameParser, InvalidNameException, InvalidShowExce
|
|||
from sickbeard.rssfeeds import RSSFeeds
|
||||
import itertools
|
||||
|
||||
|
||||
class CacheDBConnection(db.DBConnection):
|
||||
def __init__(self, providerName):
|
||||
db.DBConnection.__init__(self, 'cache.db')
|
||||
|
@ -44,6 +45,7 @@ class CacheDBConnection(db.DBConnection):
|
|||
if str(e) != 'table lastUpdate already exists':
|
||||
raise
|
||||
|
||||
|
||||
class TVCache:
|
||||
def __init__(self, provider):
|
||||
|
||||
|
@ -56,7 +58,7 @@ class TVCache:
|
|||
return CacheDBConnection(self.providerID)
|
||||
|
||||
def _clearCache(self):
|
||||
if self.shouldClearCache():
|
||||
if self.should_clear_cache():
|
||||
myDB = self.get_db()
|
||||
myDB.action('DELETE FROM provider_cache WHERE provider = ?', [self.providerID])
|
||||
|
||||
|
@ -81,21 +83,16 @@ class TVCache:
|
|||
logger.log(u'Authentication error: ' + ex(e), logger.ERROR)
|
||||
return []
|
||||
|
||||
if self.shouldUpdate():
|
||||
# as long as the http request worked we count this as an update
|
||||
if self.should_update():
|
||||
data = self._cache_data()
|
||||
if not data:
|
||||
return []
|
||||
|
||||
# clear cache
|
||||
self._clearCache()
|
||||
|
||||
# set updated
|
||||
self.setLastUpdate()
|
||||
if data:
|
||||
self._clearCache()
|
||||
|
||||
# parse data
|
||||
cl = []
|
||||
for item in data:
|
||||
for item in data or []:
|
||||
title, url = self._title_and_url(item)
|
||||
ci = self._parseItem(title, url)
|
||||
if ci is not None:
|
||||
|
@ -105,6 +102,9 @@ class TVCache:
|
|||
myDB = self.get_db()
|
||||
myDB.mass_action(cl)
|
||||
|
||||
# set updated as time the attempt to fetch data is
|
||||
self.setLastUpdate()
|
||||
|
||||
return []
|
||||
|
||||
def getRSSFeed(self, url, **kwargs):
|
||||
|
@ -180,21 +180,13 @@ class TVCache:
|
|||
lastUpdate = property(_getLastUpdate)
|
||||
lastSearch = property(_getLastSearch)
|
||||
|
||||
def shouldUpdate(self):
|
||||
def should_update(self):
|
||||
# if we've updated recently then skip the update
|
||||
if datetime.datetime.today() - self.lastUpdate < datetime.timedelta(minutes=self.update_freq):
|
||||
logger.log(u'Last update was too soon, using old cache: today()-' + str(self.lastUpdate) + '<' + str(
|
||||
datetime.timedelta(minutes=self.update_freq)), logger.DEBUG)
|
||||
return False
|
||||
return datetime.datetime.today() - self.lastUpdate >= datetime.timedelta(minutes=self.update_freq)
|
||||
|
||||
return True
|
||||
|
||||
def shouldClearCache(self):
|
||||
def should_clear_cache(self):
|
||||
# if recent search hasn't used our previous results yet then don't clear the cache
|
||||
if self.lastUpdate > self.lastSearch:
|
||||
return False
|
||||
|
||||
return True
|
||||
return self.lastSearch >= self.lastUpdate
|
||||
|
||||
def add_cache_entry(self, name, url, parse_result=None, indexer_id=0):
|
||||
|
||||
|
|
|
@ -4662,10 +4662,7 @@ class ConfigProviders(Config):
|
|||
|
||||
providerDict[name].key = key
|
||||
# a 0 in the key spot indicates that no key is needed
|
||||
if key == '0':
|
||||
providerDict[name].needs_auth = False
|
||||
else:
|
||||
providerDict[name].needs_auth = True
|
||||
providerDict[name].needs_auth = '0' != key
|
||||
|
||||
return providerDict[name].get_id() + '|' + providerDict[name].config_str()
|
||||
|
||||
|
@ -4767,16 +4764,11 @@ class ConfigProviders(Config):
|
|||
def saveProviders(self, newznab_string='', torrentrss_string='', provider_order=None, **kwargs):
|
||||
|
||||
results = []
|
||||
|
||||
provider_str_list = provider_order.split()
|
||||
provider_list = []
|
||||
|
||||
newznabProviderDict = dict(
|
||||
zip([x.get_id() for x in sickbeard.newznabProviderList], sickbeard.newznabProviderList))
|
||||
|
||||
finishedNames = []
|
||||
|
||||
# add all the newznab info we got into our list
|
||||
# add all the newznab info we have into our list
|
||||
newznab_sources = dict(zip([x.get_id() for x in sickbeard.newznabProviderList], sickbeard.newznabProviderList))
|
||||
active_ids = []
|
||||
if newznab_string:
|
||||
for curNewznabProviderStr in newznab_string.split('!!!'):
|
||||
|
||||
|
@ -4789,282 +4781,157 @@ class ConfigProviders(Config):
|
|||
if starify(cur_key, True):
|
||||
cur_key = ''
|
||||
|
||||
newProvider = newznab.NewznabProvider(cur_name, cur_url, key=cur_key)
|
||||
new_provider = newznab.NewznabProvider(cur_name, cur_url, key=cur_key)
|
||||
|
||||
cur_id = newProvider.get_id()
|
||||
cur_id = new_provider.get_id()
|
||||
|
||||
# if it already exists then update it
|
||||
if cur_id in newznabProviderDict:
|
||||
newznabProviderDict[cur_id].name = cur_name
|
||||
newznabProviderDict[cur_id].url = cur_url
|
||||
if cur_id in newznab_sources:
|
||||
nzb_src = newznab_sources[cur_id]
|
||||
|
||||
nzb_src.name, nzb_src.url, nzb_src.cat_ids = cur_name, cur_url, cur_cat
|
||||
|
||||
if cur_key:
|
||||
newznabProviderDict[cur_id].key = cur_key
|
||||
newznabProviderDict[cur_id].cat_ids = cur_cat
|
||||
nzb_src.key = cur_key
|
||||
|
||||
# a 0 in the key spot indicates that no key is needed
|
||||
if cur_key == '0':
|
||||
newznabProviderDict[cur_id].needs_auth = False
|
||||
else:
|
||||
newznabProviderDict[cur_id].needs_auth = True
|
||||
nzb_src.needs_auth = '0' != cur_key
|
||||
|
||||
try:
|
||||
newznabProviderDict[cur_id].search_mode = str(kwargs[cur_id + '_search_mode']).strip()
|
||||
except:
|
||||
pass
|
||||
attr = 'search_mode'
|
||||
if cur_id + '_' + attr in kwargs:
|
||||
setattr(nzb_src, attr, str(kwargs.get(cur_id + '_' + attr)).strip())
|
||||
|
||||
try:
|
||||
newznabProviderDict[cur_id].search_fallback = config.checkbox_to_value(
|
||||
kwargs[cur_id + '_search_fallback'])
|
||||
except:
|
||||
newznabProviderDict[cur_id].search_fallback = 0
|
||||
for attr in ['search_fallback', 'enable_recentsearch', 'enable_backlog']:
|
||||
setattr(nzb_src, attr, config.checkbox_to_value(kwargs.get(cur_id + '_' + attr)))
|
||||
|
||||
try:
|
||||
newznabProviderDict[cur_id].enable_recentsearch = config.checkbox_to_value(
|
||||
kwargs[cur_id + '_enable_recentsearch'])
|
||||
except:
|
||||
newznabProviderDict[cur_id].enable_recentsearch = 0
|
||||
|
||||
try:
|
||||
newznabProviderDict[cur_id].enable_backlog = config.checkbox_to_value(
|
||||
kwargs[cur_id + '_enable_backlog'])
|
||||
except:
|
||||
newznabProviderDict[cur_id].enable_backlog = 0
|
||||
else:
|
||||
sickbeard.newznabProviderList.append(newProvider)
|
||||
sickbeard.newznabProviderList.append(new_provider)
|
||||
|
||||
finishedNames.append(cur_id)
|
||||
active_ids.append(cur_id)
|
||||
|
||||
# delete anything that is missing
|
||||
for curProvider in sickbeard.newznabProviderList:
|
||||
if curProvider.get_id() not in finishedNames:
|
||||
sickbeard.newznabProviderList.remove(curProvider)
|
||||
|
||||
torrentRssProviderDict = dict(
|
||||
zip([x.get_id() for x in sickbeard.torrentRssProviderList], sickbeard.torrentRssProviderList))
|
||||
finishedNames = []
|
||||
for source in [x for x in sickbeard.newznabProviderList if x.get_id() not in active_ids]:
|
||||
sickbeard.newznabProviderList.remove(source)
|
||||
|
||||
# add all the torrent RSS info we have into our list
|
||||
torrent_rss_sources = dict(zip([x.get_id() for x in sickbeard.torrentRssProviderList],
|
||||
sickbeard.torrentRssProviderList))
|
||||
active_ids = []
|
||||
if torrentrss_string:
|
||||
for curTorrentRssProviderStr in torrentrss_string.split('!!!'):
|
||||
|
||||
if not curTorrentRssProviderStr:
|
||||
continue
|
||||
|
||||
curName, curURL, curCookies = curTorrentRssProviderStr.split('|')
|
||||
curURL = config.clean_url(curURL, False)
|
||||
cur_name, cur_url, cur_cookies = curTorrentRssProviderStr.split('|')
|
||||
cur_url = config.clean_url(cur_url, False)
|
||||
|
||||
if starify(curCookies, True):
|
||||
curCookies = ''
|
||||
if starify(cur_cookies, True):
|
||||
cur_cookies = ''
|
||||
|
||||
newProvider = rsstorrent.TorrentRssProvider(curName, curURL, curCookies)
|
||||
new_provider = rsstorrent.TorrentRssProvider(cur_name, cur_url, cur_cookies)
|
||||
|
||||
curID = newProvider.get_id()
|
||||
cur_id = new_provider.get_id()
|
||||
|
||||
# if it already exists then update it
|
||||
if curID in torrentRssProviderDict:
|
||||
torrentRssProviderDict[curID].name = curName
|
||||
torrentRssProviderDict[curID].url = curURL
|
||||
if curCookies:
|
||||
torrentRssProviderDict[curID].cookies = curCookies
|
||||
if cur_id in torrent_rss_sources:
|
||||
torrent_rss_sources[cur_id].name = cur_name
|
||||
torrent_rss_sources[cur_id].url = cur_url
|
||||
if cur_cookies:
|
||||
torrent_rss_sources[cur_id].cookies = cur_cookies
|
||||
else:
|
||||
sickbeard.torrentRssProviderList.append(newProvider)
|
||||
sickbeard.torrentRssProviderList.append(new_provider)
|
||||
|
||||
finishedNames.append(curID)
|
||||
active_ids.append(cur_id)
|
||||
|
||||
# delete anything that is missing
|
||||
for curProvider in sickbeard.torrentRssProviderList:
|
||||
if curProvider.get_id() not in finishedNames:
|
||||
sickbeard.torrentRssProviderList.remove(curProvider)
|
||||
for source in [x for x in sickbeard.torrentRssProviderList if x.get_id() not in active_ids]:
|
||||
sickbeard.torrentRssProviderList.remove(source)
|
||||
|
||||
# do the enable/disable
|
||||
for curProviderStr in provider_str_list:
|
||||
curProvider, curEnabled = curProviderStr.split(':')
|
||||
curEnabled = config.to_int(curEnabled)
|
||||
# enable/disable states of source providers
|
||||
provider_str_list = provider_order.split()
|
||||
sources = dict(zip([x.get_id() for x in sickbeard.providers.sortedProviderList()],
|
||||
sickbeard.providers.sortedProviderList()))
|
||||
for cur_src_str in provider_str_list:
|
||||
src_name, src_enabled = cur_src_str.split(':')
|
||||
|
||||
curProvObj = [x for x in sickbeard.providers.sortedProviderList() if
|
||||
x.get_id() == curProvider and hasattr(x, 'enabled')]
|
||||
if curProvObj:
|
||||
curProvObj[0].enabled = bool(curEnabled)
|
||||
provider_list.append(src_name)
|
||||
src_enabled = bool(config.to_int(src_enabled))
|
||||
|
||||
provider_list.append(curProvider)
|
||||
if curProvider in newznabProviderDict:
|
||||
newznabProviderDict[curProvider].enabled = bool(curEnabled)
|
||||
elif curProvider in torrentRssProviderDict:
|
||||
torrentRssProviderDict[curProvider].enabled = bool(curEnabled)
|
||||
if src_name in sources and hasattr(sources[src_name], 'enabled'):
|
||||
sources[src_name].enabled = src_enabled
|
||||
|
||||
# dynamically load provider settings
|
||||
for curTorrentProvider in [curProvider for curProvider in sickbeard.providers.sortedProviderList() if
|
||||
curProvider.providerType == sickbeard.GenericProvider.TORRENT]:
|
||||
if src_name in newznab_sources:
|
||||
newznab_sources[src_name].enabled = src_enabled
|
||||
elif src_name in torrent_rss_sources:
|
||||
torrent_rss_sources[src_name].enabled = src_enabled
|
||||
|
||||
if hasattr(curTorrentProvider, '_seed_ratio'):
|
||||
try:
|
||||
curTorrentProvider._seed_ratio = str(kwargs[curTorrentProvider.get_id() + '_ratio']).strip()
|
||||
except:
|
||||
curTorrentProvider._seed_ratio = None
|
||||
# update torrent source settings
|
||||
for torrent_src in [src for src in sickbeard.providers.sortedProviderList()
|
||||
if sickbeard.GenericProvider.TORRENT == src.providerType]:
|
||||
src_id_prefix = torrent_src.get_id() + '_'
|
||||
|
||||
if hasattr(curTorrentProvider, 'seed_time') and curTorrentProvider.get_id() + '_seed_time' in kwargs:
|
||||
curTorrentProvider.seed_time = config.to_int(str(kwargs[curTorrentProvider.get_id() + '_seed_time']).strip(), 0)
|
||||
attr = 'url_edit'
|
||||
if getattr(torrent_src, attr, None):
|
||||
url_edit = ','.join(set(['%s' % url.strip() for url in kwargs.get(
|
||||
src_id_prefix + attr, '').split(',')]))
|
||||
torrent_src.url_home = ([url_edit], [])[not url_edit]
|
||||
|
||||
if hasattr(curTorrentProvider, 'minseed'):
|
||||
try:
|
||||
curTorrentProvider.minseed = int(str(kwargs[curTorrentProvider.get_id() + '_minseed']).strip())
|
||||
except:
|
||||
curTorrentProvider.minseed = 0
|
||||
for attr in [x for x in ['username', 'uid'] if hasattr(torrent_src, x)]:
|
||||
setattr(torrent_src, attr, str(kwargs.get(src_id_prefix + attr, '')).strip())
|
||||
|
||||
if hasattr(curTorrentProvider, 'minleech'):
|
||||
try:
|
||||
curTorrentProvider.minleech = int(str(kwargs[curTorrentProvider.get_id() + '_minleech']).strip())
|
||||
except:
|
||||
curTorrentProvider.minleech = 0
|
||||
for attr in [x for x in ['password', 'api_key', 'passkey', 'digest', 'hash'] if hasattr(torrent_src, x)]:
|
||||
key = str(kwargs.get(src_id_prefix + attr, '')).strip()
|
||||
if 'password' == attr:
|
||||
set('*') != set(key) and setattr(torrent_src, attr, key)
|
||||
elif not starify(key, True):
|
||||
setattr(torrent_src, attr, key)
|
||||
|
||||
if hasattr(curTorrentProvider, 'digest'):
|
||||
try:
|
||||
key = str(kwargs[curTorrentProvider.get_id() + '_digest']).strip()
|
||||
if not starify(key, True):
|
||||
curTorrentProvider.digest = key
|
||||
except:
|
||||
curTorrentProvider.digest = None
|
||||
attr = 'ratio'
|
||||
if hasattr(torrent_src, '_seed_' + attr):
|
||||
setattr(torrent_src, '_seed_' + attr, kwargs.get(src_id_prefix + attr, '').strip() or None)
|
||||
|
||||
if hasattr(curTorrentProvider, 'hash'):
|
||||
try:
|
||||
key = str(kwargs[curTorrentProvider.get_id() + '_hash']).strip()
|
||||
if not starify(key, True):
|
||||
curTorrentProvider.hash = key
|
||||
except:
|
||||
curTorrentProvider.hash = None
|
||||
for attr in [x for x in ['minseed', 'minleech'] if hasattr(torrent_src, x)]:
|
||||
setattr(torrent_src, attr, config.to_int(str(kwargs.get(src_id_prefix + attr)).strip()))
|
||||
|
||||
if hasattr(curTorrentProvider, 'api_key'):
|
||||
try:
|
||||
key = str(kwargs[curTorrentProvider.get_id() + '_api_key']).strip()
|
||||
if not starify(key, True):
|
||||
curTorrentProvider.api_key = key
|
||||
except:
|
||||
curTorrentProvider.api_key = None
|
||||
for attr in [x for x in ['confirmed', 'freeleech', 'reject_m2ts', 'enable_recentsearch',
|
||||
'enable_backlog', 'search_fallback'] if hasattr(torrent_src, x)]:
|
||||
setattr(torrent_src, attr, config.checkbox_to_value(kwargs.get(src_id_prefix + attr)))
|
||||
|
||||
if hasattr(curTorrentProvider, 'username'):
|
||||
try:
|
||||
curTorrentProvider.username = str(kwargs[curTorrentProvider.get_id() + '_username']).strip()
|
||||
except:
|
||||
curTorrentProvider.username = None
|
||||
attr = 'seed_time'
|
||||
if hasattr(torrent_src, attr) and src_id_prefix + attr in kwargs:
|
||||
setattr(torrent_src, attr, config.to_int(str(kwargs.get(src_id_prefix + attr)).strip()))
|
||||
|
||||
if hasattr(curTorrentProvider, 'password'):
|
||||
try:
|
||||
key = str(kwargs[curTorrentProvider.get_id() + '_password']).strip()
|
||||
if set('*') != set(key):
|
||||
curTorrentProvider.password = key
|
||||
except:
|
||||
curTorrentProvider.password = None
|
||||
attr = 'search_mode'
|
||||
if hasattr(torrent_src, attr):
|
||||
setattr(torrent_src, attr, str(kwargs.get(src_id_prefix + attr, '')).strip() or 'eponly')
|
||||
|
||||
if hasattr(curTorrentProvider, 'passkey'):
|
||||
try:
|
||||
key = str(kwargs[curTorrentProvider.get_id() + '_passkey']).strip()
|
||||
if not starify(key, True):
|
||||
curTorrentProvider.passkey = key
|
||||
except:
|
||||
curTorrentProvider.passkey = None
|
||||
# update nzb source settings
|
||||
for nzb_src in [src for src in sickbeard.providers.sortedProviderList() if
|
||||
sickbeard.GenericProvider.NZB == src.providerType]:
|
||||
src_id_prefix = nzb_src.get_id() + '_'
|
||||
|
||||
if hasattr(curTorrentProvider, 'confirmed'):
|
||||
try:
|
||||
curTorrentProvider.confirmed = config.checkbox_to_value(
|
||||
kwargs[curTorrentProvider.get_id() + '_confirmed'])
|
||||
except:
|
||||
curTorrentProvider.confirmed = 0
|
||||
attr = 'api_key'
|
||||
if hasattr(nzb_src, attr):
|
||||
key = str(kwargs.get(src_id_prefix + attr, '')).strip()
|
||||
if not starify(key, True):
|
||||
setattr(nzb_src, attr, key)
|
||||
|
||||
if hasattr(curTorrentProvider, 'proxy'):
|
||||
try:
|
||||
curTorrentProvider.proxy.enabled = config.checkbox_to_value(
|
||||
kwargs[curTorrentProvider.get_id() + '_proxy'])
|
||||
except:
|
||||
curTorrentProvider.proxy.enabled = 0
|
||||
attr = 'username'
|
||||
if hasattr(nzb_src, attr):
|
||||
setattr(nzb_src, attr, str(kwargs.get(src_id_prefix + attr, '')).strip() or None)
|
||||
|
||||
if hasattr(curTorrentProvider.proxy, 'url'):
|
||||
try:
|
||||
curTorrentProvider.proxy.url = str(kwargs[curTorrentProvider.get_id() + '_proxy_url']).strip()
|
||||
except:
|
||||
curTorrentProvider.proxy.url = None
|
||||
attr = 'search_mode'
|
||||
if hasattr(nzb_src, attr):
|
||||
setattr(nzb_src, attr, str(kwargs.get(src_id_prefix + attr, '')).strip() or 'eponly')
|
||||
|
||||
if hasattr(curTorrentProvider, 'freeleech'):
|
||||
try:
|
||||
curTorrentProvider.freeleech = config.checkbox_to_value(
|
||||
kwargs[curTorrentProvider.get_id() + '_freeleech'])
|
||||
except:
|
||||
curTorrentProvider.freeleech = 0
|
||||
attr = 'enable_recentsearch'
|
||||
if hasattr(nzb_src, attr):
|
||||
setattr(nzb_src, attr, config.checkbox_to_value(kwargs.get(src_id_prefix + attr)) or
|
||||
not getattr(nzb_src, 'supports_backlog', True))
|
||||
|
||||
if hasattr(curTorrentProvider, 'reject_m2ts'):
|
||||
try:
|
||||
curTorrentProvider.reject_m2ts = config.checkbox_to_value(
|
||||
kwargs[curTorrentProvider.get_id() + '_reject_m2ts'])
|
||||
except:
|
||||
curTorrentProvider.reject_m2ts = 0
|
||||
|
||||
if hasattr(curTorrentProvider, 'search_mode'):
|
||||
try:
|
||||
curTorrentProvider.search_mode = str(kwargs[curTorrentProvider.get_id() + '_search_mode']).strip()
|
||||
except:
|
||||
curTorrentProvider.search_mode = 'eponly'
|
||||
|
||||
if hasattr(curTorrentProvider, 'search_fallback'):
|
||||
try:
|
||||
curTorrentProvider.search_fallback = config.checkbox_to_value(
|
||||
kwargs[curTorrentProvider.get_id() + '_search_fallback'])
|
||||
except:
|
||||
curTorrentProvider.search_fallback = 0 # these exceptions are catching unselected checkboxes
|
||||
|
||||
if hasattr(curTorrentProvider, 'enable_recentsearch'):
|
||||
try:
|
||||
curTorrentProvider.enable_recentsearch = config.checkbox_to_value(
|
||||
kwargs[curTorrentProvider.get_id() + '_enable_recentsearch'])
|
||||
except:
|
||||
curTorrentProvider.enable_recentsearch = 0 # these exceptions are actually catching unselected checkboxes
|
||||
|
||||
if hasattr(curTorrentProvider, 'enable_backlog'):
|
||||
try:
|
||||
curTorrentProvider.enable_backlog = config.checkbox_to_value(
|
||||
kwargs[curTorrentProvider.get_id() + '_enable_backlog'])
|
||||
except:
|
||||
curTorrentProvider.enable_backlog = 0 # these exceptions are actually catching unselected checkboxes
|
||||
|
||||
for curNzbProvider in [curProvider for curProvider in sickbeard.providers.sortedProviderList() if
|
||||
curProvider.providerType == sickbeard.GenericProvider.NZB]:
|
||||
|
||||
if hasattr(curNzbProvider, 'api_key'):
|
||||
try:
|
||||
key = str(kwargs[curNzbProvider.get_id() + '_api_key']).strip()
|
||||
if not starify(key, True):
|
||||
curNzbProvider.api_key = key
|
||||
except:
|
||||
curNzbProvider.api_key = None
|
||||
|
||||
if hasattr(curNzbProvider, 'username'):
|
||||
try:
|
||||
curNzbProvider.username = str(kwargs[curNzbProvider.get_id() + '_username']).strip()
|
||||
except:
|
||||
curNzbProvider.username = None
|
||||
|
||||
if hasattr(curNzbProvider, 'search_mode'):
|
||||
try:
|
||||
curNzbProvider.search_mode = str(kwargs[curNzbProvider.get_id() + '_search_mode']).strip()
|
||||
except:
|
||||
curNzbProvider.search_mode = 'eponly'
|
||||
|
||||
if hasattr(curNzbProvider, 'search_fallback'):
|
||||
try:
|
||||
curNzbProvider.search_fallback = config.checkbox_to_value(
|
||||
kwargs[curNzbProvider.get_id() + '_search_fallback'])
|
||||
except:
|
||||
curNzbProvider.search_fallback = 0 # these exceptions are actually catching unselected checkboxes
|
||||
|
||||
if hasattr(curNzbProvider, 'enable_recentsearch'):
|
||||
try:
|
||||
curNzbProvider.enable_recentsearch = config.checkbox_to_value(
|
||||
kwargs[curNzbProvider.get_id() + '_enable_recentsearch'])
|
||||
except:
|
||||
curNzbProvider.enable_recentsearch = 0 # these exceptions are actually catching unselected checkboxes
|
||||
|
||||
if hasattr(curNzbProvider, 'enable_backlog'):
|
||||
try:
|
||||
curNzbProvider.enable_backlog = config.checkbox_to_value(
|
||||
kwargs[curNzbProvider.get_id() + '_enable_backlog'])
|
||||
except:
|
||||
curNzbProvider.enable_backlog = 0 # these exceptions are actually catching unselected checkboxes
|
||||
for attr in [x for x in ['search_fallback', 'enable_backlog'] if hasattr(nzb_src, x)]:
|
||||
setattr(nzb_src, attr, config.checkbox_to_value(kwargs.get(src_id_prefix + attr)))
|
||||
|
||||
sickbeard.NEWZNAB_DATA = '!!!'.join([x.config_str() for x in sickbeard.newznabProviderList])
|
||||
sickbeard.PROVIDER_ORDER = provider_list
|
||||
|
@ -5073,11 +4940,10 @@ class ConfigProviders(Config):
|
|||
|
||||
sickbeard.save_config()
|
||||
|
||||
if len(results) > 0:
|
||||
if 0 < len(results):
|
||||
for x in results:
|
||||
logger.log(x, logger.ERROR)
|
||||
ui.notifications.error('Error(s) Saving Configuration',
|
||||
'<br />\n'.join(results))
|
||||
ui.notifications.error('Error(s) Saving Configuration', '<br />\n'.join(results))
|
||||
else:
|
||||
ui.notifications.message('Configuration Saved', ek.ek(os.path.join, sickbeard.CONFIG_FILE))
|
||||
|
||||
|
|