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 7658b31169b872d51480ae91faa89f592b8e8da3..229ec07b80676b248457bccec41602364c83c1e4 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,4 +1,5 @@
-language: python
+language:
+  - python
 
 python: 2.7.9
 
@@ -8,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/css/browser.css b/gui/slick/css/browser.css
index b3f5fb509eef604b91b8ee28f5c804040fc5aea4..571501723e875d0280fb31342a692f3f03755fce 100644
--- a/gui/slick/css/browser.css
+++ b/gui/slick/css/browser.css
@@ -3,10 +3,6 @@
     overflow-y: auto;
 }
 
-#fileBrowserDialog h2 {
-    font-size: 20px;
-}
-
 #fileBrowserDialog ul {
     margin: 0;
     padding: 0;
diff --git a/gui/slick/images/notifiers/boxcar.png b/gui/slick/images/notifiers/boxcar.png
deleted file mode 100644
index 3e1a700060aa601ce52c21c1502fdbc672d2bb72..0000000000000000000000000000000000000000
Binary files a/gui/slick/images/notifiers/boxcar.png and /dev/null differ
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" />&nbsp;' + 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 6a8b7f4e09910391c733070989dd23767bae6097..51f6f4849dc6d84d70570af1b4c3deedb9947821 100644
--- a/gui/slick/js/browser.js
+++ b/gui/slick/js/browser.js
@@ -1,20 +1,20 @@
-;(function($) {
-"use strict";
+;(function ($) {
+    'use strict';
 
     $.Browser = {
         defaults: {
             title:             'Choose Directory',
             url:               srRoot + '/browser/',
             autocompleteURL:   srRoot + '/browser/complete',
-            includeFiles:      0
+            includeFiles:      0,
+            showBrowseButton:  true
         }
     };
 
     var fileBrowserDialog, currentBrowserPath, currentRequest = null;
 
     function browse(path, endpoint, includeFiles) {
-
-        if (currentBrowserPath == path) {
+        if (currentBrowserPath === path) {
             return;
         }
 
@@ -28,24 +28,46 @@
 
         currentRequest = $.getJSON(endpoint, { path: path, includeFiles: includeFiles }, function (data) {
             fileBrowserDialog.empty();
-            var first_val = data[0];
+            var firstVal = data[0];
             var i = 0;
             var list, link = null;
-            data = $.grep(data, function (value) {
+            data = $.grep(data, function () {
                 return i++ !== 0;
             });
-            $('<h2>').text(first_val.current_path).appendTo(fileBrowserDialog);
+
+            $('<input type="text" class="form-control input-sm">')
+                .val(firstVal.currentPath)
+                .on('keypress', function (e) {
+                    if (e.which === 13) {
+                        browse(e.target.value, endpoint, includeFiles);
+                    }
+                })
+                .appendTo(fileBrowserDialog)
+                .fileBrowser({showBrowseButton: false})
+                .on('autocompleteselect', function (e, ui) {
+                    browse(ui.item.value, endpoint, includeFiles);
+                });
+
             list = $('<ul>').appendTo(fileBrowserDialog);
             $.each(data, function (i, entry) {
-                link = $("<a href='javascript:void(0)' />").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');
         });
     }
@@ -55,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',
@@ -71,22 +92,22 @@
         }
 
         fileBrowserDialog.dialog('option', 'buttons', [
-                    {
-                        text: "Ok",
-                        "class": "btn",
-                        click: function() {
-                            // store the browsed path to the associated text field
-                            callback(currentBrowserPath, options);
-                            $(this).dialog("close");
-                        }
-                    },
-                    {
-                        text: "Cancel",
-                        "class": "btn",
-                        click: function() {
-                            $(this).dialog("close");
-                        }
-                    }
+            {
+                text: 'Ok',
+                'class': 'btn',
+                click: function () {
+                    // store the browsed path to the associated text field
+                    callback(currentBrowserPath, options);
+                    $(this).dialog('close');
+                }
+            },
+            {
+                text: 'Cancel',
+                'class': 'btn',
+                click: function () {
+                    $(this).dialog('close');
+                }
+            }
         ]);
 
         // set up the browser and launch the dialog
@@ -109,40 +130,39 @@
         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",
-                        success: function (data, item) {
+                        dataType: 'json',
+                        success: function (data) {
                             //implement a startsWith filter for the results
-                            var matcher = new RegExp("^" + query, "i");
-                            var a = $.grep(data, function (item, index) {
+                            var matcher = new RegExp('^' + query, 'i');
+                            var a = $.grep(data, function (item) {
                                 return matcher.test(item);
                             });
                             response(a);
                         }
                     });
                 },
-                open: function (event, ui) {
-                    $(".ui-autocomplete li.ui-menu-item a").removeClass("ui-corner-all");
+                open: function () {
+                    $('.ui-autocomplete li.ui-menu-item a').removeClass('ui-corner-all');
                 }
-            })
-                .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 result_item = item.label;
-                    var x = new RegExp("(?![^&;]+;)(?!<[^<>]*)(" + query + ")(?![^<>]*>)(?![^&;]+;)", "gi");
-                    result_item = result_item.replace(x, function (FullMatch, n) {
-                        return '<b>' + FullMatch + '</b>';
-                    });
-                    return $("<li></li>")
-                        .data("ui-autocomplete-item", item)
-                        .append("<a class='nowrap'>" + result_item + "</a>")
-                        .appendTo(ul);
-                };
+            }).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');
+                resultItem = resultItem.replace(x, function (fullMatch) {
+                    return '<b>' + fullMatch + '</b>';
+                });
+                return $('<li></li>')
+                    .data('ui-autocomplete-item', item)
+                    .append('<a class="nowrap">' + resultItem + '</a>')
+                    .appendTo(ul);
+            };
         }
 
         var path, callback, ls = false;
@@ -163,16 +183,20 @@
             if (ls && options.key) {
                 localStorage['fileBrowser-' + options.key] = path;
             }
-
         };
 
-        // append the browse button and give it a click behaviour
-        return options.field.addClass('fileBrowserField').after($('<input type="button" value="Browse&hellip;" class="btn btn-inline fileBrowser" />').click(function () {
-            var initialDir = options.field.val() || (options.key && path) || '';
-            var optionsWithInitialDir = $.extend({}, options, {initialDir: initialDir});
-            $(this).nFileBrowser(callback, optionsWithInitialDir);
-            return false;
-        }));
+        options.field.addClass('fileBrowserField');
+        if (options.showBrowseButton) {
+            // append the browse button and give it a click behaviour
+            options.field.after(
+                $('<input type="button" value="Browse&hellip;" class="btn btn-inline fileBrowser">').on('click', function () {
+                    var initialDir = options.field.val() || (options.key && path) || '';
+                    var optionsWithInitialDir = $.extend({}, options, {initialDir: initialDir});
+                    $(this).nFileBrowser(callback, optionsWithInitialDir);
+                    return false;
+                })
+            );
+        }
+        return options.field;
     };
-
 })(jQuery);
diff --git a/gui/slick/js/core.js b/gui/slick/js/core.js
index 8b4aa6f88e8f2f275b729149742716d7bf1f5de7..d36035d44fc9e44f6ff1d9e2fe609a160ed29885 100644
--- a/gui/slick/js/core.js
+++ b/gui/slick/js/core.js
@@ -499,23 +499,6 @@ var SICKRAGE = {
                 });
             });
 
