Merge pull request #728 from JackDandy/feature/AddQBitTorrentClient

Add qBitTorrent to Search Settings/Torrent Search.
This commit is contained in:
JackDandy 2016-07-04 21:21:00 +01:00 committed by GitHub
commit 012c12ecd8
12 changed files with 399 additions and 303 deletions

View file

@ -102,6 +102,8 @@
* Change improve highlight of shows found in database in "Add New Show" results
* Change use full first aired date where available in "Add New Show" results
* Change prevent duplicate results in "Add New Show"
* Add qBitTorrent to Search Settings/Torrent Search
* Add "Test NZBGet" client to Search Settings/NZB Search/NZBGet
[develop changelog]
* Change send nzb data to NZBGet for Anizb instead of url

View file

@ -441,8 +441,8 @@
</label>
</div>
#end if
#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'}
#if $hasattr($cur_torrent_provider, '_seed_ratio') and $sickbeard.TORRENT_METHOD not in ('blackhole', 'qbittorrent'):
#set $torrent_method_text = {'deluge': 'Deluge', 'qbittorrent': 'qBittorrent', 'rtorrent': 'rTorrent', 'download_station': 'Synology DS', 'transmission': 'Transmission', 'utorrent': 'uTorrent'}
<div class="field-pair">
<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>

View file

