diff --git a/gui/slick/images/network/freeform.png b/gui/slick/images/network/freeform.png new file mode 100644 index 0000000000000000000000000000000000000000..338766efda25c2c6e8b55a798ee16978730f2aba Binary files /dev/null and b/gui/slick/images/network/freeform.png differ diff --git a/gui/slick/js/core.js b/gui/slick/js/core.js index c4cb8db07296728bce0703b45c6b19b26fb3d8cb..63a2a53c5d84fb6c9af01b58780ccb8aba837982 100644 --- a/gui/slick/js/core.js +++ b/gui/slick/js/core.js @@ -45,6 +45,15 @@ function isMeta(pyVar, result){ var SICKRAGE = { common: { init: function() { + (function init() { + var imgDefer = document.getElementsByTagName('img'); + for (var i=0; i<imgDefer.length; i++) { + if(imgDefer[i].getAttribute('data-src')) { + imgDefer[i].setAttribute('src',imgDefer[i].getAttribute('data-src')); + } + } + })(); + $.confirm.options = { confirmButton: "Yes", cancelButton: "Cancel", @@ -379,27 +388,27 @@ var SICKRAGE = { }); }); - $('#testPMC').on('click', function () { + $('#testPHT').on('click', function () { var plex = {}; plex.client = {}; - plex.client.host = $.trim($('#plex_host').val()); + plex.client.host = $.trim($('#plex_client_host').val()); plex.client.username = $.trim($('#plex_client_username').val()); plex.client.password = $.trim($('#plex_client_password').val()); if (!plex.client.host) { - $('#testPMC-result').html('Please fill out the necessary fields above.'); - $('#plex_host').addClass('warning'); + $('#testPHT-result').html('Please fill out the necessary fields above.'); + $('#plex_client_host').addClass('warning'); return; } - $('#plex_host').removeClass('warning'); + $('#plex_client_host').removeClass('warning'); $(this).prop('disabled', true); - $('#testPMC-result').html(loading); - $.get(srRoot + '/home/testPMC', { + $('#testPHT-result').html(loading); + $.get(srRoot + '/home/testPHT', { 'host': plex.client.host, 'username': plex.client.username, 'password': plex.client.password }).done(function (data) { - $('#testPMC-result').html(data); - $('#testPMC').prop('disabled', false); + $('#testPHT-result').html(data); + $('#testPHT').prop('disabled', false); }); }); @@ -407,8 +416,8 @@ var SICKRAGE = { var plex = {}; plex.server = {}; plex.server.host = $.trim($('#plex_server_host').val()); - plex.username = $.trim($('#plex_username').val()); - plex.password = $.trim($('#plex_password').val()); + plex.server.username = $.trim($('#plex_server_username').val()); + plex.server.password = $.trim($('#plex_server_password').val()); plex.server.token = $.trim($('#plex_server_token').val()); if (!plex.server.host) { $('#testPMS-result').html('Please fill out the necessary fields above.'); @@ -420,8 +429,8 @@ var SICKRAGE = { $('#testPMS-result').html(loading); $.get(srRoot + '/home/testPMS', { 'host': plex.server.host, - 'username': plex.username, - 'password': plex.password, + 'username': plex.server.username, + 'password': plex.server.password, 'plex_server_token': plex.server.token }).done(function (data) { $('#testPMS-result').html(data); @@ -981,7 +990,7 @@ var SICKRAGE = { }); // show instructions for plex when enabled - $('#use_plex').on('click', function() { + $('#use_plex_server').on('click', function() { if ($(this).is(':checked')) { $('.plexinfo').removeClass('hide'); } else { @@ -1793,11 +1802,11 @@ var SICKRAGE = { }); // Handle filtering in the poster layout - $('#filterShowName').on('input', _.debounce(function (e) { + $('#filterShowName').on('input', _.debounce(function() { $('.show-grid').isotope({ filter: function () { - var name = $('div.show-title', this).text(); - return (name.toLowerCase().indexOf(e.target.value.toLowerCase()) !== -1); + var name = $(this).data('name'); + return name.toLowerCase(); } }); }, 500)); @@ -1885,7 +1894,6 @@ var SICKRAGE = { 5: function(node) { return $(node).find("span:first").text(); }, 6: function(node) { return $(node).data('show-size'); }, 7: function(node) { return $(node).find("img").attr("alt"); } - }, widgets: ['saveSort', 'zebra', 'stickyHeaders', 'filter', 'columnSelector'], headers: { diff --git a/gui/slick/js/core.min.js b/gui/slick/js/core.min.js index 1036343312e0c8d5b50291c3921a2d96bca097cc..98337456ec2605e5f2ee671b6fc41e02297cb43c 100644 Binary files a/gui/slick/js/core.min.js and b/gui/slick/js/core.min.js differ diff --git a/gui/slick/views/config_general.mako b/gui/slick/views/config_general.mako index 0f792f56b71368ab036546b4a7df79f0cf8cb23c..feb4cbffe73fcc2c410226addc1e4ba2a1bf576c 100644 --- a/gui/slick/views/config_general.mako +++ b/gui/slick/views/config_general.mako @@ -750,17 +750,6 @@ </span> </label> </div> - - <div class="field-pair" hidden> - <label for="git_autoissues"> - <span class="component-title">Git auto-issues submit</span> - <span class="component-desc"> - <input type="checkbox" name="git_autoissues" id="git_autoissues" ${('', 'checked="checked"')[bool(sickbeard.GIT_AUTOISSUES)]} disable/> - <p>automatically submit bug/issue reports to our issue tracker when errors are logged</p> - </span> - </label> - </div> - <input type="submit" class="btn config_submitter" value="Save Changes" /> </fieldset> diff --git a/gui/slick/views/config_notifications.mako b/gui/slick/views/config_notifications.mako index 98953e2c31c6b8b46a51c2eec0dc53a8f644fbb4..ac84c8e66d8d1bcbdfc9221543b7605f294b9c42 100644 --- a/gui/slick/views/config_notifications.mako +++ b/gui/slick/views/config_notifications.mako @@ -37,7 +37,7 @@ <span class="component-title">Enable</span> <span class="component-desc"> <input type="checkbox" class="enabler" name="use_kodi" id="use_kodi" ${('', 'checked="checked"')[bool(sickbeard.USE_KODI)]}/> - <p>should SickRage send KODI commands ?<p> + <p>Send KODI commands?<p> </span> </label> </div> @@ -48,7 +48,7 @@ <span class="component-title">Always on</span> <span class="component-desc"> <input type="checkbox" name="kodi_always_on" id="kodi_always_on" ${('', 'checked="checked"')[bool(sickbeard.KODI_ALWAYS_ON)]}/> - <p>log errors when unreachable ?</p> + <p>log errors when unreachable?</p> </span> </label> </div> @@ -57,7 +57,7 @@ <span class="component-title">Notify on snatch</span> <span class="component-desc"> <input type="checkbox" name="kodi_notify_onsnatch" id="kodi_notify_onsnatch" ${('', 'checked="checked"')[bool(sickbeard.KODI_NOTIFY_ONSNATCH)]}/> - <p>send a notification when a download starts ?</p> + <p>send a notification when a download starts?</p> </span> </label> </div> @@ -66,7 +66,7 @@ <span class="component-title">Notify on download</span> <span class="component-desc"> <input type="checkbox" name="kodi_notify_ondownload" id="kodi_notify_ondownload" ${('', 'checked="checked"')[bool(sickbeard.KODI_NOTIFY_ONDOWNLOAD)]}/> - <p>send a notification when a download finishes ?</p> + <p>send a notification when a download finishes?</p> </span> </label> </div> @@ -75,7 +75,7 @@ <span class="component-title">Notify on subtitle download</span> <span class="component-desc"> <input type="checkbox" name="kodi_notify_onsubtitledownload" id="kodi_notify_onsubtitledownload" ${('', 'checked="checked"')[bool(sickbeard.KODI_NOTIFY_ONSUBTITLEDOWNLOAD)]}/> - <p>send a notification when subtitles are downloaded ?</p> + <p>send a notification when subtitles are downloaded?</p> </span> </label> </div> @@ -84,7 +84,7 @@ <span class="component-title">Update library</span> <span class="component-desc"> <input type="checkbox" name="kodi_update_library" id="kodi_update_library" ${('', 'checked="checked"')[bool(sickbeard.KODI_UPDATE_LIBRARY)]}/> - <p>update KODI library when a download finishes ?</p> + <p>update KODI library when a download finishes?</p> </span> </label> </div> @@ -93,7 +93,7 @@ <span class="component-title">Full library update</span> <span class="component-desc"> <input type="checkbox" name="kodi_update_full" id="kodi_update_full" ${('', 'checked="checked"')[bool(sickbeard.KODI_UPDATE_FULL)]}/> - <p>perform a full library update if update per-show fails ?</p> + <p>perform a full library update if update per-show fails?</p> </span> </label> </div> @@ -102,7 +102,7 @@ <span class="component-title">Only update first host</span> <span class="component-desc"> <input type="checkbox" name="kodi_update_onlyfirst" id="kodi_update_onlyfirst" ${('', 'checked="checked"')[bool(sickbeard.KODI_UPDATE_ONLYFIRST)]}/> - <p>only send library updates to the first active host ?</p> + <p>only send library updates to the first active host?</p> </span> </label> </div> @@ -122,7 +122,7 @@ </div> <div class="field-pair"> <label for="kodi_username"> - <span class="component-title">KODI username</span> + <span class="component-title">Username</span> <input type="text" name="kodi_username" id="kodi_username" value="${sickbeard.KODI_USERNAME}" class="form-control input-sm input250" autocapitalize="off" autocomplete="no" /> </label> <label> @@ -132,7 +132,7 @@ </div> <div class="field-pair"> <label for="kodi_password"> - <span class="component-title">KODI password</span> + <span class="component-title">Password</span> <input type="password" name="kodi_password" id="kodi_password" value="${sickbeard.KODI_PASSWORD}" class="form-control input-sm input250" autocomplete="no" autocapitalize="off" /> </label> <label> @@ -149,7 +149,6 @@ </div><!-- /kodi component-group //--> - <div class="component-group"> <div class="component-group-desc"> <img class="notifier-icon" src="${srRoot}/images/notifiers/plex.png" alt="" title="Plex Media Server" /> @@ -159,16 +158,16 @@ </div> <fieldset class="component-group-list"> <div class="field-pair"> - <label for="use_plex"> + <label for="use_plex_server"> <span class="component-title">Enable</span> <span class="component-desc"> - <input type="checkbox" class="enabler" name="use_plex" id="use_plex" ${('', 'checked="checked"')[bool(sickbeard.USE_PLEX)]}/> - <p>should SickRage send Plex commands ?</p> + <input type="checkbox" class="enabler" name="use_plex_server" id="use_plex_server" ${('', 'checked="checked"')[bool(sickbeard.USE_PLEX_SERVER)]}/> + <p>Send Plex Media Server library updates?</p> </span> </label> </div> - <div id="content_use_plex"> + <div id="content_use_plex_server"> <div class="field-pair"> <label for="plex_server_token"> <span class="component-title">Plex Media Server Auth Token</span> @@ -185,29 +184,28 @@ </div> <div class="component-group" style="padding: 0; min-height: 130px"> <div class="field-pair"> - <label for="plex_username"> - <span class="component-title">Server Username</span> + <label for="plex_server_username"> + <span class="component-title">Username</span> <span class="component-desc"> - <input type="text" name="plex_username" id="plex_username" value="${sickbeard.PLEX_USERNAME}" class="form-control input-sm input250" autocapitalize="off" autocomplete="no" /> + <input type="text" name="plex_server_username" id="plex_server_username" value="${sickbeard.PLEX_SERVER_USERNAME}" class="form-control input-sm input250" autocapitalize="off" autocomplete="no" /> <p>blank = no authentication</p> </span> </label> </div> <div class="field-pair"> - <label for="plex_password"> - <span class="component-title">Server/client password</span> + <label for="plex_server_password"> + <span class="component-title">Password</span> <span class="component-desc"> - <input type="password" name="plex_password" id="plex_password" value="${'*' * len(sickbeard.PLEX_PASSWORD)}" class="form-control input-sm input250" autocomplete="no" autocapitalize="off" /> + <input type="password" name="plex_server_password" id="plex_server_password" value="${'*' * len(sickbeard.PLEX_SERVER_PASSWORD)}" class="form-control input-sm input250" autocomplete="no" autocapitalize="off" /> <p>blank = no authentication</p> </span> </label> </div> </div> - <div class="component-group" style="padding: 0; min-height: 50px"> <div class="field-pair"> <label for="plex_update_library"> - <span class="component-title">Update server library</span> + <span class="component-title">Update Library</span> <span class="component-desc"> <input type="checkbox" class="enabler" name="plex_update_library" id="plex_update_library" ${('', 'checked="checked"')[bool(sickbeard.PLEX_UPDATE_LIBRARY)]}/> <p>update Plex Media Server library when a download finishes</p> @@ -226,31 +224,39 @@ </span> </label> </div> - <div class="field-pair"> - <div class="testNotification" id="testPMS-result">Click below to test Plex server(s)</div> - <input class="btn" type="button" value="Test Plex Server" id="testPMS" /> + <label for="plex_server_https"> + <span class="component-title">HTTPS</span> + <span class="component-desc"> + <input type="checkbox" name="plex_server_https" id="plex_server_https" ${('', 'checked="checked"')[bool(sickbeard.PLEX_SERVER_HTTPS)]}/> + <p>use https for plex media server requests?</p> + </span> + </label> + </div> + <div class="field-pair"> + <div class="testNotification" id="testPMS-result">Click below to test Plex Media Server(s)</div> + <input class="btn" type="button" value="Test Plex Media Server" id="testPMS" /> <input type="submit" class="config_submitter btn" value="Save Changes" /> <div class="clear-left"> </div> </div> </div> </div> - </div><!-- /content_use_plex --> + </div><!-- /content_use_plex_server --> </fieldset> </div><!-- /plex media server component-group --> <div class="component-group"> <div class="component-group-desc"> - <img class="notifier-icon" src="${srRoot}/images/notifiers/plex.png" alt="" title="Plex Media Client" /> - <h3><a href="${anon_url('http://www.plexapp.com/')}" rel="noreferrer" onclick="window.open(this.href, '_blank'); return false;">Plex Media Client</a></h3> + <img class="notifier-icon" src="${srRoot}/images/notifiers/plex.png" alt="" title="Plex Home Theater" /> + <h3><a href="${anon_url('http://www.plexapp.com/')}" rel="noreferrer" onclick="window.open(this.href, '_blank'); return false;">Plex Home Theater</a></h3> </div> <fieldset class="component-group-list"> <div class="field-pair"> <label for="use_plex_client"> <span class="component-title">Enable</span> <span class="component-desc"> - <input type="checkbox" class="enabler" name="use_plex" id="use_plex_client" ${('', 'checked="checked"')[bool(sickbeard.USE_PLEX_CLIENT)]}/> - <p>should SickRage send Plex commands ?</p> + <input type="checkbox" class="enabler" name="use_plex_client" id="use_plex_client" ${('', 'checked="checked"')[bool(sickbeard.USE_PLEX_CLIENT)]}/> + <p>Send Plex Home Theater notifications?</p> </span> </label> </div> @@ -261,7 +267,7 @@ <span class="component-title">Notify on snatch</span> <span class="component-desc"> <input type="checkbox" name="plex_notify_onsnatch" id="plex_notify_onsnatch" ${('', 'checked="checked"')[bool(sickbeard.PLEX_NOTIFY_ONSNATCH)]}/> - <p>send a notification when a download starts ?</p> + <p>send a notification when a download starts?</p> </span> </label> </div> @@ -270,7 +276,7 @@ <span class="component-title">Notify on download</span> <span class="component-desc"> <input type="checkbox" name="plex_notify_ondownload" id="plex_notify_ondownload" ${('', 'checked="checked"')[bool(sickbeard.PLEX_NOTIFY_ONDOWNLOAD)]}/> - <p>send a notification when a download finishes ?</p> + <p>send a notification when a download finishes?</p> </span> </label> </div> @@ -279,25 +285,25 @@ <span class="component-title">Notify on subtitle download</span> <span class="component-desc"> <input type="checkbox" name="plex_notify_onsubtitledownload" id="plex_notify_onsubtitledownload" ${('', 'checked="checked"')[bool(sickbeard.PLEX_NOTIFY_ONSUBTITLEDOWNLOAD)]}/> - <p>send a notification when subtitles are downloaded ?</p> + <p>send a notification when subtitles are downloaded?</p> </span> </label> </div> <div class="field-pair"> - <label for="plex_host"> - <span class="component-title">Plex Client IP:Port</span> + <label for="plex_client_host"> + <span class="component-title">Plex Home Theater IP:Port</span> <span class="component-desc"> - <input type="text" name="plex_host" id="plex_host" value="${sickbeard.PLEX_HOST}" class="form-control input-sm input350" autocapitalize="off" /> + <input type="text" name="plex_client_host" id="plex_client_host" value="${sickbeard.PLEX_CLIENT_HOST}" class="form-control input-sm input350" autocapitalize="off" /> <div class="clear-left"> - <p>one or more hosts running Plex client<br>(eg. 192.168.1.100:3000, 192.168.1.101:3000)</p> + <p>one or more hosts running Plex Home Theater<br>(eg. 192.168.1.100:3000, 192.168.1.101:3000)</p> </div> </span> </label> </div> <div class="component-group" style="padding: 0; min-height: 130px"> <div class="field-pair"> - <label for="plex_username"> - <span class="component-title">Server Username</span> + <label for="plex_server_username"> + <span class="component-title">Username</span> <span class="component-desc"> <input type="text" name="plex_client_username" id="plex_client_username" value="${sickbeard.PLEX_CLIENT_USERNAME}" class="form-control input-sm input250" autocapitalize="off" autocomplete="no" /> <p>blank = no authentication</p> @@ -306,7 +312,7 @@ </div> <div class="field-pair"> <label for="plex_client_password"> - <span class="component-title">Client Password</span> + <span class="component-title">Password</span> <span class="component-desc"> <input type="password" name="plex_client_password" id="plex_client_password" value="${'*' * len(sickbeard.PLEX_CLIENT_PASSWORD)}" class="form-control input-sm input250" autocomplete="no" autocapitalize="off" /> <p>blank = no authentication</p> @@ -316,14 +322,14 @@ </div> <div class="field-pair"> - <div class="testNotification" id="testPMC-result">Click below to test Plex client(s)</div> - <input class="btn" type="button" value="Test Plex Client" id="testPMC" /> + <div class="testNotification" id="testPHT-result">Click below to test Plex Home Theater(s)</div> + <input class="btn" type="button" value="Test Plex Home Theater" id="testPHT" /> <input type="submit" class="config_submitter btn" value="Save Changes" /> - <div class=clear-left><p>Note: some Plex clients <b class="boldest">do not</b> support notifications e.g. Plexapp for Samsung TVs</p></div> + <div class=clear-left><p>Note: some Plex Home Theaters <b class="boldest">do not</b> support notifications e.g. Plexapp for Samsung TVs</p></div> </div> </div><!-- /content_use_plex_client --> </fieldset> - </div><!-- /plex client component-group --> + </div><!-- /Plex Home Theater component-group --> <div class="component-group"> @@ -338,7 +344,7 @@ <span class="component-title">Enable</span> <span class="component-desc"> <input type="checkbox" class="enabler" name="use_emby" id="use_emby" ${('', 'checked="checked"')[bool(sickbeard.USE_EMBY)]} /> - <p>should SickRage send update commands to Emby?<p> + <p>Send update commands to Emby?<p> </span> </label> </div> @@ -380,7 +386,7 @@ <span class="component-title">Enable</span> <span class="component-desc"> <input type="checkbox" class="enabler" name="use_nmj" id="use_nmj" ${('', 'checked="checked"')[bool(sickbeard.USE_NMJ)]}/> - <p>should SickRage send update commands to NMJ ?</p> + <p>Send update commands to NMJ?</p> </span> </label> </div> @@ -446,7 +452,7 @@ <span class="component-title">Enable</span> <span class="component-desc"> <input type="checkbox" class="enabler" name="use_nmjv2" id="use_nmjv2" ${('', 'checked="checked"')[bool(sickbeard.USE_NMJv2)]}/> - <p>should SickRage send update commands to NMJv2 ?</p> + <p>Send update commands to NMJv2?</p> </span> </label> </div> @@ -536,7 +542,7 @@ <span class="component-title">Enable</span> <span class="component-desc"> <input type="checkbox" class="enabler" name="use_synoindex" id="use_synoindex" ${('', 'checked="checked"')[bool(sickbeard.USE_SYNOINDEX)]}/> - <p>should SickRage send Synology notifications ?</p> + <p>Send Synology notifications?</p> </span> </label> <label> @@ -566,7 +572,7 @@ <span class="component-title">Enable</span> <span class="component-desc"> <input type="checkbox" class="enabler" name="use_synologynotifier" id="use_synologynotifier" ${('', 'checked="checked"')[bool(sickbeard.USE_SYNOLOGYNOTIFIER)]}/> - <p>should SickRage send notifications to the Synology Notifier ?</p> + <p>Send notifications to the Synology Notifier?</p> </span> </label> <label> @@ -580,7 +586,7 @@ <span class="component-title">Notify on snatch</span> <span class="component-desc"> <input type="checkbox" name="synologynotifier_notify_onsnatch" id="synologynotifier_notify_onsnatch" ${('', 'checked="checked"')[bool(sickbeard.SYNOLOGYNOTIFIER_NOTIFY_ONSNATCH)]}/> - <p>send a notification when a download starts ?</p> + <p>send a notification when a download starts?</p> </span> </label> </div> @@ -589,7 +595,7 @@ <span class="component-title">Notify on download</span> <span class="component-desc"> <input type="checkbox" name="synologynotifier_notify_ondownload" id="synologynotifier_notify_ondownload" ${('', 'checked="checked"')[bool(sickbeard.SYNOLOGYNOTIFIER_NOTIFY_ONDOWNLOAD)]}/> - <p>send a notification when a download finishes ?</p> + <p>send a notification when a download finishes?</p> </span> </label> </div> @@ -598,7 +604,7 @@ <span class="component-title">Notify on subtitle download</span> <span class="component-desc"> <input type="checkbox" name="synologynotifier_notify_onsubtitledownload" id="synologynotifier_notify_onsubtitledownload" ${('', 'checked="checked"')[bool(sickbeard.SYNOLOGYNOTIFIER_NOTIFY_ONSUBTITLEDOWNLOAD)]}/> - <p>send a notification when subtitles are downloaded ?</p> + <p>send a notification when subtitles are downloaded?</p> </span> </label> </div> @@ -620,7 +626,7 @@ <span class="component-title">Enable</span> <span class="component-desc"> <input type="checkbox" class="enabler" name="use_pytivo" id="use_pytivo" ${('', 'checked="checked"')[bool(sickbeard.USE_PYTIVO)]}/> - <p>should SickRage send notifications to pyTivo ?</p> + <p>Send notifications to pyTivo?</p> </span> </label> <label> @@ -682,7 +688,7 @@ <span class="component-title">Enable</span> <span class="component-desc"> <input type="checkbox" class="enabler" name="use_growl" id="use_growl" ${('', 'checked="checked"')[bool(sickbeard.USE_GROWL)]}/> - <p>should SickRage send Growl notifications ?</p> + <p>Send Growl notifications?</p> </span> </label> </div> @@ -693,7 +699,7 @@ <span class="component-title">Notify on snatch</span> <span class="component-desc"> <input type="checkbox" name="growl_notify_onsnatch" id="growl_notify_onsnatch" ${('', 'checked="checked"')[bool(sickbeard.GROWL_NOTIFY_ONSNATCH)]}/> - <p>send a notification when a download starts ?</p> + <p>send a notification when a download starts?</p> </span> </label> </div> @@ -702,7 +708,7 @@ <span class="component-title">Notify on download</span> <span class="component-desc"> <input type="checkbox" name="growl_notify_ondownload" id="growl_notify_ondownload" ${('', 'checked="checked"')[bool(sickbeard.GROWL_NOTIFY_ONDOWNLOAD)]}/> - <p>send a notification when a download finishes ?</p> + <p>send a notification when a download finishes?</p> </span> </label> </div> @@ -711,7 +717,7 @@ <span class="component-title">Notify on subtitle download</span> <span class="component-desc"> <input type="checkbox" name="growl_notify_onsubtitledownload" id="growl_notify_onsubtitledownload" ${('', 'checked="checked"')[bool(sickbeard.GROWL_NOTIFY_ONSUBTITLEDOWNLOAD)]}/> - <p>send a notification when subtitles are downloaded ?</p> + <p>send a notification when subtitles are downloaded?</p> </span> </label> </div> @@ -727,7 +733,7 @@ </div> <div class="field-pair"> <label for="growl_password"> - <span class="component-title">Growl password</span> + <span class="component-title">Password</span> <input type="password" name="growl_password" id="growl_password" value="${sickbeard.GROWL_PASSWORD}" class="form-control input-sm input250" autocomplete="no" autocapitalize="off" /> </label> <label> @@ -760,7 +766,7 @@ <span class="component-title">Enable</span> <span class="component-desc"> <input type="checkbox" class="enabler" name="use_prowl" id="use_prowl" ${('', 'checked="checked"')[bool(sickbeard.USE_PROWL)]}/> - <p>should SickRage send Prowl notifications ?</p> + <p>Send Prowl notifications?</p> </span> </label> </div> @@ -771,7 +777,7 @@ <span class="component-title">Notify on snatch</span> <span class="component-desc"> <input type="checkbox" name="prowl_notify_onsnatch" id="prowl_notify_onsnatch" ${('', 'checked="checked"')[bool(sickbeard.PROWL_NOTIFY_ONSNATCH)]}/> - <p>send a notification when a download starts ?</p> + <p>send a notification when a download starts?</p> </span> </label> </div> @@ -780,7 +786,7 @@ <span class="component-title">Notify on download</span> <span class="component-desc"> <input type="checkbox" name="prowl_notify_ondownload" id="prowl_notify_ondownload" ${('', 'checked="checked"')[bool(sickbeard.PROWL_NOTIFY_ONDOWNLOAD)]}/> - <p>send a notification when a download finishes ?</p> + <p>send a notification when a download finishes?</p> </span> </label> </div> @@ -789,7 +795,7 @@ <span class="component-title">Notify on subtitle download</span> <span class="component-desc"> <input type="checkbox" name="prowl_notify_onsubtitledownload" id="prowl_notify_onsubtitledownload" ${('', 'checked="checked"')[bool(sickbeard.PROWL_NOTIFY_ONSUBTITLEDOWNLOAD)]}/> - <p>send a notification when subtitles are downloaded ?</p> + <p>send a notification when subtitles are downloaded?</p> </span> </label> </div> @@ -872,7 +878,7 @@ <span class="component-title">Enable</span> <span class="component-desc"> <input type="checkbox" class="enabler" name="use_libnotify" id="use_libnotify" ${('', 'checked="checked"')[bool(sickbeard.USE_LIBNOTIFY)]}/> - <p>should SickRage send Libnotify notifications ?</p> + <p>Send Libnotify notifications?</p> </span> </label> </div> @@ -883,7 +889,7 @@ <span class="component-title">Notify on snatch</span> <span class="component-desc"> <input type="checkbox" name="libnotify_notify_onsnatch" id="libnotify_notify_onsnatch" ${('', 'checked="checked"')[bool(sickbeard.LIBNOTIFY_NOTIFY_ONSNATCH)]}/> - <p>send a notification when a download starts ?</p> + <p>send a notification when a download starts?</p> </span> </label> </div> @@ -892,7 +898,7 @@ <span class="component-title">Notify on download</span> <span class="component-desc"> <input type="checkbox" name="libnotify_notify_ondownload" id="libnotify_notify_ondownload" ${('', 'checked="checked"')[bool(sickbeard.LIBNOTIFY_NOTIFY_ONDOWNLOAD)]}/> - <p>send a notification when a download finishes ?</p> + <p>send a notification when a download finishes?</p> </span> </label> </div> @@ -901,7 +907,7 @@ <span class="component-title">Notify on subtitle download</span> <span class="component-desc"> <input type="checkbox" name="libnotify_notify_onsubtitledownload" id="libnotify_notify_onsubtitledownload" ${('', 'checked="checked"')[bool(sickbeard.LIBNOTIFY_NOTIFY_ONSUBTITLEDOWNLOAD)]}/> - <p>send a notification when subtitles are downloaded ?</p> + <p>send a notification when subtitles are downloaded?</p> </span> </label> </div> @@ -926,7 +932,7 @@ <span class="component-title">Enable</span> <span class="component-desc"> <input type="checkbox" class="enabler" name="use_pushover" id="use_pushover" ${('', 'checked="checked"')[bool(sickbeard.USE_PUSHOVER)]}/> - <p>should SickRage send Pushover notifications ?</p> + <p>Send Pushover notifications?</p> </span> </label> </div> @@ -937,7 +943,7 @@ <span class="component-title">Notify on snatch</span> <span class="component-desc"> <input type="checkbox" name="pushover_notify_onsnatch" id="pushover_notify_onsnatch" ${('', 'checked="checked"')[bool(sickbeard.PUSHOVER_NOTIFY_ONSNATCH)]}/> - <p>send a notification when a download starts ?</p> + <p>send a notification when a download starts?</p> </span> </label> </div> @@ -946,7 +952,7 @@ <span class="component-title">Notify on download</span> <span class="component-desc"> <input type="checkbox" name="pushover_notify_ondownload" id="pushover_notify_ondownload" ${('', 'checked="checked"')[bool(sickbeard.PUSHOVER_NOTIFY_ONDOWNLOAD)]}/> - <p>send a notification when a download finishes ?</p> + <p>send a notification when a download finishes?</p> </span> </label> </div> @@ -955,7 +961,7 @@ <span class="component-title">Notify on subtitle download</span> <span class="component-desc"> <input type="checkbox" name="pushover_notify_onsubtitledownload" id="pushover_notify_onsubtitledownload" ${('', 'checked="checked"')[bool(sickbeard.PUSHOVER_NOTIFY_ONSUBTITLEDOWNLOAD)]}/> - <p>send a notification when subtitles are downloaded ?</p> + <p>send a notification when subtitles are downloaded?</p> </span> </label> </div> @@ -1043,7 +1049,7 @@ <span class="component-title">Enable</span> <span class="component-desc"> <input type="checkbox" class="enabler" name="use_boxcar2" id="use_boxcar2" ${('', 'checked="checked"')[bool(sickbeard.USE_BOXCAR2)]}/> - <p>should SickRage send Boxcar notifications ?</p> + <p>Send Boxcar notifications?</p> </span> </label> </div> @@ -1054,7 +1060,7 @@ <span class="component-title">Notify on snatch</span> <span class="component-desc"> <input type="checkbox" name="boxcar2_notify_onsnatch" id="boxcar2_notify_onsnatch" ${('', 'checked="checked"')[bool(sickbeard.BOXCAR2_NOTIFY_ONSNATCH)]}/> - <p>send a notification when a download starts ?</p> + <p>send a notification when a download starts?</p> </span> </label> </div> @@ -1063,7 +1069,7 @@ <span class="component-title">Notify on download</span> <span class="component-desc"> <input type="checkbox" name="boxcar2_notify_ondownload" id="boxcar2_notify_ondownload" ${('', 'checked="checked"')[bool(sickbeard.BOXCAR2_NOTIFY_ONDOWNLOAD)]}/> - <p>send a notification when a download finishes ?</p> + <p>send a notification when a download finishes?</p> </span> </label> </div> @@ -1072,7 +1078,7 @@ <span class="component-title">Notify on subtitle download</span> <span class="component-desc"> <input type="checkbox" name="boxcar2_notify_onsubtitledownload" id="boxcar2_notify_onsubtitledownload" ${('', 'checked="checked"')[bool(sickbeard.BOXCAR2_NOTIFY_ONSUBTITLEDOWNLOAD)]}/> - <p>send a notification when subtitles are downloaded ?</p> + <p>send a notification when subtitles are downloaded?</p> </span> </label> </div> @@ -1106,7 +1112,7 @@ <span class="component-title">Enable</span> <span class="component-desc"> <input type="checkbox" class="enabler" name="use_nma" id="use_nma" ${('', 'checked="checked"')[bool(sickbeard.USE_NMA)]}/> - <p>should SickRage send NMA notifications ?</p> + <p>Send NMA notifications?</p> </span> </label> </div> @@ -1117,7 +1123,7 @@ <span class="component-title">Notify on snatch</span> <span class="component-desc"> <input type="checkbox" name="nma_notify_onsnatch" id="nma_notify_onsnatch" ${('', 'checked="checked"')[bool(sickbeard.NMA_NOTIFY_ONSNATCH)]}/> - <p>send a notification when a download starts ?</p> + <p>send a notification when a download starts?</p> </span> </label> </div> @@ -1126,7 +1132,7 @@ <span class="component-title">Notify on download</span> <span class="component-desc"> <input type="checkbox" name="nma_notify_ondownload" id="nma_notify_ondownload" ${('', 'checked="checked"')[bool(sickbeard.NMA_NOTIFY_ONDOWNLOAD)]}/> - <p>send a notification when a download finishes ?</p> + <p>send a notification when a download finishes?</p> </span> </label> </div> @@ -1135,7 +1141,7 @@ <span class="component-title">Notify on subtitle download</span> <span class="component-desc"> <input type="checkbox" name="nma_notify_onsubtitledownload" id="nma_notify_onsubtitledownload" ${('', 'checked="checked"')[bool(sickbeard.NMA_NOTIFY_ONSUBTITLEDOWNLOAD)]}/> - <p>send a notification when subtitles are downloaded ?</p> + <p>send a notification when subtitles are downloaded?</p> </span> </label> </div> @@ -1185,7 +1191,7 @@ <span class="component-title">Enable</span> <span class="component-desc"> <input type="checkbox" class="enabler" name="use_pushalot" id="use_pushalot" ${('', 'checked="checked"')[bool(sickbeard.USE_PUSHALOT)]}/> - <p>should SickRage send Pushalot notifications ? + <p>Send Pushalot notifications ? </span> </label> </div> @@ -1196,7 +1202,7 @@ <span class="component-title">Notify on snatch</span> <span class="component-desc"> <input type="checkbox" name="pushalot_notify_onsnatch" id="pushalot_notify_onsnatch" ${('', 'checked="checked"')[bool(sickbeard.PUSHALOT_NOTIFY_ONSNATCH)]}/> - <p>send a notification when a download starts ?</p> + <p>send a notification when a download starts?</p> </span> </label> </div> @@ -1205,7 +1211,7 @@ <span class="component-title">Notify on download</span> <span class="component-desc"> <input type="checkbox" name="pushalot_notify_ondownload" id="pushalot_notify_ondownload" ${('', 'checked="checked"')[bool(sickbeard.PUSHALOT_NOTIFY_ONDOWNLOAD)]}/> - <p>send a notification when a download finishes ?</p> + <p>send a notification when a download finishes?</p> </span> </label> </div> @@ -1214,7 +1220,7 @@ <span class="component-title">Notify on subtitle download</span> <span class="component-desc"> <input type="checkbox" name="pushalot_notify_onsubtitledownload" id="pushalot_notify_onsubtitledownload" ${('', 'checked="checked"')[bool(sickbeard.PUSHALOT_NOTIFY_ONSUBTITLEDOWNLOAD)]}/> - <p>send a notification when subtitles are downloaded ?</p> + <p>send a notification when subtitles are downloaded?</p> </span> </label> </div> @@ -1248,7 +1254,7 @@ <span class="component-title">Enable</span> <span class="component-desc"> <input type="checkbox" class="enabler" name="use_pushbullet" id="use_pushbullet" ${('', 'checked="checked"')[bool(sickbeard.USE_PUSHBULLET)]}/> - <p>should SickRage send Pushbullet notifications ?</p> + <p>Send Pushbullet notifications?</p> </span> </label> </div> @@ -1259,7 +1265,7 @@ <span class="component-title">Notify on snatch</span> <span class="component-desc"> <input type="checkbox" name="pushbullet_notify_onsnatch" id="pushbullet_notify_onsnatch" ${('', 'checked="checked"')[bool(sickbeard.PUSHBULLET_NOTIFY_ONSNATCH)]}/> - <p>send a notification when a download starts ?</p> + <p>send a notification when a download starts?</p> </span> </label> </div> @@ -1268,7 +1274,7 @@ <span class="component-title">Notify on download</span> <span class="component-desc"> <input type="checkbox" name="pushbullet_notify_ondownload" id="pushbullet_notify_ondownload" ${('', 'checked="checked"')[bool(sickbeard.PUSHBULLET_NOTIFY_ONDOWNLOAD)]}/> - <p>send a notification when a download finishes ?</p> + <p>send a notification when a download finishes?</p> </span> </label> </div> @@ -1277,7 +1283,7 @@ <span class="component-title">Notify on subtitle download</span> <span class="component-desc"> <input type="checkbox" name="pushbullet_notify_onsubtitledownload" id="pushbullet_notify_onsubtitledownload" ${('', 'checked="checked"')[bool(sickbeard.PUSHBULLET_NOTIFY_ONSUBTITLEDOWNLOAD)]}/> - <p>send a notification when subtitles are downloaded ?</p> + <p>send a notification when subtitles are downloaded?</p> </span> </label> </div> @@ -1322,7 +1328,7 @@ <span class="component-title">Enable</span> <span class="component-desc"> <input type="checkbox" class="enabler" name="use_freemobile" id="use_freemobile" ${('', 'checked="checked"')[bool(sickbeard.USE_FREEMOBILE)]}/> - <p>should SickRage send SMS notifications ?</p> + <p>Send SMS notifications?</p> </span> </label> </div> @@ -1333,7 +1339,7 @@ <span class="component-title">Notify on snatch</span> <span class="component-desc"> <input type="checkbox" name="freemobile_notify_onsnatch" id="freemobile_notify_onsnatch" ${('', 'checked="checked"')[bool(sickbeard.FREEMOBILE_NOTIFY_ONSNATCH)]}/> - <p>send a SMS when a download starts ?</p> + <p>send a SMS when a download starts?</p> </span> </label> </div> @@ -1342,7 +1348,7 @@ <span class="component-title">Notify on download</span> <span class="component-desc"> <input type="checkbox" name="freemobile_notify_ondownload" id="freemobile_notify_ondownload" ${('', 'checked="checked"')[bool(sickbeard.FREEMOBILE_NOTIFY_ONDOWNLOAD)]}/> - <p>send a SMS when a download finishes ?</p> + <p>send a SMS when a download finishes?</p> </span> </label> </div> @@ -1351,7 +1357,7 @@ <span class="component-title">Notify on subtitle download</span> <span class="component-desc"> <input type="checkbox" name="freemobile_notify_onsubtitledownload" id="freemobile_notify_onsubtitledownload" ${('', 'checked="checked"')[bool(sickbeard.FREEMOBILE_NOTIFY_ONSUBTITLEDOWNLOAD)]}/> - <p>send a SMS when subtitles are downloaded ?</p> + <p>send a SMS when subtitles are downloaded?</p> </span> </label> </div> @@ -1398,7 +1404,7 @@ <span class="component-title">Enable</span> <span class="component-desc"> <input type="checkbox" class="enabler" name="use_twitter" id="use_twitter" ${('', 'checked="checked"')[bool(sickbeard.USE_TWITTER)]}/> - <p>should SickRage post tweets on Twitter ?</p> + <p>should SickRage post tweets on Twitter?</p> </span> </label> <label> @@ -1413,7 +1419,7 @@ <span class="component-title">Notify on snatch</span> <span class="component-desc"> <input type="checkbox" name="twitter_notify_onsnatch" id="twitter_notify_onsnatch" ${('', 'checked="checked"')[bool(sickbeard.TWITTER_NOTIFY_ONSNATCH)]}/> - <p>send a notification when a download starts ?</p> + <p>send a notification when a download starts?</p> </span> </label> </div> @@ -1422,7 +1428,7 @@ <span class="component-title">Notify on download</span> <span class="component-desc"> <input type="checkbox" name="twitter_notify_ondownload" id="twitter_notify_ondownload" ${('', 'checked="checked"')[bool(sickbeard.TWITTER_NOTIFY_ONDOWNLOAD)]}/> - <p>send a notification when a download finishes ?</p> + <p>send a notification when a download finishes?</p> </span> </label> </div> @@ -1431,7 +1437,7 @@ <span class="component-title">Notify on subtitle download</span> <span class="component-desc"> <input type="checkbox" name="twitter_notify_onsubtitledownload" id="twitter_notify_onsubtitledownload" ${('', 'checked="checked"')[bool(sickbeard.TWITTER_NOTIFY_ONSUBTITLEDOWNLOAD)]}/> - <p>send a notification when subtitles are downloaded ?</p> + <p>send a notification when subtitles are downloaded?</p> </span> </label> </div> @@ -1500,7 +1506,7 @@ <span class="component-title">Enable</span> <span class="component-desc"> <input type="checkbox" class="enabler" name="use_trakt" id="use_trakt" ${('', 'checked="checked"')[bool(sickbeard.USE_TRAKT)]}/> - <p>should SickRage send Trakt.tv notifications ?</p> + <p>Send Trakt.tv notifications?</p> </span> </label> </div> @@ -1508,7 +1514,7 @@ <div id="content_use_trakt"> <div class="field-pair"> <label for="trakt_username"> - <span class="component-title">Trakt username</span> + <span class="component-title">Username</span> <input type="text" name="trakt_username" id="trakt_username" value="${sickbeard.TRAKT_USERNAME}" class="form-control input-sm input250" autocapitalize="off" autocomplete="no" /> </label> <p> @@ -1661,7 +1667,7 @@ <span class="component-title">Enable</span> <span class="component-desc"> <input type="checkbox" class="enabler" name="use_email" id="use_email" ${('', 'checked="checked"')[bool(sickbeard.USE_EMAIL)]}/> - <p>should SickRage send email notifications ?</p> + <p>Send email notifications?</p> </span> </label> </div> @@ -1672,7 +1678,7 @@ <span class="component-title">Notify on snatch</span> <span class="component-desc"> <input type="checkbox" name="email_notify_onsnatch" id="email_notify_onsnatch" ${('', 'checked="checked"')[bool(sickbeard.EMAIL_NOTIFY_ONSNATCH)]}/> - <p>send a notification when a download starts ?</p> + <p>send a notification when a download starts?</p> </span> </label> </div> @@ -1681,7 +1687,7 @@ <span class="component-title">Notify on download</span> <span class="component-desc"> <input type="checkbox" name="email_notify_ondownload" id="email_notify_ondownload" ${('', 'checked="checked"')[bool(sickbeard.EMAIL_NOTIFY_ONDOWNLOAD)]}/> - <p>send a notification when a download finishes ?</p> + <p>send a notification when a download finishes?</p> </span> </label> </div> @@ -1690,7 +1696,7 @@ <span class="component-title">Notify on subtitle download</span> <span class="component-desc"> <input type="checkbox" name="email_notify_onsubtitledownload" id="email_notify_onsubtitledownload" ${('', 'checked="checked"')[bool(sickbeard.EMAIL_NOTIFY_ONSUBTITLEDOWNLOAD)]}/> - <p>send a notification when subtitles are downloaded ?</p> + <p>send a notification when subtitles are downloaded?</p> </span> </label> </div> diff --git a/gui/slick/views/home.mako b/gui/slick/views/home.mako index efa1090e2b9c669870dfd19dee6b892ce586babb..7f72b5311227a9c0267ff3fac6c86b46b47907c7 100644 --- a/gui/slick/views/home.mako +++ b/gui/slick/views/home.mako @@ -92,7 +92,7 @@ % for curLoadingShow in sickbeard.showQueueScheduler.action.loadingShowList: % if curLoadingShow.show is None: <div class="show-container" data-name="0" data-date="010101" data-network="0" data-progress="101"> - <img alt="" title="${curLoadingShow.show_name}" class="show-image" style="border-bottom: 1px solid #111;" src="${srRoot}/images/poster.png" /> + <img alt="" title="${curLoadingShow.show_name}" class="show-image" style="border-bottom: 1px solid #111;" src="data:image/png;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=" data-src="${srRoot}/images/poster.png" /> <div class="show-details"> <div class="show-add">Loading... (${curLoadingShow.show_name})</div> </div> @@ -165,7 +165,7 @@ %> <div class="show-container" id="show${curShow.indexerid}" data-name="${curShow.name}" data-date="${data_date}" data-network="${curShow.network}" data-progress="${progressbar_percent}"> <div class="show-image"> - <a href="${srRoot}/home/displayShow?show=${curShow.indexerid}"><img alt="" class="show-image" src="${srRoot}/showPoster/?show=${curShow.indexerid}&which=poster_thumb" /></a> + <a href="${srRoot}/home/displayShow?show=${curShow.indexerid}"><img alt="" class="show-image" src="data:image/png;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=" data-src="${srRoot}/showPoster/?show=${curShow.indexerid}&which=poster_thumb" /></a> </div> <div class="progressbar hidden-print" style="position:relative;" data-show-id="${curShow.indexerid}" data-progress-percentage="${progressbar_percent}"></div> @@ -209,9 +209,9 @@ <td class="show-table"> % if sickbeard.HOME_LAYOUT != 'simple': % if curShow.network: - <span title="${curShow.network}"><img class="show-network-image" src="${srRoot}/showPoster/?show=${curShow.indexerid}&which=network" alt="${curShow.network}" title="${curShow.network}" /></span> + <span title="${curShow.network}"><img class="show-network-image" src="data:image/png;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=" data-src="${srRoot}/showPoster/?show=${curShow.indexerid}&which=network" alt="${curShow.network}" title="${curShow.network}" /></span> % else: - <span title="No Network"><img class="show-network-image" src="${srRoot}/images/network/nonetwork.png" alt="No Network" title="No Network" /></span> + <span title="No Network"><img class="show-network-image" src="data:image/png;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=" data-src="${srRoot}/images/network/nonetwork.png" alt="No Network" title="No Network" /></span> % endif % else: <span title="${curShow.network}">${curShow.network}</span> @@ -371,7 +371,7 @@ <td class="tvShow"> <div class="imgsmallposter ${sickbeard.HOME_LAYOUT}"> <a href="${srRoot}/home/displayShow?show=${curShow.indexerid}" title="${curShow.name}"> - <img src="${srRoot}/showPoster/?show=${curShow.indexerid}&which=poster_thumb" class="${sickbeard.HOME_LAYOUT}" alt="${curShow.indexerid}"/> + <img src="data:image/png;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=" data-src="${srRoot}/showPoster/?show=${curShow.indexerid}&which=poster_thumb" class="${sickbeard.HOME_LAYOUT}" alt="${curShow.indexerid}"/> </a> <a href="${srRoot}/home/displayShow?show=${curShow.indexerid}" style="vertical-align: middle;">${curShow.name}</a> </div> @@ -381,7 +381,7 @@ <span style="display: none;">${curShow.name}</span> <div class="imgbanner ${sickbeard.HOME_LAYOUT}"> <a href="${srRoot}/home/displayShow?show=${curShow.indexerid}"> - <img src="${srRoot}/showPoster/?show=${curShow.indexerid}&which=banner" class="${sickbeard.HOME_LAYOUT}" alt="${curShow.indexerid}" title="${curShow.name}"/> + <img src="data:image/png;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=" data-src="${srRoot}/showPoster/?show=${curShow.indexerid}&which=banner" class="${sickbeard.HOME_LAYOUT}" alt="${curShow.indexerid}" title="${curShow.name}"/> </div> </td> % elif sickbeard.HOME_LAYOUT == 'simple': @@ -391,10 +391,10 @@ % if sickbeard.HOME_LAYOUT != 'simple': <td align="center"> % if curShow.network: - <span title="${curShow.network}" class="hidden-print"><img id="network" width="54" height="27" src="${srRoot}/showPoster/?show=${curShow.indexerid}&which=network" alt="${curShow.network}" title="${curShow.network}" /></span> + <span title="${curShow.network}" class="hidden-print"><img id="network" width="54" height="27" src="data:image/png;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=" data-src="${srRoot}/showPoster/?show=${curShow.indexerid}&which=network" alt="${curShow.network}" title="${curShow.network}" /></span> <span class="visible-print-inline">${curShow.network}</span> % else: - <span title="No Network" class="hidden-print"><img id="network" width="54" height="27" src="${srRoot}/images/network/nonetwork.png" alt="No Network" title="No Network" /></span> + <span title="No Network" class="hidden-print"><img id="network" width="54" height="27" src="data:image/png;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=" data-src="${srRoot}/images/network/nonetwork.png" alt="No Network" title="No Network" /></span> <span class="visible-print-inline">No Network</span> % endif </td> @@ -417,7 +417,7 @@ <td align="center"> <% paused = int(curShow.paused) == 0 and curShow.status == 'Continuing' %> - <img src="${srRoot}/images/${('no16.png', 'yes16.png')[bool(paused)]}" alt="${('No', 'Yes')[bool(paused)]}" width="16" height="16" /> + <img src="data:image/png;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=" data-src="${srRoot}/images/${('no16.png', 'yes16.png')[bool(paused)]}" alt="${('No', 'Yes')[bool(paused)]}" width="16" height="16" /> </td> <td align="center"> diff --git a/gui/slick/views/layouts/main.mako b/gui/slick/views/layouts/main.mako index fda12eb262d2cf65d166987b6720b9d7ced94e81..41f3702157c6cce92f5e20b01898109604545f7c 100644 --- a/gui/slick/views/layouts/main.mako +++ b/gui/slick/views/layouts/main.mako @@ -141,7 +141,7 @@ <li><a href="${srRoot}/manage/backlogOverview/"><i class="menu-icon-backlog-view"></i> Backlog Overview</a></li> <li><a href="${srRoot}/manage/manageSearches/"><i class="menu-icon-manage-searches"></i> Manage Searches</a></li> <li><a href="${srRoot}/manage/episodeStatuses/"><i class="menu-icon-backlog"></i> Episode Status Management</a></li> - % if sickbeard.USE_PLEX and sickbeard.PLEX_SERVER_HOST != "": + % if sickbeard.USE_PLEX_SERVER and sickbeard.PLEX_SERVER_HOST != "": <li><a href="${srRoot}/home/updatePLEX/"><i class="menu-icon-backlog-view"></i> Update PLEX</a></li> % endif % if sickbeard.USE_KODI and sickbeard.KODI_HOST != "": diff --git a/lib/subliminal/video.py b/lib/subliminal/video.py index 11fbfcd90d7816d6c5861a0507033ccf8ec5cf12..b04d535cb60f25ddfb4023837cb9d99ff278a9f1 100644 --- a/lib/subliminal/video.py +++ b/lib/subliminal/video.py @@ -386,7 +386,7 @@ def scan_video(path, subtitles=True, embedded_subtitles=True, subtitles_dir=None else: logger.debug('MKV has no subtitle track') - except EnzymeError: + except: logger.exception('Parsing video metadata with enzyme failed') return video diff --git a/sickbeard/__init__.py b/sickbeard/__init__.py index 98224fc0078606b1bb2b697c540b75b7d1c43556..904c818b9adec751b983044e6a5504824be579c7 100644 --- a/sickbeard/__init__.py +++ b/sickbeard/__init__.py @@ -76,7 +76,7 @@ CFG = None CONFIG_FILE = None # This is the version of the config we EXPECT to find -CONFIG_VERSION = 7 +CONFIG_VERSION = 8 # Default encryption version (0 for None) ENCRYPTION_VERSION = 0 @@ -137,7 +137,6 @@ GIT_REPO = 'SickRage' GIT_USERNAME = None GIT_PASSWORD = None GIT_PATH = None -GIT_AUTOISSUES = False DEVELOPER = False NEWS_URL = 'http://sickrage.github.io/sickrage-news/news.md' @@ -343,19 +342,20 @@ KODI_HOST = '' KODI_USERNAME = None KODI_PASSWORD = None -USE_PLEX = False +USE_PLEX_SERVER = False PLEX_NOTIFY_ONSNATCH = False PLEX_NOTIFY_ONDOWNLOAD = False PLEX_NOTIFY_ONSUBTITLEDOWNLOAD = False PLEX_UPDATE_LIBRARY = False PLEX_SERVER_HOST = None PLEX_SERVER_TOKEN = None -PLEX_HOST = None -PLEX_USERNAME = None -PLEX_PASSWORD = None +PLEX_CLIENT_HOST = None +PLEX_SERVER_USERNAME = None +PLEX_SERVER_PASSWORD = None USE_PLEX_CLIENT = False PLEX_CLIENT_USERNAME = None PLEX_CLIENT_PASSWORD = None +PLEX_SERVER_HTTPS = None USE_EMBY = False EMBY_HOST = None @@ -587,8 +587,8 @@ def initialize(consoleLogging=True): USE_KODI, KODI_ALWAYS_ON, KODI_NOTIFY_ONSNATCH, KODI_NOTIFY_ONDOWNLOAD, KODI_NOTIFY_ONSUBTITLEDOWNLOAD, KODI_UPDATE_FULL, KODI_UPDATE_ONLYFIRST, \ KODI_UPDATE_LIBRARY, KODI_HOST, KODI_USERNAME, KODI_PASSWORD, BACKLOG_FREQUENCY, \ USE_TRAKT, TRAKT_USERNAME, TRAKT_ACCESS_TOKEN, TRAKT_REFRESH_TOKEN, TRAKT_REMOVE_WATCHLIST, TRAKT_SYNC_WATCHLIST, TRAKT_REMOVE_SHOW_FROM_SICKRAGE, TRAKT_METHOD_ADD, TRAKT_START_PAUSED, traktCheckerScheduler, TRAKT_USE_RECOMMENDED, TRAKT_SYNC, TRAKT_SYNC_REMOVE, TRAKT_DEFAULT_INDEXER, TRAKT_REMOVE_SERIESLIST, TRAKT_TIMEOUT, TRAKT_BLACKLIST_NAME, \ - USE_PLEX, PLEX_NOTIFY_ONSNATCH, PLEX_NOTIFY_ONDOWNLOAD, PLEX_NOTIFY_ONSUBTITLEDOWNLOAD, PLEX_UPDATE_LIBRARY, USE_PLEX_CLIENT, PLEX_CLIENT_USERNAME, PLEX_CLIENT_PASSWORD, \ - PLEX_SERVER_HOST, PLEX_SERVER_TOKEN, PLEX_HOST, PLEX_USERNAME, PLEX_PASSWORD, MIN_BACKLOG_FREQUENCY, SKIP_REMOVED_FILES, ALLOWED_EXTENSIONS, \ + USE_PLEX_SERVER, PLEX_NOTIFY_ONSNATCH, PLEX_NOTIFY_ONDOWNLOAD, PLEX_NOTIFY_ONSUBTITLEDOWNLOAD, PLEX_UPDATE_LIBRARY, USE_PLEX_CLIENT, PLEX_CLIENT_USERNAME, PLEX_CLIENT_PASSWORD, \ + PLEX_SERVER_HOST, PLEX_SERVER_TOKEN, PLEX_CLIENT_HOST, PLEX_SERVER_USERNAME, PLEX_SERVER_PASSWORD, PLEX_SERVER_HTTPS, MIN_BACKLOG_FREQUENCY, SKIP_REMOVED_FILES, ALLOWED_EXTENSIONS, \ USE_EMBY, EMBY_HOST, EMBY_APIKEY, \ showUpdateScheduler, __INITIALIZED__, INDEXER_DEFAULT_LANGUAGE, EP_DEFAULT_DELETED_STATUS, LAUNCH_BROWSER, TRASH_REMOVE_SHOW, TRASH_ROTATE_LOGS, SORT_ARTICLE, showList, loadingShowList, \ NEWZNAB_DATA, NZBS, NZBS_UID, NZBS_HASH, INDEXER_DEFAULT, INDEXER_TIMEOUT, USENET_RETENTION, TORRENT_DIR, \ @@ -622,7 +622,7 @@ def initialize(consoleLogging=True): AUTOPOSTPROCESSER_FREQUENCY, SHOWUPDATE_HOUR, \ ANIME_DEFAULT, NAMING_ANIME, ANIMESUPPORT, USE_ANIDB, ANIDB_USERNAME, ANIDB_PASSWORD, ANIDB_USE_MYLIST, \ ANIME_SPLIT_HOME, SCENE_DEFAULT, DOWNLOAD_URL, BACKLOG_DAYS, GIT_USERNAME, GIT_PASSWORD, \ - GIT_AUTOISSUES, DEVELOPER, gh, DISPLAY_ALL_SEASONS, SSL_VERIFY, NEWS_LAST_READ, NEWS_LATEST, SOCKET_TIMEOUT + DEVELOPER, gh, DISPLAY_ALL_SEASONS, SSL_VERIFY, NEWS_LAST_READ, NEWS_LATEST, SOCKET_TIMEOUT if __INITIALIZED__: return False @@ -654,8 +654,6 @@ def initialize(consoleLogging=True): ENCRYPTION_VERSION = check_setting_int(CFG, 'General', 'encryption_version', 0) ENCRYPTION_SECRET = check_setting_str(CFG, 'General', 'encryption_secret', helpers.generateCookieSecret(), censor_log=True) - GIT_AUTOISSUES = bool(check_setting_int(CFG, 'General', 'git_autoissues', 0)) - # git login info GIT_USERNAME = check_setting_str(CFG, 'General', 'git_username', '') GIT_PASSWORD = check_setting_str(CFG, 'General', 'git_password', '', censor_log=True) @@ -990,19 +988,20 @@ def initialize(consoleLogging=True): KODI_USERNAME = check_setting_str(CFG, 'KODI', 'kodi_username', '', censor_log=True) KODI_PASSWORD = check_setting_str(CFG, 'KODI', 'kodi_password', '', censor_log=True) - USE_PLEX = bool(check_setting_int(CFG, 'Plex', 'use_plex', 0)) + USE_PLEX_SERVER = bool(check_setting_int(CFG, 'Plex', 'use_plex_server', 0)) PLEX_NOTIFY_ONSNATCH = bool(check_setting_int(CFG, 'Plex', 'plex_notify_onsnatch', 0)) PLEX_NOTIFY_ONDOWNLOAD = bool(check_setting_int(CFG, 'Plex', 'plex_notify_ondownload', 0)) PLEX_NOTIFY_ONSUBTITLEDOWNLOAD = bool(check_setting_int(CFG, 'Plex', 'plex_notify_onsubtitledownload', 0)) PLEX_UPDATE_LIBRARY = bool(check_setting_int(CFG, 'Plex', 'plex_update_library', 0)) PLEX_SERVER_HOST = check_setting_str(CFG, 'Plex', 'plex_server_host', '') PLEX_SERVER_TOKEN = check_setting_str(CFG, 'Plex', 'plex_server_token', '') - PLEX_HOST = check_setting_str(CFG, 'Plex', 'plex_host', '') - PLEX_USERNAME = check_setting_str(CFG, 'Plex', 'plex_username', '', censor_log=True) - PLEX_PASSWORD = check_setting_str(CFG, 'Plex', 'plex_password', '', censor_log=True) + PLEX_CLIENT_HOST = check_setting_str(CFG, 'Plex', 'plex_client_host', '') + PLEX_SERVER_USERNAME = check_setting_str(CFG, 'Plex', 'plex_server_username', '', censor_log=True) + PLEX_SERVER_PASSWORD = check_setting_str(CFG, 'Plex', 'plex_server_password', '', censor_log=True) USE_PLEX_CLIENT = bool(check_setting_int(CFG, 'Plex', 'use_plex_client', 0)) PLEX_CLIENT_USERNAME = check_setting_str(CFG, 'Plex', 'plex_client_username', '', censor_log=True) PLEX_CLIENT_PASSWORD = check_setting_str(CFG, 'Plex', 'plex_client_password', '', censor_log=True) + PLEX_SERVER_HTTPS = bool(check_setting_int(CFG, 'Plex', 'plex_server_https', 0)) USE_EMBY = bool(check_setting_int(CFG, 'Emby', 'use_emby', 0)) EMBY_HOST = check_setting_str(CFG, 'Emby', 'emby_host', '') @@ -1601,7 +1600,6 @@ def save_config(): # For passwords you must include the word `password` in the item_name and add `helpers.encrypt(ITEM_NAME, ENCRYPTION_VERSION)` in save_config() new_config['General'] = {} - new_config['General']['git_autoissues'] = int(GIT_AUTOISSUES) new_config['General']['git_username'] = GIT_USERNAME new_config['General']['git_password'] = helpers.encrypt(GIT_PASSWORD, ENCRYPTION_VERSION) new_config['General']['git_reset'] = int(GIT_RESET) @@ -1898,16 +1896,21 @@ def save_config(): new_config['KODI']['kodi_password'] = helpers.encrypt(KODI_PASSWORD, ENCRYPTION_VERSION) new_config['Plex'] = {} - new_config['Plex']['use_plex'] = int(USE_PLEX) + new_config['Plex']['use_plex_server'] = int(USE_PLEX_SERVER) new_config['Plex']['plex_notify_onsnatch'] = int(PLEX_NOTIFY_ONSNATCH) new_config['Plex']['plex_notify_ondownload'] = int(PLEX_NOTIFY_ONDOWNLOAD) new_config['Plex']['plex_notify_onsubtitledownload'] = int(PLEX_NOTIFY_ONSUBTITLEDOWNLOAD) new_config['Plex']['plex_update_library'] = int(PLEX_UPDATE_LIBRARY) new_config['Plex']['plex_server_host'] = PLEX_SERVER_HOST new_config['Plex']['plex_server_token'] = PLEX_SERVER_TOKEN - new_config['Plex']['plex_host'] = PLEX_HOST - new_config['Plex']['plex_username'] = PLEX_USERNAME - new_config['Plex']['plex_password'] = helpers.encrypt(PLEX_PASSWORD, ENCRYPTION_VERSION) + new_config['Plex']['plex_client_host'] = PLEX_CLIENT_HOST + new_config['Plex']['plex_server_username'] = PLEX_SERVER_USERNAME + new_config['Plex']['plex_server_password'] = helpers.encrypt(PLEX_SERVER_PASSWORD, ENCRYPTION_VERSION) + + new_config['Plex']['use_plex_client'] = int(USE_PLEX_CLIENT) + new_config['Plex']['plex_client_username'] = PLEX_CLIENT_USERNAME + new_config['Plex']['plex_client_password'] = helpers.encrypt(PLEX_CLIENT_PASSWORD, ENCRYPTION_VERSION) + new_config['Plex']['plex_server_https'] = int(PLEX_SERVER_HTTPS) new_config['Emby'] = {} new_config['Emby']['use_emby'] = int(USE_EMBY) diff --git a/sickbeard/common.py b/sickbeard/common.py index e7d34ee3737b42df0db71a5a9a7d5425ff81de68..d28c3654e9a657d6726504772f674b066552462c 100644 --- a/sickbeard/common.py +++ b/sickbeard/common.py @@ -416,6 +416,7 @@ class Quality(object): :param status: to split :returns: a tuple containing (status, quality) """ + status = long(status) if status == UNKNOWN: return UNKNOWN, Quality.UNKNOWN diff --git a/sickbeard/config.py b/sickbeard/config.py index 1c12d9ef855f7ddc2178a1adb3162580d7423a94..5b6ce6acf6eabcd7e8d0cf44aa2d1f81917f33df 100644 --- a/sickbeard/config.py +++ b/sickbeard/config.py @@ -467,17 +467,12 @@ def clean_hosts(hosts, default_port=None): """ cleaned_hosts = [] - for cur_host in [x.strip() for x in hosts.split(",")]: - if cur_host: - cleaned_host = clean_host(cur_host, default_port) - if cleaned_host: - cleaned_hosts.append(cleaned_host) - - if cleaned_hosts: - cleaned_hosts = ",".join(cleaned_hosts) + for cur_host in [host.strip() for host in hosts.split(",") if host.strip()]: + cleaned_host = clean_host(cur_host, default_port) + if cleaned_host: + cleaned_hosts.append(cleaned_host) - else: - cleaned_hosts = '' + cleaned_hosts = ",".join(cleaned_hosts) if cleaned_hosts else '' return cleaned_hosts @@ -626,7 +621,8 @@ class ConfigMigrator(object): 4: 'Add newznab catIDs', 5: 'Metadata update', 6: 'Convert from XBMC to new KODI variables', - 7: 'Use version 2 for password encryption' + 7: 'Use version 2 for password encryption', + 8: 'Convert Plex setting keys' } def migrate_config(self): @@ -734,7 +730,6 @@ class ConfigMigrator(object): "s%0Se%0E", "S%0SE%0E", "%0Sx%0E") - naming_sep_type = (" - ", " ") # set up our data to use if use_periods: @@ -914,3 +909,9 @@ class ConfigMigrator(object): # Migration v6: Use version 2 for password encryption def _migrate_v7(self): sickbeard.ENCRYPTION_VERSION = 2 + + def _migrate_v8(self): + sickbeard.PLEX_CLIENT_HOST = check_setting_str(self.config_obj, 'Plex', 'plex_host', '') + sickbeard.PLEX_SERVER_USERNAME = check_setting_str(self.config_obj, 'Plex', 'plex_username', '', censor_log=True) + sickbeard.PLEX_SERVER_PASSWORD = check_setting_str(self.config_obj, 'Plex', 'plex_password', '', censor_log=True) + sickbeard.USE_PLEX_SERVER = bool(check_setting_int(self.config_obj, 'Plex', 'use_plex', 0)) diff --git a/sickbeard/databases/cache_db.py b/sickbeard/databases/cache_db.py index 316955a574211bc3da1bfc9860a21e0e93f4a870..847505a6540c9da648f6791375b0908a5ddf7b5a 100644 --- a/sickbeard/databases/cache_db.py +++ b/sickbeard/databases/cache_db.py @@ -100,3 +100,14 @@ class AddSceneExceptionsRefresh(AddSceneExceptionsCustom): def execute(self): self.connection.action( "CREATE TABLE scene_exceptions_refresh (list TEXT PRIMARY KEY, last_refreshed INTEGER);") + +class ConvertSceneExeptionsToIndexerScheme(AddSceneExceptionsRefresh): + def test(self): + return self.hasColumn("scene_exceptions", "indexer_id") + + def execute(self): + self.connection.action("DROP TABLE IF EXISTS tmp_scene_exceptions;") + self.connection.action("ALTER TABLE scene_exceptions RENAME TO tmp_scene_exceptions;") + self.connection.action("CREATE TABLE scene_exceptions (exception_id INTEGER PRIMARY KEY, indexer_id INTEGER KEY, show_name TEXT, season NUMERIC DEFAULT -1, custom NUMERIC DEFAULT 0);") + self.connection.action("INSERT INTO scene_exceptions SELECT exception_id, tvdb_id as indexer_id, show_name, season, custom FROM tmp_scene_exceptions;") + self.connection.action("DROP TABLE tmp_scene_exceptions;") diff --git a/sickbeard/databases/mainDB.py b/sickbeard/databases/mainDB.py index 2c1584fe973f180a90f3fc2c479315f8fbcda749..62af35149a123ed32d3920b20ae270cb3562c0e7 100644 --- a/sickbeard/databases/mainDB.py +++ b/sickbeard/databases/mainDB.py @@ -357,7 +357,7 @@ class AddSizeAndSceneNameFields(InitialSchema): def execute(self): - backupDatabase(10) + backupDatabase(self.checkDBVersion()) if not self.hasColumn("tv_episodes", "file_size"): self.addColumn("tv_episodes", "file_size") @@ -468,12 +468,14 @@ class RenameSeasonFolders(AddSizeAndSceneNameFields): return self.checkDBVersion() >= 11 def execute(self): + backupDatabase(self.checkDBVersion()) + # rename the column + self.connection.action("DROP TABLE IF EXISTS tmp_tv_shows") self.connection.action("ALTER TABLE tv_shows RENAME TO tmp_tv_shows") self.connection.action( "CREATE TABLE tv_shows (show_id INTEGER PRIMARY KEY, location TEXT, show_name TEXT, tvdb_id NUMERIC, network TEXT, genre TEXT, runtime NUMERIC, quality NUMERIC, airs TEXT, status TEXT, flatten_folders NUMERIC, paused NUMERIC, startyear NUMERIC, tvr_id NUMERIC, tvr_name TEXT, air_by_date NUMERIC, lang TEXT)") - sql = "INSERT INTO tv_shows SELECT * FROM tmp_tv_shows" - self.connection.action(sql) + self.connection.action("INSERT INTO tv_shows SELECT * FROM tmp_tv_shows") # flip the values to be opposite of what they were before self.connection.action("UPDATE tv_shows SET flatten_folders = 2 WHERE flatten_folders = 1") @@ -626,7 +628,7 @@ class AddShowidTvdbidIndex(Add1080pAndRawHDQualities): return self.checkDBVersion() >= 13 def execute(self): - backupDatabase(13) + backupDatabase(self.checkDBVersion()) logger.log(u"Check for duplicate shows before adding unique index.") MainSanityCheck(self.connection).fix_duplicate_shows('tvdb_id') @@ -647,7 +649,7 @@ class AddLastUpdateTVDB(AddShowidTvdbidIndex): return self.checkDBVersion() >= 14 def execute(self): - backupDatabase(14) + backupDatabase(self.checkDBVersion()) logger.log(u"Adding column last_update_tvdb to tvshows") if not self.hasColumn("tv_shows", "last_update_tvdb"): @@ -661,6 +663,7 @@ class AddDBIncreaseTo15(AddLastUpdateTVDB): return self.checkDBVersion() >= 15 def execute(self): + backupDatabase(self.checkDBVersion()) self.incDBVersion() @@ -669,6 +672,7 @@ class AddIMDbInfo(AddDBIncreaseTo15): return self.checkDBVersion() >= 16 def execute(self): + backupDatabase(self.checkDBVersion()) self.connection.action( "CREATE TABLE imdb_info (tvdb_id INTEGER PRIMARY KEY, imdb_id TEXT, title TEXT, year NUMERIC, akas TEXT, runtimes NUMERIC, genres TEXT, countries TEXT, country_codes TEXT, certificates TEXT, rating TEXT, votes INTEGER, last_update NUMERIC)") @@ -683,6 +687,7 @@ class AddProperNamingSupport(AddIMDbInfo): return self.checkDBVersion() >= 17 def execute(self): + backupDatabase(self.checkDBVersion()) self.addColumn("tv_episodes", "is_proper") self.incDBVersion() @@ -692,6 +697,7 @@ class AddEmailSubscriptionTable(AddProperNamingSupport): return self.checkDBVersion() >= 18 def execute(self): + backupDatabase(self.checkDBVersion()) self.addColumn('tv_shows', 'notify_list', 'TEXT', None) self.incDBVersion() @@ -701,7 +707,7 @@ class AddProperSearch(AddEmailSubscriptionTable): return self.checkDBVersion() >= 19 def execute(self): - backupDatabase(19) + backupDatabase(self.checkDBVersion()) logger.log(u"Adding column last_proper_search to info") if not self.hasColumn("info", "last_proper_search"): @@ -715,6 +721,7 @@ class AddDvdOrderOption(AddProperSearch): return self.checkDBVersion() >= 20 def execute(self): + backupDatabase(self.checkDBVersion()) logger.log(u"Adding column dvdorder to tvshows") if not self.hasColumn("tv_shows", "dvdorder"): self.addColumn("tv_shows", "dvdorder", "NUMERIC", "0") @@ -727,6 +734,7 @@ class AddSubtitlesSupport(AddDvdOrderOption): return self.checkDBVersion() >= 21 def execute(self): + backupDatabase(self.checkDBVersion()) if not self.hasColumn("tv_shows", "subtitles"): self.addColumn("tv_shows", "subtitles") self.addColumn("tv_episodes", "subtitles", "TEXT", "") @@ -740,17 +748,18 @@ class ConvertTVShowsToIndexerScheme(AddSubtitlesSupport): return self.checkDBVersion() >= 22 def execute(self): - backupDatabase(22) + backupDatabase(self.checkDBVersion()) logger.log(u"Converting TV Shows table to Indexer Scheme...") - if self.hasTable("tmp_tv_shows"): - logger.log(u"Removing temp tv show tables left behind from previous updates...") - self.connection.action("DROP TABLE tmp_tv_shows") + self.connection.action("DROP TABLE IF EXISTS tmp_tv_shows") self.connection.action("ALTER TABLE tv_shows RENAME TO tmp_tv_shows") self.connection.action("CREATE TABLE tv_shows (show_id INTEGER PRIMARY KEY, indexer_id NUMERIC, indexer NUMERIC, show_name TEXT, location TEXT, network TEXT, genre TEXT, classification TEXT, runtime NUMERIC, quality NUMERIC, airs TEXT, status TEXT, flatten_folders NUMERIC, paused NUMERIC, startyear NUMERIC, air_by_date NUMERIC, lang TEXT, subtitles NUMERIC, notify_list TEXT, imdb_id TEXT, last_update_indexer NUMERIC, dvdorder NUMERIC)") - self.connection.action("INSERT INTO tv_shows SELECT * FROM tmp_tv_shows") + self.connection.action( + "INSERT INTO tv_shows (show_id, indexer_id, show_name, location, network, genre, runtime, quality, airs, status, flatten_folders, paused, startyear, air_by_date, lang, subtitles, dvdorder) " + + "SELECT show_id, tvdb_id as indexer_id, show_name, location, network, genre, runtime, quality, airs, status, flatten_folders, paused, startyear, air_by_date, lang, subtitles, dvdorder FROM tmp_tv_shows" + ) self.connection.action("DROP TABLE tmp_tv_shows") self.connection.action("CREATE UNIQUE INDEX idx_indexer_id ON tv_shows (indexer_id);") @@ -766,19 +775,21 @@ class ConvertTVEpisodesToIndexerScheme(ConvertTVShowsToIndexerScheme): return self.checkDBVersion() >= 23 def execute(self): - backupDatabase(23) + backupDatabase(self.checkDBVersion()) logger.log(u"Converting TV Episodes table to Indexer Scheme...") - if self.hasTable("tmp_tv_episodes"): - logger.log(u"Removing temp tv episode tables left behind from previous updates...") - self.connection.action("DROP TABLE tmp_tv_episodes") + self.connection.action("DROP TABLE IF EXISTS tmp_tv_episodes") self.connection.action("ALTER TABLE tv_episodes RENAME TO tmp_tv_episodes") self.connection.action( "CREATE TABLE tv_episodes (episode_id INTEGER PRIMARY KEY, showid NUMERIC, indexerid NUMERIC, indexer NUMERIC, name TEXT, season NUMERIC, episode NUMERIC, description TEXT, airdate NUMERIC, hasnfo NUMERIC, hastbn NUMERIC, status NUMERIC, location TEXT, file_size NUMERIC, release_name TEXT, subtitles TEXT, subtitles_searchcount NUMERIC, subtitles_lastsearch TIMESTAMP, is_proper NUMERIC)") + self.connection.action( - "INSERT INTO tv_episodes SELECT * FROM tmp_tv_episodes") + "INSERT INTO tv_episodes (episode_id, showid, indexerid, name, season, episode, description, airdate, hasnfo, hastbn, status, location, file_size, release_name, subtitles, subtitles_searchcount, subtitles_lastsearch) " + + "SELECT episode_id, showid, tvdbid as indexerid, name, season, episode, description, airdate, hasnfo, hastbn, status, location, file_size, release_name, subtitles, subtitles_searchcount, subtitles_lastsearch FROM tmp_tv_episodes" + ) + self.connection.action("DROP TABLE tmp_tv_episodes") self.connection.action("CREATE INDEX idx_tv_episodes_showid_airdate ON tv_episodes(showid,airdate);") @@ -787,7 +798,7 @@ class ConvertTVEpisodesToIndexerScheme(ConvertTVShowsToIndexerScheme): self.connection.action("CREATE INDEX idx_sta_epi_air ON tv_episodes (status,episode, airdate)") self.connection.action("CREATE INDEX idx_sta_epi_sta_air ON tv_episodes (season,episode, status, airdate)") - self.connection.action("UPDATE tv_episodes SET indexer = 1") + self.connection.action("UPDATE tv_episodes SET indexer = 1, is_proper = 0") self.incDBVersion() @@ -797,20 +808,22 @@ class ConvertIMDBInfoToIndexerScheme(ConvertTVEpisodesToIndexerScheme): return self.checkDBVersion() >= 24 def execute(self): - backupDatabase(24) + backupDatabase(self.checkDBVersion()) logger.log(u"Converting IMDB Info table to Indexer Scheme...") - if self.hasTable("tmp_imdb_info"): - logger.log(u"Removing temp imdb info tables left behind from previous updates...") - self.connection.action("DROP TABLE tmp_imdb_info") + self.connection.action("DROP TABLE IF EXISTS tmp_imdb_info") + + if self.hasTable("imdb_info"): + self.connection.action("ALTER TABLE imdb_info RENAME TO tmp_imdb_info") - self.connection.action("ALTER TABLE imdb_info RENAME TO tmp_imdb_info") self.connection.action( "CREATE TABLE imdb_info (indexer_id INTEGER PRIMARY KEY, imdb_id TEXT, title TEXT, year NUMERIC, akas TEXT, runtimes NUMERIC, genres TEXT, countries TEXT, country_codes TEXT, certificates TEXT, rating TEXT, votes INTEGER, last_update NUMERIC)") - self.connection.action( - "INSERT INTO imdb_info SELECT * FROM tmp_imdb_info") - self.connection.action("DROP TABLE tmp_imdb_info") + + if self.hasTable("tmp_imdb_info"): + self.connection.action("INSERT INTO imdb_info SELECT * FROM tmp_imdb_info") + + self.connection.action("DROP TABLE IF EXISTS tmp_imdb_info") self.incDBVersion() @@ -820,13 +833,11 @@ class ConvertInfoToIndexerScheme(ConvertIMDBInfoToIndexerScheme): return self.checkDBVersion() >= 25 def execute(self): - backupDatabase(25) + backupDatabase(self.checkDBVersion()) logger.log(u"Converting Info table to Indexer Scheme...") - if self.hasTable("tmp_info"): - logger.log(u"Removing temp info tables left behind from previous updates...") - self.connection.action("DROP TABLE tmp_info") + self.connection.action("DROP TABLE IF EXISTS tmp_info") self.connection.action("ALTER TABLE info RENAME TO tmp_info") self.connection.action( @@ -843,7 +854,7 @@ class AddArchiveFirstMatchOption(ConvertInfoToIndexerScheme): return self.checkDBVersion() >= 26 def execute(self): - backupDatabase(26) + backupDatabase(self.checkDBVersion()) logger.log(u"Adding column archive_firstmatch to tvshows") if not self.hasColumn("tv_shows", "archive_firstmatch"): @@ -857,7 +868,7 @@ class AddSceneNumbering(AddArchiveFirstMatchOption): return self.checkDBVersion() >= 27 def execute(self): - backupDatabase(27) + backupDatabase(self.checkDBVersion()) if self.hasTable("scene_numbering"): self.connection.action("DROP TABLE scene_numbering") @@ -873,7 +884,7 @@ class ConvertIndexerToInteger(AddSceneNumbering): return self.checkDBVersion() >= 28 def execute(self): - backupDatabase(28) + backupDatabase(self.checkDBVersion()) cl = [] logger.log(u"Converting Indexer to Integer ...", logger.INFO) @@ -896,7 +907,7 @@ class AddRequireAndIgnoreWords(ConvertIndexerToInteger): return self.checkDBVersion() >= 29 def execute(self): - backupDatabase(29) + backupDatabase(self.checkDBVersion()) logger.log(u"Adding column rls_require_words to tvshows") if not self.hasColumn("tv_shows", "rls_require_words"): @@ -914,7 +925,7 @@ class AddSportsOption(AddRequireAndIgnoreWords): return self.checkDBVersion() >= 30 def execute(self): - backupDatabase(30) + backupDatabase(self.checkDBVersion()) logger.log(u"Adding column sports to tvshows") if not self.hasColumn("tv_shows", "sports"): @@ -940,7 +951,7 @@ class AddSceneNumberingToTvEpisodes(AddSportsOption): return self.checkDBVersion() >= 31 def execute(self): - backupDatabase(31) + backupDatabase(self.checkDBVersion()) logger.log(u"Adding column scene_season and scene_episode to tvepisodes") self.addColumn("tv_episodes", "scene_season", "NUMERIC", "NULL") @@ -954,7 +965,7 @@ class AddAnimeTVShow(AddSceneNumberingToTvEpisodes): return self.checkDBVersion() >= 32 def execute(self): - backupDatabase(32) + backupDatabase(self.checkDBVersion()) logger.log(u"Adding column anime to tv_episodes") self.addColumn("tv_shows", "anime", "NUMERIC", "0") @@ -967,7 +978,7 @@ class AddAbsoluteNumbering(AddAnimeTVShow): return self.checkDBVersion() >= 33 def execute(self): - backupDatabase(33) + backupDatabase(self.checkDBVersion()) logger.log(u"Adding column absolute_number to tv_episodes") self.addColumn("tv_episodes", "absolute_number", "NUMERIC", "0") @@ -980,7 +991,7 @@ class AddSceneAbsoluteNumbering(AddAbsoluteNumbering): return self.checkDBVersion() >= 34 def execute(self): - backupDatabase(34) + backupDatabase(self.checkDBVersion()) logger.log(u"Adding column absolute_number and scene_absolute_number to scene_numbering") self.addColumn("scene_numbering", "absolute_number", "NUMERIC", "0") @@ -995,7 +1006,7 @@ class AddAnimeBlacklistWhitelist(AddSceneAbsoluteNumbering): return self.checkDBVersion() >= 35 def execute(self): - backupDatabase(35) + backupDatabase(self.checkDBVersion()) cl = [ ["CREATE TABLE blacklist (show_id INTEGER, range TEXT, keyword TEXT)"], @@ -1012,7 +1023,7 @@ class AddSceneAbsoluteNumbering2(AddAnimeBlacklistWhitelist): return self.checkDBVersion() >= 36 def execute(self): - backupDatabase(36) + backupDatabase(self.checkDBVersion()) logger.log(u"Adding column scene_absolute_number to tv_episodes") self.addColumn("tv_episodes", "scene_absolute_number", "NUMERIC", "0") @@ -1025,7 +1036,7 @@ class AddXemRefresh(AddSceneAbsoluteNumbering2): return self.checkDBVersion() >= 37 def execute(self): - backupDatabase(37) + backupDatabase(self.checkDBVersion()) logger.log(u"Creating table xem_refresh") self.connection.action( @@ -1039,7 +1050,7 @@ class AddSceneToTvShows(AddXemRefresh): return self.checkDBVersion() >= 38 def execute(self): - backupDatabase(38) + backupDatabase(self.checkDBVersion()) logger.log(u"Adding column scene to tv_shows") self.addColumn("tv_shows", "scene", "NUMERIC", "0") @@ -1052,7 +1063,7 @@ class AddIndexerMapping(AddSceneToTvShows): return self.checkDBVersion() >= 39 def execute(self): - backupDatabase(39) + backupDatabase(self.checkDBVersion()) if self.hasTable("indexer_mapping"): self.connection.action("DROP TABLE indexer_mapping") @@ -1069,7 +1080,7 @@ class AddVersionToTvEpisodes(AddIndexerMapping): return self.checkDBVersion() >= 40 def execute(self): - backupDatabase(40) + backupDatabase(self.checkDBVersion()) logger.log(u"Adding column version to tv_episodes and history") self.addColumn("tv_episodes", "version", "NUMERIC", "-1") @@ -1084,7 +1095,7 @@ class AddDefaultEpStatusToTvShows(AddVersionToTvEpisodes): return self.checkDBVersion() >= 41 def execute(self): - backupDatabase(41) + backupDatabase(self.checkDBVersion()) logger.log(u"Adding column default_ep_status to tv_shows") self.addColumn("tv_shows", "default_ep_status", "NUMERIC", "-1") @@ -1097,9 +1108,10 @@ class AlterTVShowsFieldTypes(AddDefaultEpStatusToTvShows): return self.checkDBVersion() >= 42 def execute(self): - backupDatabase(42) + backupDatabase(self.checkDBVersion()) logger.log(u"Converting column indexer and default_ep_status field types to numeric") + self.connection.action("DROP TABLE IF EXISTS tmp_tv_shows") self.connection.action("ALTER TABLE tv_shows RENAME TO tmp_tv_shows") self.connection.action("CREATE TABLE tv_shows (show_id INTEGER PRIMARY KEY, indexer_id NUMERIC, indexer NUMERIC, show_name TEXT, location TEXT, network TEXT, genre TEXT, classification TEXT, runtime NUMERIC, quality NUMERIC, airs TEXT, status TEXT, flatten_folders NUMERIC, paused NUMERIC, startyear NUMERIC, air_by_date NUMERIC, lang TEXT, subtitles NUMERIC, notify_list TEXT, imdb_id TEXT, last_update_indexer NUMERIC, dvdorder NUMERIC, archive_firstmatch NUMERIC, rls_require_words TEXT, rls_ignore_words TEXT, sports NUMERIC, anime NUMERIC, scene NUMERIC, default_ep_status NUMERIC)") self.connection.action("INSERT INTO tv_shows SELECT * FROM tmp_tv_shows") diff --git a/sickbeard/db.py b/sickbeard/db.py index d015831da7b3bbc616b92e14cedba29e878086f2..584efe471e34b1dd8a19949d791db12687320818 100644 --- a/sickbeard/db.py +++ b/sickbeard/db.py @@ -55,33 +55,40 @@ class DBConnection(object): self.row_type = row_type try: - if self.filename not in db_cons: + if self.filename not in db_cons or not db_cons[self.filename]: db_locks[self.filename] = threading.Lock() self.connection = sqlite3.connect(dbFilename(self.filename, self.suffix), 20, check_same_thread=False) - self.connection.text_factory = self._unicode_text_factory + self.connection.text_factory = DBConnection._unicode_text_factory db_cons[self.filename] = self.connection else: self.connection = db_cons[self.filename] - if self.row_type == "dict": - self.connection.row_factory = self._dict_factory - else: - self.connection.row_factory = sqlite3.Row + # start off row factory configured as before out of + # paranoia but wait to do so until other potential users + # of the shared connection are done using + # it... technically not required as row factory is reset + # in all the public methods after the lock has been + # aquired + with db_locks[self.filename]: + self._set_row_factory() + except Exception as e: logger.log(u"DB error: " + ex(e), logger.ERROR) raise - def _execute(self, query, args): - try: - if not args: - return self.connection.cursor().execute(query) - return self.connection.cursor().execute(query, args) - except Exception: - raise + def _set_row_factory(self): + """ + once lock is aquired we can configure the connection for + this particular instance of DBConnection + """ + if self.row_type == "dict": + self.connection.row_factory = DBConnection._dict_factory + else: + self.connection.row_factory = sqlite3.Row - def execute(self, query, args=None, fetchall=False, fetchone=False): + def _execute(self, query, args=None, fetchall=False, fetchone=False): """ Executes DB query @@ -92,12 +99,16 @@ class DBConnection(object): :return: query results """ try: + if not args: + sqlResult = self.connection.cursor().execute(query) + else: + sqlResult = self.connection.cursor().execute(query, args) if fetchall: - return self._execute(query, args).fetchall() + return sqlResult.fetchall() elif fetchone: - return self._execute(query, args).fetchone() + return sqlResult.fetchone() else: - return self._execute(query, args) + return sqlResult except Exception: raise @@ -136,17 +147,18 @@ class DBConnection(object): attempt = 0 with db_locks[self.filename]: + self._set_row_factory() while attempt < 5: try: for qu in querylist: if len(qu) == 1: if logTransaction: logger.log(qu[0], logger.DEBUG) - sqlResult.append(self.execute(qu[0], fetchall=fetchall)) + sqlResult.append(self._execute(qu[0], fetchall=fetchall)) elif len(qu) > 1: if logTransaction: logger.log(qu[0] + " with args " + str(qu[1]), logger.DEBUG) - sqlResult.append(self.execute(qu[0], qu[1], fetchall=fetchall)) + sqlResult.append(self._execute(qu[0], qu[1], fetchall=fetchall)) self.connection.commit() logger.log(u"Transaction with " + str(len(querylist)) + u" queries executed", logger.DEBUG) @@ -191,6 +203,7 @@ class DBConnection(object): attempt = 0 with db_locks[self.filename]: + self._set_row_factory() while attempt < 5: try: if args is None: @@ -198,7 +211,7 @@ class DBConnection(object): else: logger.log(self.filename + ": " + query + " with args " + str(args), logger.DB) - sqlResult = self.execute(query, args, fetchall=fetchall, fetchone=fetchone) + sqlResult = self._execute(query, args, fetchall=fetchall, fetchone=fetchone) self.connection.commit() # get out of the connection attempt loop since we were successful @@ -287,7 +300,8 @@ class DBConnection(object): columns[column['name']] = {'type': column['type']} return columns - def _unicode_text_factory(self, x): + @staticmethod + def _unicode_text_factory(x): """ Convert text to unicode @@ -300,7 +314,8 @@ class DBConnection(object): except: return unicode(x, sickbeard.SYS_ENCODING, errors="ignore") - def _dict_factory(self, cursor, row): + @staticmethod + def _dict_factory(cursor, row): d = {} for idx, col in enumerate(cursor.description): d[col[0]] = row[idx] @@ -392,27 +407,10 @@ def _processUpgrade(connection, upgradeClass): logger.log(u"Database upgrade required: " + prettyName(upgradeClass.__name__), logger.DEBUG) try: instance.execute() - except sqlite3.DatabaseError as e: - # attemping to restore previous DB backup and perform upgrade - try: - instance.execute() - except: - restored = False - result = connection.select("SELECT db_version FROM db_version") - if result: - version = int(result[0]["db_version"]) - - # close db before attempting restore - connection.close() - - if restoreDatabase(version): - # initialize the main SB database - upgradeDatabase(DBConnection(), sickbeard.mainDB.InitialSchema) - restored = True - - if not restored: - print "Error in " + str(upgradeClass.__name__) + ": " + ex(e) - raise + except Exception as e: + logger.log("Error in " + str(upgradeClass.__name__) + ": " + ex(e), logger.ERROR) + raise + logger.log(upgradeClass.__name__ + " upgrade completed", logger.DEBUG) else: logger.log(upgradeClass.__name__ + " upgrade not required", logger.DEBUG) diff --git a/sickbeard/logger.py b/sickbeard/logger.py index 56fb098e151c818ec40c9f5f180cb93c1e41bde2..2c20fc430a3ae8b51ca78dbc74ba6320bd949ad6 100644 --- a/sickbeard/logger.py +++ b/sickbeard/logger.py @@ -160,8 +160,8 @@ class Logger(object): # pylint: disable=too-many-instance-attributes message = meThread + u" :: " + msg # Change the SSL error to a warning with a link to information about how to fix it. - check = re.sub(ur'error \[Errno 1\] _ssl.c:\d{3}: error:\d{8}:SSL routines:SSL23_GET_SERVER_HELLO:tlsv1 alert internal error', 'See: http://git.io/vJrkM', message) - if check is not message: + check = re.sub(ur'error \[Errno 1\] _ssl.c:\d{3}: error:\d{8}:SSL routines:SSL23_GET_SERVER_HELLO:tlsv1 alert internal error', 'See: http://git.io/vuU5V', message) + if check != message: message = check level = WARNING @@ -170,9 +170,6 @@ class Logger(object): # pylint: disable=too-many-instance-attributes elif level == WARNING: classes.WarningViewer.add(classes.UIError(message)) - # if sickbeard.GIT_AUTOISSUES: - # self.submit_errors() - if level == ERROR: self.logger.exception(message, *args, **kwargs) else: @@ -186,7 +183,7 @@ class Logger(object): # pylint: disable=too-many-instance-attributes else: sys.exit(1) - def submit_errors(self): # Too many local variables, too many branches, pylint: disable=too-many-branches,too-many-locals + def submit_errors(self): # pylint: disable=too-many-branches,too-many-locals submitter_result = u'' issue_id = None diff --git a/sickbeard/metadata/generic.py b/sickbeard/metadata/generic.py index b2e11566c16344220b5f9302d0fbcb9f551c8a2d..72e54aefd5d40897ab7644764382a8cb58743c3a 100644 --- a/sickbeard/metadata/generic.py +++ b/sickbeard/metadata/generic.py @@ -746,7 +746,7 @@ class GenericMetadata(object): except (sickbeard.indexer_error, IOError) as e: logger.log(u"Unable to look up show on " + sickbeard.indexerApi( show_obj.indexer).name + ", not downloading images: " + ex(e), logger.WARNING) - logger.log(u"Indexer " + sickbeard.indexerApi(show_obj.indexer).name + "maybe experiencing some problems. Try again later", logger.DEBUG) + logger.log(u"%s may be experiencing some problems. Try again later." % sickbeard.indexerApi(show_obj.indexer).name, logger.DEBUG) return None if image_type not in ('fanart', 'poster', 'banner', 'poster_thumb', 'banner_thumb'): @@ -816,7 +816,7 @@ class GenericMetadata(object): except (sickbeard.indexer_error, IOError) as e: logger.log(u"Unable to look up show on " + sickbeard.indexerApi( show_obj.indexer).name + ", not downloading images: " + ex(e), logger.WARNING) - logger.log(u"Indexer " + sickbeard.indexerApi(show_obj.indexer).name + "maybe experiencing some problems. Try again later", logger.DEBUG) + logger.log(u"%s may be experiencing some problems. Try again later." % sickbeard.indexerApi(show_obj.indexer).name, logger.DEBUG) return result # if we have no season banners then just finish @@ -870,7 +870,7 @@ class GenericMetadata(object): except (sickbeard.indexer_error, IOError) as e: logger.log(u"Unable to look up show on " + sickbeard.indexerApi( show_obj.indexer).name + ", not downloading images: " + ex(e), logger.WARNING) - logger.log(u"Indexer " + sickbeard.indexerApi(show_obj.indexer).name + "maybe experiencing some problems. Try again later", logger.DEBUG) + logger.log(u"%s may be experiencing some problems. Try again later." % sickbeard.indexerApi(show_obj.indexer).name, logger.DEBUG) return result # if we have no season banners then just finish diff --git a/sickbeard/notifiers/kodi.py b/sickbeard/notifiers/kodi.py index f46d41baa1d52eb479443b39eb1c25ca301bf78f..9ff6c6dbc1c17ca2704a86ee9e47463bc93338bb 100644 --- a/sickbeard/notifiers/kodi.py +++ b/sickbeard/notifiers/kodi.py @@ -45,7 +45,7 @@ except ImportError: class KODINotifier(object): sr_logo_url = 'https://raw.githubusercontent.com/SickRage/SickRage/master/gui/slick/images/sickrage-shark-mascot.png' - def _get_kodi_version(self, host, username, password): + def _get_kodi_version(self, host, username, password, dest_app="KODI"): """Returns KODI JSON-RPC API version (odd # = dev, even # = stable) Sends a request to the KODI host using the JSON-RPC to determine if @@ -77,7 +77,7 @@ class KODINotifier(object): socket.setdefaulttimeout(10) checkCommand = '{"jsonrpc":"2.0","method":"JSONRPC.Version","id":1}' - result = self._send_to_kodi_json(checkCommand, host, username, password) + result = self._send_to_kodi_json(checkCommand, host, username, password, dest_app) # revert back to default socket timeout socket.setdefaulttimeout(sickbeard.SOCKET_TIMEOUT) @@ -87,14 +87,14 @@ class KODINotifier(object): else: # fallback to legacy HTTPAPI method testCommand = {'command': 'Help'} - request = self._send_to_kodi(testCommand, host, username, password) + request = self._send_to_kodi(testCommand, host, username, password, dest_app) if request: # return a fake version number, so it uses the legacy method return 1 else: return False - def _notify_kodi(self, message, title="SickRage", host=None, username=None, password=None, force=False): + def _notify_kodi(self, message, title="SickRage", host=None, username=None, password=None, force=False, dest_app="KODI"): # pylint: disable=too-many-arguments """Internal wrapper for the notify_snatch and notify_download functions Detects JSON-RPC version then branches the logic for either the JSON-RPC or legacy HTTP API methods. @@ -123,17 +123,17 @@ class KODINotifier(object): # suppress notifications if the notifier is disabled but the notify options are checked if not sickbeard.USE_KODI and not force: - logger.log(u"Notification for KODI not enabled, skipping this notification", logger.DEBUG) + logger.log(u"Notification for %s not enabled, skipping this notification" % dest_app, logger.DEBUG) return False result = '' - for curHost in [x.strip() for x in host.split(",")]: - logger.log(u"Sending KODI notification to '" + curHost + "' - " + message, logger.DEBUG) + for curHost in [x.strip() for x in host.split(",") if x.strip()]: + logger.log(u"Sending %s notification to '%s' - %s" % (dest_app, curHost, message), logger.DEBUG) - kodiapi = self._get_kodi_version(curHost, username, password) + kodiapi = self._get_kodi_version(curHost, username, password, dest_app) if kodiapi: if kodiapi <= 4: - logger.log(u"Detected KODI version <= 11, using KODI HTTP API", logger.DEBUG) + logger.log(u"Detected %s version <= 11, using %s HTTP API" % (dest_app, dest_app), logger.DEBUG) command = {'command': 'ExecBuiltIn', 'parameter': 'Notification(' + title.encode("utf-8") + ',' + message.encode( "utf-8") + ')'} @@ -141,15 +141,15 @@ class KODINotifier(object): if notifyResult: result += curHost + ':' + str(notifyResult) else: - logger.log(u"Detected KODI version >= 12, using KODI JSON API", logger.DEBUG) + logger.log(u"Detected %s version >= 12, using %s JSON API" % (dest_app, dest_app), logger.DEBUG) command = '{"jsonrpc":"2.0","method":"GUI.ShowNotification","params":{"title":"%s","message":"%s", "image": "%s"},"id":1}' % ( title.encode("utf-8"), message.encode("utf-8"), self.sr_logo_url) - notifyResult = self._send_to_kodi_json(command, curHost, username, password) - if notifyResult and notifyResult.get('result'): + notifyResult = self._send_to_kodi_json(command, curHost, username, password, dest_app) + if notifyResult and notifyResult.get('result'): # pylint: disable=no-member result += curHost + ':' + notifyResult["result"].decode(sickbeard.SYS_ENCODING) else: if sickbeard.KODI_ALWAYS_ON or force: - logger.log(u"Failed to detect KODI version for '" + curHost + "', check configuration and try again.", logger.WARNING) + logger.log(u"Failed to detect %s version for '%s', check configuration and try again." % (dest_app, curHost), logger.WARNING) result += curHost + ':False' return result @@ -168,7 +168,7 @@ class KODINotifier(object): """ - logger.log(u"Sending request to update library for KODI host: '" + host + "'", logger.DEBUG) + logger.log(u"Sending request to update library for KODI host: '%s'" % host, logger.DEBUG) kodiapi = self._get_kodi_version(host, sickbeard.KODI_USERNAME, sickbeard.KODI_PASSWORD) if kodiapi: @@ -195,7 +195,8 @@ class KODINotifier(object): # Legacy HTTP API (pre KODI 12) methods ############################################################################## - def _send_to_kodi(self, command, host=None, username=None, password=None): + @staticmethod + def _send_to_kodi(command, host=None, username=None, password=None, dest_app="KODI"): # pylint: disable=too-many-arguments """Handles communication to KODI servers via HTTP API Args: @@ -216,7 +217,7 @@ class KODINotifier(object): password = sickbeard.KODI_PASSWORD if not host: - logger.log(u'No KODI host passed, aborting update', logger.WARNING) + logger.log(u'No %s host passed, aborting update' % dest_app, logger.WARNING) return False for key in command: @@ -224,8 +225,9 @@ class KODINotifier(object): command[key] = command[key].encode('utf-8') enc_command = urllib.urlencode(command) - logger.log(u"KODI encoded API command: " + enc_command, logger.DEBUG) + logger.log(u"%s encoded API command: %r" % (dest_app, enc_command), logger.DEBUG) + # url = 'http://%s/xbmcCmds/xbmcHttp/?%s' % (host, enc_command) # maybe need for old plex? url = 'http://%s/kodiCmds/kodiHttp/?%s' % (host, enc_command) try: req = urllib2.Request(url) @@ -234,27 +236,27 @@ class KODINotifier(object): base64string = base64.encodestring('%s:%s' % (username, password))[:-1] authheader = "Basic %s" % base64string req.add_header("Authorization", authheader) - logger.log(u"Contacting KODI (with auth header) via url: " + ss(url), logger.DEBUG) + logger.log(u"Contacting %s (with auth header) via url: %s" % (dest_app, ss(url)), logger.DEBUG) else: - logger.log(u"Contacting KODI via url: " + ss(url), logger.DEBUG) + logger.log(u"Contacting %s via url: %s" % (dest_app, ss(url)), logger.DEBUG) try: response = urllib2.urlopen(req) except (httplib.BadStatusLine, urllib2.URLError) as e: - logger.log(u"Couldn't contact KODI HTTP at %r : %r" % (url, ex(e)), logger.DEBUG) + logger.log(u"Couldn't contact %s HTTP at %r : %r" % (dest_app, url, ex(e)), logger.DEBUG) return False result = response.read().decode(sickbeard.SYS_ENCODING) response.close() - logger.log(u"KODI HTTP response: " + result.replace('\n', ''), logger.DEBUG) + logger.log(u"%s HTTP response: %s" % (dest_app, result.replace('\n', '')), logger.DEBUG) return result except Exception as e: - logger.log(u"Couldn't contact KODI HTTP at %r : %r" % (url, ex(e)), logger.DEBUG) + logger.log(u"Couldn't contact %s HTTP at %r : %r" % (dest_app, url, ex(e)), logger.DEBUG) return False - def _update_library(self, host=None, showName=None): + def _update_library(self, host=None, showName=None): # pylint: disable=too-many-locals, too-many-return-statements """Handles updating KODI host via HTTP API Attempts to update the KODI video library for a specific tv show if passed, @@ -344,7 +346,8 @@ class KODINotifier(object): # JSON-RPC API (KODI 12+) methods ############################################################################## - def _send_to_kodi_json(self, command, host=None, username=None, password=None): + @staticmethod + def _send_to_kodi_json(command, host=None, username=None, password=None, dest_app="KODI"): """Handles communication to KODI servers via JSONRPC Args: @@ -365,11 +368,11 @@ class KODINotifier(object): password = sickbeard.KODI_PASSWORD if not host: - logger.log(u'No KODI host passed, aborting update', logger.WARNING) + logger.log(u'No %s host passed, aborting update' % dest_app, logger.WARNING) return False command = command.encode('utf-8') - logger.log(u"KODI JSON command: " + command, logger.DEBUG) + logger.log(u"%s JSON command: %s" % (dest_app, command), logger.DEBUG) url = 'http://%s/jsonrpc' % host try: @@ -380,22 +383,22 @@ class KODINotifier(object): base64string = base64.encodestring('%s:%s' % (username, password))[:-1] authheader = "Basic %s" % base64string req.add_header("Authorization", authheader) - logger.log(u"Contacting KODI (with auth header) via url: " + ss(url), logger.DEBUG) + logger.log(u"Contacting %s (with auth header) via url: %s" % (dest_app, ss(url)), logger.DEBUG) else: - logger.log(u"Contacting KODI via url: " + ss(url), logger.DEBUG) + logger.log(u"Contacting %s via url: %s" % (dest_app, ss(url)), logger.DEBUG) try: response = urllib2.urlopen(req) except (httplib.BadStatusLine, urllib2.URLError) as e: if sickbeard.KODI_ALWAYS_ON: - logger.log(u"Error while trying to retrieve KODI API version for " + host + ": " + ex(e), logger.WARNING) + logger.log(u"Error while trying to retrieve %s API version for %s: %r" % (dest_app, host, ex(e)), logger.WARNING) return False # parse the json result try: result = json.load(response) response.close() - logger.log(u"KODI JSON response: " + str(result), logger.DEBUG) + logger.log(u"%s JSON response: %s" % (dest_app, result), logger.DEBUG) return result # need to return response for parsing except ValueError as e: logger.log(u"Unable to decode JSON: " + str(response.read()), logger.WARNING) @@ -403,10 +406,10 @@ class KODINotifier(object): except IOError as e: if sickbeard.KODI_ALWAYS_ON: - logger.log(u"Warning: Couldn't contact KODI JSON API at " + ss(url) + " " + ex(e), logger.WARNING) + logger.log(u"Warning: Couldn't contact %s JSON API at %s: %r" % (dest_app, ss(url), ex(e)), logger.WARNING) return False - def _update_library_json(self, host=None, showName=None): + def _update_library_json(self, host=None, showName=None): # pylint: disable=too-many-return-statements, too-many-branches """Handles updating KODI host via HTTP JSON-RPC Attempts to update the KODI video library for a specific tv show if passed, diff --git a/sickbeard/notifiers/plex.py b/sickbeard/notifiers/plex.py index c3c2e125bdf49cea0bc400fc9a73c4e74701a754..217485ad7a921c8f5ba35a23d15c786949566654 100644 --- a/sickbeard/notifiers/plex.py +++ b/sickbeard/notifiers/plex.py @@ -37,69 +37,14 @@ except ImportError: class PLEXNotifier(object): - def _send_to_plex(self, command, host, username=None, password=None): - """Handles communication to Plex hosts via HTTP API - - Args: - command: Dictionary of field/data pairs, encoded via urllib and passed to the legacy xbmcCmds HTTP API - host: Plex host:port - username: Plex API username - password: Plex API password - - Returns: - Returns 'OK' for successful commands or False if there was an error - - """ - - # fill in omitted parameters - if not username: - username = sickbeard.PLEX_CLIENT_USERNAME - if not password: - password = sickbeard.PLEX_CLIENT_PASSWORD - - if not host: - logger.log(u'PLEX: No host specified, check your settings', logger.WARNING) - return False - - for key in command: - if type(command[key]) == unicode: - command[key] = command[key].encode('utf-8') - - enc_command = urllib.urlencode(command) - logger.log(u'PLEX: Encoded API command: ' + enc_command, logger.DEBUG) - - url = u'http://%s/xbmcCmds/xbmcHttp/?%s' % (host, enc_command) - try: - req = urllib2.Request(url) - # if we have a password, use authentication - if password: - base64string = base64.encodestring('%s:%s' % (username, password))[:-1] - authheader = 'Basic %s' % base64string - req.add_header('Authorization', authheader) - logger.log(u'PLEX: Contacting (with auth header) via url: ' + url, logger.DEBUG) - else: - logger.log(u'PLEX: Contacting via url: ' + url, logger.DEBUG) - - response = urllib2.urlopen(req) - - result = response.read().decode(sickbeard.SYS_ENCODING) - response.close() - - logger.log(u'PLEX: HTTP response: ' + result.replace('\n', ''), logger.DEBUG) - # could return result response = re.compile('<html><li>(.+\w)</html>').findall(result) - return 'OK' - - except (urllib2.URLError, IOError) as e: - logger.log(u'PLEX: Warning: Couldn\'t contact Plex at ' + url + ' ' + ex(e), logger.WARNING) - return False - - def _notify_pmc(self, message, title='SickRage', host=None, username=None, password=None, force=False): + @staticmethod + def _notify_pht(message, title='SickRage', host=None, username=None, password=None, force=False): # pylint: disable=too-many-arguments """Internal wrapper for the notify_snatch and notify_download functions Args: message: Message body of the notice to send title: Title of the notice to send - host: Plex Media Client(s) host:port + host: Plex Home Theater(s) host:port username: Plex username password: Plex password force: Used for the Test method to override config safety checks @@ -116,22 +61,13 @@ class PLEXNotifier(object): # fill in omitted parameters if not host: - host = sickbeard.PLEX_HOST + host = sickbeard.PLEX_CLIENT_HOST if not username: username = sickbeard.PLEX_CLIENT_USERNAME if not password: password = sickbeard.PLEX_CLIENT_PASSWORD - result = '' - for curHost in [x.strip() for x in host.split(',')]: - logger.log(u'PLEX: Sending notification to \'%s\' - %s' % (curHost, message), logger.DEBUG) - - command = {'command': 'ExecBuiltIn', 'parameter': 'Notification(%s,%s)' % (title.encode('utf-8'), message.encode('utf-8'))} - notify_result = self._send_to_plex(command, curHost, username, password) - if notify_result: - result += '%s:%s' % (curHost, str(notify_result)) - - return result + return sickbeard.notifiers.kodi_notifier._notify_kodi(message, title=title, host=host, username=username, password=password, force=force, dest_app="PLEX") # pylint: disable=protected-access ############################################################################## # Public functions @@ -139,36 +75,37 @@ class PLEXNotifier(object): def notify_snatch(self, ep_name): if sickbeard.PLEX_NOTIFY_ONSNATCH: - self._notify_pmc(ep_name, common.notifyStrings[common.NOTIFY_SNATCH]) + self._notify_pht(ep_name, common.notifyStrings[common.NOTIFY_SNATCH]) def notify_download(self, ep_name): if sickbeard.PLEX_NOTIFY_ONDOWNLOAD: - self._notify_pmc(ep_name, common.notifyStrings[common.NOTIFY_DOWNLOAD]) + self._notify_pht(ep_name, common.notifyStrings[common.NOTIFY_DOWNLOAD]) def notify_subtitle_download(self, ep_name, lang): if sickbeard.PLEX_NOTIFY_ONSUBTITLEDOWNLOAD: - self._notify_pmc(ep_name + ': ' + lang, common.notifyStrings[common.NOTIFY_SUBTITLE_DOWNLOAD]) + self._notify_pht(ep_name + ': ' + lang, common.notifyStrings[common.NOTIFY_SUBTITLE_DOWNLOAD]) def notify_git_update(self, new_version='??'): - if sickbeard.USE_PLEX: + if sickbeard.USE_PLEX_SERVER: update_text = common.notifyStrings[common.NOTIFY_GIT_UPDATE_TEXT] title = common.notifyStrings[common.NOTIFY_GIT_UPDATE] if update_text and title and new_version: - self._notify_pmc(update_text + new_version, title) + self._notify_pht(update_text + new_version, title) def notify_login(self, ipaddress=""): - if sickbeard.USE_PLEX: + if sickbeard.USE_PLEX_SERVER: update_text = common.notifyStrings[common.NOTIFY_LOGIN_TEXT] title = common.notifyStrings[common.NOTIFY_LOGIN] - self._notify_pmc(update_text.format(ipaddress), title) + self._notify_pht(update_text.format(ipaddress), title) - def test_notify_pmc(self, host, username, password): - return self._notify_pmc('This is a test notification from SickRage', 'Test Notification', host, username, password, force=True) + def test_notify_pht(self, host, username, password): + return self._notify_pht('This is a test notification from SickRage', 'Test Notification', host, username, password, force=True) def test_notify_pms(self, host, username, password, plex_server_token): return self.update_library(host=host, username=username, password=password, plex_server_token=plex_server_token, force=False) - def update_library(self, ep_obj=None, host=None, username=None, password=None, plex_server_token=None, force=True): + @staticmethod + def update_library(ep_obj=None, host=None, username=None, password=None, plex_server_token=None, force=True): # pylint: disable=too-many-arguments, too-many-locals, too-many-statements, too-many-branches """Handles updating the Plex Media Server host via HTTP API Plex Media Server currently only supports updating the whole video library and not a specific path. @@ -178,18 +115,19 @@ class PLEXNotifier(object): """ - if sickbeard.USE_PLEX and sickbeard.PLEX_UPDATE_LIBRARY: - - if not sickbeard.PLEX_SERVER_HOST: - logger.log(u'PLEX: No Plex Media Server host specified, check your settings', logger.DEBUG) - return False + if sickbeard.USE_PLEX_SERVER and sickbeard.PLEX_UPDATE_LIBRARY: if not host: + if not sickbeard.PLEX_SERVER_HOST: + logger.log(u'PLEX: No Plex Media Server host specified, check your settings', logger.DEBUG) + return False host = sickbeard.PLEX_SERVER_HOST + if not username: - username = sickbeard.PLEX_USERNAME + username = sickbeard.PLEX_SERVER_USERNAME + if not password: - password = sickbeard.PLEX_PASSWORD + password = sickbeard.PLEX_SERVER_PASSWORD if not plex_server_token: plex_server_token = sickbeard.PLEX_SERVER_TOKEN @@ -221,13 +159,13 @@ class PLEXNotifier(object): logger.log(u'PLEX: Error parsing plex.tv response: ' + ex(e), logger.DEBUG) file_location = '' if None is ep_obj else ep_obj.location - host_list = [x.strip() for x in host.split(',')] + host_list = [x.strip() for x in host.split(',') if x.strip()] hosts_all = {} hosts_match = {} hosts_failed = [] for cur_host in host_list: - url = 'http://%s/library/sections%s' % (cur_host, token_arg) + url = 'http%s://%s/library/sections%s' % (('', 's')[sickbeard.PLEX_SERVER_HTTPS], cur_host, token_arg) try: xml_tree = etree.parse(urllib.urlopen(url)) media_container = xml_tree.getroot() @@ -269,9 +207,10 @@ class PLEXNotifier(object): host_list = [] for section_key, cur_host in hosts_try.iteritems(): - url = 'http://%s/library/sections/%s/refresh%s' % (cur_host, section_key, token_arg) + url = 'http%s://%s/library/sections/%s/refresh%s' % (('', 's')[sickbeard.PLEX_SERVER_HTTPS], cur_host, section_key, token_arg) try: - force and urllib.urlopen(url) + if force: + urllib.urlopen(url) host_list.append(cur_host) except Exception as e: logger.log(u'PLEX: Error updating library section for Plex Media Server: ' + ex(e), logger.WARNING) diff --git a/sickbeard/tv.py b/sickbeard/tv.py index 2146c5471f586e1c0399c077d580b339c7b5302a..f9d0a51bb2bc2f702023c258a807bc48b41d53b6 100644 --- a/sickbeard/tv.py +++ b/sickbeard/tv.py @@ -16,6 +16,7 @@ # # You should have received a copy of the GNU General Public License # along with SickRage. If not, see <http://www.gnu.org/licenses/>. +# pylint: disable=too-many-lines import os.path import datetime @@ -77,7 +78,7 @@ def dirty_setter(attr_name): return wrapper -class TVShow(object): +class TVShow(object): # pylint: disable=too-many-instance-attributes, too-many-public-methods def __init__(self, indexer, indexerid, lang=""): self._indexerid = int(indexerid) self._indexer = int(indexer) @@ -231,7 +232,7 @@ class TVShow(object): return ep_list - def getEpisode(self, season=None, episode=None, file=None, noCreate=False, absolute_number=None, forceUpdate=False): + def getEpisode(self, season=None, episode=None, file=None, noCreate=False, absolute_number=None): # pylint: disable=too-many-arguments season = try_int(season, None) episode = try_int(episode, None) absolute_number = try_int(absolute_number, None) @@ -449,7 +450,7 @@ class TVShow(object): myDB = db.DBConnection() myDB.mass_action(sql_l) - def loadEpisodesFromDB(self): + def loadEpisodesFromDB(self): # pylint: disable=too-many-locals logger.log(u"Loading all episodes from the DB", logger.DEBUG) scannedEps = {} @@ -590,7 +591,7 @@ class TVShow(object): return scannedEps - def getImages(self, fanart=None, poster=None): + def getImages(self): fanart_result = poster_result = banner_result = False season_posters_result = season_banners_result = season_all_poster_result = season_all_banner_result = False @@ -610,7 +611,7 @@ class TVShow(object): return fanart_result or poster_result or banner_result or season_posters_result or season_banners_result or season_all_poster_result or season_all_banner_result # make a TVEpisode object from a media file - def makeEpFromFile(self, file): + def makeEpFromFile(self, file): # pylint: disable=too-many-locals, too-many-branches, too-many-statements if not ek(os.path.isfile, file): logger.log(str(self.indexerid) + u": That isn't even a real file dude... " + file) @@ -727,9 +728,8 @@ class TVShow(object): if newStatus is not None: with curEp.lock: - logger.log(u"STATUS: we have an associated file, so setting the status from " + str( - curEp.status) + u" to DOWNLOADED/" + str(Quality.statusFromName(file, anime=self.is_anime)), - logger.DEBUG) + logger.log(u"STATUS: we have an associated file, so setting the status from %s to DOWNLOADED/%s" % (curEp.status, Quality.statusFromName(file, anime=self.is_anime)), + logger.DEBUG) curEp.status = Quality.compositeStatus(newStatus, newQuality) with curEp.lock: @@ -746,7 +746,7 @@ class TVShow(object): return rootEp - def loadFromDB(self, skipNFO=False): + def loadFromDB(self): # pylint: disable=too-many-branches, too-many-statements logger.log(str(self.indexerid) + u": Loading show info from database", logger.DEBUG) @@ -825,131 +825,135 @@ class TVShow(object): self.dirty = False return True - def loadFromIndexer(self, cache=True, tvapi=None, cachedSeason=None): + def loadFromIndexer(self, cache=True, tvapi=None): - if self.indexer is not INDEXER_TVRAGE: - logger.log(str(self.indexerid) + u": Loading show info from " + sickbeard.indexerApi(self.indexer).name, logger.DEBUG) - - # There's gotta be a better way of doing this but we don't wanna - # change the cache value elsewhere - if tvapi is None: - lINDEXER_API_PARMS = sickbeard.indexerApi(self.indexer).api_params.copy() - - if not cache: - lINDEXER_API_PARMS['cache'] = False - - if self.lang: - lINDEXER_API_PARMS['language'] = self.lang - - if self.dvdorder != 0: - lINDEXER_API_PARMS['dvdorder'] = True - - t = sickbeard.indexerApi(self.indexer).indexer(**lINDEXER_API_PARMS) - - else: - t = tvapi + if self.indexer == INDEXER_TVRAGE: + return - myEp = t[self.indexerid] + logger.log(str(self.indexerid) + u": Loading show info from " + sickbeard.indexerApi(self.indexer).name, logger.DEBUG) - try: - self.name = myEp['seriesname'].strip() - except AttributeError: - raise sickbeard.indexer_attributenotfound( - "Found %s, but attribute 'seriesname' was empty." % self.indexerid) + # There's gotta be a better way of doing this but we don't wanna + # change the cache value elsewhere + if tvapi: + t = tvapi + else: + lINDEXER_API_PARMS = sickbeard.indexerApi(self.indexer).api_params.copy() - self.classification = getattr(myEp, 'classification', 'Scripted') - self.genre = getattr(myEp, 'genre', '') - self.network = getattr(myEp, 'network', '') - self.runtime = getattr(myEp, 'runtime', '') + if not cache: + lINDEXER_API_PARMS['cache'] = False - self.imdbid = getattr(myEp, 'imdb_id', '') + if self.lang: + lINDEXER_API_PARMS['language'] = self.lang - if getattr(myEp, 'airs_dayofweek', None) is not None and getattr(myEp, 'airs_time', None) is not None: - self.airs = myEp["airs_dayofweek"] + " " + myEp["airs_time"] + if self.dvdorder != 0: + lINDEXER_API_PARMS['dvdorder'] = True - if self.airs is None: - self.airs = '' + t = sickbeard.indexerApi(self.indexer).indexer(**lINDEXER_API_PARMS) - if getattr(myEp, 'firstaired', None) is not None: - self.startyear = int(str(myEp["firstaired"]).split('-')[0]) + myEp = t[self.indexerid] - self.status = getattr(myEp, 'status', 'Unknown') - else: - logger.log(str(self.indexerid) + u": NOT loading info from " + sickbeard.indexerApi(self.indexer).name + " as it is temporarily disabled.", logger.WARNING) - - def loadIMDbInfo(self, imdbapi=None): - - imdb_info = {'imdb_id': self.imdbid, - 'title': '', - 'year': '', - 'akas': [], - 'runtimes': '', - 'genres': [], - 'countries': '', - 'country_codes': [], - 'certificates': [], - 'rating': '', - 'votes': '', - 'last_update': ''} + try: + self.name = myEp['seriesname'].strip() + except AttributeError: + raise sickbeard.indexer_attributenotfound( + "Found %s, but attribute 'seriesname' was empty." % self.indexerid) + + self.classification = getattr(myEp, 'classification', 'Scripted') + self.genre = getattr(myEp, 'genre', '') + self.network = getattr(myEp, 'network', '') + self.runtime = getattr(myEp, 'runtime', '') + + self.imdbid = getattr(myEp, 'imdb_id', '') + + if getattr(myEp, 'airs_dayofweek', None) is not None and getattr(myEp, 'airs_time', None) is not None: + self.airs = myEp["airs_dayofweek"] + " " + myEp["airs_time"] + + if self.airs is None: + self.airs = '' + + if getattr(myEp, 'firstaired', None) is not None: + self.startyear = int(str(myEp["firstaired"]).split('-')[0]) + + self.status = getattr(myEp, 'status', 'Unknown') + + def loadIMDbInfo(self): # pylint: disable=too-many-branches + + imdb_info = { + 'imdb_id': self.imdbid, + 'title': '', + 'year': '', + 'akas': [], + 'runtimes': '', + 'genres': [], + 'countries': '', + 'country_codes': [], + 'certificates': [], + 'rating': '', + 'votes': '', + 'last_update': '' + } i = imdb.IMDb() if not self.imdbid: self.imdbid = i.title2imdbID(self.name, kind='tv series') - if self.imdbid: - logger.log(str(self.indexerid) + u": Loading show info from IMDb", logger.DEBUG) + if not self.imdbid: + logger.log(str(self.indexerid) + u": Not loading show info from IMDb, because we don't know the imdbid", logger.DEBUG) + return - imdbTv = i.get_movie(str(re.sub(r"[^0-9]", "", self.imdbid))) + logger.log(str(self.indexerid) + u": Loading show info from IMDb", logger.DEBUG) - for key in [x for x in imdb_info.keys() if x.replace('_', ' ') in imdbTv.keys()]: - # Store only the first value for string type - if isinstance(imdb_info[key], basestring) and isinstance(imdbTv.get(key.replace('_', ' ')), list): - imdb_info[key] = imdbTv.get(key.replace('_', ' '))[0] - else: - imdb_info[key] = imdbTv.get(key.replace('_', ' ')) + imdbTv = i.get_movie(str(re.sub(r"[^0-9]", "", self.imdbid))) - # Filter only the value - if imdb_info['runtimes']: - imdb_info['runtimes'] = re.search(r'\d+', imdb_info['runtimes']).group(0) + for key in [x for x in imdb_info.keys() if x.replace('_', ' ') in imdbTv.keys()]: + # Store only the first value for string type + if isinstance(imdb_info[key], basestring) and isinstance(imdbTv.get(key.replace('_', ' ')), list): + imdb_info[key] = imdbTv.get(key.replace('_', ' '))[0] else: - imdb_info['runtimes'] = self.runtime + imdb_info[key] = imdbTv.get(key.replace('_', ' ')) - if imdb_info['akas']: - imdb_info['akas'] = '|'.join(imdb_info['akas']) - else: - imdb_info['akas'] = '' + # Filter only the value + if imdb_info['runtimes']: + imdb_info['runtimes'] = re.search(r'\d+', imdb_info['runtimes']).group(0) + else: + imdb_info['runtimes'] = self.runtime - # Join all genres in a string - if imdb_info['genres']: - imdb_info['genres'] = '|'.join(imdb_info['genres']) - else: - imdb_info['genres'] = '' + if imdb_info['akas']: + imdb_info['akas'] = '|'.join(imdb_info['akas']) + else: + imdb_info['akas'] = '' - # Get only the production country certificate if any - if imdb_info['certificates'] and imdb_info['countries']: - dct = {} - try: - for item in imdb_info['certificates']: - dct[item.split(':')[0]] = item.split(':')[1] + # Join all genres in a string + if imdb_info['genres']: + imdb_info['genres'] = '|'.join(imdb_info['genres']) + else: + imdb_info['genres'] = '' - imdb_info['certificates'] = dct[imdb_info['countries']] - except Exception: - imdb_info['certificates'] = '' + # Get only the production country certificate if any + if imdb_info['certificates'] and imdb_info['countries']: + dct = {} + try: + for item in imdb_info['certificates']: + dct[item.split(':')[0]] = item.split(':')[1] - else: + imdb_info['certificates'] = dct[imdb_info['countries']] + except Exception: imdb_info['certificates'] = '' - if imdb_info['country_codes']: - imdb_info['country_codes'] = '|'.join(imdb_info['country_codes']) - else: - imdb_info['country_codes'] = '' + else: + imdb_info['certificates'] = '' + + if imdb_info['country_codes']: + imdb_info['country_codes'] = '|'.join(imdb_info['country_codes']) + else: + imdb_info['country_codes'] = '' - imdb_info['last_update'] = datetime.date.today().toordinal() + imdb_info['last_update'] = datetime.date.today().toordinal() - # Rename dict keys without spaces for DB upsert - self.imdb_info = dict( - (k.replace(' ', '_'), k(v) if hasattr(v, 'keys') else v) for k, v in imdb_info.iteritems()) - logger.log(str(self.indexerid) + u": Obtained info from IMDb ->" + str(self.imdb_info), logger.DEBUG) + # Rename dict keys without spaces for DB upsert + self.imdb_info = dict( + (k.replace(' ', '_'), k(v) if hasattr(v, 'keys') else v) for k, v in imdb_info.iteritems()) + logger.log(str(self.indexerid) + u": Obtained info from IMDb ->" + str(self.imdb_info), logger.DEBUG) def nextEpisode(self): logger.log(str(self.indexerid) + ": Finding the episode which airs next", logger.DEBUG) @@ -1106,7 +1110,6 @@ class TVShow(object): myDB.mass_action(sql_l) def download_subtitles(self, force=False): - # TODO: Add support for force option if not ek(os.path.isdir, self._location): logger.log(str(self.indexerid) + ": Show dir doesn't exist, can't download subtitles", logger.DEBUG) return @@ -1195,10 +1198,11 @@ class TVShow(object): toReturn += "anime: " + str(self.is_anime) + "\n" return toReturn - def qualitiesToString(self, qualities=None): + @staticmethod + def qualitiesToString(qualities=None): return ', '.join([Quality.qualityStrings[quality] for quality in qualities or [] if quality and quality in Quality.qualityStrings]) or 'None' - def wantEpisode(self, season, episode, quality, manualSearch=False, downCurQuality=False): + def wantEpisode(self, season, episode, quality, manualSearch=False, downCurQuality=False): # pylint: disable=too-many-return-statements, too-many-arguments # if the quality isn't one we want under any circumstances then just say no allowed_qualities, preferred_qualities = Quality.splitQuality(self.quality) @@ -1209,7 +1213,7 @@ class TVShow(object): if quality not in allowed_qualities + preferred_qualities or quality is UNKNOWN: logger.log(u"Don't want this quality, ignoring found result for %s S%02dE%02d with quality %s" % - (self.name, season or 0, episode or 0, Quality.qualityStrings[quality]), logger.DEBUG) + (self.name, season or 0, episode or 0, Quality.qualityStrings[quality]), logger.DEBUG) return False myDB = db.DBConnection() @@ -1218,7 +1222,7 @@ class TVShow(object): if not sqlResults or not len(sqlResults): logger.log(u"Unable to find a matching episode in database, ignoring found result for %s S%02dE%02d with quality %s" % - (self.name, season or 0, episode or 0, Quality.qualityStrings[quality]), logger.DEBUG) + (self.name, season or 0, episode or 0, Quality.qualityStrings[quality]), logger.DEBUG) return False epStatus = int(sqlResults[0]["status"]) @@ -1227,15 +1231,15 @@ class TVShow(object): # if we know we don't want it then just say no if epStatus in Quality.ARCHIVED + [UNAIRED, SKIPPED, IGNORED] and not manualSearch: logger.log(u"Existing episode status is '%s', ignoring found result for %s S%02dE%02d with quality %s" % - (epStatus_text, self.name, season or 0, episode or 0, Quality.qualityStrings[quality]), logger.DEBUG) + (epStatus_text, self.name, season or 0, episode or 0, Quality.qualityStrings[quality]), logger.DEBUG) return False - curStatus, curQuality = Quality.splitCompositeStatus(epStatus) + _, curQuality = Quality.splitCompositeStatus(epStatus) # if it's one of these then we want it as long as it's in our allowed initial qualities if epStatus in (WANTED, SKIPPED, UNKNOWN): logger.log(u"Existing episode status is '%s', getting found result for %s S%02dE%02d with quality %s" % - (epStatus_text, self.name, season or 0, episode or 0, Quality.qualityStrings[quality]), logger.DEBUG) + (epStatus_text, self.name, season or 0, episode or 0, Quality.qualityStrings[quality]), logger.DEBUG) return True elif manualSearch: if (downCurQuality and quality >= curQuality) or (not downCurQuality and quality > curQuality): @@ -1247,18 +1251,18 @@ class TVShow(object): # if we are re-downloading then we only want it if it's in our preferred_qualities list and better than what we have, or we only have one bestQuality and we do not have that quality yet if epStatus in Quality.DOWNLOADED + Quality.SNATCHED + Quality.SNATCHED_PROPER and quality in preferred_qualities and (quality > curQuality or curQuality not in preferred_qualities): logger.log(u"Episode already exists with quality %s but the found result quality %s is wanted more, getting found result for %s S%02dE%02d" % - (Quality.qualityStrings[curQuality], Quality.qualityStrings[quality], self.name, season or 0, episode or 0), logger.DEBUG) + (Quality.qualityStrings[curQuality], Quality.qualityStrings[quality], self.name, season or 0, episode or 0), logger.DEBUG) return True elif curQuality == Quality.UNKNOWN and manualSearch: logger.log(u"Episode already exists but quality is Unknown, getting found result for %s S%02dE%02d with quality %s" % - (self.name, season or 0, episode or 0, Quality.qualityStrings[quality]), logger.DEBUG) + (self.name, season or 0, episode or 0, Quality.qualityStrings[quality]), logger.DEBUG) return True else: logger.log(u"Episode already exists with quality %s and the found result has same/lower quality, ignoring found result for %s S%02dE%02d with quality %s" % - (Quality.qualityStrings[curQuality], self.name, season or 0, episode or 0, Quality.qualityStrings[quality]), logger.DEBUG) + (Quality.qualityStrings[curQuality], self.name, season or 0, episode or 0, Quality.qualityStrings[quality]), logger.DEBUG) return False - def getOverview(self, epStatus): + def getOverview(self, epStatus): # pylint: disable=too-many-return-statements, too-many-branches """ Get the Overview status from the Episode status @@ -1289,13 +1293,7 @@ class TVShow(object): ep_status, cur_quality = Quality.splitCompositeStatus(ep_status) if cur_quality not in allowed_qualities + preferred_qualities: - if cur_quality != Quality.UNKNOWN and ( - (allowed_qualities and cur_quality > max(allowed_qualities)) or - (preferred_qualities and cur_quality > max(preferred_qualities)) - ): - return Overview.GOOD - else: - return Overview.QUAL + return Overview.QUAL elif preferred_qualities and cur_quality not in preferred_qualities: return Overview.QUAL else: @@ -1303,7 +1301,6 @@ class TVShow(object): else: logger.log(u'Could not parse episode status into a valid overview status: %s' % epStatus, logger.ERROR) - def __getstate__(self): d = dict(self.__dict__) del d['lock'] @@ -1314,7 +1311,7 @@ class TVShow(object): self.__dict__.update(d) -class TVEpisode(object): +class TVEpisode(object): # pylint: disable=too-many-instance-attributes, too-many-public-methods def __init__(self, show, season, episode, file=""): self._name = "" self._season = season @@ -1448,13 +1445,13 @@ class TVEpisode(object): if ek(os.path.isfile, self.location): for cur_provider in sickbeard.metadata_provider_dict.values(): if cur_provider.episode_metadata: - new_result = cur_provider._has_episode_metadata(self) + new_result = cur_provider._has_episode_metadata(self) # pylint: disable=protected-access else: new_result = False cur_nfo = new_result or cur_nfo if cur_provider.episode_thumbnails: - new_result = cur_provider._has_episode_thumb(self) + new_result = cur_provider._has_episode_thumb(self) # pylint: disable=protected-access else: new_result = False cur_tbn = new_result or cur_tbn @@ -1488,7 +1485,7 @@ class TVEpisode(object): if not result: raise EpisodeNotFoundException("Couldn't find episode S%02dE%02d" % (season or 0, episode or 0)) - def loadFromDB(self, season, episode): + def loadFromDB(self, season, episode): # pylint: disable=too-many-branches # logger.log(u"%s: Loading episode details for %s S%02dE%02d from DB" % (self.show.indexerid, self.show.name, season or 0, episode or 0), logger.DEBUG) myDB = db.DBConnection() @@ -1565,7 +1562,7 @@ class TVEpisode(object): self.dirty = False return True - def loadFromIndexer(self, season=None, episode=None, cache=True, tvapi=None, cachedSeason=None): + def loadFromIndexer(self, season=None, episode=None, cache=True, tvapi=None, cachedSeason=None): # pylint: disable=too-many-arguments, too-many-branches, too-many-statements if season is None: season = self.season @@ -1578,8 +1575,12 @@ class TVEpisode(object): indexer_lang = self.show.lang try: - if cachedSeason is None: - if tvapi is None: + if cachedSeason: + myEp = cachedSeason[episode] + else: + if tvapi: + t = tvapi + else: lINDEXER_API_PARMS = sickbeard.indexerApi(self.indexer).api_params.copy() if not cache: @@ -1592,19 +1593,14 @@ class TVEpisode(object): lINDEXER_API_PARMS['dvdorder'] = True t = sickbeard.indexerApi(self.indexer).indexer(**lINDEXER_API_PARMS) - else: - t = tvapi myEp = t[self.show.indexerid][season][episode] - else: - myEp = cachedSeason[episode] except (sickbeard.indexer_error, IOError) as e: logger.log(u"" + sickbeard.indexerApi(self.indexer).name + " threw up an error: " + ex(e), logger.DEBUG) # if the episode is already valid just log it, if not throw it up if self.name: - logger.log(u"" + sickbeard.indexerApi( - self.indexer).name + " timed out but we have enough info from other sources, allowing the error", - logger.DEBUG) + logger.log(u"" + sickbeard.indexerApi(self.indexer).name + + " timed out but we have enough info from other sources, allowing the error", logger.DEBUG) return else: logger.log(u"" + sickbeard.indexerApi(self.indexer).name + " timed out, unable to create the episode", @@ -1621,10 +1617,6 @@ class TVEpisode(object): if getattr(myEp, 'episodename', None) is None: logger.log(u"This episode %s - S%02dE%02d has no name on %s. Setting to an empty string" % (self.show.name, season or 0, episode or 0, sickbeard.indexerApi(self.indexer).name)) setattr(myEp, 'episodename', '') - # # if I'm incomplete on TVDB but I once was complete then just delete myself from the DB for now - # if self.indexerid != -1: - # self.deleteEpisode() - # return False if getattr(myEp, 'absolute_number', None) is None: logger.log(u"%s: This episode %s - S%02dE%02d has no absolute number on %s" % (self.show.indexerid, self.show.name, season or 0, episode or 0, sickbeard.indexerApi(self.indexer).name), logger.DEBUG) @@ -1675,8 +1667,8 @@ class TVEpisode(object): return False # don't update show status if show dir is missing, unless it's missing on purpose - if not ek(os.path.isdir, self.show._location) and not sickbeard.CREATE_MISSING_SHOW_DIRS and not sickbeard.ADD_SHOWS_WO_DIR: - logger.log(u"The show dir %s is missing, not bothering to change the episode statuses since it'd probably be invalid" % self.show._location) + if not ek(os.path.isdir, self.show._location) and not sickbeard.CREATE_MISSING_SHOW_DIRS and not sickbeard.ADD_SHOWS_WO_DIR: # pylint: disable=protected-access + logger.log(u"The show dir %s is missing, not bothering to change the episode statuses since it'd probably be invalid" % self.show._location) # pylint: disable=protected-access return if self.location: @@ -1708,9 +1700,9 @@ class TVEpisode(object): logger.log(u"6 Status changes from " + str(self.status) + " to " + str(UNKNOWN), logger.DEBUG) self.status = UNKNOWN - def loadFromNFO(self, location): + def loadFromNFO(self, location): # pylint: disable=too-many-branches - if not ek(os.path.isdir, self.show._location): + if not ek(os.path.isdir, self.show._location): # pylint: disable=protected-access logger.log( str(self.show.indexerid) + u": The show dir is missing, not bothering to try loading the episode NFO") return @@ -1723,11 +1715,10 @@ class TVEpisode(object): if self.location != "": - if self.status == UNKNOWN: - if sickbeard.helpers.isMediaFile(self.location): - logger.log(u"7 Status changes from " + str(self.status) + " to " + str( - Quality.statusFromName(self.location, anime=self.show.is_anime)), logger.DEBUG) - self.status = Quality.statusFromName(self.location, anime=self.show.is_anime) + if self.status == UNKNOWN and sickbeard.helpers.isMediaFile(self.location): + logger.log(u"7 Status changes from " + str(self.status) + " to " + str( + Quality.statusFromName(self.location, anime=self.show.is_anime)), logger.DEBUG) + self.status = Quality.statusFromName(self.location, anime=self.show.is_anime) nfoFile = replace_extension(self.location, "nfo") logger.log(str(self.show.indexerid) + u": Using NFO name " + nfoFile, logger.DEBUG) @@ -1808,7 +1799,7 @@ class TVEpisode(object): def createMetaFiles(self): - if not ek(os.path.isdir, self.show._location): + if not ek(os.path.isdir, self.show._location): # pylint: disable=protected-access logger.log(str(self.show.indexerid) + u": The show dir is missing, not bothering to try to create metadata") return @@ -2040,7 +2031,7 @@ class TVEpisode(object): return goodName - def _replace_map(self): + def _replace_map(self): # pylint: disable=too-many-branches """ Generates a replacement map for this episode which maps all possible custom naming patterns to the correct value for this episode. @@ -2158,7 +2149,8 @@ class TVEpisode(object): '%RT': "PROPER" if self.is_proper else "", } - def _format_string(self, pattern, replace_map): + @staticmethod + def _format_string(pattern, replace_map): """ Replaces all template strings with the correct value """ @@ -2173,7 +2165,7 @@ class TVEpisode(object): return result_name - def _format_pattern(self, pattern=None, multi=None, anime_type=None): + def _format_pattern(self, pattern=None, multi=None, anime_type=None): # pylint: disable=too-many-branches, too-many-statements, too-many-locals """ Manipulates an episode naming pattern and then fills the template in """ @@ -2297,7 +2289,7 @@ class TVEpisode(object): if multi == NAMING_LIMITED_EXTEND_E_PREFIXED: ep_string += 'E' - ep_string += other_ep._format_string(ep_format.upper(), other_ep._replace_map()) + ep_string += other_ep._format_string(ep_format.upper(), other_ep._replace_map()) # pylint: disable=protected-access if anime_type != 3: if self.absolute_number == 0: @@ -2405,7 +2397,7 @@ class TVEpisode(object): return sanitize_filename(self._format_pattern(name_groups[-1], multi, anime_type)) - def rename(self): + def rename(self): # pylint: disable=too-many-locals, too-many-branches """ Renames an episode file and all related files to the location and filename as specified in the naming settings. diff --git a/sickbeard/webapi.py b/sickbeard/webapi.py index 0403c3234b25dcb2f958007337621f0b4feac1ae..be38f1b8eba78fed7b918daef3300e3d43be4aaa 100644 --- a/sickbeard/webapi.py +++ b/sickbeard/webapi.py @@ -2775,7 +2775,7 @@ class CMD_Shows(ApiCall): "desc": "Get all shows in SickRage", "optionalParameters": { "sort": {"desc": "The sorting strategy to apply to the list of shows"}, - "paused": {"desc": "True to include paused shows, False otherwise"}, + "paused": {"desc": "True: show paused, False: show un-paused, otherwise show all"}, }, } @@ -2791,9 +2791,9 @@ class CMD_Shows(ApiCall): """ Get all shows in SickRage """ shows = {} for curShow in sickbeard.showList: - - if not self.paused and curShow.paused: # If we're not including paused shows, and the current show is paused - continue # continue with the next show + # If self.paused is None: show all, 0: show un-paused, 1: show paused + if self.paused is not None and self.paused != curShow.paused: + continue indexer_show = helpers.mapIndexersToShow(curShow) diff --git a/sickbeard/webserve.py b/sickbeard/webserve.py index d160599662f044d4ab976191427316c251697533..fd4f08c47685fd1906dfdf8813777fb82efa25f0 100644 --- a/sickbeard/webserve.py +++ b/sickbeard/webserve.py @@ -751,7 +751,7 @@ class Home(WebRoot): @staticmethod def havePLEX(): - return sickbeard.USE_PLEX and sickbeard.PLEX_UPDATE_LIBRARY + return sickbeard.USE_PLEX_SERVER and sickbeard.PLEX_UPDATE_LIBRARY @staticmethod def haveEMBY(): @@ -884,7 +884,7 @@ class Home(WebRoot): return finalResult - def testPMC(self, host=None, username=None, password=None): + def testPHT(self, host=None, username=None, password=None): self.set_header('Cache-Control', 'max-age=0,no-cache,no-store') if None is not password and set('*') == set(password): @@ -892,14 +892,14 @@ class Home(WebRoot): finalResult = '' for curHost in [x.strip() for x in host.split(',')]: - curResult = notifiers.plex_notifier.test_notify_pmc(urllib.unquote_plus(curHost), username, password) + curResult = notifiers.plex_notifier.test_notify_pht(urllib.unquote_plus(curHost), username, password) if len(curResult.split(':')) > 2 and 'OK' in curResult.split(':')[2]: - finalResult += 'Successful test notice sent to Plex client ... ' + urllib.unquote_plus(curHost) + finalResult += 'Successful test notice sent to Plex Home Theater ... ' + urllib.unquote_plus(curHost) else: - finalResult += 'Test failed for Plex client ... ' + urllib.unquote_plus(curHost) + finalResult += 'Test failed for Plex Home Theater ... ' + urllib.unquote_plus(curHost) finalResult += '<br>' + '\n' - ui.notifications.message('Tested Plex client(s): ', urllib.unquote_plus(host.replace(',', ', '))) + ui.notifications.message('Tested Plex Home Theater(s): ', urllib.unquote_plus(host.replace(',', ', '))) return finalResult @@ -907,17 +907,17 @@ class Home(WebRoot): self.set_header('Cache-Control', 'max-age=0,no-cache,no-store') if password is not None and set('*') == set(password): - password = sickbeard.PLEX_PASSWORD + password = sickbeard.PLEX_SERVER_PASSWORD finalResult = '' curResult = notifiers.plex_notifier.test_notify_pms(urllib.unquote_plus(host), username, password, plex_server_token) if curResult is None: - finalResult += 'Successful test of Plex server(s) ... ' + urllib.unquote_plus(host.replace(',', ', ')) + finalResult += 'Successful test of Plex Media Server(s) ... ' + urllib.unquote_plus(host.replace(',', ', ')) elif curResult is False: finalResult += 'Test failed, No Plex Media Server host specified' else: - finalResult += 'Test failed for Plex server(s) ... ' + urllib.unquote_plus(str(curResult).replace(',', ', ')) + finalResult += 'Test failed for Plex Media Server(s) ... ' + urllib.unquote_plus(str(curResult).replace(',', ', ')) finalResult += '<br>' + '\n' ui.notifications.message('Tested Plex Media Server host(s): ', urllib.unquote_plus(host.replace(',', ', '))) @@ -3755,7 +3755,7 @@ class ConfigGeneral(Config): calendar_unprotected=None, calendar_icons=None, debug=None, ssl_verify=None, no_restart=None, coming_eps_missed_range=None, fuzzy_dating=None, trim_zero=None, date_preset=None, date_preset_na=None, time_preset=None, indexer_timeout=None, download_url=None, rootDir=None, theme_name=None, default_page=None, - git_reset=None, git_username=None, git_password=None, git_autoissues=None, display_all_seasons=None): + git_reset=None, git_username=None, git_password=None, display_all_seasons=None): results = [] @@ -3787,7 +3787,6 @@ class ConfigGeneral(Config): # sickbeard.GIT_RESET = config.checkbox_to_value(git_reset) # Force GIT_RESET sickbeard.GIT_RESET = 1 - sickbeard.GIT_AUTOISSUES = config.checkbox_to_value(git_autoissues) sickbeard.GIT_PATH = git_path sickbeard.GIT_REMOTE = git_remote sickbeard.CALENDAR_UNPROTECTED = config.checkbox_to_value(calendar_unprotected) @@ -4516,8 +4515,8 @@ class ConfigProviders(Config): provider_list = provider_list + disabled_list # dynamically load provider settings - for curTorrentProvider in [curProvider for curProvider in sickbeard.providers.sortedProviderList() if - curProvider.provider_type == GenericProvider.TORRENT]: + for curTorrentProvider in [prov for prov in sickbeard.providers.sortedProviderList() if + prov.provider_type == GenericProvider.TORRENT]: if hasattr(curTorrentProvider, 'custom_url'): try: @@ -4667,8 +4666,8 @@ class ConfigProviders(Config): except Exception: curTorrentProvider.subtitle = 0 - for curNzbProvider in [curProvider for curProvider in sickbeard.providers.sortedProviderList() if - curProvider.provider_type == GenericProvider.NZB]: + for curNzbProvider in [prov for prov in sickbeard.providers.sortedProviderList() if + prov.provider_type == GenericProvider.NZB]: if hasattr(curNzbProvider, 'api_key'): try: @@ -4742,11 +4741,11 @@ class ConfigNotifications(Config): kodi_notify_onsubtitledownload=None, kodi_update_onlyfirst=None, kodi_update_library=None, kodi_update_full=None, kodi_host=None, kodi_username=None, kodi_password=None, - use_plex=None, plex_notify_onsnatch=None, plex_notify_ondownload=None, + use_plex_server=None, plex_notify_onsnatch=None, plex_notify_ondownload=None, plex_notify_onsubtitledownload=None, plex_update_library=None, - plex_server_host=None, plex_server_token=None, plex_host=None, plex_username=None, plex_password=None, + plex_server_host=None, plex_server_token=None, plex_client_host=None, plex_server_username=None, plex_server_password=None, use_plex_client=None, plex_client_username=None, plex_client_password=None, - use_emby=None, emby_host=None, emby_apikey=None, + plex_server_https=None, use_emby=None, emby_host=None, emby_apikey=None, use_growl=None, growl_notify_onsnatch=None, growl_notify_ondownload=None, growl_notify_onsubtitledownload=None, growl_host=None, growl_password=None, use_freemobile=None, freemobile_notify_onsnatch=None, freemobile_notify_ondownload=None, @@ -4799,19 +4798,20 @@ class ConfigNotifications(Config): sickbeard.KODI_USERNAME = kodi_username sickbeard.KODI_PASSWORD = kodi_password - sickbeard.USE_PLEX = config.checkbox_to_value(use_plex) + sickbeard.USE_PLEX_SERVER = config.checkbox_to_value(use_plex_server) sickbeard.PLEX_NOTIFY_ONSNATCH = config.checkbox_to_value(plex_notify_onsnatch) sickbeard.PLEX_NOTIFY_ONDOWNLOAD = config.checkbox_to_value(plex_notify_ondownload) sickbeard.PLEX_NOTIFY_ONSUBTITLEDOWNLOAD = config.checkbox_to_value(plex_notify_onsubtitledownload) sickbeard.PLEX_UPDATE_LIBRARY = config.checkbox_to_value(plex_update_library) - sickbeard.PLEX_HOST = config.clean_hosts(plex_host) + sickbeard.PLEX_CLIENT_HOST = config.clean_hosts(plex_client_host) sickbeard.PLEX_SERVER_HOST = config.clean_hosts(plex_server_host) sickbeard.PLEX_SERVER_TOKEN = config.clean_host(plex_server_token) - sickbeard.PLEX_USERNAME = plex_username - sickbeard.PLEX_PASSWORD = plex_password - sickbeard.USE_PLEX_CLIENT = config.checkbox_to_value(use_plex) - sickbeard.PLEX_CLIENT_USERNAME = plex_username - sickbeard.PLEX_CLIENT_PASSWORD = plex_password + sickbeard.PLEX_SERVER_USERNAME = plex_server_username + sickbeard.PLEX_SERVER_PASSWORD = plex_server_password + sickbeard.USE_PLEX_CLIENT = config.checkbox_to_value(use_plex_server) + sickbeard.PLEX_CLIENT_USERNAME = plex_client_username + sickbeard.PLEX_CLIENT_PASSWORD = plex_client_password + sickbeard.PLEX_SERVER_HTTPS = config.checkbox_to_value(plex_server_https) sickbeard.USE_EMBY = config.checkbox_to_value(use_emby) sickbeard.EMBY_HOST = config.clean_host(emby_host) diff --git a/tests/sickrage_tests/show/show_tests.py b/tests/sickrage_tests/show/show_tests.py index ab53550f74df3e19ee60403ec98af27044d6c335..f28ec0c6b71a3d9297166abb8dcee4bfcd571b81 100644 --- a/tests/sickrage_tests/show/show_tests.py +++ b/tests/sickrage_tests/show/show_tests.py @@ -133,11 +133,9 @@ class TestTVShow(TVShow): def __init__(self, indexer, indexer_id): super(TestTVShow, self).__init__(indexer, indexer_id) - def loadFromDB(self, skip_nfo=False): + def loadFromDB(self): """ Override TVShow.loadFromDB to avoid DB access during testing - - :param skip_nfo: ...not used """ pass diff --git a/tests/tv_tests.py b/tests/tv_tests.py index 810d95c99a7bf0f435a02d8711d44a1168e624dc..1b02e70940040affdf6db4977df94336d4a78a01 100644 --- a/tests/tv_tests.py +++ b/tests/tv_tests.py @@ -66,11 +66,11 @@ class TVShowTests(test.SickbeardTestDBCase): show.startyear = 1987 show.saveToDB() - show.loadFromDB(skipNFO=True) + show.loadFromDB() show.indexerid = 0002 show.saveToDB() - show.loadFromDB(skipNFO=True) + show.loadFromDB() self.assertEqual(show.indexerid, 0002) @@ -81,7 +81,7 @@ class TVShowTests(test.SickbeardTestDBCase): show = TVShow(1, 0001, "en") show.name = "newName" show.saveToDB() - show.loadFromDB(skipNFO=True) + show.loadFromDB() self.assertEqual(show.name, "newName")