diff --git a/TODO.txt b/TODO.txt
index b18ae2199fbad4053a364723d07e6ab03f2f09ec..084a6bcc9237e271abd4249a00a59e673fd35d01 100644
--- a/TODO.txt
+++ b/TODO.txt
@@ -11,9 +11,6 @@
 -Add 'add show and add another show' button to add show page
 -Change the hardcoded global ignore words to optional
 
-2014-10-08
-VAdd login page for http auth as opposed to browser dialog box
-
 2014-10-13
 -Fix broken backlog
 -Fix season searches
diff --git a/gui/slick/images/donate.jpg b/gui/slick/images/donate.jpg
index 67b8c319a2b1c6b1b95380f0b9d49e16e04e6b2a..7c4c7d7268b20bd66a2ce5e3910fd893b9d9e0de 100644
Binary files a/gui/slick/images/donate.jpg and b/gui/slick/images/donate.jpg differ
diff --git a/gui/slick/interfaces/default/config_general.tmpl b/gui/slick/interfaces/default/config_general.tmpl
index 792c9856be01cd3bffb291728fce373d38830997..aff6a9b2e5d01713a31173b8c3162c429a0bc9c6 100644
--- a/gui/slick/interfaces/default/config_general.tmpl
+++ b/gui/slick/interfaces/default/config_general.tmpl
@@ -93,7 +93,21 @@
 								</span>
 							</label>
 						</div>
-
+						<div class="field-pair">
+							<label for="default_page">
+								<span class="component-title">Initial page</span>
+								<span class="component-desc">
+									<select id="default_page" name="default_page" class="form-control input-sm">
+										<option value="news" #if $sickbeard.DEFAULT_PAGE == 'news' then 'selected="selected"' else ''#>News</option>
+										<option value="home" #if $sickbeard.DEFAULT_PAGE == 'home' then 'selected="selected"' else ''#>Home</option>
+										<option value="comingEpisodes" #if $sickbeard.DEFAULT_PAGE == 'comingEpisodes' then 'selected="selected"' else ''#>Coming Episodes</option>
+										<option value="history" #if $sickbeard.DEFAULT_PAGE == 'history' then 'selected="selected"' else ''#>History</option>
+										<option value="IRC" #if $sickbeard.DEFAULT_PAGE == 'IRC' then 'selected="selected"' else ''#>IRC</option>
+									</select>
+									<span>when launching SickRage interface</span>
+								</span>
+							</label>
+						</div>
 						<div class="field-pair">
 							<label for="showupdate_hour">
 								<span class="component-title">When to update shows</span>
@@ -309,6 +323,9 @@
 								<span class="component-desc">
 									<input type="checkbox" name="filter_row" id="filter_row" #if $sickbeard.FILTER_ROW == True then 'checked="checked"' else ''#/>
 									<p>Add a filter row to the show display on the home page</p>
+									<p>Supports =, >, >=, <=, <, xx to yy , xx - yy</p>
+									<p><b>Note:</b> =, >, >=, <=, < should be first, followed by a space, then the value.</p>
+									<p>Examples: '> 90', '= 100', '0 to 99'</p>
 								</span>
 							</label>
 						</div>                        
diff --git a/gui/slick/interfaces/default/manage_episodeStatuses.tmpl b/gui/slick/interfaces/default/manage_episodeStatuses.tmpl
index 78a67891baeee3bebf6e17555f5248ddfbec30f8..4f7a06fc3cc4f3718d9e55ae6bc64f5350605134 100644
--- a/gui/slick/interfaces/default/manage_episodeStatuses.tmpl
+++ b/gui/slick/interfaces/default/manage_episodeStatuses.tmpl
@@ -61,6 +61,7 @@ $statusList.remove($int($whichStatus))
 $statusList.append($common.FAILED)
 #end if
 
+<select>
 #for $curStatus in $statusList:
 <option value="$curStatus">$common.statusStrings[$curStatus]</option>
 #end for
diff --git a/gui/slick/interfaces/default/manage_subtitleMissed.tmpl b/gui/slick/interfaces/default/manage_subtitleMissed.tmpl
index f5962e1db98d2a576aaa77fa37cc6eba1707eb09..e3cf6050c6e01323d14b7e02cc08369488149cec 100644
--- a/gui/slick/interfaces/default/manage_subtitleMissed.tmpl
+++ b/gui/slick/interfaces/default/manage_subtitleMissed.tmpl
@@ -55,7 +55,7 @@ Download missed subtitles for selected episodes <input class="btn btn-inline" ty
 #for $cur_indexer_id in $sorted_show_ids:
  <tr id="$cur_indexer_id">
   <th><input type="checkbox" class="allCheck" id="allCheck-$cur_indexer_id" name="$cur_indexer_id-all" checked="checked" /></th>
-  <th colspan="3" style="width: 100%; text-align: left;"><a class="whitelink" href="$sbRoot/home/displayShow?show=$cur_indexer_id">$show_names[$cur_indexer_id]</a> ($ep_counts[$cur_indexer_id]) <input type="button" class="get_more_eps btn" id="$cur_indexer_id" value="Expand" /></th>
+  <th colspan="3" style="width: 100%; text-align: left;"><a class="whitelink" href="$sbRoot/home/displayShow?show=$cur_indexer_id">$show_names[$cur_indexer_id]</a> ($ep_counts[$cur_indexer_id]) <input type="button" class="pull-right get_more_eps btn" id="$cur_indexer_id" value="Expand" /></th>
  </tr>
 #end for
 </table>
diff --git a/gui/slick/interfaces/default/restart_bare.tmpl b/gui/slick/interfaces/default/restart_bare.tmpl
index f48b50d69551236631326b8704049f864d0ac587..ac795e04f8a8a035131f5f61158a745fbd255e42 100644
--- a/gui/slick/interfaces/default/restart_bare.tmpl
+++ b/gui/slick/interfaces/default/restart_bare.tmpl
@@ -18,11 +18,12 @@ sbHttpPort = "$curSBHttpPort";
 sbHttpsEnabled = "$curSBHttpsEnabled";
 sbHandleReverseProxy = "$curSBHandleReverseProxy";
 sbHost = "$curSBHost";