@ -9,7 +9,11 @@
##
#import os.path
#include $os.path.join($sickbeard.PROG_DIR, 'gui/slick/interfaces/default/inc_top.tmpl')
<script>
<!--
var config = {defaultHost: $clients.default_host}
//-->
</script>
<script type="text/javascript" src="$sbRoot/js/configSearch.js?v=$sbPID"></script>
<script type="text/javascript" src="$sbRoot/js/config.js?v=$sbPID"></script>
@ -211,7 +215,7 @@
</label>
</div>
<div id="blackhole_settings">
<div id="blackhole-settings">
<div class="field-pair">
<label>
<span class="component-title">Black hole folder location</span>
@ -223,7 +227,7 @@
</div>
</div>
<div id="sabnzbd_settings">
<div id="sabnzbd-settings">
<div class="field-pair">
<label>
<span class="component-title">SABnzbd server URL</span>
@ -275,7 +279,7 @@
</div>
</div>
<div id="nzbget_settings">
<div id="nzbget-settings">
<div class="field-pair">
<label for="nzbget_use_https">
<span class="component-title">Connect using HTTPS</span>
@ -302,7 +306,7 @@
<label>
<span class="component-title">NZBget username</span>
<span class="component-desc">
<input type="text" name="nzbget_username" value="$sickbeard.NZBGET_USERNAME" class="form-control input-sm input200">
<input type="text" name="nzbget_username" id="nzbget_username" value="$sickbeard.NZBGET_USERNAME" class="form-control input-sm input200">
<p>locate in nzbget.conf (default:nzbget)</p>
</span>
</label>
@ -367,8 +371,9 @@
</div>
</div>
<div class="testNotification" id="testSABnzbd_result">Click below to test</div>
<input class="btn" type="button" value="Test SABnzbd" id="testSABnzbd" class="btn test-button">
<div class="testNotification" id="test-nzb-result">Click below to test</div>
<input type="button" value="Test SABnzbd" id="test_sabnzbd" class="btn test-button sabnzbd">
<input type="button" value="Test NZBget" id="test_nzbget" class="btn test-button nzbget">
<input type="submit" class="btn config_submitter" value="Save Changes"><br />
</div><!-- /content_use_nzbs //-->
@ -401,16 +406,17 @@
<label for="torrent_method">
<span class="component-title">Send .torrent files to:</span>
<span class="component-desc">
<select name="torrent_method" id="torrent_method" class="form-control input-sm">
#set $torrent_method_text = {'blackhole': "Black hole", 'utorrent': "uTorrent", 'transmission': "Transmission", 'deluge': "Deluge", 'download_station': "Synology DS", 'rtorrent': "rTorrent"}
#for $curAction in ('blackhole', 'utorrent', 'transmission', 'deluge', 'download_station', 'rtorrent'):
<select name="torrent_method" id="torrent_method" class="form-control input-sm">
#set $torrent_method_text = {'blackhole': "Black hole", 'utorrent': "uTorrent", 'transmission': "Transmission", 'qbittorrent': "qBittorrent", 'deluge': "Deluge", 'download_station': "Synology DS", 'rtorrent': "rTorrent"}
#for $curAction in ('blackhole', 'deluge', 'qbittorrent', 'rtorrent', 'download_station', 'transmission', 'utorrent'):
#set $selected = $html_selected if $sickbeard.TORRENT_METHOD == $curAction else ''
<option value="$curAction"$selected>$torrent_method_text[$curAction]</option>
<option value="$curAction"$selected>$torrent_method_text[$curAction]</option>
#end for
</select>
</select>
</span>
</label>
<div id="options_torrent_blackhole">
<div id="options-torrent-blackhole">
<div class="field-pair">
<label>
<span class="component-title">Black hole folder location</span>
@ -426,22 +432,22 @@
</div>
</div>
<div id="options_torrent_clients">
<div id="options-torrent-clients">
<div class="field-pair">
<label>
<span class="component-title" id="host_title">Torrent host:port</span>
<span class="component-title" id="host-title">Torrent host:port</span>
<span class="component-desc">
<input type="text" name="torrent_host" id="torrent_host" value="$sickbeard.TORRENT_HOST" class="form-control input-sm input350">
<p class="clear-left note">
<span id="host_desc_torrent">URL to your torrent client (e.g. http://localhost:8000/)</span>
<span id="host_desc_rtorrent" style="display:none"><b>Note:</b> <i>rTorrent</i> client URLs use e.g. scgi://localhost:5000/</span>
<span id="host_desc_deluge" style="display:none">URL to your Deluge WebUI (e.g. http://localhost:8112/)</span>
<span id="host-desc-torrent">URL to your torrent client (e.g. <span class="default-host">http://localhost:8000</span>/)</span>
<span id="host-desc-deluge" style="display:none">URL to your Deluge WebUI (e.g. <span class="default-host">http://localhost:8112</span>/)</span>
<span id="host-desc-rtorrent" style="display:none"><b>Note:</b> <i>rTorrent</i> client URLs use e.g. <span class="default-host">scgi://localhost:5000</span>/</span>
</p>
</span>
</label>
</div>
<div class="field-pair" id="torrent_verify_cert_option">
<div class="field-pair" id="torrent-verify-cert-option">
<label for="torrent_verify_cert">
<span class="component-title">Verify certificate</span>
<span class="component-desc">
@ -451,9 +457,9 @@
</label>
</div>
<div class="field-pair" id="torrent_username_option">
<div class="field-pair" id="torrent-username-option">
<label>
<span class="component-title" id="username_title">Client username</span>
<span class="component-title" id="username-title">Client username</span>
<span class="component-desc">
<input type="text" name="torrent_username" id="torrent_username" value="$sickbeard.TORRENT_USERNAME" class="form-control input-sm input200">
<p>(blank for none)</p>
@ -463,7 +469,7 @@
<div class="field-pair">
<label>
<span class="component-title" id="password_title">Client password</span>
<span class="component-title" id="password-title">Client password</span>
<span class="component-desc">
<input type="password" name="torrent_password" id="torrent_password" value="#echo '*' * len($sickbeard.TORRENT_PASSWORD)#" class="form-control input-sm input200">
<p>(blank for none)</p>
@ -471,31 +477,36 @@
</label>
</div>
<div class="field-pair" id="torrent_label_option">
<div class="field-pair" id="torrent-label-option">
<label>
<span class="component-title">Add label to torrent</span>
<span class="component-title">Set torrent label<span class="qbittorrent">/category</span></span>
<span class="component-desc">
<input type="text" name="torrent_label" id="torrent_label" value="$sickbeard.TORRENT_LABEL" class="form-control input-sm input200">
<span id="label_warning_deluge" style="display:none"><p>(blank spaces are not allowed)</p>
<span id="label-warning-deluge" style="display:none"><p>(blank spaces are not allowed)</p>
<p class="clear-left note">note: label plugin must be enabled in Deluge clients</p>
</span>
<span class="qbittorrent" style="display:none"><p>(qB 3.3.1 and newer clients)</p></span>
</span>
</label>
</div>
<div class="field-pair" id="torrent_path_option">
<div class="field-pair" id="torrent-path-option">
<label>
<span class="component-title" id="directory_title">Downloaded files location</span>
<span class="component-title">Downloaded files location</span>
<span class="component-desc">
<input type="text" name="torrent_path" id="torrent_path" value="$sickbeard.TORRENT_PATH" class="form-control input-sm input350">
<p class="clear-left note">where <span id="torrent_client">the torrent client</span> will save downloaded files <span id="path_blank">(blank for client default)</span>
<span id="path_synology"> <b>note:</b> the destination has to be a shared folder for Synology DS</span>
<span id="path_transmission" class="grey-text"> (v2.92 and newer should <em>not</em> be blank)</span></p>
<p class="clear-left note">
where <span id="torrent-client">the torrent client</span> will save files
<span class="qbittorrent">(blank otherwise set will ignore label/category)</span>
<span id="path-blank">(blank for client default)</span>
<span class="synology"> <b>note:</b> the destination has to be a shared folder for Synology DS</span>
<span class="transmission grey-text"> (v2.92 and newer should <em>not</em> be blank)</span>
</p>
</span>
</label>
</div>
<div class="field-pair" id="torrent_seed_time_option">
<div class="field-pair" id="torrent-seed-time-option">
<label>
<span class="component-title">Seed time (minimum default)</span>
<span class="component-desc"><input type="number" step="0.1" name="torrent_seed_time" id="torrent_seed_time" value="$sickbeard.TORRENT_SEED_TIME" class="form-control input-sm input100">
@ -503,7 +514,7 @@
</label>
</div>
<div class="field-pair" id="torrent_paused_option">
<div class="field-pair" id="torrent-paused-option">
<label>
<span class="component-title">Start torrent paused</span>
<span class="component-desc">
@ -513,7 +524,7 @@
</label>
</div>
<div class="field-pair" id="torrent_high_bandwidth_option">
<div class="field-pair" id="torrent-high-bandwidth-option">
<label>
<span class="component-title">Allow high bandwidth</span>
<span class="component-desc">
@ -523,8 +534,8 @@
</label>
</div>
<div class="testNotification" id="test_torrent_result">Click below to test</div>
<input class="btn" type="button" value="Test Connection" id="test_torrent" class="btn test-button">
<div class="testNotification" id="test-torrent-result">Click below to test</div>
<input type="button" value="Test Connection" id="test_torrent" class="btn test-button">
<input type="submit" class="btn config_submitter" value="Save Changes"><br />
</div>
</div><!-- /content_use_torrents //-->

View file

@ -1,158 +1,154 @@
/** @namespace config.defaultHost */
$(document).ready(function(){
var loading = '<img src="' + sbRoot + '/images/loading16' + themeSpinner + '.gif" height="16" width="16" />';
function toggle_torrent_title(){
if ($('#use_torrents').prop('checked'))
$('#no_torrents').show();
else
$('#no_torrents').hide();
}
var loading = '<img src="' + sbRoot + '/images/loading16' + themeSpinner + '.gif" height="16" width="16" />';
$.fn.nzb_method_handler = function() {
function toggleTorrentTitle() {
var noTorrent$ = $('#no_torrents');
if ($('#use_torrents').prop('checked'))
noTorrent$.show();
else
noTorrent$.hide();
}
var selectedProvider = $('#nzb_method :selected').val(),
blackhole_settings = '#blackhole_settings',
sabnzbd_settings = '#sabnzbd_settings',
testSABnzbd = '#testSABnzbd',
testSABnzbd_result = '#testSABnzbd_result',
nzbget_settings = '#nzbget_settings';
$.fn.nzbMethodHandler = function() {
$(blackhole_settings).hide();
$(sabnzbd_settings).hide();
$(testSABnzbd).hide();
$(testSABnzbd_result).hide();
$(nzbget_settings).hide();
var selectedProvider = $('#nzb_method').find(':selected').val(),
blackholeSettings = '#blackhole-settings',
nzbgetSettings = '#nzbget-settings, #test-nzb-result, .nzbget',
sabnzbdSettings = '#sabnzbd-settings, #test-nzb-result, .sabnzbd';
if ('blackhole' == selectedProvider) {
$(blackhole_settings).show();
} else if ('nzbget' == selectedProvider) {
$(nzbget_settings).show();
} else {
$(sabnzbd_settings).show();
$(testSABnzbd).show();
$(testSABnzbd_result).show();
}
}
$('#test-sabnzbd-result').html('Click below to test');
$([blackholeSettings, nzbgetSettings, sabnzbdSettings].join(',')).hide();
$.fn.torrent_method_handler = function() {
if ('blackhole' == selectedProvider) {
$(blackholeSettings).show();
} else if ('nzbget' == selectedProvider) {
$(nzbgetSettings).show();
} else {
$(sabnzbdSettings).show();
}
};
$('#nzb_method').change($(this).nzbMethodHandler);
$(this).nzbMethodHandler();
$('#options_torrent_clients').hide();
$('#options_torrent_blackhole').hide();
$.fn.torrentMethodHandler = function() {
var selectedProvider = $('#torrent_method :selected').val(),
host = ' host:port',
username = ' username',
password = ' password',
label = ' label',
directory = ' directory',
client = '',
option_panel = '#options_torrent_blackhole';
var selectedProvider = $('#torrent_method').find(':selected').val(),
host = ' host:port', username = ' username', password = ' password',
label = ' label',
directory = ' directory',
client = '',
hideHostDesc = !1, hidePausedOption = !1, hideLabelOption = !1, hidePathBlank = !1,
optionsBlackhole = '#options-torrent-blackhole',
optionsClients = '#options-torrent-clients',
optionsPanel = optionsBlackhole;
if ('blackhole' != selectedProvider) {
var label_warning_deluge = '#label_warning_deluge',
host_desc_rtorrent = '#host_desc_rtorrent',
host_desc_torrent = '#host_desc_torrent',
torrent_verify_cert_option = '#torrent_verify_cert_option',
torrent_path_option = '#torrent_path_option',
torrent_seed_time_option = '#torrent_seed_time_option',
torrent_high_bandwidth_option = '#torrent_high_bandwidth_option',
torrent_label_option = '#torrent_label_option',
path_blank = '#path_blank',
path_transmission = '#path_transmission',
path_synology = '#path_synology',
torrent_paused_option = '#torrent_paused_option';
$(optionsBlackhole).hide();
$(optionsClients).hide();
$(label_warning_deluge).hide();
$(host_desc_rtorrent).hide();
$(host_desc_deluge).hide();
$(host_desc_torrent).show();
$(torrent_username_option).show();
$(torrent_verify_cert_option).hide();
$(torrent_path_option).show();
$(torrent_path_option).find('.fileBrowser').show();
$(torrent_seed_time_option).hide();
$(torrent_high_bandwidth_option).hide();
$(torrent_label_option).show();
$(path_blank).show();
$(path_transmission).hide();
$(path_synology).hide();
$(torrent_paused_option).show();
$('#test-torrent-result').html('Click below to test');
$('.default-host').html(config.defaultHost[selectedProvider]);
if ('utorrent' == selectedProvider) {
client = 'uTorrent';
$(torrent_path_option).hide();
$(torrent_seed_time_option).show();
} else if ('transmission' == selectedProvider){
client = 'Transmission';
$(torrent_high_bandwidth_option).show();
$(torrent_label_option).hide();
//$('#directory_title').text(client + directory);
$(path_blank).hide();
$(path_transmission).show();
} else if ('deluge' == selectedProvider){
client = 'Deluge';
$(torrent_verify_cert_option).show();
$(label_warning_deluge).show();
$(host_desc_torrent).hide();
$(host_desc_deluge).show();
$(torrent_username_option).hide();
//$('#directory_title').text(client + directory);
} else if ('download_station' == selectedProvider){
client = 'Synology DS';
$(torrent_label_option).hide();
$('#torrent_paused_option').hide();
$(torrent_path_option).find('.fileBrowser').hide();
//$('#directory_title').text(client + directory);
$(path_synology).show();
} else if ('rtorrent' == selectedProvider){
client = 'rTorrent';
$(host_desc_torrent).hide();
$(host_desc_rtorrent).show();
$(torrent_paused_option).hide();
//$('#directory_title').text(client + directory);
}
$('#host_title').text(client + host);
$('#username_title').text(client + username);
$('#password_title').text(client + password);
$('#torrent_client').text(client);
option_panel = '#options_torrent_clients';
}
$(option_panel).show();
}
if ('blackhole' != selectedProvider) {
var labelWarningDeluge = '#label-warning-deluge',
hostDesc = '#host-desc-torrent',
hostDescDeluge = '#host-desc-deluge',
hostDescRtorrent = '#host-desc-rtorrent',
usernameOption = '#torrent-username-option',
verifyCertOption = '#torrent-verify-cert-option',
labelOption = '#torrent-label-option',
qBitTorrent = '.qbittorrent',
synology = '.synology',
transmission = '.transmission',
pathOption = '#torrent-path-option',
pathBlank = '#path-blank',
seedTimeOption = '#torrent-seed-time-option',
pausedOption = '#torrent-paused-option',
highBandwidthOption = '#torrent-high-bandwidth-option';
$('#nzb_method').change($(this).nzb_method_handler);
$([labelWarningDeluge, hostDescDeluge, hostDescRtorrent, verifyCertOption, seedTimeOption,
highBandwidthOption, qBitTorrent, synology, transmission].join(',')).hide();
$(this).nzb_method_handler();
$([hostDesc, usernameOption, pathOption, labelOption, pathBlank, pausedOption].join(',')).show();
$(pathOption).find('.fileBrowser').show();
$('#testSABnzbd').click(function(){
$('#testSABnzbd_result').html(loading);
var sab_host = $('#sab_host').val();
var sab_username = $('#sab_username').val();
var sab_password = $('#sab_password').val();
var sab_apiKey = $('#sab_apikey').val();
switch (selectedProvider) {
case 'utorrent':
client = 'uTorrent';
$(pathOption).hide();
$(seedTimeOption).show();
break;
case 'deluge':
client = 'Deluge'; hideHostDesc = !0;
$(usernameOption).hide();
$([hostDescDeluge, verifyCertOption, labelWarningDeluge].join(',')).show();
break;
case 'transmission':
client = 'Transmission'; hideLabelOption = !0; hidePathBlank = !0;
$([transmission, highBandwidthOption].join(',')).show();
break;
case 'qbittorrent':
// Setting Paused is buggy on qB, remove from use
client = 'qBittorrent'; hidePausedOption = !0; hidePathBlank = !0;
$(qBitTorrent).show();
break;
case 'download_station':
client = 'Synology DS'; hideLabelOption = !0; hidePausedOption = !0;
$(pathOption).find('.fileBrowser').hide();
$(synology).show();
break;
case 'rtorrent':
client = 'rTorrent'; hideHostDesc = !0; hidePausedOption = !0;
$(hostDescRtorrent).show();
break;
}
hideHostDesc && $(hostDesc).hide();
hideLabelOption && $(labelOption).hide();
hidePausedOption && $(pausedOption).hide();
hidePathBlank && $(pathBlank).hide();
$('#host-title').text(client + host);
$('#username-title').text(client + username);
$('#password-title').text(client + password);
$('#torrent-client').text(client);
optionsPanel = optionsClients;
}
$(optionsPanel).show();
};
$('#torrent_method').change($(this).torrentMethodHandler);
$(this).torrentMethodHandler();
$.get(sbRoot + '/home/testSABnzbd', {'host': sab_host, 'username': sab_username, 'password': sab_password, 'apikey': sab_apiKey},
function (data){ $('#testSABnzbd_result').html(data); });
});
$('#use_torrents').click(function() {
toggleTorrentTitle();
});
$.fn.testResult = function(data, test$) {
// endpoint changed so gracefully handle 404s until restarted
$(test$).html(/404/.test(data) ? 'Test not found, a restart should fix' : data);
};
$('#torrent_method').change($(this).torrent_method_handler);
$('#test_torrent').click(function() {
$('#test-torrent-result').html(loading);
$.get(sbRoot + '/home/test_torrent',
{'torrent_method': $('#torrent_method').find(':selected').val(), 'host': $('#torrent_host').val(),
'username': $('#torrent_username').val(), 'password': $('#torrent_password').val()},
function(data) { $(this).testResult(data, '#test-torrent-result'); });
});
$(this).torrent_method_handler();
$('#test_nzbget').click(function() {
$('#test-nzb-result').html(loading);
$.get(sbRoot + '/home/test_nzbget',
{'host': $('#nzbget_host').val(), 'use_https': $('#nzbget_use_https').prop('checked'),
'username': $('#nzbget_username').val(), 'password': $('#nzbget_password').val()},
function(data) { $(this).testResult(data, '#test-nzb-result'); });
});
$('#use_torrents').click(function(){
toggle_torrent_title();
});
$('#test_torrent').click(function(){
$('#test_torrent_result').html(loading);
var torrent_method = $('#torrent_method :selected').val();
var torrent_host = $('#torrent_host').val();
var torrent_username = $('#torrent_username').val();
var torrent_password = $('#torrent_password').val();
$.get(sbRoot + '/home/testTorrent', {'torrent_method': torrent_method, 'host': torrent_host, 'username': torrent_username, 'password': torrent_password},
function (data){ $('#test_torrent_result').html(data); });
});
$('#test_sabnzbd').click(function() {
$('#test-nzb-result').html(loading);
$.get(sbRoot + '/home/test_sabnzbd',
{'host': $('#sab_host').val(), 'username': $('#sab_username').val(),
'password': $('#sab_password').val(), 'apikey': $('#sab_apikey').val()},
function(data) { $(this).testResult(data, '#test-nzb-result'); });
});
});

View file

@ -721,7 +721,8 @@ def initialize(consoleLogging=True):
NZB_METHOD = 'blackhole'
TORRENT_METHOD = check_setting_str(CFG, 'General', 'torrent_method', 'blackhole')
if TORRENT_METHOD not in ('blackhole', 'utorrent', 'transmission', 'deluge', 'download_station', 'rtorrent'):
if TORRENT_METHOD not in ('blackhole', 'deluge', 'download_station', 'qbittorrent',
'rtorrent', 'transmission', 'utorrent'):
TORRENT_METHOD = 'blackhole'
DOWNLOAD_PROPERS = bool(check_setting_int(CFG, 'General', 'download_propers', 1))

View file

@ -1,5 +1,4 @@
# Author: Nic Wolfe <nic@wolfeden.ca>
# URL: http://code.google.com/p/sickbeard/
#
# This file is part of SickGear.
#
@ -11,22 +10,31 @@
# 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.
# 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/>.
__all__ = ['utorrent',
'transmission',
'deluge',
'download_station',
'rtorrent'
]
import sickbeard
from os import sys
__all__ = ['deluge', 'download_station', 'qbittorrent', 'rtorrent', 'transmission', 'utorrent']
default_host = {
'deluge': 'http://localhost:8112',
'download_station': 'http://localhost:5000',
'rtorrent': 'scgi://localhost:5000',
'qbittorrent': 'http://localhost:8080',
'transmission': 'http://localhost:9091',
'utorrent': 'http://localhost:8000'}
def get_client_instance(name):
module = __import__('sickbeard.clients.%s' % name.lower(), fromlist=__all__)
return getattr(module, module.api.__class__.__name__)
# Mapping error status codes to official W3C names
http_error_code = {
300: 'Multiple Choices',
@ -65,26 +73,4 @@ http_error_code = {
503: 'Service Unavailable',
504: 'Gateway Timeout',
505: 'HTTP Version Not Supported',
511: 'Network Authentication Required',
}
default_host = {'utorrent': 'http://localhost:8000',
'transmission': 'http://localhost:9091',
'deluge': 'http://localhost:8112',
'download_station': 'http://localhost:5000',
'rtorrent': 'scgi://localhost:5000',
}
def getClientModule(name):
name = name.lower()
prefix = "sickbeard.clients."
return __import__(prefix + name, fromlist=__all__)
def getClientIstance(name):
module = getClientModule(name)
className = module.api.__class__.__name__
return getattr(module, className)
511: 'Network Authentication Required'}

View file

@ -0,0 +1,74 @@
#
# 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/>.
from sickbeard import helpers, TORRENT_LABEL, TORRENT_PATH
from sickbeard.clients.generic import GenericClient
class QbittorrentAPI(GenericClient):
def __init__(self, host=None, username=None, password=None):
super(QbittorrentAPI, self).__init__('qBittorrent', host, username, password)
self.url = self.host
def _get_auth(self):
self.auth = (6 < self.api_version() and
'Ok' in helpers.getURL('%slogin' % self.host, session=self.session,
post_data={'username': self.username, 'password': self.password}))
return self.auth
def api_version(self):
return helpers.tryInt(helpers.getURL('%sversion/api' % self.host, session=self.session))
def _post_api(self, cmd='', **kwargs):
return '' == helpers.getURL('%scommand/%s' % (self.host, cmd), session=self.session, **kwargs)
def _add_torrent(self, cmd, **kwargs):
label = TORRENT_LABEL.replace(' ', '_')
label_dict = {'label': label, 'category': label, 'savepath': TORRENT_PATH}
if 'post_data' in kwargs:
kwargs['post_data'].update(label_dict)
else:
kwargs.update({'post_data': label_dict})
return self._post_api(cmd, **kwargs)
def _add_torrent_uri(self, result):
return self._add_torrent('download', post_data={'urls': result.url})
def _add_torrent_file(self, result):
return self._add_torrent('upload', files={'torrents': ('%s.torrent' % result.name, result.content)})
###
# An issue in qB can lead to actions being ignored during the initial period after a file is added.
# Therefore, actions that need to be applied to existing items will be disabled unless fixed.
###
# def _set_torrent_priority(self, result):
#
# return self._post_api('%screasePrio' % ('de', 'in')[1 == result.priority], post_data={'hashes': result.hash})
# def _set_torrent_pause(self, result):
#
# return self._post_api(('resume', 'pause')[sickbeard.TORRENT_PAUSED], post_data={'hash': result.hash})
api = QbittorrentAPI()

View file

@ -1,5 +1,3 @@
# Author: Nic Wolfe <nic@wolfeden.ca>
# URL: http://code.google.com/p/sickbeard/
#
# This file is part of SickGear.
#
@ -16,133 +14,148 @@
# You should have received a copy of the GNU General Public License
# along with SickGear. If not, see <http://www.gnu.org/licenses/>.
from lib.six import moves
import datetime
import re
import sickbeard
import config
from lib.six import moves
from base64 import standard_b64encode
from common import Quality
from sickbeard import logger
from sickbeard.helpers import tryInt
from sickbeard.providers.generic import GenericProvider
from sickbeard import logger, helpers
from common import Quality
def test_nzbget(host, use_https, username, password):
result = False
if not host:
msg = 'No NZBget host found. Please configure it'
logger.log(msg, logger.ERROR)
return result, msg, None
def sendNZB(nzb, proper=False):
addToTop = False
nzbgetprio = 0
if sickbeard.NZBGET_USE_HTTPS:
nzbgetXMLrpc = "https://%(username)s:%(password)s@%(host)s/xmlrpc"
else:
nzbgetXMLrpc = "http://%(username)s:%(password)s@%(host)s/xmlrpc"
if sickbeard.NZBGET_HOST == None:
logger.log(u"No NZBget host found in configuration. Please configure it.", logger.ERROR)
return False
url = nzbgetXMLrpc % {"host": sickbeard.NZBGET_HOST, "username": sickbeard.NZBGET_USERNAME,
"password": sickbeard.NZBGET_PASSWORD}
nzbGetRPC = moves.xmlrpc_client.ServerProxy(url)
url = 'http%(scheme)s://%(username)s:%(password)s@%(host)s/xmlrpc' % {
'scheme': ('', 's')[use_https], 'host': re.sub('(?:https?://)?(.*?)/?$', r'\1', host),
'username': username, 'password': password}
rpc_client = moves.xmlrpc_client.ServerProxy(url)
try:
if nzbGetRPC.writelog("INFO", "SickGear connected to drop off %s any moment now." % (nzb.name + ".nzb")):
logger.log(u"Successfully connected to NZBget", logger.DEBUG)
msg = 'Success. Connected'
if rpc_client.writelog('INFO', 'SickGear connected as a test'):
logger.log(msg, logger.DEBUG)
else:
logger.log(u"Successfully connected to NZBget, but unable to send a message", logger.ERROR)
msg += ', but unable to send a message'
logger.log(msg, logger.ERROR)
result = True
logger.log(u'NZBGet URL: %s' % url, logger.DEBUG)
except moves.http_client.socket.error:
logger.log(
u"Please check your NZBget host and port (if it is running). NZBget is not responding to this combination",
logger.ERROR)
return False
msg = 'Please check NZBget host and port (if it is running). NZBget is not responding to these values'
logger.log(msg, logger.ERROR)
except moves.xmlrpc_client.ProtocolError as e:
if (e.errmsg == "Unauthorized"):
logger.log(u"NZBget username or password is incorrect.", logger.ERROR)
if 'Unauthorized' == e.errmsg:
msg = 'NZBget username or password is incorrect'
logger.log(msg, logger.ERROR)
else:
logger.log(u"Protocol Error: " + e.errmsg, logger.ERROR)
return False
msg = 'Protocol Error: %s' % e.errmsg
logger.log(msg, logger.ERROR)
dupekey = ""
return result, msg, rpc_client
def send_nzb(nzb, proper=False):
result = False
add_to_top = False
nzbget_prio = 0
authed, auth_msg, rpc_client = test_nzbget(
sickbeard.NZBGET_HOST, sickbeard.NZBGET_USE_HTTPS, sickbeard.NZBGET_USERNAME, sickbeard.NZBGET_PASSWORD)
if not authed:
return authed
dupekey = ''
dupescore = 0
# if it aired recently make it high priority and generate DupeKey/Score
for curEp in nzb.episodes:
if dupekey == "":
if curEp.show.indexer == 1:
dupekey = "SickGear-" + str(curEp.show.indexerid)
elif curEp.show.indexer == 2:
dupekey = "SickGear-tvr" + str(curEp.show.indexerid)
dupekey += "-" + str(curEp.season) + "." + str(curEp.episode)
if datetime.date.today() - curEp.airdate <= datetime.timedelta(days=7):
addToTop = True
nzbgetprio = sickbeard.NZBGET_PRIORITY
if '' == dupekey:
if 1 == curEp.show.indexer:
dupekey = 'SickGear-%s' % curEp.show.indexerid
elif 2 == curEp.show.indexer:
dupekey = 'SickGear-tvr%s' % curEp.show.indexerid
dupekey += '-%s.%s' % (curEp.season, curEp.episode)
if nzb.quality != Quality.UNKNOWN:
if datetime.date.today() - curEp.airdate <= datetime.timedelta(days=7):
add_to_top = True
nzbget_prio = sickbeard.NZBGET_PRIORITY
if Quality.UNKNOWN != nzb.quality:
dupescore = nzb.quality * 100
if proper:
dupescore += 10
nzbcontent64 = None
if nzb.resultType == "nzbdata":
if 'nzbdata' == nzb.resultType:
data = nzb.extraInfo[0]
nzbcontent64 = standard_b64encode(data)
elif 'Anizb' == nzb.provider.name and 'nzb' == nzb.resultType:
gen_provider = GenericProvider('')
data = gen_provider.get_url(nzb.url)
if None is data:
return False
return result
nzbcontent64 = standard_b64encode(data)
logger.log(u"Sending NZB to NZBGet: %s" % nzb.name)
logger.log(u"NZBGet URL: " + url, logger.DEBUG)
logger.log(u'Sending NZB to NZBGet: %s' % nzb.name)
try:
# Find out if nzbget supports priority (Version 9.0+), old versions beginning with a 0.x will use the old command
nzbget_version_str = nzbGetRPC.version()
nzbget_version = helpers.tryInt(nzbget_version_str[:nzbget_version_str.find(".")])
if nzbget_version == 0:
if nzbcontent64 is not None:
nzbget_result = nzbGetRPC.append(nzb.name + ".nzb", sickbeard.NZBGET_CATEGORY, addToTop, nzbcontent64)
else:
if nzb.resultType == "nzb":
genProvider = GenericProvider("")
data = genProvider.get_url(nzb.url)
if (data == None):
return False
nzbcontent64 = standard_b64encode(data)
nzbget_result = nzbGetRPC.append(nzb.name + ".nzb", sickbeard.NZBGET_CATEGORY, addToTop, nzbcontent64)
elif nzbget_version == 12:
if nzbcontent64 is not None:
nzbget_result = nzbGetRPC.append(nzb.name + ".nzb", sickbeard.NZBGET_CATEGORY, nzbgetprio, False,
nzbcontent64, False, dupekey, dupescore, "score")
else:
nzbget_result = nzbGetRPC.appendurl(nzb.name + ".nzb", sickbeard.NZBGET_CATEGORY, nzbgetprio, False,
nzb.url, False, dupekey, dupescore, "score")
# v13+ has a new combined append method that accepts both (url and content)
# also the return value has changed from boolean to integer
# Find out if nzbget supports priority (Version 9.0+), old versions beginning with a 0.x will use the old cmd
nzbget_version_str = rpc_client.version()
nzbget_version = tryInt(nzbget_version_str[:nzbget_version_str.find('.')])
# v13+ has a combined append method that accepts both (url and content)
# also the return value has changed from boolean to integer
# (Positive number representing NZBID of the queue item. 0 and negative numbers represent error codes.)
elif nzbget_version >= 13:
nzbget_result = True if nzbGetRPC.append(nzb.name + ".nzb", nzbcontent64 if nzbcontent64 is not None else nzb.url,
sickbeard.NZBGET_CATEGORY, nzbgetprio, False, False, dupekey, dupescore,
"score") > 0 else False
if 13 <= nzbget_version:
nzbget_result = rpc_client.append(
'%s.nzb' % nzb.name, (nzbcontent64, nzb.url)[None is nzbcontent64], sickbeard.NZBGET_CATEGORY,
nzbget_prio, False, False, dupekey, dupescore, 'score') > 0
elif 12 == nzbget_version:
if nzbcontent64 is not None:
nzbget_result = rpc_client.append('%s.nzb' % nzb.name, sickbeard.NZBGET_CATEGORY,
nzbget_prio, False, nzbcontent64, False, dupekey, dupescore, 'score')
else:
nzbget_result = rpc_client.appendurl('%s.nzb' % nzb.name, sickbeard.NZBGET_CATEGORY,
nzbget_prio, False, nzb.url, False, dupekey, dupescore, 'score')
elif 0 == nzbget_version:
if nzbcontent64 is not None:
nzbget_result = rpc_client.append('%s.nzb' % nzb.name, sickbeard.NZBGET_CATEGORY,
add_to_top, nzbcontent64)
else:
if 'nzb' == nzb.resultType:
gen_provider = GenericProvider('')
data = gen_provider.get_url(nzb.url)
if None is data:
return result
nzbcontent64 = standard_b64encode(data)
nzbget_result = rpc_client.append('%s.nzb' % nzb.name, sickbeard.NZBGET_CATEGORY,
add_to_top, nzbcontent64)
else:
if nzbcontent64 is not None:
nzbget_result = nzbGetRPC.append(nzb.name + ".nzb", sickbeard.NZBGET_CATEGORY, nzbgetprio, False,
nzbcontent64)
nzbget_result = rpc_client.append('%s.nzb' % nzb.name, sickbeard.NZBGET_CATEGORY,
nzbget_prio, False, nzbcontent64)
else:
nzbget_result = nzbGetRPC.appendurl(nzb.name + ".nzb", sickbeard.NZBGET_CATEGORY, nzbgetprio, False,
nzb.url)
nzbget_result = rpc_client.appendurl('%s.nzb' % nzb.name, sickbeard.NZBGET_CATEGORY,
nzbget_prio, False, nzb.url)
if nzbget_result:
logger.log(u"NZB sent to NZBget successfully", logger.DEBUG)
return True
logger.log(u'NZB sent to NZBget successfully', logger.DEBUG)
result = True
else:
logger.log(u"NZBget could not add %s to the queue" % (nzb.name + ".nzb"), logger.ERROR)
return False
logger.log(u'NZBget could not add %s to the queue' % ('%s.nzb' % nzb.name), logger.ERROR)
except:
logger.log(u"Connect Error to NZBget: could not add %s to the queue" % (nzb.name + ".nzb"), logger.ERROR)
return False
logger.log(u'Connect Error to NZBget: could not add %s to the queue' % ('%s.nzb' % nzb.name), logger.ERROR)
return result

View file

@ -32,7 +32,7 @@ from sickbeard import history
from sickbeard.common import DOWNLOADED, SNATCHED, SNATCHED_PROPER, Quality
from name_parser.parser import NameParser
from name_parser.parser import NameParser, InvalidNameException, InvalidShowException
def search_propers():
@ -112,6 +112,8 @@ def _get_proper_list(aired_since_shows, recent_shows, recent_anime):
x.provider = cur_provider
propers[name] = x
count += 1
except (InvalidNameException, InvalidShowException):
continue
except Exception:
continue

View file

@ -681,7 +681,7 @@ class TorrentProvider(object, GenericProvider):
@property
def url(self):
if None is self._url:
if None is self._url or (hasattr(self, 'url_tmpl') and not self.urls):
self._url = self._valid_home()
self._valid_url()
return self._url

View file

@ -120,7 +120,7 @@ def snatch_episode(result, end_status=SNATCHED):
dl_result = sab.send_nzb(result)
elif 'nzbget' == sickbeard.NZB_METHOD:
is_proper = True if SNATCHED_PROPER == end_status else False
dl_result = nzbget.sendNZB(result, is_proper)
dl_result = nzbget.send_nzb(result, is_proper)
else:
logger.log(u'Unknown NZB action specified in config: %s' % sickbeard.NZB_METHOD, logger.ERROR)
dl_result = False
@ -138,7 +138,7 @@ def snatch_episode(result, end_status=SNATCHED):
logger.log(u'Torrent content failed to download from %s' % result.url, logger.ERROR)
return False
# Snatches torrent with client
client = clients.getClientIstance(sickbeard.TORRENT_METHOD)()
client = clients.get_client_instance(sickbeard.TORRENT_METHOD)()
dl_result = client.send_torrent(result)
else:
logger.log(u'Unknown result type, unable to download it', logger.ERROR)

View file

@ -36,8 +36,9 @@ from Cheetah.Template import Template
from six import iteritems
import sickbeard
from sickbeard import config, sab, clients, history, notifiers, processTV, ui, logger, helpers, exceptions, classes, \
db, search_queue, image_cache, naming, scene_exceptions, search_propers, subtitles, network_timezones, sbdatetime
from sickbeard import config, sab, nzbget, clients, history, notifiers, processTV, ui, logger, helpers, exceptions,\
classes, db, search_queue, image_cache, naming, scene_exceptions, search_propers, subtitles, network_timezones,\
sbdatetime
from sickbeard import encodingKludge as ek
from sickbeard.providers import newznab, rsstorrent
from sickbeard.common import Quality, Overview, statusStrings, qualityPresetStrings
@ -649,7 +650,7 @@ class Home(MainHandler):
return t.respond()
def testSABnzbd(self, host=None, username=None, password=None, apikey=None):
def test_sabnzbd(self, host=None, username=None, password=None, apikey=None):
self.set_header('Cache-Control', 'max-age=0,no-cache,no-store')
host = config.clean_url(host)
@ -667,14 +668,24 @@ class Home(MainHandler):
return u'Authentication failed. %s' % auth_msg
return u'Unable to connect to host'
def testTorrent(self, torrent_method=None, host=None, username=None, password=None):
def test_nzbget(self, host=None, use_https=None, username=None, password=None):
self.set_header('Cache-Control', 'max-age=0,no-cache,no-store')
host = config.clean_url(host)
if None is not password and set('*') == set(password):
password = sickbeard.NZBGET_PASSWORD
authed, auth_msg, void = nzbget.test_nzbget(host, bool(config.checkbox_to_value(use_https)), username, password)
return auth_msg
def test_torrent(self, torrent_method=None, host=None, username=None, password=None):
self.set_header('Cache-Control', 'max-age=0,no-cache,no-store')
host = config.clean_url(host)
if None is not password and set('*') == set(password):
password = sickbeard.TORRENT_PASSWORD
client = clients.getClientIstance(torrent_method)
client = clients.get_client_instance(torrent_method)
connection, accesMsg = client(host, username, password).test_authentication()