-            $('#testBoxcar').on('click', function() {
-                var boxcar = {};
-                boxcar.username = $.trim($('#boxcar_username').val());
-                if (!boxcar.username) {
-                    $('#testBoxcar-result').html('Please fill out the necessary fields above.');
-                    $('#boxcar_username').addClass('warning');
-                    return;
-                }
-                $('#boxcar_username').removeClass('warning');
-                $(this).prop('disabled', true);
-                $('#testBoxcar-result').html(loading);
-                $.get(srRoot + '/home/testBoxcar', {'username': boxcar.username}).done(function (data) {
-                    $('#testBoxcar-result').html(data);
-                    $('#testBoxcar').prop('disabled', false);
-                });
-            });
-
             $('#testBoxcar2').on('click', function () {
                 var boxcar2 = {};
                 boxcar2.accesstoken = $.trim($('#boxcar2_accesstoken').val());
@@ -944,7 +927,7 @@ var SICKRAGE = {
             });
 
             // Update the internal data struct anytime settings are saved to the server
-            $('#email_show').bind('notify', function() {
+            $('#email_show').on('notify', function() {
                 loadShowNotifyLists();
             });
 
diff --git a/gui/slick/js/core.min.js b/gui/slick/js/core.min.js
index d2a846defd11f043b320502e71c8617dea6c4705..93decfd76f1258eb1f4a317e1d6679e7406c6869 100644
Binary files a/gui/slick/js/core.min.js and b/gui/slick/js/core.min.js differ
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_notifications.mako b/gui/slick/views/config_notifications.mako
index 769cdacd311d244719cb03096d1802c9fd639bb8..fa45a445132e4b0851360a3771934fc4878eb003 100644
--- a/gui/slick/views/config_notifications.mako
+++ b/gui/slick/views/config_notifications.mako
@@ -1001,71 +1001,8 @@
 
                 <div class="component-group">
                     <div class="component-group-desc">
-                        <img class="notifier-icon" src="${srRoot}/images/notifiers/boxcar.png" alt="" title="Boxcar" />
-                        <h3><a href="${anon_url('http://boxcar.io/')}" rel="noreferrer" onclick="window.open(this.href, '_blank'); return false;">Boxcar</a></h3>
-                        <p>Universal push notification for iOS. Read your messages where and when you want them! A subscription will be sent if needed.</p>
-                    </div>
-                    <fieldset class="component-group-list">
-                        <div class="field-pair">
-                            <label for="use_boxcar">
-                                <span class="component-title">Enable</span>
-                                <span class="component-desc">
-                                    <input type="checkbox" class="enabler" name="use_boxcar" id="use_boxcar" ${('', 'checked="checked"')[bool(sickbeard.USE_BOXCAR)]}/>
-                                    <p>should SickRage send Boxcar notifications ?</p>
-                                </span>
-                            </label>
-                        </div>
-
-                        <div id="content_use_boxcar">
-                            <div class="field-pair">
-                                <label for="boxcar_notify_onsnatch">
-                                    <span class="component-title">Notify on snatch</span>
-                                    <span class="component-desc">
-                                        <input type="checkbox" name="boxcar_notify_onsnatch" id="boxcar_notify_onsnatch" ${('', 'checked="checked"')[bool(sickbeard.BOXCAR_NOTIFY_ONSNATCH)]}/>
-                                        <p>send a notification when a download starts ?</p>
-                                    </span>
-                                </label>
-                            </div>
-                            <div class="field-pair">
-                                <label for="boxcar_notify_ondownload">
-                                    <span class="component-title">Notify on download</span>
-                                    <span class="component-desc">
-                                        <input type="checkbox" name="boxcar_notify_ondownload" id="boxcar_notify_ondownload" ${('', 'checked="checked"')[bool(sickbeard.BOXCAR_NOTIFY_ONDOWNLOAD)]}/>
-                                        <p>send a notification when a download finishes ?</p>
-                                    </span>
-                                </label>
-                            </div>
-                            <div class="field-pair">
-                                <label for="boxcar_notify_onsubtitledownload">
-                                    <span class="component-title">Notify on subtitle download</span>
-                                    <span class="component-desc">
-                                        <input type="checkbox" name="boxcar_notify_onsubtitledownload" id="boxcar_notify_onsubtitledownload" ${('', 'checked="checked"')[bool(sickbeard.BOXCAR_NOTIFY_ONSUBTITLEDOWNLOAD)]}/>
-                                        <p>send a notification when subtitles are downloaded ?</p>
-                                    </span>
-                                </label>
-                            </div>
-                            <div class="field-pair">
-                                <label for="boxcar_username">
-                                    <span class="component-title">Boxcar username</span>
-                                    <input type="text" name="boxcar_username" id="boxcar_username" value="${sickbeard.BOXCAR_USERNAME}" class="form-control input-sm input250" />
-                                </label>
-                                <label>
-                                    <span class="component-title">&nbsp;</span>
-                                    <span class="component-desc">username of your Boxcar account</span>
-                                </label>
-                            </div>
-                            <div class="testNotification" id="testBoxcar-result">Click below to test.</div>
-                            <input  class="btn" type="button" value="Test Boxcar" id="testBoxcar" />
-                            <input type="submit" class="config_submitter btn" value="Save Changes" />
-                        </div><!-- /content_use_boxcar //-->
-
-                    </fieldset>
-                </div><!-- /boxcar component-group //-->
-
-                <div class="component-group">
-                    <div class="component-group-desc">
-                        <img class="notifier-icon" src="${srRoot}/images/notifiers/boxcar2.png" alt="" title="Boxcar2"/>
-                        <h3><a href="${anon_url('https://new.boxcar.io/')}" rel="noreferrer" onclick="window.open(this.href, '_blank'); return false;">Boxcar2</a></h3>
+                        <img class="notifier-icon" src="${srRoot}/images/notifiers/boxcar2.png" alt="" title="Boxcar 2"/>
+                        <h3><a href="${anon_url('https://new.boxcar.io/')}" rel="noreferrer" onclick="window.open(this.href, '_blank'); return false;">Boxcar 2</a></h3>
                         <p>Read your messages where and when you want them!</p>
                     </div>
                     <fieldset class="component-group-list">
@@ -1074,7 +1011,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 Boxcar2 notifications ?</p>
+                                    <p>should SickRage send Boxcar notifications ?</p>
                                 </span>
                             </label>
                         </div>
@@ -1114,11 +1051,11 @@
                                 </label>
                                 <label>
                                     <span class="component-title">&nbsp;</span>
-                                    <span class="component-desc">access token for your Boxcar2 account.</span>
+                                    <span class="component-desc">access token for your Boxcar account.</span>
                                 </label>
                             </div>
                             <div class="testNotification" id="testBoxcar2-result">Click below to test.</div>
-                            <input  class="btn" type="button" value="Test Boxcar2" id="testBoxcar2" />
+                            <input  class="btn" type="button" value="Test Boxcar" id="testBoxcar2" />
                             <input type="submit" class="config_submitter btn" value="Save Changes" />
                         </div><!-- /content_use_boxcar2 //-->
 
diff --git a/gui/slick/views/config_postProcessing.mako b/gui/slick/views/config_postProcessing.mako
index 9fd8161b2d9c0dd06a7757580ae4be07992ceae9..cb202f50dcabc8b674a29b9b7851f9e19c31f463 100644
--- a/gui/slick/views/config_postProcessing.mako
+++ b/gui/slick/views/config_postProcessing.mako
@@ -104,6 +104,14 @@
                                 <span class="component-desc">comma seperated list of extensions SickRage ignores when Post Processing</span>
                             </label>
                         </div>
+                        <div class="field-pair">
+                            <input type="checkbox" name="postpone_if_no_subs" id="postpone_if_no_subs" ${('', 'checked="checked"')[bool(sickbeard.POSTPONE_IF_NO_SUBS)]}/>
+                            <label for="postpone_if_no_subs">
+                                <span class="component-title">Postpone if no subtitle</span>
+                                <span class="component-desc">Wait to process a file until subtitles are present</span>
+                                <span class="component-desc">Language names are allowed in subtitle filename (en.srt, pt-br.srt, ita.srt, etc.)</span>
+                            </label>
+                        </div>
                         <div class="field-pair">
                             <input type="checkbox" name="rename_episodes" id="rename_episodes" ${('', 'checked="checked"')[bool(sickbeard.RENAME_EPISODES)]}/>
                             <label for="rename_episodes">
@@ -129,7 +137,17 @@
                             <input type="checkbox" name="move_associated_files" id="move_associated_files" ${('', 'checked="checked"')[bool(sickbeard.MOVE_ASSOCIATED_FILES)]}/>
                             <label for="move_associated_files">
                                 <span class="component-title">Move Associated Files</span>
-                                <span class="component-desc">Move srr/srt/sfv/etc files with the episode when processed?</span>
+                                <span class="component-desc">Move srr/sfv/etc files with the episode when processed?</span>
+                            </label>
+                        </div>
+                        <div class="field-pair">
+                            <label class="nocheck">
+                                <span class="component-title">Allowed associated file extensions</span>
+                                <input type="text" name="allowed_extensions" id="allowed_extensions" value="${sickbeard.ALLOWED_EXTENSIONS}" class="form-control input-sm input350" />
+                            </label>
+                            <label class="nocheck">
+                                <span class="component-title">&nbsp;</span>
+                                <span class="component-desc">Comma seperated list of associated file extensions SickRage should move while Post Processing. Leaving it empty means all extensions will be allowed</span>
                             </label>
                         </div>
                         <div class="field-pair">
diff --git a/gui/slick/views/config_search.mako b/gui/slick/views/config_search.mako
index 8bc218adac83a4d0d6d9fbe3039bb56fdd85ca5e..8beab44b50b58c03bfb4e521465188ef95c2a202 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>
@@ -115,6 +125,18 @@
                             </label>
                         </div>
 
+                        <div class="field-pair">
+                            <label>
+                                <span class="component-title">Trackers list</span>
+                                <span class="component-desc">
+                                    <input type="text" name="trackers_list" value="${sickbeard.TRACKERS_LIST}" class="form-control input-sm input350" />
+                                    <div class="clear-left">Trackers that will be added to magnets without trackers<br>
+                                    separate trackers with a comma, e.g. "tracker1,tracker2,tracker3"
+                                    </div>
+                                </span>
+                            </label>
+                        </div>
+
                         <div class="field-pair">
                             <label>
                                 <span class="component-title">Ignore language names in subbed results</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/errorlogs.mako b/gui/slick/views/errorlogs.mako
index 47e52a636cf2d74bdc2cc41bc84c29a33adb0692..978561785d4ad748bf533720ccbc6663a9520dd4 100644
--- a/gui/slick/views/errorlogs.mako
+++ b/gui/slick/views/errorlogs.mako
@@ -13,9 +13,6 @@ pre {
 }
 </style>
 </%block>
-<%block name="scripts">
-<script type="text/javascript" src="${srRoot}/js/new/errorlogs.js"></script>
-</%block>
 <%block name="content">
 <%
     if logLevel == sickbeard.logger.WARNING:
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_episodeStatuses.mako b/gui/slick/views/manage_episodeStatuses.mako
index ebf0cdff4f3766b851b3e27341edb20f34633736..8bb6aa0d1d459cd6d1c15999498a98587b2fe28c 100644
--- a/gui/slick/views/manage_episodeStatuses.mako
+++ b/gui/slick/views/manage_episodeStatuses.mako
@@ -19,7 +19,7 @@
 % if not whichStatus or (whichStatus and not ep_counts):
 
 % if whichStatus:
-<h2>None of your episodes have status ${common.statusStrings[int(whichStatus)]}</h2>
+<h2>None of your episodes have status ${common.statusStrings[whichStatus]}</h2>
 <br>
 % endif
 
@@ -39,7 +39,7 @@ Manage episodes with status <select name="whichStatus" class="form-control form-
 <form action="${srRoot}/manage/changeEpisodeStatuses" method="post">
 <input type="hidden" id="oldStatus" name="oldStatus" value="${whichStatus}" />
 
-<h2>Shows containing ${common.statusStrings[int(whichStatus)]} episodes</h2>
+<h2>Shows containing ${common.statusStrings[whichStatus]} episodes</h2>
 
 <br>
 
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}&amp;${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/gui/slick/views/viewlogs.mako b/gui/slick/views/viewlogs.mako
index cda4163c94dc5250995e434adcacc004f17de30c..73e7200c149333126a653410ef38d3306ff1ac0e 100644
--- a/gui/slick/views/viewlogs.mako
+++ b/gui/slick/views/viewlogs.mako
@@ -4,8 +4,14 @@
     from sickbeard import classes
     from sickbeard.logger import reverseNames
 %>
-<%block name="scripts">
-<script type="text/javascript" src="${srRoot}/js/new/viewlogs.js"></script>
+<%block name="css">
+<style>
+pre {
+  overflow: auto;
+  word-wrap: normal;
+  white-space: pre;
+}
+</style>
 </%block>
 <%block name="content">
 % if not header is UNDEFINED:
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
 
 #### [![Feature Requests](https://cloud.githubusercontent.com/assets/390379/10127973/045b3a96-6560-11e5-9b20-31a2032956b2.png)](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/__init__.py b/sickbeard/__init__.py
index 68a714dfd2ddba7aabe6d83fa45235580c115d4f..765cb7626f51adc6a439087e0f43185bb0fce420 100644
--- a/sickbeard/__init__.py
+++ b/sickbeard/__init__.py
@@ -275,10 +275,12 @@ PROCESS_METHOD = None
 DELRARCONTENTS = False
 MOVE_ASSOCIATED_FILES = False
 POSTPONE_IF_SYNC_FILES = True
+POSTPONE_IF_NO_SUBS = False
 NFO_RENAME = True
 TV_DOWNLOAD_DIR = None
 UNPACK = False
 SKIP_REMOVED_FILES = False
+ALLOWED_EXTENSIONS = "nfo,srr,sfv"
 
 NZBS = False
 NZBS_UID = None
@@ -385,14 +387,6 @@ TWITTER_PREFIX = None
 TWITTER_DMTO = None
 TWITTER_USEDM = False
 
-USE_BOXCAR = False
-BOXCAR_NOTIFY_ONSNATCH = False
-BOXCAR_NOTIFY_ONDOWNLOAD = False
-BOXCAR_NOTIFY_ONSUBTITLEDOWNLOAD = False
-BOXCAR_USERNAME = None
-BOXCAR_PASSWORD = None
-BOXCAR_PREFIX = None
-
 USE_BOXCAR2 = False
 BOXCAR2_NOTIFY_ONSNATCH = False
 BOXCAR2_NOTIFY_ONDOWNLOAD = False
@@ -543,6 +537,7 @@ DELETE_FAILED = False
 EXTRA_SCRIPTS = []
 
 IGNORE_WORDS = "german,french,core2hd,dutch,swedish,reenc,MrLss"
+TRACKERS_LIST = "udp://coppersurfer.tk:6969/announce,udp://open.demonii.com:1337,udp://exodus.desync.com:6969,udp://9.rarbg.me:2710/announce,udp://glotorrents.pw:6969/announce,udp://tracker.openbittorrent.com:80/announce,udp://9.rarbg.to:2710/announce"
 REQUIRE_WORDS = ""
 IGNORED_SUBS_LIST = "dk,fin,heb,kor,nor,nordic,pl,swe"
 SYNC_FILES = "!sync,lftp-pget-status,part,bts,!qb"
@@ -585,7 +580,7 @@ def initialize(consoleLogging=True):
             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, \
+            PLEX_SERVER_HOST, PLEX_SERVER_TOKEN, PLEX_HOST, PLEX_USERNAME, PLEX_PASSWORD, 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, \
@@ -603,17 +598,16 @@ def initialize(consoleLogging=True):
             RENAME_EPISODES, AIRDATE_EPISODES, FILE_TIMESTAMP_TIMEZONE, properFinderScheduler, PROVIDER_ORDER, autoPostProcesserScheduler, \
             providerList, newznabProviderList, torrentRssProviderList, \
             EXTRA_SCRIPTS, USE_TWITTER, TWITTER_USERNAME, TWITTER_PASSWORD, TWITTER_PREFIX, DAILYSEARCH_FREQUENCY, TWITTER_DMTO, TWITTER_USEDM, \
-            USE_BOXCAR, BOXCAR_USERNAME, BOXCAR_NOTIFY_ONDOWNLOAD, BOXCAR_NOTIFY_ONSUBTITLEDOWNLOAD, BOXCAR_NOTIFY_ONSNATCH, \
             USE_BOXCAR2, BOXCAR2_ACCESSTOKEN, BOXCAR2_NOTIFY_ONDOWNLOAD, BOXCAR2_NOTIFY_ONSUBTITLEDOWNLOAD, BOXCAR2_NOTIFY_ONSNATCH, \
             USE_PUSHOVER, PUSHOVER_USERKEY, PUSHOVER_APIKEY, PUSHOVER_DEVICE, PUSHOVER_NOTIFY_ONDOWNLOAD, PUSHOVER_NOTIFY_ONSUBTITLEDOWNLOAD, PUSHOVER_NOTIFY_ONSNATCH, PUSHOVER_SOUND, \
             USE_LIBNOTIFY, LIBNOTIFY_NOTIFY_ONSNATCH, LIBNOTIFY_NOTIFY_ONDOWNLOAD, LIBNOTIFY_NOTIFY_ONSUBTITLEDOWNLOAD, USE_NMJ, NMJ_HOST, NMJ_DATABASE, NMJ_MOUNT, USE_NMJv2, NMJv2_HOST, NMJv2_DATABASE, NMJv2_DBLOC, USE_SYNOINDEX, \
             USE_SYNOLOGYNOTIFIER, SYNOLOGYNOTIFIER_NOTIFY_ONSNATCH, SYNOLOGYNOTIFIER_NOTIFY_ONDOWNLOAD, SYNOLOGYNOTIFIER_NOTIFY_ONSUBTITLEDOWNLOAD, \
             USE_EMAIL, EMAIL_HOST, EMAIL_PORT, EMAIL_TLS, EMAIL_USER, EMAIL_PASSWORD, EMAIL_FROM, EMAIL_NOTIFY_ONSNATCH, EMAIL_NOTIFY_ONDOWNLOAD, EMAIL_NOTIFY_ONSUBTITLEDOWNLOAD, EMAIL_LIST, \
             USE_LISTVIEW, METADATA_KODI, METADATA_KODI_12PLUS, METADATA_MEDIABROWSER, METADATA_PS3, metadata_provider_dict, \
-            NEWZBIN, NEWZBIN_USERNAME, NEWZBIN_PASSWORD, GIT_PATH, MOVE_ASSOCIATED_FILES, SYNC_FILES, POSTPONE_IF_SYNC_FILES, dailySearchScheduler, NFO_RENAME, \
+            NEWZBIN, NEWZBIN_USERNAME, NEWZBIN_PASSWORD, GIT_PATH, MOVE_ASSOCIATED_FILES, SYNC_FILES, POSTPONE_IF_SYNC_FILES, POSTPONE_IF_NO_SUBS, dailySearchScheduler, NFO_RENAME, \
             GUI_NAME, HOME_LAYOUT, HISTORY_LAYOUT, DISPLAY_SHOW_SPECIALS, COMING_EPS_LAYOUT, COMING_EPS_SORT, COMING_EPS_DISPLAY_PAUSED, COMING_EPS_MISSED_RANGE, FUZZY_DATING, TRIM_ZERO, DATE_PRESET, TIME_PRESET, TIME_PRESET_W_SECONDS, THEME_NAME, FILTER_ROW, \
             POSTER_SORTBY, POSTER_SORTDIR, HISTORY_LIMIT, CREATE_MISSING_SHOW_DIRS, ADD_SHOWS_WO_DIR, \
-            METADATA_WDTV, METADATA_TIVO, METADATA_MEDE8ER, IGNORE_WORDS, IGNORED_SUBS_LIST, REQUIRE_WORDS, CALENDAR_UNPROTECTED, CALENDAR_ICONS, NO_RESTART, \
+            METADATA_WDTV, METADATA_TIVO, METADATA_MEDE8ER, IGNORE_WORDS, TRACKERS_LIST, IGNORED_SUBS_LIST, REQUIRE_WORDS, CALENDAR_UNPROTECTED, CALENDAR_ICONS, NO_RESTART, \
             USE_SUBTITLES, SUBTITLES_LANGUAGES, SUBTITLES_DIR, SUBTITLES_SERVICES_LIST, SUBTITLES_SERVICES_ENABLED, SUBTITLES_HISTORY, SUBTITLES_FINDER_FREQUENCY, SUBTITLES_MULTI, EMBEDDED_SUBTITLES_ALL, SUBTITLES_EXTRA_SCRIPTS, subtitlesFinderScheduler, \
             SUBTITLES_HEARING_IMPAIRED, ADDIC7ED_USER, ADDIC7ED_PASS, LEGENDASTV_USER, LEGENDASTV_PASS, OPENSUBTITLES_USER, OPENSUBTITLES_PASS, \
             USE_FAILED_DOWNLOADS, DELETE_FAILED, ANON_REDIRECT, LOCALHOST_IP, DEBUG, DEFAULT_PAGE, PROXY_SETTING, PROXY_INDEXERS, \
@@ -636,7 +630,6 @@ def initialize(consoleLogging=True):
         CheckSection(CFG, 'Growl')
         CheckSection(CFG, 'Prowl')
         CheckSection(CFG, 'Twitter')
-        CheckSection(CFG, 'Boxcar')
         CheckSection(CFG, 'Boxcar2')
         CheckSection(CFG, 'NMJ')
         CheckSection(CFG, 'NMJv2')
@@ -879,6 +872,8 @@ def initialize(consoleLogging=True):
 
         SKIP_REMOVED_FILES = bool(check_setting_int(CFG, 'General', 'skip_removed_files', 0))
 
+        ALLOWED_EXTENSIONS = check_setting_str(CFG, 'General', 'allowed_extensions', ALLOWED_EXTENSIONS)
+
         USENET_RETENTION = check_setting_int(CFG, 'General', 'usenet_retention', 500)
 
         AUTOPOSTPROCESSER_FREQUENCY = check_setting_int(CFG, 'General', 'autopostprocesser_frequency',
@@ -926,6 +921,7 @@ def initialize(consoleLogging=True):
         DELRARCONTENTS = bool(check_setting_int(CFG, 'General', 'del_rar_contents', 0))
         MOVE_ASSOCIATED_FILES = bool(check_setting_int(CFG, 'General', 'move_associated_files', 0))
         POSTPONE_IF_SYNC_FILES = bool(check_setting_int(CFG, 'General', 'postpone_if_sync_files', 1))
+        POSTPONE_IF_NO_SUBS = bool(check_setting_int(CFG, 'General', 'postpone_if_no_subs', 0))
         SYNC_FILES = check_setting_str(CFG, 'General', 'sync_files', SYNC_FILES)
         NFO_RENAME = bool(check_setting_int(CFG, 'General', 'nfo_rename', 1))
         CREATE_MISSING_SHOW_DIRS = bool(check_setting_int(CFG, 'General', 'create_missing_show_dirs', 0))
@@ -1034,12 +1030,6 @@ def initialize(consoleLogging=True):
         TWITTER_DMTO = check_setting_str(CFG, 'Twitter', 'twitter_dmto', '')
         TWITTER_USEDM = bool(check_setting_int(CFG, 'Twitter', 'twitter_usedm', 0))
 
-        USE_BOXCAR = bool(check_setting_int(CFG, 'Boxcar', 'use_boxcar', 0))
-        BOXCAR_NOTIFY_ONSNATCH = bool(check_setting_int(CFG, 'Boxcar', 'boxcar_notify_onsnatch', 0))
-        BOXCAR_NOTIFY_ONDOWNLOAD = bool(check_setting_int(CFG, 'Boxcar', 'boxcar_notify_ondownload', 0))
-        BOXCAR_NOTIFY_ONSUBTITLEDOWNLOAD = bool(check_setting_int(CFG, 'Boxcar', 'boxcar_notify_onsubtitledownload', 0))
-        BOXCAR_USERNAME = check_setting_str(CFG, 'Boxcar', 'boxcar_username', '', censor_log=True)
-
         USE_BOXCAR2 = bool(check_setting_int(CFG, 'Boxcar2', 'use_boxcar2', 0))
         BOXCAR2_NOTIFY_ONSNATCH = bool(check_setting_int(CFG, 'Boxcar2', 'boxcar2_notify_onsnatch', 0))
         BOXCAR2_NOTIFY_ONDOWNLOAD = bool(check_setting_int(CFG, 'Boxcar2', 'boxcar2_notify_ondownload', 0))
@@ -1173,6 +1163,7 @@ def initialize(consoleLogging=True):
         GIT_PATH = check_setting_str(CFG, 'General', 'git_path', '')
 
         IGNORE_WORDS = check_setting_str(CFG, 'General', 'ignore_words', IGNORE_WORDS)
+        TRACKERS_LIST = check_setting_str(CFG, 'General', 'trackers_list', TRACKERS_LIST)
         REQUIRE_WORDS = check_setting_str(CFG, 'General', 'require_words', REQUIRE_WORDS)
         IGNORED_SUBS_LIST = check_setting_str(CFG, 'General', 'ignored_subs_list', IGNORED_SUBS_LIST)
 
@@ -1709,6 +1700,7 @@ def save_config():
     new_config['General']['check_propers_interval'] = CHECK_PROPERS_INTERVAL
     new_config['General']['allow_high_priority'] = int(ALLOW_HIGH_PRIORITY)
     new_config['General']['skip_removed_files'] = int(SKIP_REMOVED_FILES)
+    new_config['General']['allowed_extensions'] = ALLOWED_EXTENSIONS
     new_config['General']['quality_default'] = int(QUALITY_DEFAULT)
     new_config['General']['status_default'] = int(STATUS_DEFAULT)
     new_config['General']['status_default_after'] = int(STATUS_DEFAULT_AFTER)
@@ -1762,6 +1754,7 @@ def save_config():
     new_config['General']['move_associated_files'] = int(MOVE_ASSOCIATED_FILES)
     new_config['General']['sync_files'] = SYNC_FILES
     new_config['General']['postpone_if_sync_files'] = int(POSTPONE_IF_SYNC_FILES)
+    new_config['General']['postpone_if_no_subs'] = int(POSTPONE_IF_NO_SUBS)
     new_config['General']['nfo_rename'] = int(NFO_RENAME)
     new_config['General']['process_automatically'] = int(PROCESS_AUTOMATICALLY)
     new_config['General']['no_delete'] = int(NO_DELETE)
@@ -1775,6 +1768,7 @@ def save_config():
     new_config['General']['extra_scripts'] = '|'.join(EXTRA_SCRIPTS)
     new_config['General']['git_path'] = GIT_PATH
     new_config['General']['ignore_words'] = IGNORE_WORDS
+    new_config['General']['trackers_list'] = TRACKERS_LIST
     new_config['General']['require_words'] = REQUIRE_WORDS
     new_config['General']['ignored_subs_list'] = IGNORED_SUBS_LIST
     new_config['General']['calendar_unprotected'] = int(CALENDAR_UNPROTECTED)
@@ -1998,13 +1992,6 @@ def save_config():
     new_config['Twitter']['twitter_dmto'] = TWITTER_DMTO
     new_config['Twitter']['twitter_usedm'] = int(TWITTER_USEDM)
 
-    new_config['Boxcar'] = {}
-    new_config['Boxcar']['use_boxcar'] = int(USE_BOXCAR)
-    new_config['Boxcar']['boxcar_notify_onsnatch'] = int(BOXCAR_NOTIFY_ONSNATCH)
-    new_config['Boxcar']['boxcar_notify_ondownload'] = int(BOXCAR_NOTIFY_ONDOWNLOAD)
-    new_config['Boxcar']['boxcar_notify_onsubtitledownload'] = int(BOXCAR_NOTIFY_ONSUBTITLEDOWNLOAD)
-    new_config['Boxcar']['boxcar_username'] = BOXCAR_USERNAME
-
     new_config['Boxcar2'] = {}
     new_config['Boxcar2']['use_boxcar2'] = int(USE_BOXCAR2)
     new_config['Boxcar2']['boxcar2_notify_onsnatch'] = int(BOXCAR2_NOTIFY_ONSNATCH)
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 a20d543eacc6211fb5c9702d16d5e857824e9a88..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.
@@ -528,7 +528,7 @@ class StatusStrings(NumDict):
     # todo: Make views return Qualities too
     # todo:
 
-    qualities = Quality.DOWNLOADED + Quality.SNATCHED + Quality.SNATCHED_PROPER + Quality.SNATCHED_BEST + Quality.ARCHIVED
+    qualities = Quality.DOWNLOADED + Quality.SNATCHED + Quality.SNATCHED_PROPER + Quality.SNATCHED_BEST + Quality.ARCHIVED + Quality.FAILED
 
     @property
     def statusStrings(self):  # for backwards compatibility
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 d0b0ed9878200ee76b76de1116ffb9202ee42df6..2a84178ee552aa8091c4b7048159a85d472a66f5 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.
@@ -747,7 +747,7 @@ def chmodAsParent(childPath):
     parentPathStat = os.stat(parentPath)
     parentMode = stat.S_IMODE(parentPathStat[stat.ST_MODE])
 
-    childPathStat = os.stat(childPath)
+    childPathStat = os.stat(childPath.encode(sickbeard.SYS_ENCODING))
     childPath_mode = stat.S_IMODE(childPathStat[stat.ST_MODE])
 
     if os.path.isfile(childPath):
@@ -792,7 +792,7 @@ def fixSetGroupID(childPath):
 
     if parentMode & stat.S_ISGID:
         parentGID = parentStat[stat.ST_GID]
-        childStat = os.stat(childPath)
+        childStat = os.stat(childPath.encode(sickbeard.SYS_ENCODING))
         childGID = childStat[stat.ST_GID]
 
         if childGID == parentGID:
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/notifiers/__init__.py b/sickbeard/notifiers/__init__.py
index d7112c67cdd924e4d706c6891ceb4e0269a5d1b2..4ed59e1f7c62e9933dd781af5811876840d012fc 100644
--- a/sickbeard/notifiers/__init__.py
+++ b/sickbeard/notifiers/__init__.py
@@ -32,7 +32,6 @@ import growl
 import prowl
 from . import libnotify
 import pushover
-import boxcar
 import boxcar2
 import nma
 import pushalot
@@ -57,7 +56,6 @@ growl_notifier = growl.GrowlNotifier()
 prowl_notifier = prowl.ProwlNotifier()
 libnotify_notifier = libnotify.LibnotifyNotifier()
 pushover_notifier = pushover.PushoverNotifier()
-boxcar_notifier = boxcar.BoxcarNotifier()
 boxcar2_notifier = boxcar2.Boxcar2Notifier()
 nma_notifier = nma.NMA_Notifier()
 pushalot_notifier = pushalot.PushalotNotifier()
@@ -81,7 +79,6 @@ notifiers = [
     freemobile_notifier,
     prowl_notifier,
     pushover_notifier,
-    boxcar_notifier,
     boxcar2_notifier,
     nma_notifier,
     pushalot_notifier,
diff --git a/sickbeard/notifiers/boxcar.py b/sickbeard/notifiers/boxcar.py
deleted file mode 100644
index 0834075a6034580cca4a6916cf95a2d87b1302b2..0000000000000000000000000000000000000000
--- a/sickbeard/notifiers/boxcar.py
+++ /dev/null
@@ -1,156 +0,0 @@
-# coding=utf-8
-
-# Author: Marvin Pinto <me@marvinp.ca>
-# Author: Dennis Lutter <lad1337@gmail.com>
-# URL: http://code.google.com/p/sickbeard/
-#
-# This file is part of SickRage.
-#
-# SickRage is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# SickRage is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#  GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with SickRage.  If not, see <http://www.gnu.org/licenses/>.
-
-import urllib
-import urllib2
-import time
-
-import sickbeard
-
-from sickbeard import logger
-from sickbeard.common import notifyStrings, NOTIFY_SNATCH, NOTIFY_DOWNLOAD, NOTIFY_SUBTITLE_DOWNLOAD, NOTIFY_GIT_UPDATE, NOTIFY_GIT_UPDATE_TEXT
-from sickrage.helper.exceptions import ex
-
-API_URL = "https://boxcar.io/devices/providers/fWc4sgSmpcN6JujtBmR6/notifications"
-
-
-class BoxcarNotifier(object):
-    def test_notify(self, boxcar_username):
-        return self._notifyBoxcar("This is a test notification from Sick Beard", "Test", boxcar_username, force=True)
-
-    def _sendBoxcar(self, msg, title, email, subscribe=False):
-        """
-        Sends a boxcar notification to the address provided
-
-        msg: The message to send (unicode)
-        title: The title of the message
-        email: The email address to send the message to (or to subscribe with)
-        subscribe: If true then instead of sending a message this function will send a subscription notification (optional, default is False)
-
-        returns: True if the message succeeded, False otherwise
-        """
-
-        # build up the URL and parameters
-        msg = msg.strip()
-        curUrl = API_URL
-
-        # if this is a subscription notification then act accordingly
-        if subscribe:
-            data = urllib.urlencode({'email': email})
-            curUrl += "/subscribe"
-
-        # for normal requests we need all these parameters
-        else:
-            data = urllib.urlencode({
-                'email': email,
-                'notification[from_screen_name]': title,
-                'notification[message]': msg.encode('utf-8'),
-                'notification[from_remote_service_id]': int(time.time())
-            })
-
-        # send the request to boxcar
-        try:
-            req = urllib2.Request(curUrl)
-            handle = urllib2.urlopen(req, data)
-            handle.close()
-
-        except urllib2.HTTPError, e:
-            # if we get an error back that doesn't have an error code then who knows what's really happening
-            if not hasattr(e, 'code'):
-                logger.log(u"Boxcar notification failed. Error code: " + ex(e), logger.ERROR)
-                return False
-            else:
-                logger.log(u"Boxcar notification failed. Error code: " + str(e.code), logger.WARNING)
-
-            # HTTP status 404 if the provided email address isn't a Boxcar user.
-            if e.code == 404:
-                logger.log(u"Username is wrong/not a boxcar email. Boxcar will send an email to it", logger.WARNING)
-                return False
-
-            # For HTTP status code 401's, it is because you are passing in either an invalid token, or the user has not added your service.
-            elif e.code == 401:
-
-                # If the user has already added your service, we'll return an HTTP status code of 401.
-                if subscribe:
-                    logger.log(u"Already subscribed to service", logger.ERROR)
-                    # i don't know if this is true or false ... its neither but i also don't know how we got here in the first place
-                    return False
-
-                # HTTP status 401 if the user doesn't have the service added
-                else:
-                    subscribeNote = self._sendBoxcar(msg, title, email, True)
-                    if subscribeNote:
-                        logger.log(u"Subscription send", logger.DEBUG)
-                        return True
-                    else:
-                        logger.log(u"Subscription could not be send", logger.ERROR)
-                        return False
-
-            # If you receive an HTTP status code of 400, it is because you failed to send the proper parameters
-            elif e.code == 400:
-                logger.log(u"Wrong data sent to boxcar", logger.ERROR)
-                return False
-
-        logger.log(u"Boxcar notification successful.", logger.INFO)
-        return True
-
-    def notify_snatch(self, ep_name, title=notifyStrings[NOTIFY_SNATCH]):
-        if sickbeard.BOXCAR_NOTIFY_ONSNATCH:
-            self._notifyBoxcar(title, ep_name)
-
-    def notify_download(self, ep_name, title=notifyStrings[NOTIFY_DOWNLOAD]):
-        if sickbeard.BOXCAR_NOTIFY_ONDOWNLOAD:
-            self._notifyBoxcar(title, ep_name)
-
-    def notify_subtitle_download(self, ep_name, lang, title=notifyStrings[NOTIFY_SUBTITLE_DOWNLOAD]):
-        if sickbeard.BOXCAR_NOTIFY_ONSUBTITLEDOWNLOAD:
-            self._notifyBoxcar(title, ep_name + ": " + lang)
-
-    def notify_git_update(self, new_version="??"):
-        if sickbeard.USE_BOXCAR:
-            update_text = notifyStrings[NOTIFY_GIT_UPDATE_TEXT]
-            title = notifyStrings[NOTIFY_GIT_UPDATE]
-            self._notifyBoxcar(title, update_text + new_version)
-
-    def _notifyBoxcar(self, title, message, username=None, force=False):
-        """
-        Sends a boxcar notification based on the provided info or SB config
-
-        title: The title of the notification to send
-        message: The message string to send
-        username: The username to send the notification to (optional, defaults to the username in the config)
-        force: If True then the notification will be sent even if Boxcar is disabled in the config
-        """
-
-        if not sickbeard.USE_BOXCAR and not force:
-            logger.log(u"Notification for Boxcar not enabled, skipping this notification", logger.DEBUG)
-            return False
-
-        # if no username was given then use the one from the config
-        if not username:
-            username = sickbeard.BOXCAR_USERNAME
-
-        logger.log(u"Sending notification for " + message, logger.DEBUG)
-
-        return self._sendBoxcar(message, title, username)
-
-
-notifier = BoxcarNotifier
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 1cd7afa6aa66f8b64fb2128e4c4bed4f6cd76f7d..ab01e21d2618b89ca3eb6e9186c8b4645c126c0c 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.
@@ -158,7 +158,7 @@ class PostProcessor(object):
         """
         def recursive_glob(treeroot, pattern):
             results = []
-            for base, _, files in os.walk(treeroot):
+            for base, _, files in os.walk(treeroot.encode(sickbeard.SYS_ENCODING)):
                 goodfiles = fnmatch.filter(files, pattern)
                 results.extend(os.path.join(base, f) for f in goodfiles)
             return results
@@ -171,6 +171,8 @@ class PostProcessor(object):
 
         file_path_list = []
 
+        extensions_to_delete = []
+
         if subfolders:
             base_name = ek(os.path.basename, globbable_file_path).rpartition('.')[0]
         else:
@@ -207,6 +209,7 @@ class PostProcessor(object):
             # only add associated to list
             if associated_file_path == file_path:
                 continue
+
             # only list it if the only non-shared part is the extension or if it is a subtitle
             if subtitles_only and not associated_file_path[len(associated_file_path) - 3:] in common.subtitleExtensions:
                 continue
@@ -215,13 +218,24 @@ class PostProcessor(object):
             if re.search(r'(^.+\.(rar|r\d+)$)', associated_file_path):
                 continue
 
+            # Add the extensions that the user doesn't allow to the 'extensions_to_delete' list
+            if sickbeard.MOVE_ASSOCIATED_FILES and sickbeard.ALLOWED_EXTENSIONS:
+                allowed_extensions = sickbeard.ALLOWED_EXTENSIONS.split(",")
+                if not associated_file_path[-3:] in allowed_extensions and not associated_file_path[-3:] in common.subtitleExtensions:
+                    if ek(os.path.isfile, associated_file_path):
+                        extensions_to_delete.append(associated_file_path)
+
             if ek(os.path.isfile, associated_file_path):
                 file_path_list.append(associated_file_path)
 
         if file_path_list:
-            self._log(u"Found the following associated files: " + str(file_path_list), logger.DEBUG)
+            self._log(u"Found the following associated files for %s: %s" % (file_path, file_path_list), logger.DEBUG)
+            if extensions_to_delete:
+                # Rebuild the 'file_path_list' list only with the extensions the user allows
+                file_path_list = [associated_file for associated_file in file_path_list if associated_file not in extensions_to_delete]
+                self._delete(extensions_to_delete)
         else:
-            self._log(u"No associated files were during this pass", logger.DEBUG)
+            self._log(u"No associated files for %s were found during this pass" % file_path, logger.DEBUG)
 
         return file_path_list
 
@@ -236,8 +250,13 @@ class PostProcessor(object):
         if not file_path:
             return
 
+        # Check if file_path is a list, if not, make it one
+        if not isinstance(file_path, list):
+            file_list = [file_path]
+        else:
+            file_list = file_path
+
         # figure out which files we want to delete
-        file_list = [file_path]
         if associated_files:
             file_list = file_list + self.list_associated_files(file_path, base_name_only=True, subfolders=True)
 
@@ -940,6 +959,19 @@ class PostProcessor(object):
                 self._log(u"File exists and new file is same size, marking it unsafe to replace")
                 return False
 
+            # Check if the processed file season is already in our indexer. If not, the file is most probably mislabled/fake and will be skipped
+            # Only proceed if the file season is > 0
+            if int(ep_obj.season) > 0:
+                myDB = db.DBConnection()
+                max_season = myDB.select(
+                    "SELECT MAX(season) as maxseason FROM tv_episodes WHERE showid = ? and indexer = ?",
+                    [show.indexerid, show.indexer])
+                # If the file season (ep_obj.season) is bigger than the indexer season (max_season[0][0]), skip the file
+                if int(ep_obj.season) > int(max_season[0][0]):
+                    self._log(u"File has season %s, while the indexer is on season %s. The file may be incorrectly labeled or fake, aborting."
+                              % (str(ep_obj.season), str(max_season[0][0])))
+                    return False
+
         # if the file is priority then we're going to replace it even if it exists
         else:
             self._log(
diff --git a/sickbeard/processTV.py b/sickbeard/processTV.py
index 6e74a64a09d05a8c0160aa5c798279f8e1dd70eb..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.
@@ -542,11 +542,20 @@ def process_media(processPath, videoFiles, nzbName, process_method, force, is_pr
         cur_video_file_path = ek(os.path.join, processPath, cur_video_file)
 
         if already_postprocessed(processPath, cur_video_file, force, result):
-            result.output += logHelper(u"Already Processed " + cur_video_file_path + " : Skipping", logger.DEBUG)
+            result.output += logHelper(u"Already Processed " + cur_video_file + " : Skipping", logger.DEBUG)
             continue
 
         try:
             processor = postProcessor.PostProcessor(cur_video_file_path, nzbName, process_method, is_priority)
+            # This feature prevents PP for files that do not have subtitle associated with the video file        
+            if sickbeard.POSTPONE_IF_NO_SUBS:
+                associatedFiles = processor.list_associated_files(cur_video_file_path, subtitles_only=True)
+                if not [associatedFile for associatedFile in associatedFiles if associatedFile[-3:] in common.subtitleExtensions]:
+                    result.output += logHelper(u"No subtitles associated. Postponing the post-process of this file: %s" % cur_video_file, logger.DEBUG)
+                    continue
+                else:
+                    result.output += logHelper(u"Found subtitles associated. Continuing the post-process of this file: %s" % cur_video_file) 
+        
             result.result = processor.process()
             process_fail_message = ""
         except EpisodePostProcessingFailedException, e:
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..553e7e320bfcd1a66395b6c964a350d9e31e5ca2 100644
--- a/sickbeard/providers/btdigg.py
+++ b/sickbeard/providers/btdigg.py
@@ -19,11 +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/>.
 
+
 from sickbeard.providers import generic
 from urllib import urlencode
 from sickbeard import logger
 from sickbeard import tvcache
 
+
 class BTDIGGProvider(generic.TorrentProvider):
 
     def __init__(self):
@@ -70,7 +72,7 @@ class BTDIGGProvider(generic.TorrentProvider):
                 for torrent in jdata:
                     if not torrent['ff']:
                         title = torrent['name']
-                        download_url = torrent['magnet']
+                        download_url = torrent['magnet'] + self._custom_trackers
                         size = torrent['size']
                         # FIXME
                         seeders = 1
diff --git a/sickbeard/providers/generic.py b/sickbeard/providers/generic.py
index 37c992b75956101ae95fcbe510ec56d0d9095392..b1c59d0650abde589970abfedd7a5c95d33fc5cb 100644
--- a/sickbeard/providers/generic.py
+++ b/sickbeard/providers/generic.py
@@ -639,6 +639,10 @@ class TorrentProvider(GenericProvider):
     def _clean_title_from_provider(title):
         return (title or '').replace(' ', '.')
 
+    @property
+    def _custom_trackers(self):
+        return ('', '&tr=' + '&tr='.join(set([x.strip() for x in sickbeard.TRACKERS_LIST.split(',') if x.strip()])))[self.public] if sickbeard.TRACKERS_LIST else ''
+
     def findPropers(self, search_date=datetime.datetime.today()):
 
         results = []
diff --git a/sickbeard/providers/newpct.py b/sickbeard/providers/newpct.py
index 0985f73ce75456c0c0533597e4d23e555574c0c5..e4ca108dd15520ffb452be980646de8de0cd3b6b 100644
--- a/sickbeard/providers/newpct.py
+++ b/sickbeard/providers/newpct.py
@@ -106,7 +106,7 @@ class newpctProvider(generic.TorrentProvider):
                     with BS4Parser(data, features=["html5lib", "permissive"]) as html:
                         torrent_tbody = html.find('tbody')
 
-                        if not len(torrent_tbody):
+                        if torrent_tbody is None:
                             logger.log(u"Data returned from provider does not contain any torrents", logger.DEBUG)
                             continue
 
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/providers/torrentproject.py b/sickbeard/providers/torrentproject.py
index 7e53ac31459e9e05cf688e9fa2b09015596f766f..b9c52266d88910d4ea7ab80137ec22b5279499cc 100644
--- a/sickbeard/providers/torrentproject.py
+++ b/sickbeard/providers/torrentproject.py
@@ -24,6 +24,7 @@ from sickbeard import helpers
 from sickbeard.providers import generic
 from sickbeard.common import USER_AGENT
 
+
 class TORRENTPROJECTProvider(generic.TorrentProvider):
 
     def __init__(self):
@@ -83,7 +84,7 @@ class TORRENTPROJECTProvider(generic.TorrentProvider):
                         assert jdata is not "maintenance"
                         download_url = "magnet:?xt=urn:btih:" + t_hash + "&dn=" + title + "".join(["&tr=" + s for s in jdata])
                     except (Exception, AssertionError):
-                        download_url = "magnet:?xt=urn:btih:" + t_hash + "&dn=" + title + "&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"
+                        download_url = "magnet:?xt=urn:btih:" + t_hash + "&dn=" + title + self._custom_trackers
 
                     if not all([title, download_url]):
                         continue
diff --git a/sickbeard/providers/torrentz.py b/sickbeard/providers/torrentz.py
index bc93864ec303f17aafd2a6421f2c3c83da408822..f1dd3e8ffaba848dfced0340fdbe8c4e770df8c5 100644
--- a/sickbeard/providers/torrentz.py
+++ b/sickbeard/providers/torrentz.py
@@ -30,6 +30,7 @@ from sickbeard import tvcache
 from sickbeard.providers import generic
 from sickbeard.common import cpu_presets
 
+
 class TORRENTZProvider(generic.TorrentProvider):
 
     def __init__(self):
@@ -106,7 +107,7 @@ class TORRENTZProvider(generic.TorrentProvider):
                         continue
 
                     # TODO: Add method to generic provider for building magnet from hash.
-                    download_url = "magnet:?xt=urn:btih:" + t_hash + "&dn=" + title + "&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"
+                    download_url = "magnet:?xt=urn:btih:" + t_hash + "&dn=" + title + self._custom_trackers
                     size, seeders, leechers = self._split_description(item.get('description', ''))
 
                     # Filter unseeded torrent
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/webapi.py b/sickbeard/webapi.py
index 9fbe6cfaef7b7b760382fb65d659aac3e423c814..4a4a8bd980c7466cc8209ebffb3558696582a208 100644
--- a/sickbeard/webapi.py
+++ b/sickbeard/webapi.py
@@ -851,7 +851,7 @@ class CMD_EpisodeSetStatus(ApiCall):
             return _responds(RESULT_FAILURE, msg="Show not found")
 
         # convert the string status to a int
-        for status in statusStrings.statusStrings:
+        for status in statusStrings:
             if str(statusStrings[status]).lower() == str(self.status).lower():
                 self.status = status
                 break
@@ -1778,12 +1778,12 @@ class CMD_SickBeardSetDefaults(ApiCall):
 
         if self.status:
             # convert the string status to a int
-            for status in statusStrings.statusStrings:
+            for status in statusStrings:
                 if statusStrings[status].lower() == str(self.status).lower():
                     self.status = status
                     break
             # this should be obsolete bcause of the above
-            if not self.status in statusStrings.statusStrings:
+            if not self.status in statusStrings:
                 raise ApiError("Invalid Status")
             # only allow the status options we want
             if int(self.status) not in (3, 5, 6, 7):
@@ -2128,12 +2128,12 @@ class CMD_ShowAddNew(ApiCall):
         newStatus = sickbeard.STATUS_DEFAULT
         if self.status:
             # convert the string status to a int
-            for status in statusStrings.statusStrings:
+            for status in statusStrings:
                 if statusStrings[status].lower() == str(self.status).lower():
                     self.status = status
                     break
 
-            if self.status not in statusStrings.statusStrings:
+            if self.status not in statusStrings:
                 raise ApiError("Invalid Status")
 
             # only allow the status options we want
@@ -2145,12 +2145,12 @@ class CMD_ShowAddNew(ApiCall):
         default_ep_status_after = sickbeard.STATUS_DEFAULT_AFTER
         if self.future_status:
             # convert the string status to a int
-            for status in statusStrings.statusStrings:
+            for status in statusStrings:
                 if statusStrings[status].lower() == str(self.future_status).lower():
                     self.future_status = status
                     break
 
-            if self.future_status not in statusStrings.statusStrings:
+            if self.future_status not in statusStrings:
                 raise ApiError("Invalid Status")
 
             # only allow the status options we want
@@ -2672,7 +2672,7 @@ class CMD_ShowStats(ApiCall):
         # show stats
         episode_status_counts_total = {}
         episode_status_counts_total["total"] = 0
-        for status in statusStrings.statusStrings.keys():
+        for status in statusStrings:
             if status in [UNKNOWN, DOWNLOADED, SNATCHED, SNATCHED_PROPER, ARCHIVED]:
                 continue
             episode_status_counts_total[status] = 0
@@ -2747,7 +2747,7 @@ class CMD_ShowStats(ApiCall):
                 episodes_stats["total"] = episode_status_counts_total[statusCode]
                 continue
             status, quality = Quality.splitCompositeStatus(int(statusCode))
-            statusString = statusStrings.statusStrings[statusCode].lower().replace(" ", "_").replace("(", "").replace(
+            statusString = statusStrings[statusCode].lower().replace(" ", "_").replace("(", "").replace(
                 ")", "")
             episodes_stats[statusString] = episode_status_counts_total[statusCode]
 
diff --git a/sickbeard/webserve.py b/sickbeard/webserve.py
index 12d42c81647d538024037ad616a8fa9fbb755994..b5ee0d8a09aaac682580f824844f63e588b6a432 100644
--- a/sickbeard/webserve.py
+++ b/sickbeard/webserve.py
@@ -816,15 +816,6 @@ class Home(WebRoot):
         else:
             return "Test prowl notice failed"
 
-    @staticmethod
-    def testBoxcar(username=None):
-
-        result = notifiers.boxcar_notifier.test_notify(username)
-        if result:
-            return "Boxcar notification succeeded. Check your Boxcar clients to make sure it worked"
-        else:
-            return "Error sending Boxcar notification"
-
     @staticmethod
     def testBoxcar2(accesstoken=None):
 
@@ -1662,7 +1653,7 @@ class Home(WebRoot):
                 return self._genericMessage("Error", errMsg)
 
         # Use .has_key() since it is overridden for statusStrings in common.py
-        if not statusStrings.has_key(int(status)):
+        if status not in statusStrings:
             errMsg = "Invalid status"
             if direct:
                 ui.notifications.error('Error', errMsg)
@@ -2244,6 +2235,19 @@ class HomeAddShows(Home):
 
         search_term = search_term.encode('utf-8')
 
+        searchTerms = [search_term]
+
+        # If search term ends with what looks like a year, enclose it in ()
+        matches = re.match(r'^(.+ |)([12][0-9]{3})$', search_term)
+        if matches:
+            searchTerms.append("%s(%s)" % (matches.group(1), matches.group(2)))
+
+        for searchTerm in searchTerms:
+            # If search term begins with an article, let's also search for it without
+            matches = re.match(r'^(?:a|an|the) (.+)$', searchTerm, re.I)
+            if matches:
+                searchTerms.append(matches.group(1))
+
         results = {}
         final_results = []
 
@@ -2254,13 +2258,16 @@ class HomeAddShows(Home):
             lINDEXER_API_PARMS['custom_ui'] = classes.AllShowsListUI
             t = sickbeard.indexerApi(indexer).indexer(**lINDEXER_API_PARMS)
 
-            logger.log(u"Searching for Show with searchterm: %s on Indexer: %s" % (
-                search_term, sickbeard.indexerApi(indexer).name), logger.DEBUG)
-            try:
+            logger.log(u"Searching for Show with searchterm(s): %s on Indexer: %s" % (
+                searchTerms, sickbeard.indexerApi(indexer).name), logger.DEBUG)
+            for searchTerm in searchTerms:
+                try:
+                    indexerResults = t[searchTerm]
+                except Exception:
+                    continue
+
                 # add search results
-                results.setdefault(indexer, []).extend(t[search_term])
-            except Exception:
-                continue
+                results.setdefault(indexer, []).extend(indexerResults)
 
         for i, shows in results.iteritems():
             final_results.extend([[sickbeard.indexerApi(i).name, i, sickbeard.indexerApi(i).config["show_url"], int(show['id']),
@@ -3846,14 +3853,14 @@ 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,
                    torrent_dir=None, torrent_username=None, torrent_password=None, torrent_host=None,
                    torrent_label=None, torrent_label_anime=None, torrent_path=None, torrent_verify_cert=None,
                    torrent_seed_time=None, torrent_paused=None, torrent_high_bandwidth=None,
-                   torrent_rpcurl=None, torrent_auth_type=None, ignore_words=None, require_words=None, ignored_subs_list=None):
+                   torrent_rpcurl=None, torrent_auth_type=None, ignore_words=None, trackers_list=None, require_words=None, ignored_subs_list=None):
 
         results = []
 
@@ -3866,6 +3873,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)
@@ -3875,6 +3883,7 @@ class ConfigSearch(Config):
         sickbeard.USENET_RETENTION = config.to_int(usenet_retention, default=500)
 
         sickbeard.IGNORE_WORDS = ignore_words if ignore_words else ""
+        sickbeard.TRACKERS_LIST = trackers_list if trackers_list else ""
         sickbeard.REQUIRE_WORDS = require_words if require_words else ""
         sickbeard.IGNORED_SUBS_LIST = ignored_subs_list if ignored_subs_list else ""
 
@@ -3954,8 +3963,8 @@ class ConfigPostProcessing(Config):
                            del_rar_contents=None, process_automatically=None,
                            no_delete=None, rename_episodes=None, airdate_episodes=None,
                            file_timestamp_timezone=None, unpack=None, move_associated_files=None,
-                           sync_files=None, postpone_if_sync_files=None, nfo_rename=None,
-                           tv_download_dir=None, naming_custom_abd=None, naming_anime=None,
+                           sync_files=None, postpone_if_sync_files=None, postpone_if_no_subs=None, nfo_rename=None,
+                           allowed_extensions=None, tv_download_dir=None, naming_custom_abd=None, naming_anime=None,
                            create_missing_show_dirs=None, add_shows_wo_dir=None,
                            naming_abd_pattern=None, naming_strip_year=None,
                            use_failed_downloads=None, delete_failed=None, extra_scripts=None,
@@ -3991,7 +4000,9 @@ class ConfigPostProcessing(Config):
         sickbeard.FILE_TIMESTAMP_TIMEZONE = file_timestamp_timezone
         sickbeard.MOVE_ASSOCIATED_FILES = config.checkbox_to_value(move_associated_files)
         sickbeard.SYNC_FILES = sync_files
+        sickbeard.ALLOWED_EXTENSIONS = allowed_extensions
         sickbeard.POSTPONE_IF_SYNC_FILES = config.checkbox_to_value(postpone_if_sync_files)
+        sickbeard.POSTPONE_IF_NO_SUBS = config.checkbox_to_value(postpone_if_no_subs)
         sickbeard.NAMING_CUSTOM_ABD = config.checkbox_to_value(naming_custom_abd)
         sickbeard.NAMING_CUSTOM_SPORTS = config.checkbox_to_value(naming_custom_sports)
         sickbeard.NAMING_CUSTOM_ANIME = config.checkbox_to_value(naming_custom_anime)
@@ -4646,8 +4657,6 @@ class ConfigNotifications(Config):
                           prowl_notify_onsubtitledownload=None, prowl_api=None, prowl_priority=0,
                           use_twitter=None, twitter_notify_onsnatch=None, twitter_notify_ondownload=None,
                           twitter_notify_onsubtitledownload=None, twitter_usedm=None, twitter_dmto=None,
-                          use_boxcar=None, boxcar_notify_onsnatch=None, boxcar_notify_ondownload=None,
-                          boxcar_notify_onsubtitledownload=None, boxcar_username=None,
                           use_boxcar2=None, boxcar2_notify_onsnatch=None, boxcar2_notify_ondownload=None,
                           boxcar2_notify_onsubtitledownload=None, boxcar2_accesstoken=None,
                           use_pushover=None, pushover_notify_onsnatch=None, pushover_notify_ondownload=None,
@@ -4737,12 +4746,6 @@ class ConfigNotifications(Config):
         sickbeard.TWITTER_USEDM = config.checkbox_to_value(twitter_usedm)
         sickbeard.TWITTER_DMTO = twitter_dmto
 
-        sickbeard.USE_BOXCAR = config.checkbox_to_value(use_boxcar)
-        sickbeard.BOXCAR_NOTIFY_ONSNATCH = config.checkbox_to_value(boxcar_notify_onsnatch)
-        sickbeard.BOXCAR_NOTIFY_ONDOWNLOAD = config.checkbox_to_value(boxcar_notify_ondownload)
-        sickbeard.BOXCAR_NOTIFY_ONSUBTITLEDOWNLOAD = config.checkbox_to_value(boxcar_notify_onsubtitledownload)
-        sickbeard.BOXCAR_USERNAME = boxcar_username
-
         sickbeard.USE_BOXCAR2 = config.checkbox_to_value(use_boxcar2)
         sickbeard.BOXCAR2_NOTIFY_ONSNATCH = config.checkbox_to_value(boxcar2_notify_onsnatch)
         sickbeard.BOXCAR2_NOTIFY_ONDOWNLOAD = config.checkbox_to_value(boxcar2_notify_ondownload)
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