+sbDefaultPage = "$sbDefaultPage";
 //-->
 </script>
 
 <script type="text/javascript" src="$sbRoot/js/lib/jquery-1.11.2.min.js?$sbPID"></script>
-<script type="text/javascript" src="$sbRoot/js/restart.js?$sbPID"></script>
+<script type="text/javascript" src="$sbRoot/js/restart.js?$sbPID&$sbDefaultPage"></script>
 
 #set themeSpinner = '-dark' if 'dark' == themeSpinner else ''
 <h2>Performing Restart</h2>
@@ -41,7 +42,7 @@ Waiting for SickRage to start again:
 </div>
 
 <div id="refresh_message" style="display: none;">
-Loading the home page:
+Loading the default page:
 <img src="$sbRoot/images/loading16${themeSpinner}.gif" height="16" width="16" id="refresh_loading" />
 </div>
 
diff --git a/gui/slick/js/manageSubtitleMissed.js b/gui/slick/js/manageSubtitleMissed.js
index 262ecbb282e38fbba962c0813ac97ca310d6ae03..08c78d890b2b38342d10ab8ac1394d285a6b2d1f 100644
--- a/gui/slick/js/manageSubtitleMissed.js
+++ b/gui/slick/js/manageSubtitleMissed.js
@@ -5,21 +5,21 @@ $(document).ready(function() {
             var checked = ' checked';
         else
             var checked = '';
-        
+
         var row = '';
-        row += ' <tr class="good">';
+        row += ' <tr class="good show-' + indexer_id + '">';
         row += '  <td align="center"><input type="checkbox" class="'+indexer_id+'-epcheck" name="'+indexer_id+'-'+season+'x'+episode+'"'+checked+'></td>';
         row += '  <td style="width: 1%;">'+season+'x'+episode+'</td>';
         row += '  <td>'+name+'</td>';
         row += '  <td style="float: right;">'; 
         	subtitles = subtitles.split(',')
-        	for (i in subtitles)
+        	for (var i in subtitles)
         	{
         		row += '   <img src="/images/subtitles/flags/'+subtitles[i]+'.png" width="16" height="11" alt="'+subtitles[i]+'" />&nbsp;';
         	}
         row += '  </td>';
         row += ' </tr>'
-        
+
         return row;
     }
 
@@ -32,21 +32,35 @@ $(document).ready(function() {
         var cur_indexer_id = $(this).attr('id');
         var checked = $('#allCheck-'+cur_indexer_id).prop('checked');
         var last_row = $('tr#'+cur_indexer_id);
-        
-        $.getJSON(sbRoot+'/manage/showSubtitleMissed',
+        var clicked = $(this).attr('data-clicked');
+        var action = $(this).attr('value');
+
+        if (!clicked) {
+            $.getJSON(sbRoot + '/manage/showSubtitleMissed',
                   {
                    indexer_id: cur_indexer_id,
                    whichSubs: $('#selectSubLang').val()
                   },
                   function (data) {
-                      $.each(data, function(season,eps){
+                      $.each(data, function(season, eps) {
                           $.each(eps, function(episode, data) {
                               //alert(season+'x'+episode+': '+name);
                               last_row.after(make_row(cur_indexer_id, season, episode, data.name, data.subtitles, checked));
                           });
                       });
                   });
-        $(this).hide();
+            $(this).attr('data-clicked', 1);
+            $(this).prop('value', 'Collapse');
+        } else {
+            if (action === 'Collapse') {
+                $('table tr').filter('.show-' + cur_indexer_id).hide();
+                $(this).prop('value', 'Expand');
+            }
+            else if (action === 'Expand') {
+                $('table tr').filter('.show-' + cur_indexer_id).show();
+                $(this).prop('value', 'Collapse');
+            }
+        }
     });
 
     // selects all visible episode checkboxes.
@@ -68,5 +82,4 @@ $(document).ready(function() {
                 this.checked = false;
         });
     });
-
 });
diff --git a/gui/slick/js/restart.js b/gui/slick/js/restart.js
index 1ee32d09fa3b3a36e361842f94e5586e0cf0f30e..ae7fb75b6007ecea0ddc6083f7d0afe1f14304dd 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 = sbRoot + '/home/';}, 5000);
+					setTimeout(function(){window.location = sbRoot + '/' + sbDefaultPage + '/';}, 5000);
 				}
 			}
 			
diff --git a/sickbeard/__init__.py b/sickbeard/__init__.py
index 603f19aeee8489473798583e3512faa97018afbc..e81ec3161a90f36e560842a8edbc92ae8c765fb0 100644
--- a/sickbeard/__init__.py
+++ b/sickbeard/__init__.py
@@ -184,6 +184,7 @@ TRASH_ROTATE_LOGS = False
 SORT_ARTICLE = False
 DEBUG = False
 DISPLAY_ALL_SEASONS = True
+DEFAULT_PAGE = 'home'
 
 
 USE_LISTVIEW = False
@@ -585,7 +586,7 @@ def initialize(consoleLogging=True):
             POSTER_SORTBY, POSTER_SORTDIR, \
             METADATA_WDTV, METADATA_TIVO, METADATA_MEDE8ER, IGNORE_WORDS, REQUIRE_WORDS, CALENDAR_UNPROTECTED, NO_RESTART, CREATE_MISSING_SHOW_DIRS, \
             ADD_SHOWS_WO_DIR, 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, \
-            USE_FAILED_DOWNLOADS, DELETE_FAILED, ANON_REDIRECT, LOCALHOST_IP, TMDB_API_KEY, DEBUG, PROXY_SETTING, PROXY_INDEXERS, \
+            USE_FAILED_DOWNLOADS, DELETE_FAILED, ANON_REDIRECT, LOCALHOST_IP, TMDB_API_KEY, DEBUG, DEFAULT_PAGE, PROXY_SETTING, PROXY_INDEXERS, \
             AUTOPOSTPROCESSER_FREQUENCY, SHOWUPDATE_HOUR, DEFAULT_AUTOPOSTPROCESSER_FREQUENCY, MIN_AUTOPOSTPROCESSER_FREQUENCY, \
             ANIME_DEFAULT, NAMING_ANIME, ANIMESUPPORT, USE_ANIDB, ANIDB_USERNAME, ANIDB_PASSWORD, ANIDB_USE_MYLIST, \
             ANIME_SPLIT_HOME, SCENE_DEFAULT, DOWNLOAD_URL, BACKLOG_DAYS, GIT_ORG, GIT_REPO, GIT_USERNAME, GIT_PASSWORD, \
