Merge pull request #673 from JackDandy/feature/ChangeValidateProv
Change validate and improve specific Torrent provider connections…
|
@ -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))
|
||||
|
||||
|
|