Commit 057e85a3 authored by Alexandre Beloin's avatar Alexandre Beloin

Merge branch 'develop'

parents 281409d3 9035ccc4
### 4.0.17 (2015-04-19)
[full changelog](https://github.com/SiCKRAGETV/SickRage/compare/v4.0.16...v4.0.17)
* libnotify: Use gir-notify instead of pynotify.
* Fix for xml_declaration unexpected keyword in python 2.6.
* Fix UnboundLocalError exception can be thrown at piList.append(curQueueItem).
* Fix Auto determine indexer when indexer tag not present in nfo.
* Fix editShow: Select the default indexer language instead of forcing en.
* Fix Catch emailnotify smtp error.
* Fix Change log timeout errors to WARNING in requests provider clients.
* Fix Ignore OSError when obtaining the size of a path in get_size.
* New Add RSS to EZTV provider.
* New SceneTime provider.
* Fix iptorrent: Add missing import.
* New Add Pause Button on displayShow page.
* Fix Episode Thumbnail url when show is in DVD Order.
* Fix Catch all errors from Kodi notify.
* Fix Add user agent to RARBG when login.
* New Use better logging for get_size exceptions.
* New Added qbittorrent support.
* Fix rarbg: remove urllib.quote.
* Update PNotify to latest version.
* Fix Plex Notification.
* New added the option to use Plex Token vs Username / Password.
* Fix PP Case Sensitive associated files check.
* Fix unknown quality being accepted as a valid quality in PP.
* Fix added notification of unsupported multiepisode torrent.
* Fix proper: saveSearch broken for download propers.
* New Add logline to show found associated files.
* New Add a log line containing connecting IP on login.
* Fix eztv provider.
* Fix Title of None for Errors submitted through UI.
* New Stay on Show Page after "Update Kodi".
* Fix NoneType object has no attribute getOverview.
* New Manage Rolling Download on unpause from submenu button.
* Fix provide a more detailed http code error.
* Fix Show subtitle service unavailable as info.
* New Column Selection for displayShow.
* Fix Update IPTorrents search URL.
### 4.0.16 (2015-04-12)
[full changelog](https://github.com/SiCKRAGETV/SickRage/compare/v4.0.15...v4.0.16)
* New Feature: Added option to add a filter row on main show page (enabled in general settings - interface)
* New Feature: added scheduling status page
* Fixed EZTV rss blank result
* Fixed RARBG tokend
* Fixed Home page filter: change to allow to use parsed data for active(yes/no)
* Fixed OldTPB: Check if the returned results ar proper|repack
* Don't display paused show in backlogOverview
* Trakt Sync by Episode not by Show
* Added gzip setting in config.ini
* Added TRAKTROLLING to filter in viewlog
* Redone Scheduler
* Replace fuzzy images on Add Show ( Add Trending)
* New Feature: Added option to add a filter row on main show page (enabled in general settings - interface)
* New Feature: added scheduling status page
* Fixed EZTV rss blank result
* Fixed RARBG tokend
* Fixed Home page filter: change to allow to use parsed data for active(yes/no)
* Fixed OldTPB: Check if the returned results ar proper|repack
* Don't display paused show in backlogOverview
* Trakt Sync by Episode not by Show
* Added gzip setting in config.ini
* Added TRAKTROLLING to filter in viewlog
* Redone Scheduler
* Replace fuzzy images on Add Show ( Add Trending)
### 4.0.15 (2015-04-05)
......
......@@ -1192,6 +1192,29 @@ span.snatched b {
opacity: 0.4;
}
.displayShowTable {
table-layout: auto;
width: 100%;
border-collapse: collapse;
border-spacing: 0;
text-align: center;
border: none;
empty-cells: show;
color: #000 !important;
}
.displayShowTable.display_show {
clear:both
}
.displayShowTable th.row-seasonheader {
border: none !important;
background-color: #222 !important;
color: #fff !important;
padding-top: 15px !important;
text-align: left !important;
}
.sickbeardTable {
table-layout: auto;
width: 100%;
......
.ui-pnotify{top:25px;right:25px;position:absolute;height:auto;z-index:9999}html>body>.ui-pnotify{position:fixed}.ui-pnotify .ui-pnotify-shadow{-webkit-box-shadow:0 2px 10px rgba(50,50,50,.5);-moz-box-shadow:0 2px 10px rgba(50,50,50,.5);box-shadow:0 2px 10px rgba(50,50,50,.5)}.ui-pnotify-container{background-position:0 0;padding:.8em;height:100%;margin:0}.ui-pnotify-sharp{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.ui-pnotify-title{display:block;margin-bottom:.4em;margin-top:0}.ui-pnotify-text{display:block}.ui-pnotify-icon,.ui-pnotify-icon span{display:block;float:left;margin-right:.2em}.ui-pnotify.stack-bottomleft,.ui-pnotify.stack-topleft{left:25px;right:auto}.ui-pnotify.stack-bottomleft,.ui-pnotify.stack-bottomright{bottom:25px;top:auto}.ui-pnotify-closer,.ui-pnotify-sticker{float:right;margin-left:.2em}
\ No newline at end of file
.ui-pnotify{top:25px;right:25px;position:absolute;height:auto;z-index:9999}html>body>.ui-pnotify{position:fixed}.ui-pnotify .ui-pnotify-shadow{-webkit-box-shadow:0 2px 10px rgba(50,50,50,.5);-moz-box-shadow:0 2px 10px rgba(50,50,50,.5);box-shadow:0 2px 10px rgba(50,50,50,.5)}.ui-pnotify-container{background-position:0 0;padding:.8em;height:100%;margin:0}.ui-pnotify-sharp{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.ui-pnotify-title{display:block;margin-bottom:.4em;margin-top:0}.ui-pnotify-text{display:block}.ui-pnotify-icon,.ui-pnotify-icon span{display:block;float:left;margin-right:.2em}.ui-pnotify.stack-bottomleft,.ui-pnotify.stack-topleft{left:25px;right:auto}.ui-pnotify.stack-bottomleft,.ui-pnotify.stack-bottomright{bottom:25px;top:auto}.ui-pnotify-closer,.ui-pnotify-sticker{float:right;margin-left:.2em}.ui-pnotify-history-container{position:absolute;top:0;right:18px;width:70px;border-top:none;padding:0;-webkit-border-top-left-radius:0;-moz-border-top-left-radius:0;border-top-left-radius:0;-webkit-border-top-right-radius:0;-moz-border-top-right-radius:0;border-top-right-radius:0;z-index:10000}.ui-pnotify-history-container.ui-pnotify-history-fixed{position:fixed}.ui-pnotify-history-container .ui-pnotify-history-header{padding:2px;text-align:center}.ui-pnotify-history-container button{cursor:pointer;display:block;width:100%}.ui-pnotify-history-container .ui-pnotify-history-pulldown{display:block;margin:0 auto}
\ No newline at end of file
......@@ -1167,6 +1167,29 @@ span.snatched b {
opacity: 0.4;
}
.displayShowTable {
table-layout: auto;
width: 100%;
border-collapse: collapse;
border-spacing: 0;
text-align: center;
border: none;
empty-cells: show;
color: #000 !important;
}
.displayShowTable.display_show {
clear:both
}
.displayShowTable th.row-seasonheader {
border: none !important;
background-color: #fff !important;
color: #000 !important;
padding-top: 15px !important;
text-align: left !important;
}
.sickbeardTable {
table-layout: auto;
width: 100%;
......
......@@ -1193,6 +1193,29 @@ span.snatched b {
opacity: 0.4;
}
.displayShowTable {
table-layout: auto;
width: 100%;
border-collapse: collapse;
border-spacing: 0;
text-align: center;
border: none;
empty-cells: show;
color: #000 !important;
}
.displayShowTable.display_show {
clear:both
}
.displayShowTable th.row-seasonheader {
border: none !important;
background-color: #222 !important;
color: #fff !important;
padding-top: 15px !important;
text-align: left !important;
}
.sickbeardTable {
table-layout: auto;
width: 100%;
......
This diff was suppressed by a .gitattributes entry.
......@@ -299,20 +299,11 @@
<label for="filter_row">
<span class="component-title">Filter Row</span>
<span class="component-desc">
<input type="checkbox" name="filter_row" id="display_filesize" #if $sickbeard.FILTER_ROW == True then 'checked="checked"' else ''#/>
<input type="checkbox" name="filter_row" id="filter_row" #if $sickbeard.FILTER_ROW == True then 'checked="checked"' else ''#/>
<p>Add a filter row to the show display on the home page</p>
</span>
</label>
</div>
<div class="field-pair">
<label for="display_filesize">
<span class="component-title">Display Filesizes</span>
<span class="component-desc">
<input type="checkbox" name="display_filesize" id="display_filesize" #if $sickbeard.DISPLAY_FILESIZE == True then 'checked="checked"' else ''#/>
<p>display filesizes for downloaded episodes on show page</p>
</span>
</label>
</div>
<div class="field-pair">
<label for="coming_eps_missed_range">
<span class="component-title">Missed episodes range</span>
......@@ -774,4 +765,4 @@
//-->
</script>
#include $os.path.join($sickbeard.PROG_DIR, 'gui/slick/interfaces/default/inc_bottom.tmpl')
#include $os.path.join($sickbeard.PROG_DIR, 'gui/slick/interfaces/default/inc_bottom.tmpl')
\ No newline at end of file
......@@ -448,8 +448,8 @@
<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'):
#set $torrent_method_text = {'blackhole': "Black hole", 'utorrent': "uTorrent", 'transmission': "Transmission", 'deluge': "Deluge", 'download_station': "Synology DS", 'rtorrent': "rTorrent", 'qbittorrent': "qbittorrent"}
#for $curAction in ('blackhole', 'utorrent', 'transmission', 'deluge', 'download_station', 'rtorrent', 'qbittorrent'):
#set $selected = $html_selected if $sickbeard.TORRENT_METHOD == $curAction else ''
<option value="$curAction"$selected>$torrent_method_text[$curAction]</option>
#end for
......
......@@ -78,7 +78,7 @@
<b>Info Language:</b><br />
(this will only affect the language of the retrieved metadata file contents and episode filenames)<br />
<select name="indexerLang" id="indexerLangSelect" class="form-control form-control-inline input-sm bfh-languages" data-language="en" data-available="#echo ','.join($sickbeard.indexerApi().config['valid_languages'])#"></select><br />
<select name="indexerLang" id="indexerLangSelect" class="form-control form-control-inline input-sm bfh-languages" data-language="#echo $sickbeard.INDEXER_DEFAULT_LANGUAGE#" data-available="#echo ','.join($sickbeard.indexerApi().config['valid_languages'])#"></select><br />
<br />
<b>Flatten files (no folders): </b> <input type="checkbox" name="flatten_folders" #if $show.flatten_folders == 1 and not $sickbeard.NAMING_FORCE_FOLDERS then "checked=\"checked\"" else ""# #if $sickbeard.NAMING_FORCE_FOLDERS then "disabled=\"disabled\"" else ""#/><br />
......
......@@ -119,6 +119,9 @@
\$("#SubMenu a:contains('Notification')").addClass('btn').html('<span class="ui-icon ui-icon-note pull-left"></span> Notifications');
\$("#SubMenu a:contains('Update show in KODI')").addClass('btn').html('<span class="submenu-icon-kodi pull-left"></span> Update show in KODI');
\$("#SubMenu a[href$='/home/updateKODI/']").addClass('btn').html('<span class="submenu-icon-kodi pull-left"></span> Update KODI');
\$("#SubMenu a:contains('Pause')").addClass('btn').html('<span class="ui-icon ui-icon-pause pull-left"></span> Pause');
\$("#SubMenu a:contains('Resume')").addClass('btn').html('<span class="ui-icon ui-icon-play pull-left"></span> Resume');
}
\$(document).ready(function() {
......
This diff is collapsed.
......@@ -56,24 +56,44 @@ $(document).ready(function(){
});
});
$('#testPLEX').click(function () {
var plex_host = $.trim($('#plex_host').val());
var plex_username = $.trim($('#plex_username').val());
var plex_password = $.trim($('#plex_password').val());
if (!plex_host) {
$('#testPLEX-result').html('Please fill out the necessary fields above.');
$('#testPMC').click(function () {
var plex_host = $.trim($('#plex_host').val());
var plex_username = $.trim($('#plex_username').val());
var plex_password = $.trim($('#plex_password').val());
if (!plex_host) {
$('#testPMC-result').html('Please fill out the necessary fields above.');
$('#plex_host').addClass('warning');
return;
}
$('#plex_host').removeClass('warning');
return;
}
$('#plex_host').removeClass('warning');
$(this).prop('disabled', true);
$('#testPLEX-result').html(loading);
$.get(sbRoot + '/home/testPLEX', {'host': plex_host, 'username': plex_username, 'password': plex_password})
.done(function (data) {
$('#testPLEX-result').html(data);
$('#testPLEX').prop('disabled', false);
});
});
$('#testPMC-result').html(loading);
$.get(sbRoot + '/home/testPMC', {'host': plex_host, 'username': plex_username, 'password': plex_password})
.done(function (data) {
$('#testPMC-result').html(data);
$('#testPMC').prop('disabled', false);
});
});
$('#testPMS').click(function () {
var plex_server_host = $.trim($('#plex_server_host').val());
var plex_username = $.trim($('#plex_username').val());
var plex_password = $.trim($('#plex_password').val());
var plex_server_token = $.trim($('#plex_server_token').val());
if (!plex_server_host) {
$('#testPMS-result').html('Please fill out the necessary fields above.');
$('#plex_server_host').addClass('warning');
return;
}
$('#plex_server_host').removeClass('warning');
$(this).prop('disabled', true);
$('#testPMS-result').html(loading);
$.get(sbRoot + '/home/testPMS', {'host': plex_server_host, 'username': plex_username, 'password': plex_password, 'plex_server_token': plex_server_token})
.done(function (data) {
$('#testPMS-result').html(data);
$('#testPMS').prop('disabled', false);
});
});
$('#testBoxcar').click(function() {
var boxcar_username = $.trim($('#boxcar_username').val());
......
......@@ -150,6 +150,12 @@ $(document).ready(function(){
$(torrent_verify_rtorrent).show();
$(torrent_auth_type_option).show();
//$('#directory_title').text(client + directory);
} else if ('qbittorrent' == selectedProvider){
client = 'qbittorrent';
$(torrent_path_option).hide();
$(torrent_label_option).hide();
$(torrent_label_anime_option).hide();
$('#host_desc_torrent').text('URL to your qbittorrent client (e.g. http://localhost:8080)');
}
$('#host_title').text(client + host);
$('#username_title').text(client + username);
......
......@@ -259,5 +259,5 @@ $(document).ready(function () {
sceneAbsolute = m[1];
}
setAbsoluteSceneNumbering(forAbsolute, sceneAbsolute);
});
});
});
This diff is collapsed.
......@@ -38,7 +38,7 @@ from sickbeard import providers, metadata, config, webserveInit
from sickbeard.providers.generic import GenericProvider
from providers import ezrss, btn, newznab, womble, thepiratebay, oldpiratebay, torrentleech, kat, iptorrents, \
omgwtfnzbs, scc, hdtorrents, torrentday, hdbits, hounddawgs, nextgen, speedcd, nyaatorrents, animenzb, torrentbytes, animezb, \
freshontv, morethantv, bitsoup, t411, tokyotoshokan, shazbat, rarbg, alpharatio, tntvillage, binsearch, eztv
freshontv, morethantv, bitsoup, t411, tokyotoshokan, shazbat, rarbg, alpharatio, tntvillage, binsearch, eztv, scenetime
from sickbeard.config import CheckSection, check_setting_int, check_setting_str, check_setting_float, ConfigMigrator, \
naming_ep_type
from sickbeard import searchBacklog, showUpdater, versionChecker, properFinder, autoPostProcesser, \
......@@ -482,7 +482,6 @@ COMING_EPS_LAYOUT = None
COMING_EPS_DISPLAY_PAUSED = False
COMING_EPS_SORT = None
COMING_EPS_MISSED_RANGE = None
DISPLAY_FILESIZE = False
FUZZY_DATING = False
TRIM_ZERO = False
DATE_PRESET = None
......@@ -802,7 +801,7 @@ 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', 'utorrent', 'transmission', 'deluge', 'download_station', 'rtorrent', 'qbittorrent'):
TORRENT_METHOD = 'blackhole'
DOWNLOAD_PROPERS = bool(check_setting_int(CFG, 'General', 'download_propers', 1))
......@@ -1123,7 +1122,6 @@ def initialize(consoleLogging=True):
COMING_EPS_DISPLAY_PAUSED = bool(check_setting_int(CFG, 'GUI', 'coming_eps_display_paused', 0))
COMING_EPS_SORT = check_setting_str(CFG, 'GUI', 'coming_eps_sort', 'date')
COMING_EPS_MISSED_RANGE = check_setting_int(CFG, 'GUI', 'coming_eps_missed_range', 7)
DISPLAY_FILESIZE = bool(check_setting_int(CFG, 'GUI', 'display_filesize', 0))
FUZZY_DATING = bool(check_setting_int(CFG, 'GUI', 'fuzzy_dating', 0))
TRIM_ZERO = bool(check_setting_int(CFG, 'GUI', 'trim_zero', 0))
DATE_PRESET = check_setting_str(CFG, 'GUI', 'date_preset', '%x')
......@@ -2040,7 +2038,6 @@ def save_config():
new_config['GUI']['coming_eps_display_paused'] = int(COMING_EPS_DISPLAY_PAUSED)
new_config['GUI']['coming_eps_sort'] = COMING_EPS_SORT
new_config['GUI']['coming_eps_missed_range'] = int(COMING_EPS_MISSED_RANGE)
new_config['GUI']['display_filesize'] = int(DISPLAY_FILESIZE)
new_config['GUI']['fuzzy_dating'] = int(FUZZY_DATING)
new_config['GUI']['trim_zero'] = int(TRIM_ZERO)
new_config['GUI']['date_preset'] = DATE_PRESET
......
......@@ -276,6 +276,6 @@ class UIError():
"""
def __init__(self, message):
self.title = sys.exc_info()[-2]
self.title = sys.exc_info()[-2] or message
self.message = message
self.time = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
\ No newline at end of file
......@@ -20,7 +20,8 @@ __all__ = ['utorrent',
'transmission',
'deluge',
'download_station',
'rtorrent'
'rtorrent',
'qbittorrent'
]
import sickbeard
......@@ -29,13 +30,28 @@ from os import sys
# Mapping error status codes to official W3C names
http_error_code = {
100: 'Continue',
101: 'Switching Protocols',
102: 'Processing',
200: 'OK',
201: 'Created',
202: 'Accepted',
203: 'Non-Authoritative Information',
204: 'No Content',
205: 'Reset Content',
206: 'Partial Content',
207: 'Multi-Status',
208: 'Already Reported',
226: 'IM Used',
300: 'Multiple Choices',
301: 'Moved Permanently',
302: 'Found',
303: 'See Other',
304: 'Not Modified',
305: 'Use Proxy',
306: 'Switch Proxy',
307: 'Temporary Redirect',
308: 'Permanent Redirect',
400: 'Bad Request',
401: 'Unauthorized',
402: 'Payment Required',
......@@ -54,13 +70,45 @@ http_error_code = {
415: 'Unsupported Media Type',
416: 'Requested Range Not Satisfiable',
417: 'Expectation Failed',
418: 'Im a teapot',
419: 'Authentication Timeout',
420: 'Enhance Your Calm',
422: 'Unprocessable Entity',
423: 'Locked',
424: 'Failed Dependency',
426: 'Upgrade Required',
428: 'Precondition Required',
429: 'Too Many Requests',
431: 'Request Header Fields Too Large',
440: 'Login Timeout',
444: 'No Response',
449: 'Retry With',
450: 'Blocked by Windows Parental Controls',
451: 'Redirect',
451: 'Unavailable For Legal Reasons',
494: 'Request Header Too Large',
495: 'Cert Error',
496: 'No Cert',
497: 'HTTP to HTTPS',
498: 'Token expired/invalid',
499: 'Client Closed Request',
499: 'Token required',
500: 'Internal Server Error',
501: 'Not Implemented',
502: 'Bad Gateway',
503: 'Service Unavailable',
504: 'Gateway Timeout',
505: 'HTTP Version Not Supported',
524: 'Request to host timedout waiting for reply back'
506: 'Variant Also Negotiates',
507: 'Insufficient Storage',
508: 'Loop Detected',
509: 'Bandwidth Limit Exceeded',
510: 'Not Extended',
511: 'Network Authentication Required',
522: 'Cloudfare Connection timed out',
524: 'Request to host timedout waiting for reply back',
598: 'Network read timeout error',
599: 'Network connect timeout error '
}
default_host = {'utorrent': 'http://localhost:8000',
......@@ -68,6 +116,7 @@ default_host = {'utorrent': 'http://localhost:8000',
'deluge': 'http://localhost:8112',
'download_station': 'http://localhost:5000',
'rtorrent': 'scgi://localhost:5000',
'qbittorrent': 'http://localhost:8080'
}
......@@ -82,4 +131,4 @@ def getClientIstance(name):
module = getClientModule(name)
className = module.api.__class__.__name__
return getattr(module, className)
\ No newline at end of file
return getattr(module, className)
......@@ -61,7 +61,7 @@ class GenericClient(object):
logger.log(self.name + u': Invalid HTTP Request ' + str(e), logger.ERROR)
return False
except requests.exceptions.Timeout, e:
logger.log(self.name + u': Connection Timeout ' + str(e), logger.ERROR)
logger.log(self.name + u': Connection Timeout ' + str(e), logger.WARNING)
return False
except Exception, e:
logger.log(self.name + u': Unknown exception raised when send torrent to ' + self.name + ': ' + str(e),
......
# Author: Mr_Orange <[email protected]>
# URL: http://code.google.com/p/sickbeard/
#
# This file is part of SickRage.
#
# SickRage 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.
#
# SickRage 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 SickRage. If not, see <http://www.gnu.org/licenses/>.
import sickbeard
from sickbeard import logger
from sickbeard.clients.generic import GenericClient
from lib import requests
from lib.requests.auth import HTTPDigestAuth
class qbittorrentAPI(GenericClient):
def __init__(self, host=None, username=None, password=None):
super(qbittorrentAPI, self).__init__('qbittorrent', host, username, password)
self.url = self.host
self.session.auth = HTTPDigestAuth(self.username, self.password);
def _get_auth(self):
try:
self.response = self.session.get(self.host, verify=False)
self.auth = self.response.content
except:
return None
return self.auth if not self.response.status_code == 404 else None
def _add_torrent_uri(self, result):
self.url = self.host+'command/download'
data = {'urls': result.url}
return self._request(method='post', data=data)
def _add_torrent_file(self, result):
self.url = self.host+'command/upload'
files = {'torrents': (result.name + '.torrent', result.content)}
return self._request(method='post', files=files)
def _set_torrent_priority(self, result):
self.url = self.host+'command/decreasePrio '
if result.priority == 1:
self.url = self.host+'command/increasePrio'
data = {'hashes': result.hash}
return self._request(method='post', data=data)
def _set_torrent_pause(self, result):
self.url = self.host+'command/resume'
if sickbeard.TORRENT_PAUSED:
self.url = self.host+'command/pause'
data = {'hash': result.hash}
return self._request(method='post', data=data)
api = qbittorrentAPI()
\ No newline at end of file
......@@ -230,7 +230,7 @@ def change_DOWNLOAD_PROPERS(download_propers):
else:
sickbeard.properFinderScheduler.enable = False
sickbeard.traktCheckerScheduler.silent = True
logger.log(u"Waiting for the PROPERFINDER thread to exit", logger.INFO)
logger.log(u"Stopping PROPERFINDER thread", logger.INFO)
def change_USE_TRAKT(use_trakt):
use_trakt = checkbox_to_value(use_trakt)
......
......@@ -20,6 +20,21 @@ import os
import chardet
import sickbeard
def fixStupidEncodings(x, silent=False):
if type(x) == str:
try:
return x.decode(sickbeard.SYS_ENCODING)
except UnicodeDecodeError:
logger.log(u"Unable to decode value: " + repr(x), logger.ERROR)
return None
elif type(x) == unicode:
return x
else:
logger.log(
u"Unknown value passed in, ignoring it: " + str(type(x)) + " (" + repr(x) + ":" + repr(type(x)) + ")",
logger.DEBUG if silent else logger.ERROR)
return None
def _toUnicode(x):
try:
if not isinstance(x, unicode):
......
......@@ -1037,6 +1037,9 @@ def validateShow(show, season=None, episode=None):
if indexer_lang and not indexer_lang == sickbeard.INDEXER_DEFAULT_LANGUAGE:
lINDEXER_API_PARMS['language'] = indexer_lang
if show.dvdorder != 0:
lINDEXER_API_PARMS['dvdorder'] = True
t = sickbeard.indexerApi(show.indexer).indexer(**lINDEXER_API_PARMS)
if season is None and episode is None:
return t
......@@ -1247,6 +1250,16 @@ def _getTempDir():
return os.path.join(tempfile.gettempdir(), "sickrage-%s" % (uid))
def codeDescription(status_code):
"""
Returns the description of the URL error code
"""
if status_code in clients.http_error_code:
return clients.http_error_code[status_code]
else:
logger.log(u"Unknown error code. Please submit an issue", logger.WARNING)
return 'unknown'
def getURL(url, post_data=None, params=None, headers={}, timeout=30, session=None, json=False, proxyGlypeProxySSLwarning=None):
"""
Returns a byte-string retrieved from the url provider.
......@@ -1283,7 +1296,7 @@ def getURL(url, post_data=None, params=None, headers={}, timeout=30, session=Non
if not resp.ok:
logger.log(u"Requested url " + url + " returned status code is " + str(
resp.status_code) + ': ' + clients.http_error_code[resp.status_code], logger.DEBUG)
resp.status_code) + ': ' + codeDescription(resp.status_code), logger.DEBUG)
return
if proxyGlypeProxySSLwarning is not None:
......@@ -1292,7 +1305,7 @@ def getURL(url, post_data=None, params=None, headers={}, timeout=30, session=Non
if not resp.ok:
logger.log(u"GlypeProxySSLwarning: Requested url " + url + " returned status code is " + str(
resp.status_code) + ': ' + clients.http_error_code[resp.status_code], logger.DEBUG)
resp.status_code) + ': ' + codeDescription(resp.status_code), logger.DEBUG)
return
except requests.exceptions.HTTPError, e:
......@@ -1334,9 +1347,10 @@ def download_file(url, filename, session=None):
try:
resp = session.get(url)
if not resp.ok:
logger.log(u"Requested url " + url + " returned status code is " + str(
resp.status_code) + ': ' + clients.http_error_code[resp.status_code], logger.DEBUG)
resp.status_code) + ': ' + codeDescription(resp.status_code), logger.DEBUG)
return False
with open(filename, 'wb') as fp:
......@@ -1409,7 +1423,11 @@ def get_size(start_path='.'):
for dirpath, dirnames, filenames in ek.ek(os.walk, start_path):
for f in filenames:
fp = ek.ek(os.path.join, dirpath, f)
total_size += ek.ek(os.path.getsize, fp)
try:
total_size += ek.ek(os.path.getsize, fp)
except OSError as e:
logger.log('Unable to get size for file {filePath}. Error msg is: {errorMsg}'.format(filePath=fp, errorMsg=str(e)), logger.ERROR)
logger.log(traceback.format_exc(), logger.DEBUG)
return total_size
def generateApiKey():
......@@ -1537,4 +1555,4 @@ def pretty_time_delta(seconds):
elif minutes > 0:
return '%s%02dm%02ds' % (sign_string, minutes, seconds)
else:
return '%s%02ds' % (sign_string, seconds)
\ No newline at end of file
return '%s%02ds' % (sign_string, seconds)
......@@ -951,11 +951,6 @@ class GenericMetadata():
name = showXML.findtext('title')
try:
indexer = int(showXML.findtext('indexer'))
except:
indexer = None
if showXML.findtext('tvdbid') != None:
indexer_id = int(showXML.findtext('tvdbid'))
elif showXML.findtext('id') != None:
......@@ -968,6 +963,18 @@ class GenericMetadata():
logger.log(u"Invalid Indexer ID (" + str(indexer_id) + "), not using metadata file", logger.WARNING)
return empty_return
indexer = None
if showXML.findtext('indexer') != None:
indexer = int(showXML.findtext('indexer'))
elif showXML.find('episodeguide/url') != None:
epg_url = showXML.findtext('episodeguide/url').lower()
if str(indexer_id) in epg_url:
if 'thetvdb.com' in epg_url:
indexer = 1
elif 'tvrage' in epg_url:
indexer = 2
except Exception, e:
logger.log(
u"There was an error parsing your existing metadata file: '" + metadata_path + "' error: " + ex(e),
......
......@@ -153,11 +153,8 @@ class KODI_12PlusMetadata(generic.GenericMetadata):
episodeguide = etree.SubElement(tv_node, "episodeguide")
episodeguideurl = etree.SubElement(episodeguide, "url")
episodeguideurl2 = etree.SubElement(tv_node, "episodeguideurl")
if getattr(myShow, 'id', None) is not None:
showurl = sickbeard.indexerApi(show_obj.indexer).config['base_url'] + str(myShow["id"]) + '/all/en.zip'
episodeguideurl.text = showurl
episodeguideurl2.text = showurl
episodeguideurl.text = sickbeard.indexerApi(show_obj.indexer).config['base_url'] + str(myShow["id"]) + '/all/en.zip'