@@ -630,6 +631,8 @@ def initialize(consoleLogging=True):
 
         # debugging
         DEBUG = bool(check_setting_int(CFG, 'General', 'debug', 0))
+        
+        DEFAULT_PAGE = check_setting_str(CFG, 'General', 'default_page', 'home')
 
         ACTUAL_LOG_DIR = check_setting_str(CFG, 'General', 'log_dir', 'Logs')
         LOG_DIR = os.path.normpath(os.path.join(DATA_DIR, ACTUAL_LOG_DIR))
@@ -1650,6 +1653,7 @@ def save_config():
     new_config['General']['anon_redirect'] = ANON_REDIRECT
     new_config['General']['api_key'] = API_KEY
     new_config['General']['debug'] = int(DEBUG)
+    new_config['General']['default_page'] = DEFAULT_PAGE
     new_config['General']['enable_https'] = int(ENABLE_HTTPS)
     new_config['General']['https_cert'] = HTTPS_CERT
     new_config['General']['https_key'] = HTTPS_KEY
diff --git a/sickbeard/helpers.py b/sickbeard/helpers.py
index fa5a829f4c4787e1db2cc0e8fd34de8e69b441f9..7ae880ce8325f35731623ce8533c9e71fca810a6 100644
--- a/sickbeard/helpers.py
+++ b/sickbeard/helpers.py
@@ -142,6 +142,9 @@ def remove_non_release_groups(name):
                        '^\{ www\.SceneTime\.com \} - ': 'searchre',
                        '^\[ www\.TorrentDay\.com \] - ': 'searchre',
                        '^\[ www\.Cpasbien\.pw \] ': 'searchre',
+                       '^\[ www\.Cpasbien\.com \] ': 'searchre',
+                       '^\[www\.Cpasbien\.com\] ': 'searchre',
+                       '^\[www\.Cpasbien\.pe\] ': 'searchre',
                       }
 
     _name = name
@@ -427,7 +430,7 @@ def hardlinkFile(srcFile, destFile):
     try:
         ek.ek(link, srcFile, destFile)
         fixSetGroupID(destFile)
-    except Exception, e:
+    except Exception as e:
         logger.log(u"Failed to create hardlink of " + srcFile + " at " + destFile + ": " + ex(e) + ". Copying instead",
                    logger.ERROR)
         copyFile(srcFile, destFile)
