diff --git a/.build/.snyk b/.build/.snyk new file mode 100644 index 0000000000000000000000000000000000000000..2394d030e7b885697f845e6ba8f3148ff1ca3cd5 --- /dev/null +++ b/.build/.snyk @@ -0,0 +1,15 @@ +ignore: + 'npm:semver:20150403': + - semver@2.3.2: + reason: Waiting for official update + expires: '2015-12-21T06:00:27.961Z' + 'npm:uglify-js:20150824': + - uglify-js@2.3.6: + reason: Waiting for official update + expires: '2015-12-21T06:00:27.962Z' + 'npm:uglify-js:20151024': + - uglify-js@2.3.6: + reason: Waiting for official update + expires: '2015-12-21T06:00:27.962Z' +patch: {} +version: v1 diff --git a/.build/Gruntfile.js b/.build/Gruntfile.js index c17b6261be3f3e1386b53992fd7ad1832b7e405f..8cb9dbda06574ae45961239741bc1daa60b2731e 100644 --- a/.build/Gruntfile.js +++ b/.build/Gruntfile.js @@ -53,9 +53,14 @@ module.exports = function(grunt) { }, jshint: { options: { - eqeqeq: true + jshintrc: '../.jshintrc' }, - uses_defaults: ['../gui/slick/js/**/*.js'] + all: [ + '../gui/slick/js/**/*.js', + '!../gui/slick/js/lib/**/*.js', + '!../gui/slick/js/ajaxNotifications.js', + '!../gui/slick/js/**/*.min.js', // We use this because ignores doesn't seem to work :( + ] } }); @@ -64,5 +69,12 @@ module.exports = function(grunt) { grunt.loadNpmTasks('grunt-contrib-cssmin'); grunt.loadNpmTasks('grunt-contrib-jshint'); - grunt.registerTask('default', ['bower_concat', 'uglify', 'cssmin']); + grunt.registerTask('default', [ + 'bower_concat', + 'uglify', + 'cssmin'] + ); + grunt.registerTask('travis', [ + 'jshint' + ]); }; diff --git a/.build/package.json b/.build/package.json index 6cd6e05d1d190a93b4f0d75d71fa66b4e56de98c..49d0816d9d36d12b27ea676cde6a9e567af51101 100644 --- a/.build/package.json +++ b/.build/package.json @@ -2,14 +2,6 @@ "name": "sickrage", "version": "4.0.72", "private": true, - "devDependencies": { - "grunt": "^0.4.5", - "grunt-bower-concat": "^0.5.0", - "grunt-cli": "^0.1.13", - "grunt-contrib-cssmin": "^0.14.0", - "grunt-contrib-jshint": "^0.11.3", - "grunt-contrib-uglify": "^0.9.2" - }, "repository": { "type": "git", "url": "git+https://github.com/SickRage/SickRage.git" @@ -17,5 +9,17 @@ "bugs": { "url": "https://github.com/SickRage/SickRage/issues" }, - "homepage": "https://github.com/SickRage/SickRage#readme" + "homepage": "https://github.com/SickRage/SickRage#readme", + "scripts": { + "test": "snyk test" + }, + "dependencies": { + "snyk": "^1.3.1", + "grunt": "^0.4.5", + "grunt-bower-concat": "^0.5.0", + "grunt-cli": "^0.1.13", + "grunt-contrib-cssmin": "^0.14.0", + "grunt-contrib-jshint": "^0.11.3", + "grunt-contrib-uglify": "^0.9.2" + } } diff --git a/.jshintignore b/.jshintignore new file mode 100644 index 0000000000000000000000000000000000000000..121531af8467c5344c1ddd59c7a6452793e15152 --- /dev/null +++ b/.jshintignore @@ -0,0 +1 @@ +*.min.js diff --git a/.jshintrc b/.jshintrc index d7a56347f30eba25d219bd053a83c8a6ab37b85b..1c554638c5d225598b91c26d17b6ef6ef205f8e3 100644 --- a/.jshintrc +++ b/.jshintrc @@ -11,20 +11,21 @@ "jquery": true, "latedef": true, "maxerr": 100, + "maxlen": 1000, "noarg": true, "noempty": true, "nonbsp": true, "undef": true, "unused": true, "node": true, - "globals": { + "predef": { "srRoot": true, "themeSpinner": true, "metaToBool": true, "getMeta": true, "isMeta": true, "topImageHtml": true, - "generate_bwlist": true, + "generateBlackWhiteList": true, "_": true, "bootbox": true, "PNotify": true, diff --git a/.travis.yml b/.travis.yml index 74d73d121d460d86a86baa6a5d19babc05de1fc5..229ec07b80676b248457bccec41602364c83c1e4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,5 @@ -sudo: false - -language: python +language: + - python python: 2.7.9 @@ -10,11 +9,21 @@ branches: except: - master -cache: pip +before_install: + - npm install -g grunt-cli + - npm install -g bower + - cd .build && npm install && bower install && cd .. script: + - cd .build && grunt travis && cd .. - ./tests/all_tests.py +cache: + directories: + - $HOME/.cache/pip + - .build/bower_components + - .build/node_modules + after_failure: - cat ./Logs/sickrage.log diff --git a/contributing.md b/contributing.md index e933417c35695083248d5fb63e7eaacf096bfce8..7b1c811a2cea960fb46f229ec262783aef693729 100644 --- a/contributing.md +++ b/contributing.md @@ -1,6 +1,6 @@ ### Questions about SickRage? -To get your questions answered, please ask on the [SickRage Forum](http://sickrage.tv/), or [#sickrage-issues](http://webchat.freenode.net/?channels=sickrage-issues) IRC channel on irc.freenode.net +To get your questions answered, please ask on the [#sickrage-issues](http://webchat.freenode.net/?channels=sickrage-issues) IRC channel on irc.freenode.net # Contributing to SickRage @@ -17,11 +17,9 @@ The goal of this guide is to provide the best way to contribute to the official ## Discussion -### Forum and IRC +If you think you've found a bug please [file it in the bug tracker](#how-to-report-bugs). -The SickRage development team frequently tracks posts on the [SickRage Forum](http://sickrage.tv/). If you have longer posts or questions please feel free to post them there. If you think you've found a bug please [file it in the bug tracker](#how-to-report-bugs). - -Additionally most of the SickRage development team can be found in the [#sickrage-issues](http://webchat.freenode.net/?channels=sickrage-issues) IRC channel on irc.freenode.net. +Most of the SickRage development team can be found in the [#sickrage-issues](http://webchat.freenode.net/?channels=sickrage-issues) IRC channel on irc.freenode.net. ## How to Report Bugs @@ -30,7 +28,7 @@ Additionally most of the SickRage development team can be found in the [#sickrag Many bugs reported are actually issues with the user mis-understanding of how something works (there are a bit of moving parts to an ideal setup) and most of the time can be fixed by just changing some settings to fit the users needs. -If you are new to SickRage, it is usually a much better idea to ask for help first in the [Using SickRage Forum](http://sickrage.tv) or the [SickRage IRC channel](http://webchat.freenode.net/?channels=sickrage-issues). You will get much quicker support, and you will help avoid tying up the SickRage team with invalid bug reports. +If you are new to SickRage, it is usually a much better idea to ask for help first in the [SickRage IRC channel](http://webchat.freenode.net/?channels=sickrage-issues). You will get much quicker support, and you will help avoid tying up the SickRage team with invalid bug reports. ### Try the latest version of SickRage @@ -44,7 +42,7 @@ Bugs in old versions of SickRage may have already been fixed. In order to avoid **NEVER write your patches to the master branch** - it gets messy (I say this from experience!) -**ALWAYS USE A "TOPIC" BRANCH!** Personally I like the `branch-feature_name` format that way its easy to identify the branch and feature at a glance. Also please make note of any forum post / issue number in the pull commit so we know what you are solving (it helps with cleaning up the related items later). +**ALWAYS USE A "TOPIC" BRANCH!** Personally I like the `branch-feature_name` format that way its easy to identify the branch and feature at a glance. Also please make note of any issue number in the pull commit so we know what you are solving (it helps with cleaning up the related items later). Please follow these guidelines before reporting a bug: @@ -53,7 +51,7 @@ Please follow these guidelines before reporting a bug: 2. **Use the search on sickrage-issues** — check if the issue has already been reported. If it has been, please comment on the existing issue. -3. **Provide a means to reproduce the problem** — Please provide as much details as possible, e.g. SickRage log files (obfuscate apikey/passwords), browser and operating system versions, how you started SickRage, and of course the steps to reproduce the problem. Bugs are always reported in the forums. +3. **Provide a means to reproduce the problem** — Please provide as much details as possible, e.g. SickRage log files (obfuscate apikey/passwords), browser and operating system versions, how you started SickRage, and of course the steps to reproduce the problem. ### Feature requests diff --git a/gui/slick/js/new/addTrendingShow.js b/gui/slick/js/addTrendingShow.js similarity index 87% rename from gui/slick/js/new/addTrendingShow.js rename to gui/slick/js/addTrendingShow.js index 84f00c70e938ca90e69effeb330964b3bcd8394e..ef5abbc17df8265c3d1b73b58d8eda01503a7024 100644 --- a/gui/slick/js/new/addTrendingShow.js +++ b/gui/slick/js/addTrendingShow.js @@ -1,7 +1,7 @@ $.fn.loadContent = function(path, loadingTxt, errorTxt) { $(this).html('<img id="searchingAnim" src="' + srRoot + '/images/loading32' + themeSpinner + '.gif" height="32" width="32" /> ' + loadingTxt); - $(this).load(srRoot + path + ' #container', function(response, status, xhr) { - if (status == "error") $(this).empty().html(errorTxt); + $(this).load(srRoot + path + ' #container', function(response, status) { + if (status === "error") { $(this).empty().html(errorTxt); } }); }; diff --git a/gui/slick/js/apibuilder.js b/gui/slick/js/apibuilder.js index 80e27e157271f699b31197992fad60aa81c288c1..5623ba810d5520cfa6af6a21928470199ec578e2 100644 --- a/gui/slick/js/apibuilder.js +++ b/gui/slick/js/apibuilder.js @@ -12,7 +12,7 @@ $(document).ready(function() { var name = $(item).attr('name'); var value = $(item).val(); - if(name !== undefined && value !== undefined && name != value && value) { + if(name !== undefined && value !== undefined && name !== value && value) { if($.isArray(value)) { value = value.join('|'); } @@ -21,7 +21,7 @@ $(document).ready(function() { } }); - if(profile) url += '&profile=1'; + if(profile) { url += '&profile=1'; } var requestTime = new Date().getTime(); $.get(url, function (data, textStatus, jqXHR) { @@ -33,7 +33,7 @@ $(document).ready(function() { $(timeId).text(responseTime + 'ms'); $(urlId).text(url + (jsonp ? '&jsonp=foo' : '')); - if(responseType.slice(0, 6) == 'image/') { + if(responseType.slice(0, 6) === 'image/') { target.html($('<img/>').attr('src', url)); } else { var json = JSON.stringify(data, null, 4); @@ -65,10 +65,10 @@ $(document).ready(function() { select.removeClass('hidden'); select.find('option:gt(0)').remove(); - for(var episode in episodes[show][season]) { + for(var episode in episodes[show][season]) { // jshint ignore:line select.append($('<option>', { - value: episodes[show][season][episode], - label: 'Episode ' + episodes[show][season][episode], + value: episodes[show][season][episode], // jshint ignore:line + label: 'Episode ' + episodes[show][season][episode], // jshint ignore:line })); } } @@ -84,7 +84,7 @@ $(document).ready(function() { select.removeClass('hidden'); select.find('option:gt(0)').remove(); - for(var season in episodes[show]) { + for(var season in episodes[show]) { // jshint ignore:line select.append($('<option>', { value: season, label: (season === 0) ? 'Specials' : 'Season ' + season, @@ -95,7 +95,7 @@ $(document).ready(function() { // Enable command search $('#command-search').typeahead({ - source: commands, + source: commands, // jshint ignore:line }); $('#command-search').on('change', function() { var command = $(this).typeahead('getActive'); diff --git a/gui/slick/js/blackwhite.js b/gui/slick/js/blackwhite.js index 82c51368715a39d2a6db0e6c67f361bab4461c83..39199e8ce51ac643d595388e4ded798c98db1897 100644 --- a/gui/slick/js/blackwhite.js +++ b/gui/slick/js/blackwhite.js @@ -1,4 +1,4 @@ -function generate_bwlist() { +function generateBlackWhiteList() { // jshint ignore:line var realvalues = []; $('#white option').each(function(i, selected) { @@ -13,13 +13,15 @@ function generate_bwlist() { $("#blacklist").val(realvalues.join(",")); } -function update_bwlist(show_name) { +function updateBlackWhiteList(showName) { // jshint ignore:line $('#pool').children().remove(); $('#blackwhitelist').show(); - if (show_name) { - $.getJSON(srRoot + '/home/fetch_releasegroups', {'show_name': show_name}, function (data) { - if (data.result == 'success') { + if (showName) { + $.getJSON(srRoot + '/home/fetch_releasegroups', { + 'show_name': showName + }, function (data) { + if (data.result === 'success') { $.each(data.groups, function(i, group) { var option = $("<option>"); option.attr("value", group.name); @@ -32,23 +34,23 @@ function update_bwlist(show_name) { } $('#removeW').click(function() { - !$('#white option:selected').remove().appendTo('#pool'); + !$('#white option:selected').remove().appendTo('#pool'); // jshint ignore:line }); $('#addW').click(function() { - !$('#pool option:selected').remove().appendTo('#white'); + !$('#pool option:selected').remove().appendTo('#white'); // jshint ignore:line }); $('#addB').click(function() { - !$('#pool option:selected').remove().appendTo('#black'); + !$('#pool option:selected').remove().appendTo('#black'); // jshint ignore:line }); $('#removeP').click(function() { - !$('#pool option:selected').remove(); + !$('#pool option:selected').remove(); // jshint ignore:line }); $('#removeB').click(function() { - !$('#black option:selected').remove().appendTo('#pool'); + !$('#black option:selected').remove().appendTo('#pool'); // jshint ignore:line }); $('#addToWhite').click(function() { diff --git a/gui/slick/js/browser.js b/gui/slick/js/browser.js index f1ba76ba1477831befa869dd4673227fbff60d4d..51f6f4849dc6d84d70570af1b4c3deedb9947821 100644 --- a/gui/slick/js/browser.js +++ b/gui/slick/js/browser.js @@ -1,5 +1,5 @@ ;(function ($) { - "use strict"; + 'use strict'; $.Browser = { defaults: { @@ -36,7 +36,7 @@ }); $('<input type="text" class="form-control input-sm">') - .val(firstVal.current_path) // jshint ignore:line + .val(firstVal.currentPath) .on('keypress', function (e) { if (e.which === 13) { browse(e.target.value, endpoint, includeFiles); @@ -50,15 +50,24 @@ list = $('<ul>').appendTo(fileBrowserDialog); $.each(data, function (i, entry) { - link = $("<a href='javascript:void(0)' />").on('click', function () { browse(entry.path, endpoint, includeFiles); }).text(entry.name); - $('<span class="ui-icon ui-icon-folder-collapsed"></span>').prependTo(link); - link.hover( - function () {$("span", this).addClass("ui-icon-folder-open"); }, - function () {$("span", this).removeClass("ui-icon-folder-open"); } - ); + link = $('<a href="javascript:void(0)">').on('click', function () { + if (entry.isFile) { + currentBrowserPath = entry.path; + $('.browserDialog .ui-button:contains("Ok")').click(); + } else { + browse(entry.path, endpoint, includeFiles); + } + }).text(entry.name); + if (entry.isFile) { + link.prepend('<span class="ui-icon ui-icon-blank"></span>'); + } else { + link.prepend('<span class="ui-icon ui-icon-folder-collapsed"></span>') + .on('mouseenter', function () { $('span', this).addClass('ui-icon-folder-open'); }) + .on('mouseleave', function () { $('span', this).removeClass('ui-icon-folder-open'); }); + } link.appendTo(list); }); - $("a", list).wrap('<li class="ui-state-default ui-corner-all">'); + $('a', list).wrap('<li class="ui-state-default ui-corner-all">'); fileBrowserDialog.dialog('option', 'dialogClass', 'browserDialog'); }); } @@ -68,7 +77,6 @@ // make a fileBrowserDialog object if one doesn't exist already if (!fileBrowserDialog) { - // set up the jquery dialog fileBrowserDialog = $('<div id="fileBrowserDialog" style="display:hidden"></div>').appendTo('body').dialog({ dialogClass: 'browserDialog', @@ -85,19 +93,19 @@ fileBrowserDialog.dialog('option', 'buttons', [ { - text: "Ok", - "class": "btn", + text: 'Ok', + 'class': 'btn', click: function () { // store the browsed path to the associated text field callback(currentBrowserPath, options); - $(this).dialog("close"); + $(this).dialog('close'); } }, { - text: "Cancel", - "class": "btn", + text: 'Cancel', + 'class': 'btn', click: function () { - $(this).dialog("close"); + $(this).dialog('close'); } } ]); @@ -122,17 +130,17 @@ if (options.field.autocomplete && options.autocompleteURL) { var query = ''; options.field.autocomplete({ - position: { my : "top", at: "bottom", collision: "flipfit" }, + position: { my : 'top', at: 'bottom', collision: 'flipfit' }, source: function (request, response) { //keep track of user submitted search term query = $.ui.autocomplete.escapeRegex(request.term, options.includeFiles); $.ajax({ url: options.autocompleteURL, data: request, - dataType: "json", + dataType: 'json', success: function (data) { //implement a startsWith filter for the results - var matcher = new RegExp("^" + query, "i"); + var matcher = new RegExp('^' + query, 'i'); var a = $.grep(data, function (item) { return matcher.test(item); }); @@ -141,18 +149,18 @@ }); }, open: function () { - $(".ui-autocomplete li.ui-menu-item a").removeClass("ui-corner-all"); + $('.ui-autocomplete li.ui-menu-item a').removeClass('ui-corner-all'); } - }).data("ui-autocomplete")._renderItem = function (ul, item) { + }).data('ui-autocomplete')._renderItem = function (ul, item) { //highlight the matched search term from the item -- note that this is global and will match anywhere var resultItem = item.label; - var x = new RegExp("(?![^&;]+;)(?!<[^<>]*)(" + query + ")(?![^<>]*>)(?![^&;]+;)", "gi"); + var x = new RegExp('(?![^&;]+;)(?!<[^<>]*)(' + query + ')(?![^<>]*>)(?![^&;]+;)', 'gi'); resultItem = resultItem.replace(x, function (fullMatch) { return '<b>' + fullMatch + '</b>'; }); - return $("<li></li>") - .data("ui-autocomplete-item", item) - .append("<a class='nowrap'>" + resultItem + "</a>") + return $('<li></li>') + .data('ui-autocomplete-item', item) + .append('<a class="nowrap">' + resultItem + '</a>') .appendTo(ul); }; } diff --git a/gui/slick/js/new/editShow.js b/gui/slick/js/editShow.js similarity index 91% rename from gui/slick/js/new/editShow.js rename to gui/slick/js/editShow.js index 73789ef0d67dfec3fc2278ffea6ce8b1800272c3..7201818490c220e2bd015c492797e50236676799 100644 --- a/gui/slick/js/new/editShow.js +++ b/gui/slick/js/editShow.js @@ -11,7 +11,7 @@ $('#submit').click(function() { $("#exceptions_list").val(allExceptions); - if(metaToBool('show.is_anime')) { generate_bwlist(); } + if(metaToBool('show.is_anime')) { generateBlackWhiteList(); } }); $('#addSceneName').click(function() { var sceneEx = $('#SceneName').val(); @@ -19,7 +19,7 @@ $('#addSceneName').click(function() { allExceptions = []; $("#exceptions_list option").each(function() { - allExceptions.push($(this).val()); + allExceptions.push($(this).val()); }); $('#SceneName').val(''); diff --git a/gui/slick/js/new/home_addExistingShow.js b/gui/slick/js/home_addExistingShow.js similarity index 100% rename from gui/slick/js/new/home_addExistingShow.js rename to gui/slick/js/home_addExistingShow.js diff --git a/gui/slick/js/new/home_recommendedShows.js b/gui/slick/js/home_recommendedShows.js similarity index 100% rename from gui/slick/js/new/home_recommendedShows.js rename to gui/slick/js/home_recommendedShows.js diff --git a/gui/slick/js/new/home_trendingShows.js b/gui/slick/js/home_trendingShows.js similarity index 100% rename from gui/slick/js/new/home_trendingShows.js rename to gui/slick/js/home_trendingShows.js diff --git a/gui/slick/js/new/meta.js b/gui/slick/js/meta.js similarity index 79% rename from gui/slick/js/new/meta.js rename to gui/slick/js/meta.js index e380c88217166a3f3e4c75c096fe241721af37a9..89e1ed36cb69f6fce012d834866d9e7d65bbdaf9 100644 --- a/gui/slick/js/new/meta.js +++ b/gui/slick/js/meta.js @@ -1,4 +1,4 @@ -function metaToBool(pyVar){ +function metaToBool(pyVar){ // jshint ignore:line var meta = $('meta[data-var="' + pyVar + '"]').data('content'); if(meta === undefined){ console.log(pyVar + ' is empty, did you forget to add this to main.mako?'); @@ -9,11 +9,11 @@ function metaToBool(pyVar){ } } -function getMeta(pyVar){ +function getMeta(pyVar){ // jshint ignore:line return $('meta[data-var="' + pyVar + '"]').data('content'); } -function isMeta(pyVar, result){ +function isMeta(pyVar, result){ // jshint ignore:line var reg = new RegExp(result.length > 1 ? result.join('|') : result); return (reg).test($('meta[data-var="' + pyVar + '"]').data('content')); } diff --git a/gui/slick/js/newShow.js b/gui/slick/js/newShow.js index 65135532dd8651830c42b0f77f6c669234e9a2aa..df8b4cce36e53207cf499f5531fd0ddb448fa1ee 100644 --- a/gui/slick/js/newShow.js +++ b/gui/slick/js/newShow.js @@ -3,9 +3,9 @@ $(document).ready(function () { var searchRequestXhr = null; function searchIndexers() { - if (!$('#nameToSearch').val().length) return; + if (!$('#nameToSearch').val().length) { return; } - if (searchRequestXhr) searchRequestXhr.abort(); + if (searchRequestXhr) { searchRequestXhr.abort(); } var searchingFor = $('#nameToSearch').val().trim() + ' on ' + $('#providedIndexer option:selected').text() + ' in ' + $('#indexerLangSelect').val(); $('#searchResults').empty().html('<img id="searchingAnim" src="' + srRoot + '/images/loading32' + themeSpinner + '.gif" height="32" width="32" /> searching ' + searchingFor + '...'); @@ -37,8 +37,8 @@ $(document).ready(function () { var whichSeries = obj.join('|'); - resultStr += '<input type="radio" id="whichSeries" name="whichSeries" value="' + whichSeries.replace(/"/g, "") + '"' + checked + ' /> '; - if (data.langid && data.langid !== "") { + resultStr += '<input type="radio" id="whichSeries" name="whichSeries" value="' + whichSeries.replace(/"/g, '') + '"' + checked + ' /> '; + if (data.langid && data.langid !== '') { resultStr += '<a href="' + anonURL + obj[2] + obj[3] + '&lid=' + data.langid + '" onclick=\"window.open(this.href, \'_blank\'); return false;\" ><b>' + obj[4] + '</b></a>'; } else { resultStr += '<a href="' + anonURL + obj[2] + obj[3] + '" onclick=\"window.open(this.href, \'_blank\'); return false;\" ><b>' + obj[4] + '</b></a>'; @@ -78,11 +78,11 @@ $(document).ready(function () { $('#addShowButton').click(function () { // if they haven't picked a show don't let them submit - if (!$("input:radio[name='whichSeries']:checked").val() && !$("input:hidden[name='whichSeries']").val().length) { + if (!$('input:radio[name="whichSeries"]:checked').val() && !$('input:hidden[name="whichSeries"]').val().length) { alert('You must choose a show to continue'); return false; } - generate_bwlist(); + generateBlackWhiteList(); $('#addShowForm').submit(); }); @@ -101,7 +101,7 @@ $(document).ready(function () { * Visit http://www.dynamicdrive.com/ for this script and 100s more. ***********************************************/ - var myform = new formtowizard({ + var myform = new formtowizard({ // jshint ignore:line formid: 'addShowForm', revealfx: ['slide', 500], oninit: function () { @@ -114,7 +114,7 @@ $(document).ready(function () { function goToStep(num) { $('.step').each(function () { - if ($.data(this, 'section') + 1 == num) { + if ($.data(this, 'section') + 1 === num) { $(this).click(); } }); @@ -125,53 +125,51 @@ $(document).ready(function () { function updateSampleText() { // if something's selected then we have some behavior to figure out - var show_name, sep_char; + var showName, sepChar; // if they've picked a radio button then use that if ($('input:radio[name=whichSeries]:checked').length) { - show_name = $('input:radio[name=whichSeries]:checked').val().split('|')[4]; - } - // if we provided a show in the hidden field, use that - else if ($('input:hidden[name=whichSeries]').length && $('input:hidden[name=whichSeries]').val().length) { - show_name = $('#providedName').val(); + showName = $('input:radio[name=whichSeries]:checked').val().split('|')[4]; + } else if ($('input:hidden[name=whichSeries]').length && $('input:hidden[name=whichSeries]').val().length) { // if we provided a show in the hidden field, use that + showName = $('#providedName').val(); } else { - show_name = ''; + showName = ''; } - update_bwlist(show_name); - var sample_text = 'Adding show <b>' + show_name + '</b> into <b>'; + updateBlackWhiteList(showName); + var sampleText = 'Adding show <b>' + showName + '</b> into <b>'; // if we have a root dir selected, figure out the path - if ($("#rootDirs option:selected").length) { - var root_dir_text = $('#rootDirs option:selected').val(); - if (root_dir_text.indexOf('/') >= 0) { - sep_char = '/'; - } else if (root_dir_text.indexOf('\\') >= 0) { - sep_char = '\\'; + if ($('#rootDirs option:selected').length) { + var rootDirectoryText = $('#rootDirs option:selected').val(); + if (rootDirectoryText.indexOf('/') >= 0) { + sepChar = '/'; + } else if (rootDirectoryText.indexOf('\\') >= 0) { + sepChar = '\\'; } else { - sep_char = ''; + sepChar = ''; } - if (root_dir_text.substr(sample_text.length - 1) != sep_char) { - root_dir_text += sep_char; + if (rootDirectoryText.substr(sampleText.length - 1) !== sepChar) { + rootDirectoryText += sepChar; } - root_dir_text += '<i>||</i>' + sep_char; + rootDirectoryText += '<i>||</i>' + sepChar; - sample_text += root_dir_text; + sampleText += rootDirectoryText; } else if ($('#fullShowPath').length && $('#fullShowPath').val().length) { - sample_text += $('#fullShowPath').val(); + sampleText += $('#fullShowPath').val(); } else { - sample_text += 'unknown dir.'; + sampleText += 'unknown dir.'; } - sample_text += '</b>'; + sampleText += '</b>'; // if we have a show name then sanitize and use it for the dir name - if (show_name.length) { - $.get(srRoot + '/home/addShows/sanitizeFileName', {name: show_name}, function (data) { - $('#displayText').html(sample_text.replace('||', data)); + if (showName.length) { + $.get(srRoot + '/home/addShows/sanitizeFileName', {name: showName}, function (data) { + $('#displayText').html(sampleText.replace('||', data)); }); // if not then it's unknown } else { - $('#displayText').html(sample_text.replace('||', '??')); + $('#displayText').html(sampleText.replace('||', '??')); } // also toggle the add show button @@ -186,35 +184,37 @@ $(document).ready(function () { $('#rootDirText').change(updateSampleText); $('#searchResults').on('change', '#whichSeries', updateSampleText); - $('#nameToSearch').keyup(function (event) { - if (event.keyCode == 13) { + $('#nameToSearch').keyup(function(event) { + if (event.keyCode === 13) { $('#searchName').click(); } }); - $('#anime').change (function () { + $('#anime').change (function() { updateSampleText(); myform.loadsection(2); }); - function update_bwlist (show_name) { + function updateBlackWhiteList(showName) { $('#white').children().remove(); $('#black').children().remove(); $('#pool').children().remove(); if ($('#anime').prop('checked')) { $('#blackwhitelist').show(); - if (show_name) { - $.getJSON(srRoot + '/home/fetch_releasegroups', {'show_name': show_name}, function (data) { - if (data.result == 'success') { - $.each(data.groups, function(i, group) { - var option = $("<option>"); - option.attr("value", group.name); - option.html(group.name + ' | ' + group.rating + ' | ' + group.range); - option.appendTo('#pool'); - }); - } - }); + if (showName) { + $.getJSON(srRoot + '/home/fetch_releasegroups', { + 'show_name': showName + }, function (data) { + if (data.result === 'success') { + $.each(data.groups, function(i, group) { + var option = $("<option>"); + option.attr("value", group.name); + option.html(group.name + ' | ' + group.rating + ' | ' + group.range); + option.appendTo('#pool'); + }); + } + }); } } else { $('#blackwhitelist').hide(); diff --git a/gui/slick/js/new/parsers.js b/gui/slick/js/parsers.js similarity index 100% rename from gui/slick/js/new/parsers.js rename to gui/slick/js/parsers.js diff --git a/gui/slick/js/qualityChooser.js b/gui/slick/js/qualityChooser.js index fe2880be8956acdeea6fc6cd00c6882bfea26bd9..42827f4485f856e6d1683992fa7f2eb19a7e4562 100644 --- a/gui/slick/js/qualityChooser.js +++ b/gui/slick/js/qualityChooser.js @@ -8,7 +8,7 @@ $(document).ready(function() { } $('#anyQualities option').each(function() { - var result = preset & $(this).val(); // @TODO Find out what this does + var result = preset & $(this).val(); // jshint ignore:line if (result > 0) { $(this).attr('selected', 'selected'); } else { @@ -17,7 +17,7 @@ $(document).ready(function() { }); $('#bestQualities option').each(function() { - var result = preset & ($(this).val() << 16); // @TODO Find out what this does + var result = preset & ($(this).val() << 16); // jshint ignore:line if (result > 0) { $(this).attr('selected', 'selected'); } else { diff --git a/gui/slick/js/new/recommendedShows.js b/gui/slick/js/recommendedShows.js similarity index 100% rename from gui/slick/js/new/recommendedShows.js rename to gui/slick/js/recommendedShows.js diff --git a/gui/slick/js/restart.js b/gui/slick/js/restart.js index 645e5019f2ede8b75b25b3bcc2c9e27e183e70d0..9c7ec6f0703d5fee800dec7855e7dd0408cb463a 100644 --- a/gui/slick/js/restart.js +++ b/gui/slick/js/restart.js @@ -38,7 +38,7 @@ $(document).ready(function() { $('#restart_loading').hide(); $('#restart_success').show(); $('#refresh_message').show(); - setTimeout(function(){window.location = srRoot + '/' + sbDefaultPage + '/';}, 5000); + setTimeout(function(){window.location = srRoot + '/' + sbDefaultPage + '/';}, 5000); // jshint ignore:line } } @@ -52,13 +52,13 @@ $(document).ready(function() { function ajaxError(x) { if (console_debug) { // jshint ignore:line if (x.status === 0) { - console.log(console_prefix + 'isAlive: Sickrage is not responding.'); + console.log(console_prefix + 'isAlive: Sickrage is not responding.'); // jshint ignore:line } else if (x.status === 404) { - console.log(console_prefix + 'isAlive: Requested URL not found.'); + console.log(console_prefix + 'isAlive: Requested URL not found.'); // jshint ignore:line } else if (x.status === 500) { - console.log(console_prefix + 'isAlive: Internel Server Error.'); + console.log(console_prefix + 'isAlive: Internel Server Error.'); // jshint ignore:line } else { - console.log(console_prefix + 'isAlive: Unknow Error.\n' + x.responseText); + console.log(console_prefix + 'isAlive: Unknow Error.\n' + x.responseText); // jshint ignore:line } } } diff --git a/gui/slick/js/new/trendingShows.js b/gui/slick/js/trendingShows.js similarity index 95% rename from gui/slick/js/new/trendingShows.js rename to gui/slick/js/trendingShows.js index b60a5068f35d73347702badca7b94d898713d127..aff77a1cdd7ea563475c8d727e1ce9b6c16b33f0 100644 --- a/gui/slick/js/new/trendingShows.js +++ b/gui/slick/js/trendingShows.js @@ -47,6 +47,6 @@ $(document).ready(function(){ }); $('#showsortdirection').on( 'change', function() { - $('#container').isotope({sortAscending: ('asc' == this.value)}); + $('#container').isotope({sortAscending: ('asc' === this.value)}); }); }); diff --git a/gui/slick/views/apiBuilder.mako b/gui/slick/views/apiBuilder.mako index fe48e74a997a0b8dc61679a6495136f39a2452a6..c174c1b588ae715d579acc5ca5e3d82d4ebfbbd6 100644 --- a/gui/slick/views/apiBuilder.mako +++ b/gui/slick/views/apiBuilder.mako @@ -186,7 +186,7 @@ var commands = ${sorted(commands)}; var episodes = ${episodes}; </script> <script type="text/javascript" src="${srRoot}/js/vender.min.js?${sbPID}"></script> -<script type="text/javascript" src="${srRoot}/js/new/meta.js?${sbPID}"></script> +<script type="text/javascript" src="${srRoot}/js/meta.js?${sbPID}"></script> <script type="text/javascript" src="${srRoot}/js/core.min.js?${sbPID}"></script> <script type="text/javascript" src="${srRoot}/js/apibuilder.js?${sbPID}"></script> </body> diff --git a/gui/slick/views/config.mako b/gui/slick/views/config.mako index fcd02b46c0e72ca07844a0051a54348828a57c29..a6208e93f7d37651849365107b30018ae46a52f4 100644 --- a/gui/slick/views/config.mako +++ b/gui/slick/views/config.mako @@ -63,9 +63,8 @@ <tr><td class="infoTableHeader">SR Web Root:</td><td class="infoTableCell">${sickbeard.WEB_ROOT}</td></tr> % endif <tr><td class="infoTableHeader">Python Version:</td><td class="infoTableCell">${sys.version[:120]}</td></tr> - <tr class="infoTableSeperator"><td class="infoTableHeader"><i class="icon16-sb"></i> Homepage</td><td class="infoTableCell"><a href="${anon_url('http://www.sickrage.tv/')}" rel="noreferrer" onclick="window.open(this.href, '_blank'); return false;">http://www.sickrage.tv/</a></td></tr> + <tr class="infoTableSeperator"><td class="infoTableHeader"><i class="icon16-sb"></i> Website</td><td class="infoTableCell"><a href="${anon_url('http://sickrage.github.io/')}" rel="noreferrer" onclick="window.open(this.href, '_blank'); return false;">http://sickrage.github.io/</a></td></tr> <tr><td class="infoTableHeader"><i class="icon16-WiKi"></i> WiKi</td><td class="infoTableCell"><a href="${anon_url('https://github.com/SickRage/sickrage-issues/wiki')}" rel="noreferrer" onclick="window.open(this.href, '_blank'); return false;">https://github.com/SickRage/sickrage-issues/wiki</a></td></tr> - <tr><td class="infoTableHeader"><i class="icon16-web"></i> Forums</td><td class="infoTableCell"><a href="${anon_url('http://sickrage.tv/forums/')}" rel="noreferrer" onclick="window.open(this.href, '_blank'); return false;">http://sickrage.tv/forums/</a></td></tr> <tr><td class="infoTableHeader"><i class="icon16-github"></i> Source</td><td class="infoTableCell"><a href="${anon_url('https://github.com/SickRage/SickRage/')}" rel="noreferrer" onclick="window.open(this.href, '_blank'); return false;">https://github.com/SickRage/SickRage/</a></td></tr> <tr><td class="infoTableHeader"><i class="icon16-mirc"></i> IRChat</td><td class="infoTableCell"><a href="irc://irc.freenode.net/#sickrage-issues" rel="noreferrer"><i>#sickrage-issues</i> on <i>irc.freenode.net</i></a></td></tr> </table> diff --git a/gui/slick/views/config_search.mako b/gui/slick/views/config_search.mako index 8bc218adac83a4d0d6d9fbe3039bb56fdd85ca5e..6e4359754d78c95179c3fbd1c561561b767f040e 100644 --- a/gui/slick/views/config_search.mako +++ b/gui/slick/views/config_search.mako @@ -61,6 +61,16 @@ </div> </div> + <div class="field-pair"> + <label> + <span class="component-title">Backlog search day(s)</span> + <span class="component-desc"> + <input type="text" name="backlog_days" value="${sickbeard.BACKLOG_DAYS}" class="form-control input-sm input75" /> + <p>number of day(s) that the "Forced Backlog Search" will cover (e.g. 7 Days)</p> + </span> + </label> + </div> + <div class="field-pair"> <label> <span class="component-title">Backlog search frequency</span> diff --git a/gui/slick/views/editShow.mako b/gui/slick/views/editShow.mako index ebde82a8ab5777c24a9b8ffe1a6d916a1ce25900..b1901f664591d2fde71c109595223dd1e0fd51cd 100644 --- a/gui/slick/views/editShow.mako +++ b/gui/slick/views/editShow.mako @@ -15,7 +15,7 @@ <%block name="scripts"> <script type="text/javascript" src="${srRoot}/js/qualityChooser.js?${sbPID}"></script> - <script type="text/javascript" src="${srRoot}/js/new/editShow.js"></script> + <script type="text/javascript" src="${srRoot}/js/editShow.js"></script> % if show.is_anime: <script type="text/javascript" src="${srRoot}/js/blackwhite.js?${sbPID}"></script> % endif diff --git a/gui/slick/views/history.mako b/gui/slick/views/history.mako index ce5a5b5dd8771a74fbdc831b807abf0dc47107df..8f9de80b3a77af59b13c1a3c22e72b6a34d08403 100644 --- a/gui/slick/views/history.mako +++ b/gui/slick/views/history.mako @@ -15,9 +15,6 @@ from sickrage.show.History import History %> -<%block name="scripts"> -<script type="text/javascript" src="${srRoot}/js/new/history.js"></script> -</%block> <%block name="content"> <%namespace file="/inc_defs.mako" import="renderQualityPill"/> % if not header is UNDEFINED: diff --git a/gui/slick/views/home_addExistingShow.mako b/gui/slick/views/home_addExistingShow.mako index c4f59585b206e193b59fc80eec271abe521efaf9..902429e6ba7945de409a708d7ef7fad849d41a70 100644 --- a/gui/slick/views/home_addExistingShow.mako +++ b/gui/slick/views/home_addExistingShow.mako @@ -7,7 +7,7 @@ <script type="text/javascript" src="${srRoot}/js/addExistingShow.js?${sbPID}"></script> <script type="text/javascript" src="${srRoot}/js/rootDirs.js?${sbPID}"></script> <script type="text/javascript" src="${srRoot}/js/addShowOptions.js?${sbPID}"></script> -<script type="text/javascript" src="${srRoot}/js/new/home_addExistingShow.js"></script> +<script type="text/javascript" src="${srRoot}/js/home_addExistingShow.js"></script> </%block> <%block name="content"> % if not header is UNDEFINED: diff --git a/gui/slick/views/home_postprocess.mako b/gui/slick/views/home_postprocess.mako index 795c3d3cddafa387d8b9a14801068b37554ec5cb..8876ebd9c2ed11848b9bd1ff332edab78b8c3755 100644 --- a/gui/slick/views/home_postprocess.mako +++ b/gui/slick/views/home_postprocess.mako @@ -2,9 +2,6 @@ <%! import sickbeard %> -<%block name="scripts"> -<script type="text/javascript" src="${srRoot}/js/new/home_postprocess.js"></script> -</%block> <%block name="content"> <div id="content800"> % if not header is UNDEFINED: diff --git a/gui/slick/views/home_recommendedShows.mako b/gui/slick/views/home_recommendedShows.mako index f5d77e8ea164704c4cc0b8c1ccc3cbd3b007fd03..080ecfad10833bf3d8ca1151ae32faef1c38d510 100644 --- a/gui/slick/views/home_recommendedShows.mako +++ b/gui/slick/views/home_recommendedShows.mako @@ -3,10 +3,10 @@ import sickbeard %> <%block name="scripts"> -<script type="text/javascript" src="${srRoot}/js/new/recommendedShows.js?${sbPID}"></script> +<script type="text/javascript" src="${srRoot}/js/recommendedShows.js?${sbPID}"></script> <script type="text/javascript" src="${srRoot}/js/rootDirs.js?${sbPID}"></script> <script type="text/javascript" src="${srRoot}/js/plotTooltip.js?${sbPID}"></script> -<script type="text/javascript" src="${srRoot}/js/new/home_recommendedShows.js"></script> +<script type="text/javascript" src="${srRoot}/js/home_recommendedShows.js"></script> </%block> <%block name="content"> % if not header is UNDEFINED: diff --git a/gui/slick/views/home_trendingShows.mako b/gui/slick/views/home_trendingShows.mako index a49b019d8d265f3b5842e8d0df765da3680273bf..666528478907f07bcac96e8593ff17fecdb98487 100644 --- a/gui/slick/views/home_trendingShows.mako +++ b/gui/slick/views/home_trendingShows.mako @@ -9,10 +9,10 @@ from sickbeard.helpers import anon_url %> <%block name="scripts"> -<script type="text/javascript" src="${srRoot}/js/new/addTrendingShow.js?${sbPID}"></script> +<script type="text/javascript" src="${srRoot}/js/addTrendingShow.js?${sbPID}"></script> <script type="text/javascript" src="${srRoot}/js/rootDirs.js?${sbPID}"></script> <script type="text/javascript" src="${srRoot}/js/plotTooltip.js?${sbPID}"></script> -<script type="text/javascript" src="${srRoot}/js/new/home_trendingShows.js"></script> +<script type="text/javascript" src="${srRoot}/js/home_trendingShows.js"></script> </%block> <%block name="content"> % if not header is UNDEFINED: diff --git a/gui/slick/views/layouts/main.mako b/gui/slick/views/layouts/main.mako index 0445d953b550b2be83025bfb811c57b0c268d4f7..d1bcc84bf59e367f31a8cefa795a3b9d5ad8df53 100644 --- a/gui/slick/views/layouts/main.mako +++ b/gui/slick/views/layouts/main.mako @@ -316,8 +316,8 @@ <script type="text/javascript" src="${srRoot}/js/lib/jquery.json-2.2.min.js?${sbPID}"></script> <script type="text/javascript" src="${srRoot}/js/lib/jquery.selectboxes.min.js?${sbPID}"></script> <script type="text/javascript" src="${srRoot}/js/lib/formwizard.js?${sbPID}"></script><!-- Can't be added to bower --> - <script type="text/javascript" src="${srRoot}/js/new/parsers.js?${sbPID}"></script> - <script type="text/javascript" src="${srRoot}/js/new/meta.js?${sbPID}"></script> + <script type="text/javascript" src="${srRoot}/js/parsers.js?${sbPID}"></script> + <script type="text/javascript" src="${srRoot}/js/meta.js?${sbPID}"></script> % if sickbeard.DEVELOPER: <script type="text/javascript" src="${srRoot}/js/core.js?${sbPID}"></script> % else: diff --git a/gui/slick/views/manage.mako b/gui/slick/views/manage.mako index 19035aea7041711307f047e942124f0434f7d3ea..bcac1e4bd9a5cbad61c83e517c6d20c9e0be3aeb 100644 --- a/gui/slick/views/manage.mako +++ b/gui/slick/views/manage.mako @@ -5,7 +5,6 @@ from sickbeard.common import statusStrings %> <%block name="scripts"> -<script type="text/javascript" src="${srRoot}/js/new/manage.js"></script> <script type="text/javascript" src="${srRoot}/js/massUpdate.js?${sbPID}"></script> </%block> <%block name="content"> diff --git a/gui/slick/views/manage_massEdit.mako b/gui/slick/views/manage_massEdit.mako index 816af35f24739e18d3e4e5dac33de4732656ffff..7d44bb7c46aeb6a570269ba9256007ffd17a8a80 100644 --- a/gui/slick/views/manage_massEdit.mako +++ b/gui/slick/views/manage_massEdit.mako @@ -18,7 +18,6 @@ %> <script type="text/javascript" src="${srRoot}/js/qualityChooser.js?${sbPID}"></script> <script type="text/javascript" src="${srRoot}/js/massEdit.js?${sbPID}"></script> -<script type="text/javascript" src="${srRoot}/js/new/manage_massEdit.js"></script> </%block> <%block name="content"> diff --git a/gui/slick/views/restart.mako b/gui/slick/views/restart.mako index 6c53fb34009f69583c88751caf9675a86e74c35b..5a9719d5221adc490be4a1a41a254a4572b07ebc 100644 --- a/gui/slick/views/restart.mako +++ b/gui/slick/views/restart.mako @@ -22,7 +22,6 @@ sbHandleReverseProxy = "${curSBHandleReverseProxy}"; sbHost = "${curSBHost}"; sbDefaultPage = "${sbDefaultPage}"; </script> -<script type="text/javascript" src="${srRoot}/js/lib/jquery-1.11.2.min.js?${sbPID}"></script> <script type="text/javascript" src="${srRoot}/js/restart.js?${sbPID}&${sbDefaultPage}"></script> </%block> <%block name="css"> diff --git a/gui/slick/views/schedule.mako b/gui/slick/views/schedule.mako index 98a4c2cf3b0e8152363a83397e5dec1c6d97e74f..ff76a17c3b8ca220b86e46a71de968345f04a844 100644 --- a/gui/slick/views/schedule.mako +++ b/gui/slick/views/schedule.mako @@ -10,7 +10,6 @@ <%block name="scripts"> <script type="text/javascript" src="${srRoot}/js/ajaxEpSearch.js?${sbPID}"></script> <script type="text/javascript" src="${srRoot}/js/plotTooltip.js?${sbPID}"></script> -<script type="text/javascript" src="${srRoot}/js/new/schedule.js"></script> </%block> <%block name="css"> <style type="text/css"> diff --git a/gui/slick/views/status.mako b/gui/slick/views/status.mako index 35ae7ec4181fe18f6e8e470df95e6d1d78cf2288..306d19e1884107799a54162e81ad381d80862aa0 100644 --- a/gui/slick/views/status.mako +++ b/gui/slick/views/status.mako @@ -5,9 +5,6 @@ from sickbeard.show_queue import ShowQueueActions from sickrage.helper.common import dateTimeFormat %> -<%block name="scripts"> -<script type="text/javascript" src="${srRoot}/js/new/status.js"></script> -</%block> <%block name="content"> % if not header is UNDEFINED: <h1 class="header">${header}</h1> diff --git a/gui/slick/views/trendingShows.mako b/gui/slick/views/trendingShows.mako index 54e196ab23ad9ef147188b124987e5d6145a7ae1..0a8ab311793775dbadf734c5b8602db28402722e 100644 --- a/gui/slick/views/trendingShows.mako +++ b/gui/slick/views/trendingShows.mako @@ -12,7 +12,7 @@ <meta data-var="sickbeard.SORT_ARTICLE" data-content="${sickbeard.SORT_ARTICLE}"> </%block> <%block name="scripts"> -<script type="text/javascript" src="${srRoot}/js/new/trendingShows.js"></script> +<script type="text/javascript" src="${srRoot}/js/trendingShows.js"></script> </%block> <%block name="content"> <div id="container"> diff --git a/readme.md b/readme.md index 0e781a77db6701ab1349334b458810258bcbc7d9..f179a83df193d9e6298c76112a6f70b082e9bebe 100644 --- a/readme.md +++ b/readme.md @@ -31,9 +31,6 @@ Automatic Video Library Manager for TV Shows. It watches for new episodes of you #### [](http://feathub.com/SickRage/SickRage) -#### Forums - Any questions or setup info your looking for can be found at out forums https://www.sickrage.tv - ##### [SickRage Issue Tracker](https://github.com/SickRage/sickrage-issues) ##### [FAQ](https://github.com/SickRage/SickRage/wiki/Frequently-Asked-Questions) diff --git a/runscripts/init.solaris11 b/runscripts/init.solaris11 index 56ff9e42b96d02d743854f5ad46180fc9e34cf50..fb1037d4f3c9f6089a14f5e61e3ca4c74f756c03 100755 --- a/runscripts/init.solaris11 +++ b/runscripts/init.solaris11 @@ -85,7 +85,7 @@ </common_name> <documentation> <doc_link name='sickrage' - uri='https://sickrage.tv/' /> + uri='https://sickrage.github.io/' /> </documentation> </template> diff --git a/sickbeard/blackandwhitelist.py b/sickbeard/blackandwhitelist.py index 796f82aab7409f29be0845ac618d56753bf388fb..5d8330fab6babf06944337c5d2057bdaad370580 100644 --- a/sickbeard/blackandwhitelist.py +++ b/sickbeard/blackandwhitelist.py @@ -1,6 +1,6 @@ # coding=utf-8 # Author: Dennis Lutter <lad1337@gmail.com> -# URL: https://sickrage.tv/ +# URL: https://sickrage.github.io/ # Git: https://github.com/SickRage/SickRage.git # # This file is part of SickRage. diff --git a/sickbeard/browser.py b/sickbeard/browser.py index 7f10ff350afadc1c009ae7da29b0b072dc367360..9288465ba51d605edf1c7d20e6e07dac5bb61590 100644 --- a/sickbeard/browser.py +++ b/sickbeard/browser.py @@ -1,5 +1,5 @@ # Author: Nic Wolfe <nic@wolfeden.ca> -# URL: https://sickrage.tv/ +# URL: https://sickrage.github.io/ # Git: https://github.com/SickRage/SickRage.git # # This file is part of SickRage. @@ -40,6 +40,34 @@ def getWinDrives(): return drives +def getFileList(path, includeFiles): + # prune out directories to protect the user from doing stupid things (already lower case the dir to reduce calls) + hideList = ["boot", "bootmgr", "cache", "config.msi", "msocache", "recovery", "$recycle.bin", + "recycler", "system volume information", "temporary internet files"] # windows specific + hideList += [".fseventd", ".spotlight", ".trashes", ".vol", "cachedmessages", "caches", "trash"] # osx specific + hideList += [".git"] + + fileList = [] + for filename in ek(os.listdir, path): + if filename.lower() in hideList: + continue + + fullFilename = ek(os.path.join, path, filename) + isDir = ek(os.path.isdir, fullFilename) + + if not includeFiles and not isDir: + continue + + entry = { + 'name': filename, + 'path': fullFilename + } + if not isDir: entry['isFile'] = True + fileList.append(entry) + + return fileList + + def foldersAtPath(path, includeParent=False, includeFiles=False): """ Returns a list of dictionaries with the folders contained at the given path Give the empty string as the path to list the contents of the root path @@ -60,7 +88,7 @@ def foldersAtPath(path, includeParent=False, includeFiles=False): if path == "": if os.name == 'nt': - entries = [{'current_path': 'Root'}] + entries = [{'currentPath': 'Root'}] for letter in getWinDrives(): letterPath = letter + ':\\' entries.append({'name': letterPath, 'path': letterPath}) @@ -77,25 +105,15 @@ def foldersAtPath(path, includeParent=False, includeFiles=False): parentPath = "" try: - fileList = [{'name': filename, 'path': ek(os.path.join, path, filename)} for filename in ek(os.listdir, path)] + fileList = getFileList(path, includeFiles) except OSError, e: logger.log(u"Unable to open " + path + ": " + repr(e) + " / " + str(e), logger.WARNING) - fileList = [{'name': filename, 'path': ek(os.path.join, parentPath, filename)} for filename in ek(os.listdir, parentPath)] - - if not includeFiles: - fileList = [x for x in fileList if ek(os.path.isdir, x['path'])] - - # prune out directories to protect the user from doing stupid things (already lower case the dir to reduce calls) - hideList = ["boot", "bootmgr", "cache", "msocache", "recovery", "$recycle.bin", "recycler", - "system volume information", "temporary internet files"] # windows specific - hideList += [".fseventd", ".spotlight", ".trashes", ".vol", "cachedmessages", "caches", "trash"] # osx specific - - fileList = [x for x in fileList if x['name'].lower() not in hideList] + fileList = getFileList(parentPath, includeFiles) fileList = sorted(fileList, lambda x, y: cmp(os.path.basename(x['name']).lower(), os.path.basename(y['path']).lower())) - entries = [{'current_path': path}] + entries = [{'currentPath': path}] if includeParent and parentPath != path: entries.append({'name': "..", 'path': parentPath}) entries.extend(fileList) diff --git a/sickbeard/bs4_parser.py b/sickbeard/bs4_parser.py index eb1059184286292dc3a7b9ee03466e3c301b56d7..4bba8eaea295df1eb4863d9580e70dd18cdb788e 100644 --- a/sickbeard/bs4_parser.py +++ b/sickbeard/bs4_parser.py @@ -1,5 +1,5 @@ # Author: The SickRage Dev Team -# URL: https://sickrage.tv +# URL: https://sickrage.github.io # Repository: https://github.com/SickRage/SickRage.git # # This file is part of SickRage. diff --git a/sickbeard/classes.py b/sickbeard/classes.py index a64f8db3f663f346228fbadc9d76b90258f1404b..3c226bae7bc9b11c841215d166be0cec8dc82f5b 100644 --- a/sickbeard/classes.py +++ b/sickbeard/classes.py @@ -1,5 +1,5 @@ # Author: Nic Wolfe <nic@wolfeden.ca> -# URL: https://sickrage.tv/ +# URL: https://sickrage.github.io/ # Git: https://github.com/SickRage/SickRage.git # # This file is part of SickRage. diff --git a/sickbeard/common.py b/sickbeard/common.py index db6eb7a307177c77fa72aa6057e4f9fb90a5d07c..b9ae20bb365b84496b67eb17394c2589a65079cd 100644 --- a/sickbeard/common.py +++ b/sickbeard/common.py @@ -1,5 +1,5 @@ # Author: Nic Wolfe <nic@wolfeden.ca> -# URL: https://sickrage.tv/ +# URL: https://sickrage.github.io/ # Git: https://github.com/SickRage/SickRage.git # # This file is part of SickRage. diff --git a/sickbeard/config.py b/sickbeard/config.py index 9179213b8913190a174b70d311ef5adadf4942ba..4bc496076ab559335b4dba553cac2b5f6238037d 100644 --- a/sickbeard/config.py +++ b/sickbeard/config.py @@ -1,5 +1,5 @@ # Author: Nic Wolfe <nic@wolfeden.ca> -# URL: https://sickrage.tv +# URL: https://sickrage.github.io # Git: https://github.com/SickRage/SickRage.git # # This file is part of SickRage. diff --git a/sickbeard/dailysearcher.py b/sickbeard/dailysearcher.py index f96f0c8053efc9ec5238caefb464211c2cee4fdc..89abc9ca1695d15409959450414420f082026496 100644 --- a/sickbeard/dailysearcher.py +++ b/sickbeard/dailysearcher.py @@ -1,5 +1,5 @@ # Author: Nic Wolfe <nic@wolfeden.ca> -# URL: https://sickrage.tv +# URL: https://sickrage.github.io # Git: https://github.com/SickRage/SickRage.git # # This file is part of SickRage. diff --git a/sickbeard/db.py b/sickbeard/db.py index 42592f8ccfb1e2739be1598ea7d912c4925c5a98..95d2add4e8e613c46cdcd142bf77493017ffdfc4 100644 --- a/sickbeard/db.py +++ b/sickbeard/db.py @@ -1,5 +1,5 @@ # Author: Nic Wolfe <nic@wolfeden.ca> -# URL: https://sickrage.tv +# URL: https://sickrage.github.io # Git: https://github.com/SickRage/SickRage.git # # This file is part of SickRage. diff --git a/sickbeard/failedProcessor.py b/sickbeard/failedProcessor.py index 280dca31c9414407fc1abb7b20b002a7b6e551fb..be0be4b468a0ad98b6ea01694af80017a4124d3e 100644 --- a/sickbeard/failedProcessor.py +++ b/sickbeard/failedProcessor.py @@ -1,5 +1,5 @@ # Author: Tyler Fenby <tylerfenby@gmail.com> -# URL: https://sickrage.tv +# URL: https://sickrage.github.io # Git: https://github.com/SickRage/SickRage.git # # This file is part of SickRage. diff --git a/sickbeard/failed_history.py b/sickbeard/failed_history.py index 6a3bb57177cb4e629de7847367ce616135efaa6c..177fed1c3e69d4d248920b95f1cc5428319ce908 100644 --- a/sickbeard/failed_history.py +++ b/sickbeard/failed_history.py @@ -1,5 +1,5 @@ # Author: Tyler Fenby <tylerfenby@gmail.com> -# URL: https://sickrage.tv +# URL: https://sickrage.github.io # Git: https://github.com/SickRage/SickRage.git # # This file is part of SickRage. diff --git a/sickbeard/generic_queue.py b/sickbeard/generic_queue.py index 85e445586453b67213f707c74a38e64c50f91d92..61a3aa3cf3de792abcc439686cdc5b9abb942b22 100644 --- a/sickbeard/generic_queue.py +++ b/sickbeard/generic_queue.py @@ -1,5 +1,5 @@ # Author: Nic Wolfe <nic@wolfeden.ca> -# URL: https://sickrage.tv +# URL: https://sickrage.github.io # Git: https://github.com/SickRage/SickRage.git # # This file is part of SickRage. diff --git a/sickbeard/helpers.py b/sickbeard/helpers.py index 6e3cbac62d1307a908ff57aba567752a79e38e71..4bb89db158653616980e89e98d14b77539290439 100644 --- a/sickbeard/helpers.py +++ b/sickbeard/helpers.py @@ -1,6 +1,6 @@ # coding=utf-8 # Author: Nic Wolfe <nic@wolfeden.ca> -# URL: https://sickrage.tv +# URL: https://sickrage.github.io # Git: https://github.com/SickRage/SickRage.git # # This file is part of SickRage. diff --git a/sickbeard/history.py b/sickbeard/history.py index cdc9eff3e2e5e7dc4663d86d001b1b6da5905a21..accf006f380ab2a278bf2c277443a123561717f0 100644 --- a/sickbeard/history.py +++ b/sickbeard/history.py @@ -1,5 +1,5 @@ # Author: Nic Wolfe <nic@wolfeden.ca> -# URL: https://sickrage.tv +# URL: https://sickrage.github.io # Git: https://github.com/SickRage/SickRage.git # # This file is part of SickRage. diff --git a/sickbeard/image_cache.py b/sickbeard/image_cache.py index 88c431d02d89ee46ce3772f4c6a4cdd04fb1af16..10c1d2e416d9c50f56a03c43f4ee1a7416fd1ab9 100644 --- a/sickbeard/image_cache.py +++ b/sickbeard/image_cache.py @@ -1,5 +1,5 @@ # Author: Nic Wolfe <nic@wolfeden.ca> -# URL: https://sickrage.tv +# URL: https://sickrage.github.io # Git: https://github.com/SickRage/SickRage.git # # This file is part of SickRage. diff --git a/sickbeard/logger.py b/sickbeard/logger.py index c35c15994f9472547b93e087cb03f249554a9ba9..0a14f5f36face2b9ae1eddccf184a4b0dd0e24fb 100644 --- a/sickbeard/logger.py +++ b/sickbeard/logger.py @@ -1,5 +1,5 @@ # Author: Nic Wolfe <nic@wolfeden.ca> -# URL: https://sickrage.tv +# URL: https://sickrage.github.io # Git: https://github.com/SickRage/SickRage.git # # This file is part of SickRage. diff --git a/sickbeard/name_cache.py b/sickbeard/name_cache.py index c577acd101b2618e89937fad7a4a2002b8f5fce7..60fc64acab849acafb68dd00461fa96dd127a430 100644 --- a/sickbeard/name_cache.py +++ b/sickbeard/name_cache.py @@ -1,5 +1,5 @@ # Author: Nic Wolfe <nic@wolfeden.ca> -# URL: https://sickrage.tv +# URL: https://sickrage.github.io # Git: https://github.com/SickRage/SickRage.git # # This file is part of SickRage. diff --git a/sickbeard/naming.py b/sickbeard/naming.py index 752ef9817147a864582ea6611f709687eb642ec3..1e3c0fe62f76a3856769f1f6668275474785360f 100644 --- a/sickbeard/naming.py +++ b/sickbeard/naming.py @@ -1,5 +1,5 @@ # Author: Nic Wolfe <nic@wolfeden.ca> -# URL: https://sickrage.tv +# URL: https://sickrage.github.io # Git: https://github.com/SickRage/SickRage.git # # This file is part of SickRage. diff --git a/sickbeard/network_timezones.py b/sickbeard/network_timezones.py index 82f91f3fcfb56ac443cf1a36cc4ab2e77897d9ae..15f09d15b2df9a4e9e2ec56596c2cbcd42e28da4 100644 --- a/sickbeard/network_timezones.py +++ b/sickbeard/network_timezones.py @@ -1,5 +1,5 @@ # Author: Nic Wolfe <nic@wolfeden.ca> -# URL: https://sickrage.tv +# URL: https://sickrage.github.io # Git: https://github.com/SickRage/SickRage.git # # This file is part of SickRage. diff --git a/sickbeard/nzbSplitter.py b/sickbeard/nzbSplitter.py index 5f76e0c413f06354d03657d6d083336c073629a8..09cb3df81ab386d9a3a29ce469d48acafb91d9e2 100644 --- a/sickbeard/nzbSplitter.py +++ b/sickbeard/nzbSplitter.py @@ -1,5 +1,5 @@ # Author: Nic Wolfe <nic@wolfeden.ca> -# URL: https://sickrage.tv +# URL: https://sickrage.github.io # Git: https://github.com/SickRage/SickRage.git # # This file is part of SickRage. diff --git a/sickbeard/nzbget.py b/sickbeard/nzbget.py index 40f6ddf95e7899731562e592afab72f0db4c7c26..809133a97952190fb636fe75c17ae3c4543133b0 100644 --- a/sickbeard/nzbget.py +++ b/sickbeard/nzbget.py @@ -1,5 +1,5 @@ # Author: Nic Wolfe <nic@wolfeden.ca> -# URL: https://sickrage.tv +# URL: https://sickrage.github.io # Git: https://github.com/SickRage/SickRage.git # # This file is part of SickRage. diff --git a/sickbeard/postProcessor.py b/sickbeard/postProcessor.py index 6915af51e5c1a5a79f6a22297f832d905de5a7bd..b71445381e641183256df03c483d228280e44d05 100644 --- a/sickbeard/postProcessor.py +++ b/sickbeard/postProcessor.py @@ -1,5 +1,5 @@ # Author: Nic Wolfe <nic@wolfeden.ca> -# URL: https://sickrage.tv +# URL: https://sickrage.github.io # Git: https://github.com/SickRage/SickRage.git # # This file is part of SickRage. diff --git a/sickbeard/processTV.py b/sickbeard/processTV.py index 16148afcf8c9b6e76dd82b774fbf236258651a87..d201a5885db93295c840d7872f01f64916935a64 100644 --- a/sickbeard/processTV.py +++ b/sickbeard/processTV.py @@ -1,5 +1,5 @@ # Author: Nic Wolfe <nic@wolfeden.ca> -# URL: https://sickrage.tv/ +# URL: https://sickrage.github.io/ # Git: https://github.com/SickRage/SickRage.git # # This file is part of SickRage. diff --git a/sickbeard/properFinder.py b/sickbeard/properFinder.py index f792b77b0860dc8e7cad5c3f484716816ab7d12c..23e38c56db8d81f171c9d98079920d46d6af06e6 100644 --- a/sickbeard/properFinder.py +++ b/sickbeard/properFinder.py @@ -1,5 +1,5 @@ # Author: Nic Wolfe <nic@wolfeden.ca> -# URL: https://sickrage.tv +# URL: https://sickrage.github.io # Git: https://github.com/SickRage/SickRage.git # # This file is part of SickRage. diff --git a/sickbeard/providers/btdigg.py b/sickbeard/providers/btdigg.py index c463f97755b5c1baea76b15cd597c9524ca0a773..f688b7185bb6116d3f63655083ecb8b8cb5309fd 100644 --- a/sickbeard/providers/btdigg.py +++ b/sickbeard/providers/btdigg.py @@ -70,7 +70,7 @@ class BTDIGGProvider(generic.TorrentProvider): for torrent in jdata: if not torrent['ff']: title = torrent['name'] - download_url = torrent['magnet'] + download_url = torrent['magnet'] + "&tr=udp://tracker.openbittorrent.com:80&tr=udp://tracker.coppersurfer.tk:6969&tr=udp://open.demonii.com:1337&tr=udp://tracker.leechers-paradise.org:6969&tr=udp://exodus.desync.com:6969" size = torrent['size'] # FIXME seeders = 1 diff --git a/sickbeard/providers/newznab.py b/sickbeard/providers/newznab.py index 40d447e5bb74f964ec11a5e2d36959ca3ddbf7fa..a15114d86f379536d7c649295f6ad26fe5ee7420 100644 --- a/sickbeard/providers/newznab.py +++ b/sickbeard/providers/newznab.py @@ -1,6 +1,10 @@ +# coding=utf-8 # Author: Nic Wolfe <nic@wolfeden.ca> # URL: http://code.google.com/p/sickbeard/ # +# Rewrite: Dustyn Gibson (miigotu) <miigotu@gmail.com> +# URL: http://sickrage.github.io +# # This file is part of SickRage. # # SickRage is free software: you can redistribute it and/or modify @@ -15,13 +19,13 @@ # # 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=W0703 +# pylint: disable=R0902,R0913 -import urllib -import time -import datetime import os import re +import urllib +import datetime +from bs4 import BeautifulSoup import sickbeard from sickbeard import classes @@ -33,24 +37,25 @@ from sickbeard import db from sickbeard.common import Quality from sickbeard.providers import generic from sickrage.helper.encoding import ek -from sickrage.helper.exceptions import AuthException from sickbeard.common import USER_AGENT class NewznabProvider(generic.NZBProvider): - def __init__(self, name, url, key='0', catIDs='5030,5040', search_mode='eponly', search_fallback=False, - enable_daily=False, enable_backlog=False): + """ + Generic provider for built in and custom providers who expose a newznab + compatible api. + Tested with: newznab, nzedb, spotweb, torznab + """ + def __init__(self, name, url, key='0', catIDs='5030,5040', search_mode='eponly', + search_fallback=False, enable_daily=True, enable_backlog=False): generic.NZBProvider.__init__(self, name) - self.cache = NewznabCache(self) + self.headers.update({'User-Agent': USER_AGENT}) self.urls = {'base_url': url} - self.url = self.urls['base_url'] - self.headers.update({'User-Agent': USER_AGENT}) - self.key = key self.search_mode = search_mode @@ -58,39 +63,37 @@ class NewznabProvider(generic.NZBProvider): self.enable_daily = enable_daily self.enable_backlog = enable_backlog - # a 0 in the key spot indicates that no key is needed - if self.key == '0': - self.needs_auth = False - else: - self.needs_auth = True + self.supportsBacklog = True + # 0 in the key spot indicates that no key is needed + self.needs_auth = self.key != '0' self.public = not self.needs_auth - if catIDs: - self.catIDs = catIDs - else: - self.catIDs = '5030,5040' - - self.supportsBacklog = True + self.catIDs = catIDs if catIDs else '5030,5040' self.default = False - self.last_search = datetime.datetime.now() + + self.cache = NewznabCache(self) def configStr(self): + """ + Generates a '|' delimited string of instance attributes, for saving to config.ini + """ return self.name + '|' + self.url + '|' + self.key + '|' + self.catIDs + '|' + str( int(self.enabled)) + '|' + self.search_mode + '|' + str(int(self.search_fallback)) + '|' + str( int(self.enable_daily)) + '|' + str(int(self.enable_backlog)) def imageName(self): + """ + Checks if we have an image for this provider already. + Returns found image or the default newznab image + """ if ek(os.path.isfile, ek(os.path.join, sickbeard.PROG_DIR, 'gui', sickbeard.GUI_NAME, 'images', 'providers', self.getID() + '.png')): return self.getID() + '.png' return 'newznab.png' - def _getURL(self, url, post_data=None, params=None, timeout=30, json=False): - return self.getURL(url, post_data=post_data, params=params, timeout=timeout, json=json) - def get_newznab_categories(self): """ Uses the newznab provider url and apikey to get the capabilities. @@ -100,39 +103,41 @@ class NewznabProvider(generic.NZBProvider): """ return_categories = [] - self._checkAuth() + if not self._checkAuth(): + return False, return_categories, "Provider requires auth and your key is not set" params = {"t": "caps"} if self.needs_auth and self.key: params['apikey'] = self.key - try: - data = self.cache.getRSSFeed("%s/api?%s" % (self.url, urllib.urlencode(params))) - except Exception: - logger.log(u"Error getting html for [%s]" % - ("%s/api?%s" % (self.url, '&'.join("%s=%s" % (x, y) for x, y in params.iteritems()))), logger.WARNING) - return (False, return_categories, "Error getting html for [%s]" % - ("%s/api?%s" % (self.url, '&'.join("%s=%s" % (x, y) for x, y in params.iteritems())))) + url = os.path.join(self.url, 'api?') + urllib.urlencode(params) + data = self.getURL(url) + if not data: + error_string = u"Error getting xml for [%s]" % url + logger.log(error_string, logger.WARNING) + return False, return_categories, error_string + data = BeautifulSoup(data, features=["html5lib", "permissive"]) if not self._checkAuthFromData(data): - logger.log(u"Error parsing xml", logger.DEBUG) - return False, return_categories, "Error parsing xml for [%s]" % (self.name) - - try: - for category in data.feed.categories: - if category.get('name') == 'TV': - return_categories.append(category) - for subcat in category.subcats: - return_categories.append(subcat) - except Exception: - logger.log(u"Error parsing result for [%s]" % (self.name), - logger.DEBUG) - return (False, return_categories, "Error parsing result for [%s]" % (self.name)) - + data.decompose() + error_string = u"Error parsing xml for [%s]" % (self.name) + logger.log(error_string, logger.DEBUG) + return False, return_categories, error_string + + for category in data.caps.categories.findAll('category'): + if hasattr(category, 'attrs') and category.attrs['name'] == 'TV': + return_categories.append({'id': category.attrs['id'], 'name': category.attrs['name']}) + for subcat in category.findAll('subcat'): + return_categories.append({'id': subcat.attrs['id'], 'name': subcat.attrs['name']}) + + data.decompose() return True, return_categories, "" def _get_season_search_strings(self, ep_obj): - + """ + Makes objects to pass to _doSearch for manual and backlog season pack searching + Returns a list containing dicts of search parameters + """ to_return = [] params = {} if not ep_obj: @@ -141,7 +146,6 @@ class NewznabProvider(generic.NZBProvider): params['maxage'] = (datetime.datetime.now() - datetime.datetime.combine(ep_obj.airdate, datetime.datetime.min.time())).days + 1 params['tvdbid'] = ep_obj.show.indexerid - # season if ep_obj.show.air_by_date or ep_obj.show.sports: date_str = str(ep_obj.airdate).split('-')[0] params['season'] = date_str @@ -151,10 +155,7 @@ class NewznabProvider(generic.NZBProvider): save_q = ' ' + params['q'] if 'q' in params else '' - - # add new query strings for exceptions - name_exceptions = list( - set([ep_obj.show.name] + scene_exceptions.get_scene_exceptions(ep_obj.show.indexerid))) + name_exceptions = list(set([ep_obj.show.name] + scene_exceptions.get_scene_exceptions(ep_obj.show.indexerid))) for cur_exception in name_exceptions: params['q'] = helpers.sanitizeSceneName(cur_exception) + save_q to_return.append(dict(params)) @@ -162,6 +163,10 @@ class NewznabProvider(generic.NZBProvider): return to_return def _get_episode_search_strings(self, ep_obj, add_string=''): + """ + Makes objects to pass to _doSearch for manual and backlog season pack searching + Returns a list containing dicts of search parameters + """ to_return = [] params = {} if not ep_obj: @@ -178,9 +183,7 @@ class NewznabProvider(generic.NZBProvider): params['season'] = ep_obj.scene_season params['ep'] = ep_obj.scene_episode - # add new query strings for exceptions - name_exceptions = list( - set([ep_obj.show.name] + scene_exceptions.get_scene_exceptions(ep_obj.show.indexerid))) + name_exceptions = list(set([ep_obj.show.name] + scene_exceptions.get_scene_exceptions(ep_obj.show.indexerid))) for cur_exception in name_exceptions: params['q'] = helpers.sanitizeSceneName(cur_exception) if add_string: @@ -190,129 +193,129 @@ class NewznabProvider(generic.NZBProvider): return to_return - def _doGeneralSearch(self, search_string): - return self._doSearch({'q': search_string}) - def _checkAuth(self): - + """ + Checks that user has set their api key if it is needed + Returns: True/False + """ if self.needs_auth and not self.key: logger.log(u"Invalid api key. Check your settings", logger.WARNING) - # raise AuthException("Your authentication credentials for " + self.name + " are missing, check your config.") + return False return True def _checkAuthFromData(self, data): - - if 'feed' not in data or 'entries' not in data: + """ + Checks that the returned data is valid + Returns: _checkAuth if valid otherwise False if there is an error + """ + if data.findAll('categories') + data.findAll('item'): return self._checkAuth() try: - bozo = int(data['bozo']) - bozo_exception = data['bozo_exception'] - err_code = int(data['feed']['error']['code']) - err_desc = data['feed']['error']['description'] - if not err_code or err_desc: + err_code = int(data.error.attrs['code']) + err_desc = data.error.attrs['description'] + if not (err_code or err_desc): raise - except Exception: - return True + except (AssertionError, AttributeError, ValueError): + return self._checkAuth() if err_code == 100: - raise AuthException("Your API key for " + self.name + " is incorrect, check your config.") + logger.log(u'Your API key for %s is incorrect, please check your config.' % self.name) elif err_code == 101: - raise AuthException("Your account on " + self.name + " has been suspended, contact the administrator.") + logger.log(u'Your account on %s has been suspended, contact the administrator.' % self.name) elif err_code == 102: - raise AuthException( - "Your account isn't allowed to use the API on " + self.name + ", contact the administrator") - elif bozo == 1: - raise Exception(bozo_exception) + logger.log(u'Your account is not allowed to use the API on %s, contact the administrator' % self.name) + elif err_code == 500: + logger.log(u'Your account for %s has reached the api limit' % self.name) else: - logger.log(u"Unknown error: %s" % err_desc, logger.ERROR) - - def _doSearch(self, search_params, search_mode='eponly', epcount=0, age=0, epObj=None): - - self._checkAuth() + logger.log(u'Unknown error: %s' % err_desc, logger.ERROR) - params = {"t": "tvsearch", - "maxage": (4, age)[age], - "limit": 100, - "offset": 0} - - if search_params: - params.update(search_params) - logger.log(u'Search parameters: %s' % repr(search_params), logger.DEBUG) + return False - # category ids - if self.show and self.show.is_sports: - params['cat'] = self.catIDs + ',5060' - elif self.show and self.show.is_anime: - params['cat'] = self.catIDs + ',5070' - else: - params['cat'] = self.catIDs + def _doSearch(self, search_params, search_mode='eponly', epcount=0, age=0, epObj=None): # pylint: disable=R0913,R0914 + """ + Searches indexer using the params in search_params, either for latest releases, or a string/id search + Returns: list of results in dict form + """ + results = [] + if not self._checkAuth(): + return results - params['cat'] = params['cat'].strip(', ') + params = { + "t": "tvsearch", + "maxage": (4, age)[age], + "limit": 100, + "offset": 0, + "cat": self.catIDs.strip(', ') + } if self.needs_auth and self.key: params['apikey'] = self.key + if search_params: + params.update(search_params) + params['maxage'] = min(params['maxage'], sickbeard.USENET_RETENTION) - results = [] - offset = total = 0 + search_url = os.path.join(self.url, 'api?') + urllib.urlencode(params) + logger.log(u"Search url: %s" % search_url, logger.DEBUG) + data = self.getURL(search_url) + if not data: + return results - if 'lolo.sickbeard.com' in self.url and params['maxage'] < 33: - params['maxage'] = 33 + data = BeautifulSoup(data, features=["html5lib", "permissive"]) - while total >= offset: - search_url = self.url + 'api?' + urllib.urlencode(params) + try: + torznab = 'xmlns:torznab' in data.rss.attrs.keys() + except AttributeError: + torznab = False - while(datetime.datetime.now() - self.last_search).seconds < 5: - time.sleep(1) + if not self._checkAuthFromData(data): + data.decompose() + return results - logger.log(u"Search url: %s" % search_url, logger.DEBUG) + for item in data.findAll('item'): + try: + title = item.title.next.strip() + download_url = item.link.next.strip() + except (AttributeError, TypeError): + continue - data = self.cache.getRSSFeed(search_url) + if title and download_url: + size = seeders = leechers = None + for attr in item.findAll('newznab:attr') + item.findAll('torznab:attr'): + size = helpers.tryInt(attr['value'], -1) if attr['name'] == 'size' else size + seeders = helpers.tryInt(attr['value'], 1) if attr['name'] == 'seeders' else seeders + leechers = helpers.tryInt(attr['value'], 0) if attr['name'] == 'leechers' else leechers - self.last_search = datetime.datetime.now() + if not size or (torznab and (seeders is None or leechers is None)): + continue - if not self._checkAuthFromData(data): - break + result = {'title': title, 'link': download_url, 'size': size, 'seeders': seeders, 'leechers': leechers} + results.append(result) - for item in data['entries'] or []: + data.decompose() - (title, url) = self._get_title_and_url(item) + if torznab: + results.sort(key=lambda d: d.get('seeders', 0) or 0, reverse=True) - if title and url: - results.append(item) + return results - # get total and offset attribs - try: - if total == 0: - total = int(data['feed'].newznab_response['total'] or 0) - offset = int(data['feed'].newznab_response['offset'] or 0) - except AttributeError: - break - - # No items found, prevent from doing another search - if total == 0: - break - - if offset != params['offset']: - logger.log(u"Tell your newznab provider to fix their bloody newznab responses") - break - - params['offset'] += params['limit'] - if (total > int(params['offset'])) and (offset < 500): - offset = int(params['offset']) - # if there are more items available then the amount given in one call, grab some more - logger.log(u'%d' % (total - offset) + ' more items to be fetched from provider.' + - 'Fetching another %d' % int(params['limit']) + ' items.', logger.DEBUG) - else: - logger.log(u'No more searches needed', logger.DEBUG) - break - return results + def _get_size(self, item): + """ + Gets size info from a result item + Returns int size or -1 + """ + return helpers.tryInt(item.get('size', -1), -1) + def findPropers(self, search_date=datetime.datetime.today()): + """ + Searches providers for PROPER or REPACK releases + Returns a list of objects of type classes.Proper + """ results = [] myDB = db.DBConnection() @@ -325,7 +328,7 @@ class NewznabProvider(generic.NZBProvider): ) if not sqlResults: - return [] + return results for sqlshow in sqlResults: self.show = helpers.findCertainShow(sickbeard.showList, int(sqlshow["showid"])) @@ -348,46 +351,6 @@ class NewznabCache(tvcache.TVCache): # only poll newznab providers every 30 minutes self.minTime = 30 - self.last_search = datetime.datetime.now() def _getRSSData(self): - - params = {"t": "tvsearch", - "cat": self.provider.catIDs + ',5060,5070', - "maxage": 4, - } - - if 'lolo.sickbeard.com' in self.provider.url: - params['maxage'] = 33 - - if self.provider.needs_auth and self.provider.key: - params['apikey'] = self.provider.key - - rss_url = self.provider.url + 'api?' + urllib.urlencode(params) - - while (datetime.datetime.now() - self.last_search).seconds < 5: - time.sleep(1) - - logger.log(u"Cache update URL: %s " % rss_url, logger.DEBUG) - data = self.getRSSFeed(rss_url) - - self.last_search = datetime.datetime.now() - - return data - - def _checkAuth(self, data): - # pylint: disable=W0212 - return self.provider._checkAuthFromData(data) - - def _parseItem(self, item): - title, url = self._get_title_and_url(item) - - self._checkItemAuth(title, url) - - if not title or not url: - return None - - tvrageid = 0 - - logger.log(u"Attempting to add item from RSS to cache: %s" % title, logger.DEBUG) - return self._addCacheEntry(title, url, indexer_id=tvrageid) + return {'entries': self.provider._doSearch({})} diff --git a/sickbeard/sab.py b/sickbeard/sab.py index 0dc7625aabcb4ca63e088f54847c38a8a5cb7474..b22c1b7f470fc01c3f4f31ebb7f62a492016b3e7 100644 --- a/sickbeard/sab.py +++ b/sickbeard/sab.py @@ -1,5 +1,5 @@ # Author: Nic Wolfe <nic@wolfeden.ca> -# URL: https://sickrage.tv +# URL: https://sickrage.github.io # Git: https://github.com/SickRage/SickRage # # This file is part of SickRage. diff --git a/sickbeard/sbdatetime.py b/sickbeard/sbdatetime.py index eae6a67458785b74b0ac9162856a6884c0a39559..def4ea804d1ad0d5b7ecd6cd6d58bcacbbbfc53a 100644 --- a/sickbeard/sbdatetime.py +++ b/sickbeard/sbdatetime.py @@ -1,5 +1,5 @@ # Author: Nic Wolfe <nic@wolfeden.ca> -# URL: https://sickrage.tv +# URL: https://sickrage.github.io # Git: https://github.com/SickRage/SickRage.git # # This file is part of SickRage. diff --git a/sickbeard/scene_exceptions.py b/sickbeard/scene_exceptions.py index 1de1c880d291a6d677e7bede82cf43456db9a9ba..601975157f4eba2dbe15653dea9509deff6881cf 100644 --- a/sickbeard/scene_exceptions.py +++ b/sickbeard/scene_exceptions.py @@ -1,5 +1,5 @@ # Author: Nic Wolfe <nic@wolfeden.ca> -# URL: https://sickrage.tv +# URL: https://sickrage.github.io # Git: https://github.com/SickRage/SickRage.git # # This file is part of SickRage. diff --git a/sickbeard/scene_numbering.py b/sickbeard/scene_numbering.py index 3edf0fa53eaad52f2c29605aa83fae9637f6b5bd..d4bb071d542420c676dcd2580a7dfd04b1b50f4a 100644 --- a/sickbeard/scene_numbering.py +++ b/sickbeard/scene_numbering.py @@ -1,5 +1,5 @@ # Author: Nic Wolfe <nic@wolfeden.ca> -# URL: https://sickrage.tv +# URL: https://sickrage.github.io # Git: https://github.com/SickRage/SickRage.git # # This file is part of SickRage. diff --git a/sickbeard/scheduler.py b/sickbeard/scheduler.py index 2b56e39bdc4cff66a8e3a3652a89b761632c8c2e..627351ab6d5abee7e6d6d3266a3cde3fa32329cd 100644 --- a/sickbeard/scheduler.py +++ b/sickbeard/scheduler.py @@ -1,5 +1,5 @@ # Author: Nic Wolfe <nic@wolfeden.ca> -# URL: https://sickrage.tv +# URL: https://sickrage.github.io # Git: https://github.com/SickRage/SickRage.git # # This file is part of SickRage. diff --git a/sickbeard/search.py b/sickbeard/search.py index 769ee886c964d711c0abd56fee70272c5d1d0179..57f22ea032da0afc316f1f82b575c091344fd600 100644 --- a/sickbeard/search.py +++ b/sickbeard/search.py @@ -1,5 +1,5 @@ # Author: Nic Wolfe <nic@wolfeden.ca> -# URL: https://sickrage.tv +# URL: https://sickrage.github.io # Git: https://github.com/SickRage/SickRage.git # # This file is part of SickRage. diff --git a/sickbeard/show_queue.py b/sickbeard/show_queue.py index e31752e09fd3f7515e24c2c2ace2eb594024d048..c195832099dcb91a095eff98712106131be65b32 100644 --- a/sickbeard/show_queue.py +++ b/sickbeard/show_queue.py @@ -303,7 +303,7 @@ class QueueItemAdd(ShowQueueItem): # if the show has no episodes/seasons if not s: logger.log(u"Show " + str(s['seriesname']) + " is on " + str( - sickbeard.indexerApi(self.indexer).name) + " but contains no season/episode data.", logger.ERROR) + sickbeard.indexerApi(self.indexer).name) + " but contains no season/episode data.") ui.notifications.error("Unable to add show", "Show " + str(s['seriesname']) + " is on " + str(sickbeard.indexerApi( self.indexer).name) + " but contains no season/episode data.") diff --git a/sickbeard/webserve.py b/sickbeard/webserve.py index d70c1fa5f78caea5647b161db24cb08cdfb04a27..c11ddf7e76ece02fc54dacbc4384478be26700a7 100644 --- a/sickbeard/webserve.py +++ b/sickbeard/webserve.py @@ -3837,7 +3837,7 @@ class ConfigSearch(Config): def saveSearch(self, use_nzbs=None, use_torrents=None, nzb_dir=None, sab_username=None, sab_password=None, sab_apikey=None, sab_category=None, sab_category_anime=None, sab_category_backlog=None, sab_category_anime_backlog=None, sab_host=None, nzbget_username=None, nzbget_password=None, nzbget_category=None, nzbget_category_backlog=None, nzbget_category_anime=None, nzbget_category_anime_backlog=None, nzbget_priority=None, - nzbget_host=None, nzbget_use_https=None, backlog_frequency=None, + nzbget_host=None, nzbget_use_https=None, backlog_days=None, backlog_frequency=None, dailysearch_frequency=None, nzb_method=None, torrent_method=None, usenet_retention=None, download_propers=None, check_propers_interval=None, allow_high_priority=None, sab_forced=None, randomize_providers=None, use_failed_downloads=None, delete_failed=None, @@ -3857,6 +3857,7 @@ class ConfigSearch(Config): config.change_DAILYSEARCH_FREQUENCY(dailysearch_frequency) config.change_BACKLOG_FREQUENCY(backlog_frequency) + sickbeard.BACKLOG_DAYS = config.to_int(backlog_days, default=7) sickbeard.USE_NZBS = config.checkbox_to_value(use_nzbs) sickbeard.USE_TORRENTS = config.checkbox_to_value(use_torrents) diff --git a/sickrage/helper/common.py b/sickrage/helper/common.py index 37b98eb585e7adb3776a9258fb0e6b2942fc4beb..2ac3bf6698b7a249751a80f6185c7d95038e1fa0 100644 --- a/sickrage/helper/common.py +++ b/sickrage/helper/common.py @@ -1,6 +1,6 @@ # This file is part of SickRage. # -# URL: https://www.sickrage.tv +# URL: https://sickrage.github.io # Git: https://github.com/SickRage/SickRage.git # # SickRage is free software: you can redistribute it and/or modify diff --git a/sickrage/helper/encoding.py b/sickrage/helper/encoding.py index 384136f1ae25d5a4d9aec30fdd5208ca5efd6a66..5c0908901a7db2def9ea8273f21286ae4e98feb3 100644 --- a/sickrage/helper/encoding.py +++ b/sickrage/helper/encoding.py @@ -1,5 +1,5 @@ # Author: Nic Wolfe <nic@wolfeden.ca> -# URL: https://sickrage.tv +# URL: https://sickrage.github.io # Git: https://github.com/SickRage/SickRage.git # # This file is part of SickRage. diff --git a/sickrage/helper/exceptions.py b/sickrage/helper/exceptions.py index afb886926e90fdb2c00ed98a6af28bb66921410d..746b90a87c8842494128935eefeb09ddf8fd5e04 100644 --- a/sickrage/helper/exceptions.py +++ b/sickrage/helper/exceptions.py @@ -1,6 +1,6 @@ # This file is part of SickRage. # -# URL: https://www.sickrage.tv +# URL: https://sickrage.github.io # Git: https://github.com/SickRage/SickRage.git # # SickRage is free software: you can redistribute it and/or modify diff --git a/sickrage/helper/quality.py b/sickrage/helper/quality.py index 7b52b267e5a7ec1cd8564498652d6e03b41333db..1834c37f09cd068caa71cefbc51ff4cb14157a93 100644 --- a/sickrage/helper/quality.py +++ b/sickrage/helper/quality.py @@ -1,6 +1,6 @@ # This file is part of SickRage. # -# URL: https://www.sickrage.tv +# URL: https://sickrage.github.io # Git: https://github.com/SickRage/SickRage.git # # SickRage is free software: you can redistribute it and/or modify diff --git a/sickrage/media/GenericMedia.py b/sickrage/media/GenericMedia.py index c51ae3b7ef6cd7459a50b5188752f8fd4588adcc..d323e2909e113b35aa824c2aa14c6932919ee865 100644 --- a/sickrage/media/GenericMedia.py +++ b/sickrage/media/GenericMedia.py @@ -1,6 +1,6 @@ # This file is part of SickRage. # -# URL: https://www.sickrage.tv +# URL: https://sickrage.github.io # Git: https://github.com/SickRage/SickRage.git # # SickRage is free software: you can redistribute it and/or modify diff --git a/sickrage/media/ShowBanner.py b/sickrage/media/ShowBanner.py index 525a3c234785a6474c83170371c7c45c870270b2..5ecbef9ad26e9ac6b41f65b140f57934c67864ef 100644 --- a/sickrage/media/ShowBanner.py +++ b/sickrage/media/ShowBanner.py @@ -1,6 +1,6 @@ # This file is part of SickRage. # -# URL: https://www.sickrage.tv +# URL: https://sickrage.github.io # Git: https://github.com/SickRage/SickRage.git # # SickRage is free software: you can redistribute it and/or modify diff --git a/sickrage/media/ShowFanArt.py b/sickrage/media/ShowFanArt.py index ed0831c049d8b0cda99da7a4ef2d8abb9f578851..62a588173480fc232aeaf123ec2ea03ebd63c6c4 100644 --- a/sickrage/media/ShowFanArt.py +++ b/sickrage/media/ShowFanArt.py @@ -1,6 +1,6 @@ # This file is part of SickRage. # -# URL: https://www.sickrage.tv +# URL: https://sickrage.github.io # Git: https://github.com/SickRage/SickRage.git # # SickRage is free software: you can redistribute it and/or modify diff --git a/sickrage/media/ShowNetworkLogo.py b/sickrage/media/ShowNetworkLogo.py index 270a38c2001a357b91a68267411d744a00ea8267..1a4f4c2d3dbfbf1bdf4118a832b27e54ad616a18 100644 --- a/sickrage/media/ShowNetworkLogo.py +++ b/sickrage/media/ShowNetworkLogo.py @@ -1,6 +1,6 @@ # This file is part of SickRage. # -# URL: https://www.sickrage.tv +# URL: https://sickrage.github.io # Git: https://github.com/SickRage/SickRage.git # # SickRage is free software: you can redistribute it and/or modify diff --git a/sickrage/media/ShowPoster.py b/sickrage/media/ShowPoster.py index 6bba3dc50acfab360a2f0c76407139b204ad4cc7..6039fbb4794c543fb55d5e73be41d93210c132d0 100644 --- a/sickrage/media/ShowPoster.py +++ b/sickrage/media/ShowPoster.py @@ -1,6 +1,6 @@ # This file is part of SickRage. # -# URL: https://www.sickrage.tv +# URL: https://sickrage.github.io # Git: https://github.com/SickRage/SickRage.git # # SickRage is free software: you can redistribute it and/or modify diff --git a/sickrage/show/ComingEpisodes.py b/sickrage/show/ComingEpisodes.py index 6946e1b6df9ffdd8312abb0b498c1fc5c522cb6f..65b34022839127c5404f4418df8d7c7893fae493 100644 --- a/sickrage/show/ComingEpisodes.py +++ b/sickrage/show/ComingEpisodes.py @@ -1,6 +1,6 @@ # This file is part of SickRage. # -# URL: https://www.sickrage.tv +# URL: https://sickrage.github.io # Git: https://github.com/SickRage/SickRage.git # # SickRage is free software: you can redistribute it and/or modify diff --git a/sickrage/show/History.py b/sickrage/show/History.py index ab3989e7afbb15897c8cdb0e026e9ad11d10a0ea..0b04e02aa78342a8ae52053e19a140d6a0dcf36c 100644 --- a/sickrage/show/History.py +++ b/sickrage/show/History.py @@ -1,6 +1,6 @@ # This file is part of SickRage. # -# URL: https://www.sickrage.tv +# URL: https://sickrage.github.io # Git: https://github.com/SickRage/SickRage.git # # SickRage is free software: you can redistribute it and/or modify diff --git a/sickrage/show/Show.py b/sickrage/show/Show.py index 833f7294f98d8305369fc930e80a4ee2976327c6..2e3601bce85ec339e53b1568b3307e7071e28b6a 100644 --- a/sickrage/show/Show.py +++ b/sickrage/show/Show.py @@ -1,6 +1,6 @@ # This file is part of SickRage. # -# URL: https://www.sickrage.tv +# URL: https://sickrage.github.io # Git: https://github.com/SickRage/SickRage.git # # SickRage is free software: you can redistribute it and/or modify diff --git a/sickrage/system/Restart.py b/sickrage/system/Restart.py index 65bdd22cef513f796ed58f68fd8b236581268d10..dd35c4c1a5e54e9d869e36af49c8a10a4da731ea 100644 --- a/sickrage/system/Restart.py +++ b/sickrage/system/Restart.py @@ -1,6 +1,6 @@ # This file is part of SickRage. # -# URL: https://www.sickrage.tv +# URL: https://sickrage.github.io # Git: https://github.com/SickRage/SickRage.git # # SickRage is free software: you can redistribute it and/or modify diff --git a/sickrage/system/Shutdown.py b/sickrage/system/Shutdown.py index 0abb5f6e61e3cc2c017b831dad0e5599b7642ab8..686c02c63677fe0c45754c1a7c1149ece22a93a1 100644 --- a/sickrage/system/Shutdown.py +++ b/sickrage/system/Shutdown.py @@ -1,6 +1,6 @@ # This file is part of SickRage. # -# URL: https://www.sickrage.tv +# URL: https://sickrage.github.io # Git: https://github.com/SickRage/SickRage.git # # SickRage is free software: you can redistribute it and/or modify