@@ -459,16 +462,16 @@ def make_dirs(path):
     parents
     """
 
-    logger.log(u"Checking if the path " + path + " already exists", logger.DEBUG)
+    logger.log(u"Checking if the path %s already exists" % path, logger.DEBUG)
 
     if not ek.ek(os.path.isdir, path):
         # Windows, create all missing folders
         if os.name == 'nt' or os.name == 'ce':
             try:
-                logger.log(u"Folder " + path + " didn't exist, creating it", logger.DEBUG)
+                logger.log(u"Folder %s didn't exist, creating it" % path, logger.DEBUG)
                 ek.ek(os.makedirs, path)
-            except (OSError, IOError), e:
-                logger.log(u"Failed creating " + path + " : " + ex(e), logger.ERROR)
+            except (OSError, IOError) as e:
+                logger.log(u"Failed creating %s : %s" % (path, ex(e)), logger.ERROR)
                 return False
 
         # not Windows, create all missing folders and set permissions
@@ -485,14 +488,14 @@ def make_dirs(path):
                     continue
 
                 try:
-                    logger.log(u"Folder " + sofar + " didn't exist, creating it", logger.DEBUG)
+                    logger.log(u"Folder %s didn't exist, creating it" % sofar, logger.DEBUG)
                     ek.ek(os.mkdir, sofar)
                     # use normpath to remove end separator, otherwise checks permissions against itself
                     chmodAsParent(ek.ek(os.path.normpath, sofar))
                     # do the library update for synoindex
                     notifiers.synoindex_notifier.addFolder(sofar)
-                except (OSError, IOError), e:
-                    logger.log(u"Failed creating " + sofar + " : " + ex(e), logger.ERROR)
+                except (OSError, IOError) as e:
+                    logger.log(u"Failed creating %s : %s" % (sofar, ex(e)), logger.ERROR)
                     return False
 
     return True
@@ -533,10 +536,10 @@ def rename_ep_file(cur_path, new_path, old_path_length=0):
 
     # move the file
     try:
-        logger.log(u"Renaming file from " + cur_path + " to " + new_path)
+        logger.log(u"Renaming file from %s to %s" % (cur_path, new_path))
         ek.ek(shutil.move, cur_path, new_path)
-    except (OSError, IOError), e:
-        logger.log(u"Failed renaming " + cur_path + " to " + new_path + ": " + ex(e), logger.ERROR)
+    except (OSError, IOError) as e:
+        logger.log(u"Failed renaming %s to %s : %s" % (cur_path, new_path, ex(e)), logger.ERROR)
         return False
 
     # clean up any old folders that are empty
@@ -571,7 +574,7 @@ def delete_empty_folders(check_empty_dir, keep_dir=None):
                 ek.ek(os.rmdir, check_empty_dir)
                 # do the library update for synoindex
                 notifiers.synoindex_notifier.deleteFolder(check_empty_dir)
-            except OSError, e:
+            except OSError as e:
                 logger.log(u"Unable to delete " + check_empty_dir + ": " + repr(e) + " / " + str(e), logger.WARNING)
                 break
             check_empty_dir = ek.ek(os.path.dirname, check_empty_dir)
@@ -780,7 +783,7 @@ def create_https_certificates(ssl_cert, ssl_key):
         from OpenSSL import crypto  # @UnresolvedImport
         from certgen import createKeyPair, createCertRequest, createCertificate, TYPE_RSA, \
             serial  # @UnresolvedImport
-    except Exception, e:
+    except Exception as e:
         logger.log(u"pyopenssl module missing, please install for https access", logger.WARNING)
         return False
 
@@ -811,22 +814,22 @@ def backupVersionedFile(old_file, version):
 
     while not ek.ek(os.path.isfile, new_file):
         if not ek.ek(os.path.isfile, old_file):
-            logger.log(u"Not creating backup, " + old_file + " doesn't exist", logger.DEBUG)
+            logger.log(u"Not creating backup, %s doesn't exist" % old_file, logger.DEBUG)
             break
 
         try:
-            logger.log(u"Trying to back up " + old_file + " to " + new_file, logger.DEBUG)
+            logger.log(u"Trying to back up %s to %s" % (old_file, new_file), logger.DEBUG)
             shutil.copy(old_file, new_file)
             logger.log(u"Backup done", logger.DEBUG)
             break
-        except Exception, e:
-            logger.log(u"Error while trying to back up " + old_file + " to " + new_file + " : " + ex(e), logger.WARNING)
+        except Exception as e:
+            logger.log(u"Error while trying to back up %s to %s : %s" % (old_file, new_file, ex(e)), logger.WARNING)
             numTries += 1
             time.sleep(1)
             logger.log(u"Trying again.", logger.DEBUG)
 
         if numTries >= 10:
-            logger.log(u"Unable to back up " + old_file + " to " + new_file + " please do it manually.", logger.ERROR)
+            logger.log(u"Unable to back up %s to %s please do it manually." % (old_file, new_file), logger.ERROR)
             return False
 
     return True
@@ -839,7 +842,7 @@ def restoreVersionedFile(backup_file, version):
     restore_file = new_file + '.' + 'v' + str(version)
 
     if not ek.ek(os.path.isfile, new_file):
-        logger.log(u"Not restoring, " + new_file + " doesn't exist", logger.DEBUG)
+        logger.log(u"Not restoring, %s doesn't exist" % new_file, logger.DEBUG)
         return False
 
     try:
@@ -847,7 +850,7 @@ def restoreVersionedFile(backup_file, version):
             u"Trying to backup " + new_file + " to " + new_file + "." + "r" + str(version) + " before restoring backup",
             logger.DEBUG)
         shutil.move(new_file, new_file + '.' + 'r' + str(version))
-    except Exception, e:
+    except Exception as e:
         logger.log(
             u"Error while trying to backup DB file " + restore_file + " before proceeding with restore: " + ex(e),
             logger.WARNING)
@@ -863,7 +866,7 @@ def restoreVersionedFile(backup_file, version):
             shutil.copy(restore_file, new_file)
             logger.log(u"Restore done", logger.DEBUG)
             break
-        except Exception, e:
+        except Exception as e:
             logger.log(u"Error while trying to restore " + restore_file + ": " + ex(e), logger.WARNING)
             numTries += 1
             time.sleep(1)
@@ -1258,9 +1261,9 @@ def touchFile(fname, atime=None):
             if e.errno == errno.ENOSYS:
                 logger.log(u"File air date stamping not available on your OS", logger.DEBUG)
             elif e.errno == errno.EACCES:
-                logger.log(u"File air date stamping failed(Permission denied). Check permissions for file: {0}".format(fname), logger.ERROR)
+                logger.log(u"File air date stamping failed(Permission denied). Check permissions for file: %s" % fname, logger.ERROR)
             else:
-                logger.log(u"File air date stamping failed. The error is: {0} and the message is: {1}.".format(e.errno, e.strerror), logger.ERROR)
+                logger.log(u"File air date stamping failed. The error is: %s." % ex(e), logger.ERROR)
             pass
 
     return False
@@ -1344,8 +1347,6 @@ def headURL(url, params=None, headers={}, timeout=30, session=None, json=False,
             logger.log(u"Requested headURL " + url + " returned status code is " + str(
                 resp.status_code) + ': ' + codeDescription(resp.status_code), logger.DEBUG)
             return False
-        else:
-            logger.log(u"Requested headURL " + url + " returned status code is " + str(resp.status_code) , logger.DEBUG)
 
         if proxyGlypeProxySSLwarning is not None:
             if re.search('The site you are attempting to browse is on a secure connection', resp.text):
@@ -1358,20 +1359,21 @@ def headURL(url, params=None, headers={}, timeout=30, session=None, json=False,
 
         return resp.status_code == 200
 
-    except requests.exceptions.HTTPError, e:
-        logger.log(u"HTTP error in headURL {0}. Error: {1}".format(url,e.errno), logger.WARNING)
+    except requests.exceptions.HTTPError as e:
+        logger.log(u"HTTP error in headURL %s. Error: %s" % (url, ex(e)), logger.WARNING)
         pass
-    except requests.exceptions.ConnectionError, e:
-        logger.log(u"Connection error to headURL {0}. Error: {1}".format(url,e.message), logger.WARNING)
+    except requests.exceptions.ConnectionError as e:
+        logger.log(u"Connection error in headURL %s. Error: %s " % (url, ex(e)), logger.WARNING)
         pass
-    except requests.exceptions.Timeout, e:
-        logger.log(u"Connection timed out accessing headURL {0}. Error: {1}".format(url,e.message), logger.WARNING)
+    except requests.exceptions.Timeout as e:
+        logger.log(u"Connection timed out accessing headURL %s. Error: %s" % (url, ex(e)), logger.WARNING)
         pass
     except requests.exceptions.ContentDecodingError:
         logger.log(u"Content-Encoding was gzip, but content was not compressed. headURL: %s" % url, logger.DEBUG)
+        logger.log(traceback.format_exc(), logger.DEBUG)
         pass
     except Exception as e:
-        logger.log(u"Unknown exception in headURL {0}. Error: {1}".format(url,e.message), logger.WARNING)
+        logger.log(u"Unknown exception in headURL %s. Error: %s" % (url, ex(e)), logger.WARNING)
         logger.log(traceback.format_exc(), logger.WARNING)
         pass
 
@@ -1398,8 +1400,6 @@ def getURL(url, post_data=None, params={}, headers={}, timeout=30, session=None,
             logger.log(u"Requested getURL " + url + " returned status code is " + str(
                 resp.status_code) + ': ' + codeDescription(resp.status_code), logger.DEBUG)
             return
-        else:
-            logger.log(u"Requested getURL " + url + " returned status code is " + str(resp.status_code), logger.DEBUG)
 
         if proxyGlypeProxySSLwarning is not None:
             if re.search('The site you are attempting to browse is on a secure connection', resp.text):
@@ -1410,20 +1410,21 @@ def getURL(url, post_data=None, params={}, headers={}, timeout=30, session=None,
                         resp.status_code) + ': ' + codeDescription(resp.status_code), logger.DEBUG)
                     return
 
-    except requests.exceptions.HTTPError, e:
-        logger.log(u"HTTP error in getURL {0}. Error: {1}".format(url,e.errno), logger.WARNING)
+    except requests.exceptions.HTTPError as e:
+        logger.log(u"HTTP error in getURL %s Error: %s" % (url, ex(e)), logger.WARNING)
         return
-    except requests.exceptions.ConnectionError, e:
-        logger.log(u"Connection error to getURL {0}. Error: {1}".format(url,e.message), logger.WARNING)
+    except requests.exceptions.ConnectionError as e:
+        logger.log(u"Connection error to getURL %s Error: %s" % (url, ex(e)), logger.WARNING)
         return
-    except requests.exceptions.Timeout, e:
-        logger.log(u"Connection timed out accessing getURL {0}. Error: {1}".format(url,e.message), logger.WARNING)
+    except requests.exceptions.Timeout as e:
+        logger.log(u"Connection timed out accessing getURL %s Error: %s" % (url, ex(e)), logger.WARNING)
         return
     except requests.exceptions.ContentDecodingError:
         logger.log(u"Content-Encoding was gzip, but content was not compressed. getURL: %s" % url, logger.DEBUG)
+        logger.log(traceback.format_exc(), logger.DEBUG)
         return
     except Exception as e:
-        logger.log(u"Unknown exception in getURL {0}. Error: {1}".format(url,e.message), logger.WARNING)
+        logger.log(u"Unknown exception in getURL %s Error: %s" % (url, ex(e)), logger.WARNING)
         logger.log(traceback.format_exc(), logger.WARNING)
         return
 
@@ -1453,19 +1454,19 @@ def download_file(url, filename, session=None, headers={}):
             except:
                 logger.log(u"Problem setting permissions or writing file to: %s" % filename, logger.WARNING)
 
-    except requests.exceptions.HTTPError, e:
+    except requests.exceptions.HTTPError as e:
         _remove_file_failed(filename)
-        logger.log(u"HTTP error " + str(e.errno) + " while loading download URL " + url, logger.WARNING)
+        logger.log(u"HTTP error " + ex(e) + " while loading download URL " + url, logger.WARNING)
         return False
-    except requests.exceptions.ConnectionError, e:
+    except requests.exceptions.ConnectionError as e:
         _remove_file_failed(filename)
-        logger.log(u"Connection error " + str(e.message) + " while loading download URL " + url, logger.WARNING)
+        logger.log(u"Connection error " + ex(e) + " while loading download URL " + url, logger.WARNING)
         return False
-    except requests.exceptions.Timeout, e:
+    except requests.exceptions.Timeout as e:
         _remove_file_failed(filename)
-        logger.log(u"Connection timed out " + str(e.message) + " while loading download URL " + url, logger.WARNING)
+        logger.log(u"Connection timed out " + ex(e) + " while loading download URL " + url, logger.WARNING)
         return False
-    except EnvironmentError, e:
+    except EnvironmentError as e:
         _remove_file_failed(filename)
         logger.log(u"Unable to save the file: " + ex(e), logger.WARNING)
         return False
@@ -1486,7 +1487,7 @@ def get_size(start_path='.'):
             try:
                 total_size += ek.ek(os.path.getsize, fp)
             except OSError as e:
-                logger.log('Unable to get size for file {filePath}. Error msg is: {errorMsg}'.format(filePath=fp, errorMsg=str(e)), logger.ERROR)
+                logger.log('Unable to get size for file %s Error: %s' % (fp, ex(e)), logger.ERROR)
                 logger.log(traceback.format_exc(), logger.DEBUG)
     return total_size
 
diff --git a/sickbeard/processTV.py b/sickbeard/processTV.py
index 0e7577317af58bc71f0994d9422283b5172edb82..aebf820a04efb90bf5d2a5070bd42d5b43058fe8 100644
--- a/sickbeard/processTV.py
+++ b/sickbeard/processTV.py
@@ -318,7 +318,7 @@ def validateDir(path, dirName, nzbNameOriginal, failed, result):
                 os.path.realpath, sqlShow["location"]).lower():
             result.output += logHelper(
                 u"Cannot process an episode that's already been moved to its show dir, skipping " + dirName,
-                logger.ERROR)
+                logger.WARNING)
             return False
 
     # Get the videofile list for the next checks
diff --git a/sickbeard/providers/btn.py b/sickbeard/providers/btn.py
index 4a2c6aaaeb5b3d79c4ed3788057ddfbe884bf5cd..1ca0085ab3806dfe5c1588e99471009a333cbe7d 100644
--- a/sickbeard/providers/btn.py
+++ b/sickbeard/providers/btn.py
@@ -33,7 +33,7 @@ from sickbeard.exceptions import ex, AuthException
 from sickbeard.common import MULTI_EP_RESULT, SEASON_RESULT, USER_AGENT
 from sickbeard import db
 from sickbeard.name_parser.parser import NameParser, InvalidNameException, InvalidShowException
-from sickbeard.common import Quality
+from sickbeard.common import Quality, cpu_presets
 
 import jsonrpclib
 from datetime import datetime
@@ -144,6 +144,7 @@ class BTNProvider(generic.TorrentProvider):
 
         try:
             parsedJSON = server.getTorrents(apikey, params, int(results_per_page), int(offset))
+            time.sleep(cpu_presets[sickbeard.CPU_PRESET])
 
         except jsonrpclib.jsonrpc.ProtocolError, error:
             if error.message == 'Call Limit Exceeded':
diff --git a/sickbeard/providers/newznab.py b/sickbeard/providers/newznab.py
index 501331fd7e20c365278d256451914fcc213f06d1..865bf64ed39f26683e65c54c264f300c3e5e614d 100644
--- a/sickbeard/providers/newznab.py
+++ b/sickbeard/providers/newznab.py
@@ -149,7 +149,7 @@ class NewznabProvider(generic.NZBProvider):
         rid = helpers.mapIndexersToShow(ep_obj.show)[2]
         if rid:
             cur_params['rid'] = rid
-        elif 'rid' in params:
+        elif 'rid' in cur_params:
             cur_params.pop('rid')
 
         # add new query strings for exceptions
diff --git a/sickbeard/scene_numbering.py b/sickbeard/scene_numbering.py
index 0887278d41adc44b3dd7393cf9d3607336aca63a..686729c6ab187dedf12d526c2d2545b6d3fae2e8 100644
--- a/sickbeard/scene_numbering.py
+++ b/sickbeard/scene_numbering.py
@@ -463,16 +463,12 @@ def xem_refresh(indexer_id, indexer, force=False):
     
     @param indexer_id: int
     """
-    if indexer_id is None:
+    if not indexer_id or indexer_id < 1:
         return
 
     indexer_id = int(indexer_id)
     indexer = int(indexer)
 
-    # XEM API URL
-    url = "http://thexem.de/map/all?id=%s&origin=%s&destination=scene" % (
-    indexer_id, sickbeard.indexerApi(indexer).config['xem_origin'])
-
     MAX_REFRESH_AGE_SECS = 86400  # 1 day
 
     myDB = db.DBConnection()
@@ -497,41 +493,48 @@ def xem_refresh(indexer_id, indexer, force=False):
 
         try:
             from .scene_exceptions import xem_session
+
+            # XEM MAP URL
+            url = "http://thexem.de/map/havemap?origin=%s" % sickbeard.indexerApi(indexer).config['xem_origin']
+            parsedJSON = sickbeard.helpers.getURL(url, session=xem_session, json=True)
+            if not parsedJSON or 'result' not in parsedJSON or 'success' not in parsedJSON['result'] or 'data' not in parsedJSON or indexer_id not in parsedJSON['data']:
+                return
+
+            # XEM API URL
+            url = "http://thexem.de/map/all?id=%s&origin=%s&destination=scene" % indexer_id, sickbeard.indexerApi(indexer).config['xem_origin']
+
             parsedJSON = sickbeard.helpers.getURL(url, session=xem_session, json=True)
-            if not parsedJSON or parsedJSON == '':
+            if not parsedJSON or not 'result' in parsedJSON or not 'success' in parsedJSON['result']:
                 logger.log(u'No XEM data for show "%s on %s"' % (indexer_id, sickbeard.indexerApi(indexer).name,), logger.INFO)
                 return
 
-            if 'success' in parsedJSON['result']:
-                cl = []
-                for entry in parsedJSON['data']:
-                    if 'scene' in entry:
-                        cl.append([
-                            "UPDATE tv_episodes SET scene_season = ?, scene_episode = ?, scene_absolute_number = ? WHERE showid = ? AND season = ? AND episode = ?",
-                            [entry['scene']['season'],
-                             entry['scene']['episode'],
-                             entry['scene']['absolute'],
-                             indexer_id,
-                             entry[sickbeard.indexerApi(indexer).config['xem_origin']]['season'],
-                             entry[sickbeard.indexerApi(indexer).config['xem_origin']]['episode']
-                            ]])
-                    if 'scene_2' in entry:  # for doubles
-                        cl.append([
-                            "UPDATE tv_episodes SET scene_season = ?, scene_episode = ?, scene_absolute_number = ? WHERE showid = ? AND season = ? AND episode = ?",
-                            [entry['scene_2']['season'],
-                             entry['scene_2']['episode'],
-                             entry['scene_2']['absolute'],
-                             indexer_id,
-                             entry[sickbeard.indexerApi(indexer).config['xem_origin']]['season'],
-                             entry[sickbeard.indexerApi(indexer).config['xem_origin']]['episode']
-                            ]])
-
-                if len(cl) > 0:
-                    myDB = db.DBConnection()
-                    myDB.mass_action(cl)
-            else:
-                logger.log(u"Empty lookup result - no XEM data for show %s on %s" % (
-                    indexer_id, sickbeard.indexerApi(indexer).name,), logger.DEBUG)
+            cl = []
+            for entry in parsedJSON['data']:
+                if 'scene' in entry:
+                    cl.append([
+                        "UPDATE tv_episodes SET scene_season = ?, scene_episode = ?, scene_absolute_number = ? WHERE showid = ? AND season = ? AND episode = ?",
+                        [entry['scene']['season'],
+                         entry['scene']['episode'],
+                         entry['scene']['absolute'],
+                         indexer_id,
+                         entry[sickbeard.indexerApi(indexer).config['xem_origin']]['season'],
+                         entry[sickbeard.indexerApi(indexer).config['xem_origin']]['episode']
+                        ]])
+                if 'scene_2' in entry:  # for doubles
+                    cl.append([
+                        "UPDATE tv_episodes SET scene_season = ?, scene_episode = ?, scene_absolute_number = ? WHERE showid = ? AND season = ? AND episode = ?",
+                        [entry['scene_2']['season'],
+                         entry['scene_2']['episode'],
+                         entry['scene_2']['absolute'],
+                         indexer_id,
+                         entry[sickbeard.indexerApi(indexer).config['xem_origin']]['season'],
+                         entry[sickbeard.indexerApi(indexer).config['xem_origin']]['episode']
+                        ]])
+
+            if len(cl) > 0:
+                myDB = db.DBConnection()
+                myDB.mass_action(cl)
+
         except Exception, e:
             logger.log(
                 u"Exception while refreshing XEM data for show " + str(indexer_id) + " on " + sickbeard.indexerApi(
diff --git a/sickbeard/tv.py b/sickbeard/tv.py
index deb5655fb172af006f9970c4daac38cb6baff73b..12c67056c4f0d119bb5ee755b5df447779874b0e 100644
--- a/sickbeard/tv.py
+++ b/sickbeard/tv.py
@@ -484,10 +484,12 @@ class TVShow(object):
 
         if self.lang:
             lINDEXER_API_PARMS['language'] = self.lang
+            logger.log(u"Using language: " + str(self.lang), logger.DEBUG)
 
         if self.dvdorder != 0:
             lINDEXER_API_PARMS['dvdorder'] = True
 
+        logger.log(u"lINDEXER_API_PARMS: " + str(lINDEXER_API_PARMS), logger.DEBUG)
         t = sickbeard.indexerApi(self.indexer).indexer(**lINDEXER_API_PARMS)
 
         cachedShow = t[self.indexerid]
@@ -495,6 +497,7 @@ class TVShow(object):
 
         for curResult in sqlResults:
 
+            logger.log(u"loadEpisodesFromDB curResult: " + str(curResult), logger.DEBUG)
             deleteEp = False
 
             curSeason = int(curResult["season"])
@@ -509,6 +512,7 @@ class TVShow(object):
                     deleteEp = True
 
             if not curSeason in scannedEps:
+                logger.log(u"Not curSeason in scannedEps", logger.DEBUG)
                 scannedEps[curSeason] = {}
 
             logger.log(u"Loading episode S%02dE%02d from the DB" % (curSeason, curEpisode), logger.DEBUG)
@@ -530,6 +534,8 @@ class TVShow(object):
                            logger.DEBUG)
                 continue
 
+        logger.log(u"Finished loading all episodes from the DB", logger.DEBUG)
+
         return scannedEps
 
     def loadEpisodesFromIndexer(self, cache=True):
@@ -1471,7 +1477,7 @@ class TVEpisode(object):
 
             for video, subs in foundSubs.iteritems():
                 for sub in subs:
-                    subpath = subliminal.subtitle.get_subtitle_path(video.name, sub.language)
+                    subpath = subliminal.subtitle.get_subtitle_path(video.name, sub.language if sickbeard.SUBTITLES_MULTI else None)
                     if sickbeard.SUBTITLES_DIR and ek.ek(os.path.exists, sickbeard.SUBTITLES_DIR):
                         subpath = ek.ek(os.path.join, sickbeard.SUBTITLES_DIR, ek.ek(os.path.basename, subpath))
                     helpers.chmodAsParent(subpath)
diff --git a/sickbeard/webserve.py b/sickbeard/webserve.py
index 1ac8621b1435b260a2bac5e1f60ae3c0ea92ac23..d0368cf9da9a3fbd9da1bb5013509d18fad84829 100644
--- a/sickbeard/webserve.py
+++ b/sickbeard/webserve.py
@@ -129,6 +129,7 @@ class PageTemplate(CheetahTemplate):
         self.sbHttpsEnabled = sickbeard.ENABLE_HTTPS
         self.sbHandleReverseProxy = sickbeard.HANDLE_REVERSE_PROXY
         self.sbThemeName = sickbeard.THEME_NAME
+        self.sbDefaultPage = sickbeard.DEFAULT_PAGE
         self.sbLogin = rh.get_current_user()
 
         if rh.request.headers['Host'][0] == '[':
@@ -281,8 +282,9 @@ class WebHandler(BaseHandler):
 
 class LoginHandler(BaseHandler):
     def get(self, *args, **kwargs):
+
         if self.get_current_user():
-            self.redirect('/home/')
+            self.redirect('/' + sickbeard.DEFAULT_PAGE +'/')
         else:
             t = PageTemplate(rh=self, file="login.tmpl")
             self.finish(t.respond())
@@ -301,11 +303,11 @@ class LoginHandler(BaseHandler):
         if api_key:
             remember_me = int(self.get_argument('remember_me', default=0) or 0)
             self.set_secure_cookie('sickrage_user', api_key, expires_days=30 if remember_me > 0 else None)
-            logger.log('User logged into the SickRage web interface from IP: ' + self.request.remote_ip, logger.INFO)
+            logger.log('User logged into the SickRage web interface', logger.INFO)
         else:
             logger.log('User attempted a failed login to the SickRage web interface from IP: ' + self.request.remote_ip, logger.WARNING)    
 
-        self.redirect('/home/')
+        self.redirect('/' + sickbeard.DEFAULT_PAGE +'/')
 
 
 class LogoutHandler(BaseHandler):
@@ -340,7 +342,7 @@ class WebRoot(WebHandler):
         super(WebRoot, self).__init__(*args, **kwargs)
 
     def index(self):
-        return self.redirect('/home/')
+        return self.redirect('/' + sickbeard.DEFAULT_PAGE +'/')
 
     def robots_txt(self):
         """ Keep web crawlers out """
@@ -431,7 +433,7 @@ class WebRoot(WebHandler):
             layout = 'poster'
 
         sickbeard.HOME_LAYOUT = layout
-
+        #Dont redirect to default page so user can see new layout
         return self.redirect("/home/")
 
     def setPosterSortBy(self, sort):
@@ -1115,7 +1117,7 @@ class Home(WebRoot):
 
     def shutdown(self, pid=None):
         if str(pid) != str(sickbeard.PID):
-            return self.redirect("/home/")
+            return self.redirect('/' + sickbeard.DEFAULT_PAGE +'/')
 
         sickbeard.events.put(sickbeard.events.SystemEvent.SHUTDOWN)
 
@@ -1126,7 +1128,7 @@ class Home(WebRoot):
 
     def restart(self, pid=None):
         if str(pid) != str(sickbeard.PID):
-            return self.redirect("/home/")
+            return self.redirect('/' + sickbeard.DEFAULT_PAGE +'/')
 
         t = PageTemplate(rh=self, file="restart.tmpl")
         t.submenu = self.HomeMenu()
@@ -1142,7 +1144,7 @@ class Home(WebRoot):
 
         sickbeard.versionCheckScheduler.action.check_for_new_version(force=True)
 
-        return self.redirect('/home/')
+        return self.redirect('/' + sickbeard.DEFAULT_PAGE +'/')
 
     def update(self, pid=None):
         
@@ -1164,7 +1166,7 @@ class Home(WebRoot):
                 return self._genericMessage("Update Failed",
                                             "Update wasn't successful, not restarting. Check your log for more information.")
         else:
-            return self.redirect('/home/')
+            return self.redirect('/' + sickbeard.DEFAULT_PAGE +'/')
 
     def branchCheckout(self, branch):
         if sickbeard.BRANCH != branch:
@@ -1173,7 +1175,7 @@ class Home(WebRoot):
             return self.update(sickbeard.PID)
         else:
             ui.notifications.message('Already on branch: ', branch)
-            return self.redirect('/home')
+            return self.redirect('/' + sickbeard.DEFAULT_PAGE +'/')
 
     def getDBcompare(self, branchDest=None):
 
@@ -1597,7 +1599,8 @@ class Home(WebRoot):
                                  (showObj.name,
                                   ('deleted', 'trashed')[sickbeard.TRASH_REMOVE_SHOW],
                                   ('(media untouched)', '(with all related media)')[bool(full)]))
-        return self.redirect("/home/")
+        #Dont redirect to default page so user can confirm show was deleted
+        return self.redirect('/home/')
 
 
     def refreshShow(self, show=None):
@@ -1697,7 +1700,7 @@ class Home(WebRoot):
 
     def setStatus(self, show=None, eps=None, status=None, direct=False):
 
-        if show is None or eps is None or status is None:
+        if not all([show, eps, status]):
             errMsg = "You must specify a show and at least one episode"
             if direct:
                 ui.notifications.error('Error', errMsg)
@@ -1715,7 +1718,7 @@ class Home(WebRoot):
 
         showObj = sickbeard.helpers.findCertainShow(sickbeard.showList, int(show))
 
-        if showObj is None:
+        if not showObj:
             errMsg = "Error", "Show not in show list"
             if direct:
                 ui.notifications.error('Error', errMsg)
@@ -1725,18 +1728,25 @@ class Home(WebRoot):
 
         segments = {}
         trakt_data = []
-        if eps is not None:
+        if eps:
 
             sql_l = []
             for curEp in eps.split('|'):
 
+                if not curEp:
+                    logger.log(u"curEp was empty when trying to setStatus", logger.DEBUG)
+
                 logger.log(u"Attempting to set status on episode " + curEp + " to " + status, logger.DEBUG)
 
                 epInfo = curEp.split('x')
 
+                if not all(epInfo):
+                    logger.log(u"Something went wrong when trying to setStatus, epInfo[0]: %s, epInfo[1]: %s" % (epInfo[0], epInfo[1]), logger.DEBUG)
+                    continue
+
                 epObj = showObj.getEpisode(int(epInfo[0]), int(epInfo[1]))
 
-                if epObj is None:
+                if not epObj:
                     return self._genericMessage("Error", "Episode couldn't be retrieved")
 
                 if int(status) in [WANTED, FAILED]:
@@ -1752,16 +1762,14 @@ class Home(WebRoot):
                         logger.log(u"Refusing to change status of " + curEp + " because it is UNAIRED", logger.ERROR)
                         continue
 
-                    if int(
-                            status) in Quality.DOWNLOADED and epObj.status not in Quality.SNATCHED + Quality.SNATCHED_PROPER + Quality.DOWNLOADED + [
+                    if int(status) in Quality.DOWNLOADED and epObj.status not in Quality.SNATCHED + Quality.SNATCHED_PROPER + Quality.DOWNLOADED + [
                         IGNORED] and not ek.ek(os.path.isfile, epObj.location):
                         logger.log(
                             u"Refusing to change status of " + curEp + " to DOWNLOADED because it's not SNATCHED/DOWNLOADED",
                             logger.ERROR)
                         continue
 
-                    if int(
-                            status) == FAILED and epObj.status not in Quality.SNATCHED + Quality.SNATCHED_PROPER + Quality.DOWNLOADED:
+                    if int(status) == FAILED and epObj.status not in Quality.SNATCHED + Quality.SNATCHED_PROPER + Quality.DOWNLOADED:
                         logger.log(
                             u"Refusing to change status of " + curEp + " to FAILED because it's not SNATCHED/DOWNLOADED",
                             logger.ERROR)
@@ -2706,6 +2714,7 @@ class HomeAddShows(Home):
                 logger.log(u"Unable to create the folder " + show_dir + ", can't add the show", logger.ERROR)
                 ui.notifications.error("Unable to add show",
                                        "Unable to create the folder " + show_dir + ", can't add the show")
+                #Dont redirect to default page because user wants to see the new show
                 return self.redirect("/home/")
             else:
                 helpers.chmodAsParent(show_dir)
@@ -3768,7 +3777,7 @@ class ConfigGeneral(Config):
                     proxy_setting=None, proxy_indexers=None, anon_redirect=None, git_path=None, git_remote=None,
                     calendar_unprotected=None, debug=None, ssl_verify=None, no_restart=None, coming_eps_missed_range=None,
                     filter_row=None, fuzzy_dating=None, trim_zero=None, date_preset=None, date_preset_na=None, time_preset=None,
-                    indexer_timeout=None, download_url=None, rootDir=None, theme_name=None,
+                    indexer_timeout=None, download_url=None, rootDir=None, theme_name=None, default_page=None,
                     git_reset=None, git_username=None, git_password=None, git_autoissues=None, display_all_seasons=None):
 
         results = []
@@ -3798,7 +3807,9 @@ class ConfigGeneral(Config):
         sickbeard.PROXY_INDEXERS = config.checkbox_to_value(proxy_indexers)
         sickbeard.GIT_USERNAME = git_username
         sickbeard.GIT_PASSWORD = git_password
-        sickbeard.GIT_RESET = config.checkbox_to_value(git_reset)
+        #sickbeard.GIT_RESET = config.checkbox_to_value(git_reset)
+        #Force GIT_RESET
+        sickbeard.GIT_RESET = 1        
         sickbeard.GIT_AUTOISSUES = config.checkbox_to_value(git_autoissues)
         sickbeard.GIT_PATH = git_path
         sickbeard.GIT_REMOTE = git_remote
@@ -3858,6 +3869,8 @@ class ConfigGeneral(Config):
         sickbeard.HANDLE_REVERSE_PROXY = config.checkbox_to_value(handle_reverse_proxy)
 
         sickbeard.THEME_NAME = theme_name
+        
+        sickbeard.DEFAULT_PAGE = default_page
 
         sickbeard.save_config()
 
@@ -5047,6 +5060,9 @@ class ErrorLogs(WebRoot):
 
     def viewlog(self, minLevel=logger.INFO, logFilter="<NONE>",logSearch=None, maxLines=500):
         
+        if sickbeard.DEBUG == 1:
+            minLevel = logger.DEBUG
+        
         def Get_Data(Levelmin, data_in, lines_in, regex, Filter, Search, mlines):
             
             lastLine = False