diff --git a/.travis.yml b/.travis.yml
index 6d85ba9e19dafdf3b94eac202e71ab15d9eecf5d..9e41afd1d0fedac9d35c5910cf73850290d98adc 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,8 +1,9 @@
 language: python
 python:
-  - 2.6
   - 2.7
 
+sudo: false
+
 branches:
   except:
     - master
diff --git a/SickBeard.py b/SickBeard.py
index 2ee3659706e1d7b46a869a33ff6133a8973bf6b3..0955ca7dbf77f67bf8ff4395bf4899ff482c936f 100755
--- a/SickBeard.py
+++ b/SickBeard.py
@@ -147,6 +147,30 @@ class SickRage(object):
         help_msg += "                --noresize          Prevent resizing of the banner/posters even if PIL is installed\n"
 
         return help_msg
+        
+    def fix_clients_nonsense():
+    
+        files = ["sickbeard/clients/download_station.py",
+                 "sickbeard/clients/utorrent.py",
+                 "sickbeard/clients/generic.py",
+                 "sickbeard/clients/qbittorrent.py",
+                 "sickbeard/clients/transmission.py",
+                 "sickbeard/clients/deluge.py",
+                 "sickbeard/clients/rtorrent.py"
+                ]
+                
+        for file in files:
+            file = ek.ek(os.path.join, sickbeard.PROG_DIR, file)
+            try:
+                if ek.ek(os.path.exists, file):
+                    ek.ek(os.remove, file)
+            except:
+                pass
+            try:
+                if ek.ek(os.path.exists, file + "c"):
+                    ek.ek(os.remove, file + "c")
+            except:
+                pass
 
     def start(self):
         # do some preliminary stuff
@@ -317,6 +341,9 @@ class SickRage(object):
 
         # Get PID
         sickbeard.PID = os.getpid()
+        
+        # Fix clients old files
+        self.fix_clients_nonsense()
 
         # Build from the DB to start with
         self.loadShowsFromDB()
diff --git a/gui/slick/images/flags/za.png b/gui/slick/images/flags/za.png
new file mode 100644
index 0000000000000000000000000000000000000000..c9341107300bc8a3449174e181e0ae483f2d912e
Binary files /dev/null and b/gui/slick/images/flags/za.png differ
diff --git a/gui/slick/images/network/arena.png b/gui/slick/images/network/arena.png
new file mode 100644
index 0000000000000000000000000000000000000000..4966f47ca66cfa2bddf4e752594470581eff53ab
Binary files /dev/null and b/gui/slick/images/network/arena.png differ
diff --git a/gui/slick/images/network/fyi.png b/gui/slick/images/network/fyi.png
new file mode 100644
index 0000000000000000000000000000000000000000..c46c4d35c409b1cf98ff333da3fc7b373f4cc113
Binary files /dev/null and b/gui/slick/images/network/fyi.png differ
diff --git a/gui/slick/images/network/soho.png b/gui/slick/images/network/soho.png
new file mode 100644
index 0000000000000000000000000000000000000000..82e4f728e12eec62f902423a0512c82d7bf66f51
Binary files /dev/null and b/gui/slick/images/network/soho.png differ
diff --git a/gui/slick/interfaces/default/IRC.tmpl b/gui/slick/interfaces/default/IRC.tmpl
new file mode 100644
index 0000000000000000000000000000000000000000..528f5822f3477f5543dacb24ee9aad20c12daaa0
--- /dev/null
+++ b/gui/slick/interfaces/default/IRC.tmpl
@@ -0,0 +1,9 @@
+#import sickbeard
+#from sickbeard.common import *
+
+#import os.path
+#include $os.path.join($sickbeard.PROG_DIR, "gui/slick/interfaces/default/inc_top.tmpl")
+
+<iframe id="extFrame" src="https://kiwiirc.com/client/irc.freenode.net/?nick=srforums|?&theme=basic#sickrage" width="100%" height="500" frameBorder="0" style="border: 1px black solid;"></iframe>
+
+#include $os.path.join($sickbeard.PROG_DIR, "gui/slick/interfaces/default/inc_bottom.tmpl")
diff --git a/gui/slick/interfaces/default/apiBuilder.tmpl b/gui/slick/interfaces/default/apiBuilder.tmpl
index e7b0454f48fe45a3d6cd205ec1e44fd8cf24d906..42397e4567361f7287e285d658bdf7f20558db65 100644
--- a/gui/slick/interfaces/default/apiBuilder.tmpl
+++ b/gui/slick/interfaces/default/apiBuilder.tmpl
@@ -65,6 +65,7 @@ addList("Command", "Show.AddNew", "?cmd=show.addnew", "show.addnew", "", "", "ac
 addList("Command", "Show.Cache", "?cmd=show.cache", "indexerid", "", "", "action");
 addList("Command", "Show.Delete", "?cmd=show.delete", "show.delete", "", "", "action");
 addList("Command", "Show.GetBanner", "?cmd=show.getbanner", "indexerid", "", "", "action");
+addList("Command", "Show.GetFanArt", "?cmd=show.getfanart", "indexerid", "", "", "action");
 addList("Command", "Show.GetNetworkLogo", "?cmd=show.getnetworklogo", "indexerid", "", "", "action");
 addList("Command", "Show.GetPoster", "?cmd=show.getposter", "indexerid", "", "", "action");
 addList("Command", "Show.GetQuality", "?cmd=show.getquality", "indexerid", "", "", "action");
diff --git a/gui/slick/interfaces/default/config_notifications.tmpl b/gui/slick/interfaces/default/config_notifications.tmpl
index 0686a4386a2010aa0f21fbfe25bce7ff92056fb4..ddb12a1b64b31c868ec06880bd630958c98673c5 100644
--- a/gui/slick/interfaces/default/config_notifications.tmpl
+++ b/gui/slick/interfaces/default/config_notifications.tmpl
@@ -1589,7 +1589,7 @@
                                 </label>
                                 <label>
                                     <span class="component-title">&nbsp;</span>
-                                    <span class="component-desc">Name(slug) of List on Trakt for blacklisting show on 'Add Trending Show' page</span>
+                                    <span class="component-desc">Name(slug) of List on Trakt for blacklisting show on 'Add Trending Show' & 'Add Recommended Shows' pages</span>
                                 </label>
                             </div>
                             <div class="field-pair">
diff --git a/gui/slick/interfaces/default/config_subtitles.tmpl b/gui/slick/interfaces/default/config_subtitles.tmpl
index 75e4434aeedb6fb6faa813af3b5e3ceab0be80d1..7e3cf3e7894663edd1f9eacd491000169efcd655 100644
--- a/gui/slick/interfaces/default/config_subtitles.tmpl
+++ b/gui/slick/interfaces/default/config_subtitles.tmpl
@@ -124,7 +124,33 @@
 											<p><b>Warning: </b>this will ignore <u>all</u> embedded subtitles for every video file!</p>
 										</span>
 									</label>
-								</div>   
+								</div>
+								<div class="field-pair">
+        						    <label class="nocheck">
+        						        <span class="component-title">Extra Scripts</span>
+           						        <input type="text" name="subtitles_extra_scripts" value="<%='|'.join(sickbeard.SUBTITLES_EXTRA_SCRIPTS)%>" class="form-control input-sm input350" />
+        						    </label>
+        						    <label class="nocheck">
+        						        <span class="component-title">&nbsp;</span>
+        						        <span class="component-desc"><b>NOTE:</b></span>
+        						    </label>
+        						    <label class="nocheck">
+        						        <span class="component-title">&nbsp;</span>
+        								<span class="component-desc">
+        									<ul>
+            										<li>See <a href="https://github.com/SiCKRAGETV/SickRage/wiki/Subtitle%20Scripts"><font color='red'><b>Wiki</b></font></a> for a script arguments description.</li>
+            										<li>Additional scripts separated by <b>|</b>.</li>
+            										<li>Scripts are called after each episode has searched and downloaded subtitles.</li>
+										            <li>For any scripted languages, include the interpreter executable before the script. See the following example:</li>
+										            <ul>
+											            <li>For Windows: <pre>C:\Python27\pythonw.exe C:\Script\test.py</pre></li>
+											            <li>For Linux: <pre>python /Script/test.py</pre></li>
+										            </ul>
+									        </ul>
+								        </span>
+						            </label>
+						        </div>
+
 	                    <br/><input type="submit" class="btn config_submitter" value="Save Changes" /><br/>
                         </div>
                     </fieldset>
diff --git a/gui/slick/interfaces/default/displayShow.tmpl b/gui/slick/interfaces/default/displayShow.tmpl
index c6638d170832d8b1d56813cbeb6b894419d1c70e..b3c9f04766989d7b1cb5f202cafb7dc9e7311dcd 100644
--- a/gui/slick/interfaces/default/displayShow.tmpl
+++ b/gui/slick/interfaces/default/displayShow.tmpl
@@ -547,9 +547,10 @@
                 #if $epResult['location']
                     #set $filename = $epResult['location']
                     #for $rootDir in $sickbeard.ROOT_DIRS.split('|')
-                        #if $rootDir.startswith('/')
-                            #set $filename = ntpath.basename($filename)
+                        #if not $rootDir.startswith('/')
+                            #set $filename = $filename.replace('\\','\\\\')
                         #end if
+                        #set $filename = ntpath.basename($filename)   
                     #end for
                     $filename
                 #end if    
diff --git a/gui/slick/interfaces/default/inc_top.tmpl b/gui/slick/interfaces/default/inc_top.tmpl
index 39c35fdcb5f49b8db460166bd306d23274bad575..3c2bce53b60caea47066456b74654a009334fd43 100644
--- a/gui/slick/interfaces/default/inc_top.tmpl
+++ b/gui/slick/interfaces/default/inc_top.tmpl
@@ -164,6 +164,9 @@
 					<ul class="nav navbar-nav navbar-right">
 						<li id="NAVnews">
                             <a href="$sbRoot/news/">News</a>
+                        </li>
+						<li id="NAVnews">
+                            <a href="$sbRoot/IRC/">IRC</a>
                         </li>
 						<li id="NAVhome">
                             <a href="$sbRoot/home/">Shows</a>
diff --git a/gui/slick/js/apibuilder.js b/gui/slick/js/apibuilder.js
index 48dafdca45d6be44befae965fe1d75ff7f8bec78..cdf0e730f40f8c99e545870a1b7480ca43dacb47 100644
--- a/gui/slick/js/apibuilder.js
+++ b/gui/slick/js/apibuilder.js
@@ -9,6 +9,7 @@
 
 var _disable_empty_list=false;
 var _hide_empty_list=false;
+var _image_commands=['?cmd=show.getbanner', '?cmd=show.getfanart', '?cmd=show.getnetworklogo', '?cmd=show.getposter']
 
 function goListGroup(apikey, L7, L6, L5, L4, L3, L2, L1){
     var html, GlobalOptions = "";
@@ -25,8 +26,8 @@ function goListGroup(apikey, L7, L6, L5, L4, L3, L2, L1){
         }
     });
 
-    // handle the show.getposter / show.getbanner differently as they return an image and not json
-    if (L1 == "?cmd=show.getposter" || L1 == "?cmd=show.getbanner") {
+    // Some commands return an image instead of JSON
+    if ($.inArray(L1, _image_commands) > -1) {
         var imgcache = sbRoot + "/api/" + apikey + "/" + L1 + L2 + GlobalOptions;
         html = imgcache + '<br/><br/><img src="' + sbRoot + '/images/loading16.gif" id="imgcache">';
         $('#apiResponse').html(html);
diff --git a/readme.md b/readme.md
index 932b67dfde74db3e106da2251a28da7085e76839..8f93e86656b32a17216667b4edcf479b336c3fb5 100644
--- a/readme.md
+++ b/readme.md
@@ -31,7 +31,7 @@ Automatic Video Library Manager for TV Shows. It watches for new episodes of you
 -[Mobile](http://imgur.com/a/WPyG6)
 
 ## Dependencies
- To run SickRage from source you will need Python 2.6+, Cheetah 2.1.0+, and PyOpenSSL
+ To run SickRage from source you will need Python 2.7.x, Cheetah 2.1.0+, and PyOpenSSL
 
 ## Forums
  Any questions or setup info your looking for can be found at out forums https://www.sickrage.tv
diff --git a/sickbeard/__init__.py b/sickbeard/__init__.py
index a13af38a53f883ef4ef5edfd8b54153ced579a07..e75df4eae5cbc735f5e628650ac5cf56cdf99b02 100644
--- a/sickbeard/__init__.py
+++ b/sickbeard/__init__.py
@@ -119,7 +119,7 @@ NOTIFY_ON_UPDATE = False
 CUR_COMMIT_HASH = None
 BRANCH = ''
 
-GIT_RESET = False
+GIT_RESET = True
 GIT_REMOTE = ''
 GIT_REMOTE_URL = ''
 CUR_COMMIT_BRANCH = ''
@@ -500,7 +500,7 @@ TIMEZONE_DISPLAY = None
 THEME_NAME = None
 POSTER_SORTBY = None
 POSTER_SORTDIR = None
-FILTER_ROW = False
+FILTER_ROW = True
 
 USE_SUBTITLES = False
 SUBTITLES_LANGUAGES = []
@@ -511,6 +511,7 @@ SUBTITLES_HISTORY = False
 EMBEDDED_SUBTITLES_ALL = False
 SUBTITLES_FINDER_FREQUENCY = 1
 SUBTITLES_MULTI = False
+SUBTITLES_EXTRA_SCRIPTS = []
 
 USE_FAILED_DOWNLOADS = False
 DELETE_FAILED = False
@@ -583,7 +584,7 @@ def initialize(consoleLogging=True):
             GUI_NAME, HOME_LAYOUT, HISTORY_LAYOUT, DISPLAY_SHOW_SPECIALS, COMING_EPS_LAYOUT, COMING_EPS_SORT, COMING_EPS_DISPLAY_PAUSED, COMING_EPS_MISSED_RANGE, DISPLAY_FILESIZE, FUZZY_DATING, TRIM_ZERO, DATE_PRESET, TIME_PRESET, TIME_PRESET_W_SECONDS, THEME_NAME, FILTER_ROW, \
             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, subtitlesFinderScheduler, \
+            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, \
             AUTOPOSTPROCESSER_FREQUENCY, SHOWUPDATE_HOUR, DEFAULT_AUTOPOSTPROCESSER_FREQUENCY, MIN_AUTOPOSTPROCESSER_FREQUENCY, \
             ANIME_DEFAULT, NAMING_ANIME, ANIMESUPPORT, USE_ANIDB, ANIDB_USERNAME, ANIDB_PASSWORD, ANIDB_USE_MYLIST, \
@@ -650,7 +651,7 @@ def initialize(consoleLogging=True):
             logger.log('Unable to setup github properly, github will not be available. Error: {0}'.format(ex(e)),logger.WARNING)
 
         # git reset on update
-        GIT_RESET = bool(check_setting_int(CFG, 'General', 'git_reset', 0))
+        GIT_RESET = bool(check_setting_int(CFG, 'General', 'git_reset', 1))
 
         # current git branch
         BRANCH = check_setting_str(CFG, 'General', 'branch', '')
@@ -1101,6 +1102,9 @@ def initialize(consoleLogging=True):
         SUBTITLES_FINDER_FREQUENCY = check_setting_int(CFG, 'Subtitles', 'subtitles_finder_frequency', 1)
         SUBTITLES_MULTI = bool(check_setting_int(CFG, 'Subtitles', 'subtitles_multi', 1))
 
+        SUBTITLES_EXTRA_SCRIPTS = [x.strip() for x in check_setting_str(CFG, 'Subtitles', 'subtitles_extra_scripts', '').split('|') if
+                         x.strip()]
+
         USE_FAILED_DOWNLOADS = bool(check_setting_int(CFG, 'FailedDownloads', 'use_failed_downloads', 0))
         DELETE_FAILED = bool(check_setting_int(CFG, 'FailedDownloads', 'delete_failed', 0))
 
@@ -1149,7 +1153,7 @@ def initialize(consoleLogging=True):
         TIMEZONE_DISPLAY = check_setting_str(CFG, 'GUI', 'timezone_display', 'network')
         POSTER_SORTBY = check_setting_str(CFG, 'GUI', 'poster_sortby', 'name')
         POSTER_SORTDIR = check_setting_int(CFG, 'GUI', 'poster_sortdir', 1)
-        FILTER_ROW =  bool(check_setting_int(CFG, 'GUI', 'filter_row', 0))
+        FILTER_ROW =  bool(check_setting_int(CFG, 'GUI', 'filter_row', 1))
         DISPLAY_ALL_SEASONS = bool(check_setting_int(CFG, 'General', 'display_all_seasons', 1))
 
         # initialize NZB and TORRENT providers
@@ -2094,6 +2098,7 @@ def save_config():
     new_config['Subtitles']['embedded_subtitles_all'] = int(EMBEDDED_SUBTITLES_ALL)
     new_config['Subtitles']['subtitles_finder_frequency'] = int(SUBTITLES_FINDER_FREQUENCY)
     new_config['Subtitles']['subtitles_multi'] = int(SUBTITLES_MULTI)
+    new_config['Subtitles']['subtitles_extra_scripts'] = '|'.join(SUBTITLES_EXTRA_SCRIPTS)
 
     new_config['FailedDownloads'] = {}
     new_config['FailedDownloads']['use_failed_downloads'] = int(USE_FAILED_DOWNLOADS)
diff --git a/sickbeard/common.py b/sickbeard/common.py
index bccb2acf60c9eaa5b84a3453cda6b558acf08cb9..8946ad6b6ea3e1d045d45f6ac9a1b05c65ed0b19 100644
--- a/sickbeard/common.py
+++ b/sickbeard/common.py
@@ -22,9 +22,30 @@ import platform
 import re
 import uuid
 
+from random import shuffle
+
+SPOOF_USER_AGENT = False
+
+# If some provider has an issue with functionality of SR, other than user agents, it's best to come talk to us rather than block.
+# It is no different than us going to a provider if we have questions or issues. Be a team player here.
+# This is disabled, was only added for testing, and has no config.ini or web ui setting. To enable, set SPOOF_USER_AGENT = True
+user_agents = ['Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36'
+               'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2227.1 Safari/537.36'
+               'Mozilla/5.0 (Windows NT 6.3; rv:36.0) Gecko/20100101 Firefox/36.0'
+               'Mozilla/5.0 (X11; Linux i586; rv:31.0) Gecko/20100101 Firefox/31.0'
+               'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_3) AppleWebKit/537.75.14 (KHTML, like Gecko) Version/7.0.3 Safari/7046A194A'
+               'Mozilla/5.0 (iPad; CPU OS 6_0 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Version/6.0 Mobile/10A5355d Safari/8536.25'
+               'Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; AS; rv:11.0) like Gecko'
+               'Mozilla/5.0 (compatible, MSIE 11, Windows NT 6.3; Trident/7.0; rv:11.0) like Gecko'
+              ]
+
 INSTANCE_ID = str(uuid.uuid1())
 USER_AGENT = ('SickRage/(' + platform.system() + '; ' + platform.release() + '; ' + INSTANCE_ID + ')')
 
+if SPOOF_USER_AGENT:
+    shuffle(user_agents)
+    USER_AGENT = user_agents[0]
+
 mediaExtensions = ['avi', 'mkv', 'mpg', 'mpeg', 'wmv',
                    'ogm', 'mp4', 'iso', 'img', 'divx',
                    'm2ts', 'm4v', 'ts', 'flv', 'f4v',
diff --git a/sickbeard/databases/mainDB.py b/sickbeard/databases/mainDB.py
index afe0cfd7e1bb89b17720e33c597230f3e6fe85bb..2a09c9ad10355469d3bbe4894db7b1f289c7e75f 100644
--- a/sickbeard/databases/mainDB.py
+++ b/sickbeard/databases/mainDB.py
@@ -42,6 +42,7 @@ class MainSanityCheck(db.DBSanityCheck):
         self.fix_episode_statuses()
         self.fix_invalid_airdates()
         self.fix_subtitles_codes()
+        self.fix_show_nfo_lang()
 
     def fix_duplicate_shows(self, column='indexer_id'):
 
@@ -203,6 +204,8 @@ class MainSanityCheck(db.DBSanityCheck):
             self.connection.action("UPDATE tv_episodes SET subtitles = ?, subtitles_lastsearch = ? WHERE episode_id = ?;",
                 [','.join(langs), datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"), sqlResult['episode_id']])
 
+    def fix_show_nfo_lang(self):
+        self.connection.action("UPDATE tv_shows SET lang = '' WHERE lang = 0 or lang = '0'")
 
 def backupDatabase(version):
     logger.log(u"Backing up database before upgrade")
diff --git a/sickbeard/logger.py b/sickbeard/logger.py
index b991c9f6be4e3e7c30b5189c03709f4e819bb0bb..0172c6856c079bfd1d70e8b03bfe8f5adadc4ddf 100644
--- a/sickbeard/logger.py
+++ b/sickbeard/logger.py
@@ -135,8 +135,6 @@ class Logger(object):
         # pass exception information if debugging enabled
 
         if level == ERROR:
-            #Replace the SSL error with a link to information about how to fix it.
-            message = re.sub(r'error \[Errno 1\] _ssl.c:\d{3}: error:\d{8}:SSL routines:SSL23_GET_SERVER_HELLO:tlsv1 alert internal error', r'See: http://git.io/vJrkM', message)
             self.logger.exception(message, *args, **kwargs)
             classes.ErrorViewer.add(classes.UIError(message))
 
@@ -194,8 +192,11 @@ class Logger(object):
                     title_Error = str(curError.title)
                     if not len(title_Error) or title_Error == 'None':
                         title_Error = re.match("^[A-Z0-9\-\[\] :]+::\s*(.*)$", ek.ss(str(curError.message))).group(1)
-                    if len(title_Error) > 1024:
-                        title_Error = title_Error[0:1024]
+
+                    # if len(title_Error) > (1024 - len(u"[APP SUBMITTED]: ")):
+                    # 1000 just looks better than 1007 and adds some buffer
+                    if len(title_Error) > 1000:
+                        title_Error = title_Error[0:1000]
                 except Exception as e:
                     self.log("Unable to get error title : " + sickbeard.exceptions.ex(e), ERROR)
 
diff --git a/sickbeard/metadata/generic.py b/sickbeard/metadata/generic.py
index cf792484dcb51009080fd07c63858906c1e843ad..f3e2d4df55c907855bc510ff64539a0b35201613 100644
--- a/sickbeard/metadata/generic.py
+++ b/sickbeard/metadata/generic.py
@@ -708,12 +708,12 @@ class GenericMetadata():
             logger.log(u"Image already exists, not downloading", logger.DEBUG)
             return False
 
+        image_dir = ek.ek(os.path.dirname, image_path)
+        
         if not image_data:
-            logger.log(u"Unable to retrieve image, skipping", logger.WARNING)
+            logger.log(u"Unable to retrieve image to save in %s, skipping" % ek.ss(image_dir), logger.WARNING)
             return False
 
-        image_dir = ek.ek(os.path.dirname, image_path)
-
         try:
             if not ek.ek(os.path.isdir, image_dir):
                 logger.log(u"Metadata dir didn't exist, creating it at " + image_dir, logger.DEBUG)
diff --git a/sickbeard/postProcessor.py b/sickbeard/postProcessor.py
index 51f53ddfddd1deac11699be524513e75c19e7317..c66022ea08aacdade63c001d2ae49be50e8ab4cf 100644
--- a/sickbeard/postProcessor.py
+++ b/sickbeard/postProcessor.py
@@ -912,7 +912,7 @@ class PostProcessor(object):
         
         # try to find out if we have enough space to perform the copy or move action.
         if not helpers.isFileLocked(self.file_path, False):
-            if not verify_freespace(self.file_path, ek.ek(os.path.dirname, ep_obj.show._location), [ep_obj] + ep_obj.relatedEps):
+            if not verify_freespace(self.file_path, ep_obj.show._location, [ep_obj] + ep_obj.relatedEps):
                 self._log("Not enough space to continue PP, exiting")
                 return False
         else:
diff --git a/sickbeard/providers/__init__.py b/sickbeard/providers/__init__.py
index 6fcf33dcd4905f0d048fe8684a56f9e010c8faeb..32a1d0f5bd087e263994de02e01df13b8448a9d3 100644
--- a/sickbeard/providers/__init__.py
+++ b/sickbeard/providers/__init__.py
@@ -216,7 +216,6 @@ def getDefaultNewznabProviders():
     #name|url|key|catIDs|enabled|search_mode|search_fallback|enable_daily|enable_backlog
     return 'NZB.Cat|https://nzb.cat/||5030,5040,5010|0|eponly|1|1|1!!!' + \
            'NZBGeek|https://api.nzbgeek.info/||5030,5040|0|eponly|0|0|0!!!' + \
-           'Sick Beard Index|http://lolo.sickbeard.com/|0|5030,5040|0|eponly|0|0|0!!!' + \
            'NZBs.org|https://nzbs.org/||5030,5040|0|eponly|0|0|0!!!' + \
            'Usenet-Crawler|https://www.usenet-crawler.com/||5030,5040|0|eponly|0|0|0'
 
diff --git a/sickbeard/providers/newznab.py b/sickbeard/providers/newznab.py
index a9f18435cb0e4eb8069c19b8d26da7f805c06ffc..501331fd7e20c365278d256451914fcc213f06d1 100644
--- a/sickbeard/providers/newznab.py
+++ b/sickbeard/providers/newznab.py
@@ -279,6 +279,9 @@ class NewznabProvider(generic.NZBProvider):
         results = []
         offset = total = 0
 
+        if 'lolo.sickbeard.com' in self.url and params['maxage'] < 33:
+            params['maxage'] = 33
+
         while (total >= offset):
             search_url = self.url + 'api?' + urllib.urlencode(params)
 
@@ -379,6 +382,9 @@ class NewznabCache(tvcache.TVCache):
                   "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
 
diff --git a/sickbeard/show_queue.py b/sickbeard/show_queue.py
index 29f27f0608b777409a6d9100ca7f56bbb0a7c01d..df0c9475cfb287145f6cd54c71aa967f5f827dea 100644
--- a/sickbeard/show_queue.py
+++ b/sickbeard/show_queue.py
@@ -216,14 +216,14 @@ class QueueItemAdd(ShowQueueItem):
         if sickbeard.TRAKT_USE_ROLLING_DOWNLOAD and sickbeard.USE_TRAKT:
             self.paused = sickbeard.TRAKT_ROLLING_ADD_PAUSED
 
-        # Process add show in priority
-        self.priority = generic_queue.QueuePriorities.HIGH
-
         self.show = None
 
         # this will initialize self.show to None
         ShowQueueItem.__init__(self, ShowQueueActions.ADD, self.show)
 
+        # Process add show in priority
+        self.priority = generic_queue.QueuePriorities.HIGH
+
     def _getName(self):
         """
         Returns the show name if there is a show object created, if not returns
@@ -319,12 +319,12 @@ class QueueItemAdd(ShowQueueItem):
                     self.show.release_groups.set_white_keywords(self.whitelist)
                     
             # be smartish about this
-            if self.show.genre and "talk show" in self.show.genre.lower():
-                self.show.air_by_date = 1
-            if self.show.genre and "documentary" in self.show.genre.lower():
-                self.show.air_by_date = 0
-            if self.show.classification and "sports" in self.show.classification.lower():
-                self.show.sports = 1
+            #if self.show.genre and "talk show" in self.show.genre.lower():
+            #    self.show.air_by_date = 1
+            #if self.show.genre and "documentary" in self.show.genre.lower():
+            #    self.show.air_by_date = 0
+            #if self.show.classification and "sports" in self.show.classification.lower():
+            #    self.show.sports = 1
 
         except sickbeard.indexer_exception, e:
             logger.log(
@@ -438,7 +438,7 @@ class QueueItemRefresh(ShowQueueItem):
         ShowQueueItem.__init__(self, ShowQueueActions.REFRESH, show)
 
         # do refreshes first because they're quick
-        self.priority = generic_queue.QueuePriorities.HIGH
+        self.priority = generic_queue.QueuePriorities.NORMAL
 
         # force refresh certain items
         self.force = force
diff --git a/sickbeard/subtitles.py b/sickbeard/subtitles.py
index afb63ff7b9cefbea39bf87000f3aa06057dbf866..ebb0211533f6a84b95fdbaa3bcde81c670569d8f 100644
--- a/sickbeard/subtitles.py
+++ b/sickbeard/subtitles.py
@@ -20,6 +20,7 @@ import time
 import datetime
 import sickbeard
 from sickbeard.common import *
+from sickbeard.exceptions import ex
 from sickbeard import notifiers
 from sickbeard import logger
 from sickbeard import encodingKludge as ek
@@ -27,6 +28,7 @@ from sickbeard import db
 from sickbeard import history
 import subliminal
 import babelfish
+import subprocess
 
 subliminal.cache_region.configure('dogpile.cache.memory')
 
@@ -200,3 +202,32 @@ class SubtitlesFinder():
         - the number of searches done so far (searchcount), represented by the index of the list
         """
         return {'old': [0, 24], 'new': [0, 4, 8, 4, 16, 24, 24]}
+
+
+def run_subs_extra_scripts(epObj, foundSubs):
+
+    for curScriptName in sickbeard.SUBTITLES_EXTRA_SCRIPTS:
+        script_cmd = [piece for piece in re.split("( |\\\".*?\\\"|'.*?')", curScriptName) if piece.strip()]
+        script_cmd[0] = ek.ek(os.path.abspath, script_cmd[0])
+        logger.log(u"Absolute path to script: " + script_cmd[0], logger.DEBUG)
+
+        for video, subs in foundSubs.iteritems():
+            subpaths = []
+            for sub in subs:
+                subpath = subliminal.subtitle.get_subtitle_path(video.name, sub.language)
+                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))
+
+                inner_cmd = script_cmd + [video.name] + [subpath] + [sub.language.opensubtitles] + [epObj.show.name] + \
+                                         [epObj.season] + [epObj.episode] + [epObj.name]
+
+                # use subprocess to run the command and capture output
+                logger.log(u"Executing command: %s" % inner_cmd)
+                try:
+                    p = subprocess.Popen(inner_cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE,
+                            stderr=subprocess.STDOUT, cwd=sickbeard.PROG_DIR)
+                    out, err = p.communicate()  # @UnusedVariable
+                    logger.log(u"Script result: %s" % out, logger.DEBUG)
+
+                except Exception as e:
+                    logger.log(u"Unable to run subs_extra_script: " + ex(e))
diff --git a/sickbeard/traktChecker.py b/sickbeard/traktChecker.py
index 85f00b5bf55a5f603e50f332acd9905dffe68252..cfe667cfe67ab3105ff5c99ca0350029c3b9c822 100644
--- a/sickbeard/traktChecker.py
+++ b/sickbeard/traktChecker.py
@@ -46,7 +46,7 @@ def setEpisodeToWanted(show, s, e):
             if epObj.status != SKIPPED or epObj.airdate == datetime.date.fromordinal(1):
                 return
 
-            logger.log(u"Setting episode s" + str(s) + "e" + str(e) + " of show " + show.name + " to wanted")
+            logger.log(u"Setting episode %s S%02dE%02d to wanted" %(show.name, s, e))
             # figure out what segment the episode is in and remember it so we can backlog it
 
             epObj.status = WANTED
@@ -55,8 +55,7 @@ def setEpisodeToWanted(show, s, e):
         cur_backlog_queue_item = search_queue.BacklogQueueItem(show, [epObj])
         sickbeard.searchQueueScheduler.action.add_item(cur_backlog_queue_item)
 
-        logger.log(u"Starting backlog for " + show.name + " season " + str(
-                s) + " episode " + str(e) + " because some eps were set to wanted")
+        logger.log(u"Starting backlog search for %s S%02dE%02d because some episodes were set to wanted" % (show.name, s, e))
 
 
 class TraktChecker():
@@ -192,7 +191,8 @@ class TraktChecker():
                     trakt_id = sickbeard.indexerApi(cur_episode["indexer"]).config['trakt_id']
                     if self._checkInList(trakt_id,str(cur_episode["showid"]),str(cur_episode["season"]),str(cur_episode["episode"]), List='Collection'):
                         if cur_episode["location"] == '':
-                            logger.log(u"Removing Episode: Indexer %s %s - %s - S%sE%s from Collection" % (trakt_id,str(cur_episode["showid"]), cur_episode["show_name"],str(cur_episode["season"]),str(cur_episode["episode"])), logger.DEBUG)
+                            logger.log(u"Removing Episode %s S%02dE%02d from collection" %
+                            (cur_episode["show_name"],cur_episode["season"],cur_episode["episode"]), logger.DEBUG)
                             trakt_data.append((cur_episode["showid"],cur_episode["indexer"],cur_episode["show_name"],cur_episode["startyear"],cur_episode["season"], cur_episode["episode"]))
 
             if len(trakt_data):
@@ -214,7 +214,8 @@ class TraktChecker():
                 for cur_episode in episodes:
                     trakt_id = sickbeard.indexerApi(cur_episode["indexer"]).config['trakt_id']
                     if not self._checkInList(trakt_id,str(cur_episode["showid"]),str(cur_episode["season"]),str(cur_episode["episode"]), List='Collection'):
-                        logger.log(u"Adding Episode: Indexer %s %s - %s - S%sE%s to Collection" % (trakt_id,str(cur_episode["showid"]), cur_episode["show_name"],str(cur_episode["season"]),str(cur_episode["episode"])), logger.DEBUG)                   
+                        logger.log(u"Adding Episode %s S%02dE%02d to collection" %
+                        (cur_episode["show_name"],cur_episode["season"],cur_episode["episode"]), logger.DEBUG)
                         trakt_data.append((cur_episode["showid"],cur_episode["indexer"],cur_episode["show_name"],cur_episode["startyear"],cur_episode["season"], cur_episode["episode"]))
 
                 if len(trakt_data):
@@ -252,7 +253,8 @@ class TraktChecker():
                     trakt_id = sickbeard.indexerApi(cur_episode["indexer"]).config['trakt_id']
                     if self._checkInList(trakt_id,str(cur_episode["showid"]),str(cur_episode["season"]),str(cur_episode["episode"])):
                         if cur_episode["status"] not in Quality.SNATCHED + Quality.SNATCHED_PROPER + [UNKNOWN] + [WANTED]:
-                            logger.log(u"Removing Episode: Indexer %s %s - %s - S%sE%s from Watchlist" % (trakt_id,str(cur_episode["showid"]), cur_episode["show_name"],str(cur_episode["season"]),str(cur_episode["episode"])), logger.DEBUG)
+                            logger.log(u"Removing Episode %s S%02dE%02d from watchlist" %
+                            (cur_episode["show_name"],cur_episode["season"],cur_episode["episode"]), logger.DEBUG)
                             trakt_data.append((cur_episode["showid"],cur_episode["indexer"],cur_episode["show_name"],cur_episode["startyear"],cur_episode["season"], cur_episode["episode"]))
 
             if len(trakt_data):
@@ -274,7 +276,8 @@ class TraktChecker():
                 for cur_episode in episodes:
                     trakt_id = sickbeard.indexerApi(cur_episode["indexer"]).config['trakt_id']
                     if not self._checkInList(trakt_id,str(cur_episode["showid"]),str(cur_episode["season"]),str(cur_episode["episode"])):
-                        logger.log(u"Adding Episode: Indexer %s %s - %s - S%sE%s to Watchlist" % (trakt_id,str(cur_episode["showid"]), cur_episode["show_name"],str(cur_episode["season"]),str(cur_episode["episode"])), logger.DEBUG)                     
+                        logger.log(u"Adding Episode %s S%02dE%02d to watchlist" %
+                        (cur_episode["show_name"],cur_episode["season"],cur_episode["episode"]), logger.DEBUG)                     
                         trakt_data.append((cur_episode["showid"],cur_episode["indexer"],cur_episode["show_name"],cur_episode["startyear"],cur_episode["season"], cur_episode["episode"]))
 
                 if len(trakt_data):
@@ -786,7 +789,7 @@ class TraktRolling():
                 if epObj.status != SKIPPED:
                     return
 
-                logger.log(u"Setting episode s" + str(s) + "e" + str(e) + " of show " + show.name + " to " + statusStrings[sickbeard.EP_DEFAULT_DELETED_STATUS])
+                logger.log(u"Setting episode %s S%02dE%02d to %s " % (show.name, s, e, statusStrings[sickbeard.EP_DEFAULT_DELETED_STATUS] ))
 
                 epObj.status = sickbeard.EP_DEFAULT_DELETED_STATUS
                 epObj.saveToDB()
diff --git a/sickbeard/tv.py b/sickbeard/tv.py
index 260a06b1ca5ef74cebc9ee755b321990da88ce4c..7f48acf1a1226288e4c43af989bf89379482eff2 100644
--- a/sickbeard/tv.py
+++ b/sickbeard/tv.py
@@ -263,8 +263,7 @@ class TVShow(object):
                 episode = int(sqlResults[0]["episode"])
                 season = int(sqlResults[0]["season"])
                 logger.log(
-                    "Found episode by absolute_number:" + str(absolute_number) + " which is " + str(season) + "x" + str(
-                        episode), logger.DEBUG)
+                    "Found episode by absolute_number %s which is S%02dE%02d" % (absolute_number, season, episode), logger.DEBUG)
             elif len(sqlResults) > 1:
                 logger.log("Multiple entries for absolute number: " + str(
                     absolute_number) + " in show: " + self.name + " found ", logger.ERROR)
@@ -282,8 +281,7 @@ class TVShow(object):
             if noCreate:
                 return None
 
-            logger.log(str(self.indexerid) + u": An object for episode " + str(season) + "x" + str(
-                episode) + " didn't exist in the cache, trying to create it", logger.DEBUG)
+            logger.log(str(self.indexerid) + u": An object for episode S%02dE%02d didn't exist in the cache, trying to create it" % (season, episode), logger.DEBUG)
 
             if file:
                 ep = TVEpisode(self, season, episode, file)
@@ -376,8 +374,7 @@ class TVShow(object):
         sqlResults = myDB.select("SELECT * FROM tv_episodes WHERE showid = ? AND location != ''", [self.indexerid])
 
         for epResult in sqlResults:
-            logger.log(str(self.indexerid) + u": Retrieving/creating episode " + str(epResult["season"]) + "x" + str(
-                epResult["episode"]), logger.DEBUG)
+            logger.log(str(self.indexerid) + u": Retrieving/creating episode S%02dE%02d" % (epResult["season"], epResult["episode"]), logger.DEBUG)
             curEp = self.getEpisode(epResult["season"], epResult["episode"])
             if not curEp:
                 continue
@@ -514,7 +511,7 @@ class TVShow(object):
             if not curSeason in scannedEps:
                 scannedEps[curSeason] = {}
 
-            logger.log(u"Loading episode " + str(curSeason) + "x" + str(curEpisode) + " from the DB", logger.DEBUG)
+            logger.log(u"Loading episode S%02dE%02d from the DB" % (curSeason, curEpisode), logger.DEBUG)
 
             try:
                 curEp = self.getEpisode(curSeason, curEpisode)
@@ -574,9 +571,7 @@ class TVShow(object):
                     if not ep:
                         raise exceptions.EpisodeNotFoundException
                 except exceptions.EpisodeNotFoundException:
-                    logger.log(
-                        str(self.indexerid) + ": " + sickbeard.indexerApi(self.indexer).name + " object for " + str(
-                            season) + "x" + str(episode) + " is incomplete, skipping this episode")
+                    logger.log("%s: %s object for S%02dE%02d is incomplete, skipping this episode" % (self.indexerid, sickbeard.indexerApi(self.indexer).name, season, episode))
                     continue
                 else:
                     try:
@@ -586,8 +581,7 @@ class TVShow(object):
                         continue
 
                 with ep.lock:
-                    logger.log(str(self.indexerid) + u": Loading info from " + sickbeard.indexerApi(
-                        self.indexer).name + " for episode " + str(season) + "x" + str(episode), logger.DEBUG)
+                    logger.log("%s: Loading info from %s for episode S%02dE%02d" % (self.indexerid, sickbeard.indexerApi(self.indexer).name, season, episode),logger.DEBUG)
                     ep.loadFromIndexer(season, episode, tvapi=t)
 
                     sql_l.append(ep.get_sql())
@@ -645,7 +639,7 @@ class TVShow(object):
 
         if not len(parse_result.episode_numbers):
             logger.log("parse_result: " + str(parse_result))
-            logger.log(u"No episode number found in " + file + ", ignoring it", logger.ERROR)
+            logger.log(u"No episode number found in " + file + ", ignoring it", logger.WARNING)
             return None
 
         # for now lets assume that any episode in the show dir belongs to that show
@@ -658,9 +652,7 @@ class TVShow(object):
 
             episode = int(curEpNum)
 
-            logger.log(
-                str(self.indexerid) + ": " + file + " parsed to " + self.name + " " + str(season) + "x" + str(episode),
-                logger.DEBUG)
+            logger.log("%s: %s parsed to %s S%02dE%02d" % (self.indexerid, file, self.name, season, episode), logger.DEBUG)
 
             checkQualityAgain = False
             same_file = False
@@ -987,8 +979,7 @@ class TVShow(object):
                            logger.DEBUG)
                 self.nextaired = ""
             else:
-                logger.log(str(self.indexerid) + u": Found episode " + str(sqlResults[0]["season"]) + "x" + str(
-                    sqlResults[0]["episode"]), logger.DEBUG)
+                logger.log(u"%s: Found episode S%02dE%02d" % (self.indexerid, sqlResults[0]["season"], sqlResults[0]["episode"] ) , logger.DEBUG)
                 self.nextaired = sqlResults[0]['airdate']
 
         return self.nextaired
@@ -1099,9 +1090,8 @@ class TVShow(object):
                     with curEp.lock:
                         # if it used to have a file associated with it and it doesn't anymore then set it to sickbeard.EP_DEFAULT_DELETED_STATUS
                         if curEp.location and curEp.status in Quality.DOWNLOADED:
-                            logger.log(str(self.indexerid) + u": Location for " + str(season) + "x" + str(
-                                episode) + " doesn't exist, removing it and changing our status to " + statusStrings[sickbeard.EP_DEFAULT_DELETED_STATUS],
-                                       logger.DEBUG)
+                            logger.log(u"%s: Location for S%02dE%02d doesn't exist, removing it and changing our status to %s" % 
+                            (self.indexerid, season, episode, statusStrings[sickbeard.EP_DEFAULT_DELETED_STATUS]) ,logger.DEBUG)
                             curEp.status = sickbeard.EP_DEFAULT_DELETED_STATUS
                             curEp.subtitles = list()
                             curEp.subtitles_searchcount = 0
@@ -1233,8 +1223,7 @@ class TVShow(object):
 
     def wantEpisode(self, season, episode, quality, manualSearch=False, downCurQuality=False):
 
-        logger.log(u"Checking if found episode " + "S" + str(season).zfill(2) + "E" + str(episode).zfill(2) + " is wanted at quality " +
-                   Quality.qualityStrings[quality], logger.DEBUG)
+        logger.log(u"Checking if found episode %s S%02dE%02d is wanted at quality %s" % (self.name, season, episode, Quality.qualityStrings[quality]) , logger.DEBUG)
 
         # if the quality isn't one we want under any circumstances then just say no
         anyQualities, bestQualities = Quality.splitQuality(self.quality)
@@ -1480,6 +1469,17 @@ class TVEpisode(object):
 
             subliminal.save_subtitles(foundSubs, directory=subs_new_path, single=not sickbeard.SUBTITLES_MULTI)
 
+            for video, subs in foundSubs.iteritems():
+                for sub in subs:
+                    subpath = subliminal.subtitle.get_subtitle_path(video.name, sub.language)
+                    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)
+                    helpers.fixSetGroupID(subpath)
+
+            if not sickbeard.EMBEDDED_SUBTITLES_ALL and sickbeard.SUBTITLES_EXTRA_SCRIPTS and self.location.endswith(('mkv','mp4')):
+                subtitles.run_subs_extra_scripts(self, foundSubs)
+
         except Exception as e:
             logger.log("Error occurred when downloading subtitles for: %s" % self.location)
             logger.log(traceback.format_exc(), logger.ERROR)
@@ -1550,8 +1550,7 @@ class TVEpisode(object):
                 try:
                     self.loadFromNFO(self.location)
                 except exceptions.NoNFOException:
-                    logger.log(str(self.show.indexerid) + u": There was an error loading the NFO for episode " + str(
-                        season) + "x" + str(episode), logger.ERROR)
+                    logger.log(u"%s: There was an error loading the NFO for episode S%02dE%02d" % (self.show.indexerid, season, episode), logger.ERROR)
                     pass
 
                 # if we tried loading it from NFO and didn't find the NFO, try the Indexers
@@ -1563,13 +1562,10 @@ class TVEpisode(object):
 
                     # if we failed SQL *and* NFO, Indexers then fail
                     if not result:
-                        raise exceptions.EpisodeNotFoundException(
-                            "Couldn't find episode " + str(season) + "x" + str(episode))
+                        raise exceptions.EpisodeNotFoundException("Couldn't find episode S%02dE%02d" % (season, episode))
 
     def loadFromDB(self, season, episode):
-        logger.log(
-            str(self.show.indexerid) + u": Loading episode details from DB for episode " + str(season) + "x" + str(
-                episode), logger.DEBUG)
+        logger.log(u"%s: Loading episode details from DB for episode %s S%02dE%02d" % (self.show.indexerid, self.show.name, season, episode), logger.DEBUG)
 
         myDB = db.DBConnection()
         sqlResults = myDB.select("SELECT * FROM tv_episodes WHERE showid = ? AND season = ? AND episode = ?",
@@ -1578,8 +1574,7 @@ class TVEpisode(object):
         if len(sqlResults) > 1:
             raise exceptions.MultipleDBEpisodesException("Your DB has two records for the same show somehow.")
         elif len(sqlResults) == 0:
-            logger.log(str(self.show.indexerid) + u": Episode " + str(self.season) + "x" + str(
-                self.episode) + " not found in the database", logger.DEBUG)
+            logger.log(u"%s: Episode S%02dE%02d not found in the database" % (self.show.indexerid, self.season, self.episode), logger.DEBUG)
             return False
         else:
             # NAMEIT logger.log(u"AAAAA from" + str(self.season)+"x"+str(self.episode) + " -" + self.name + " to " + str(sqlResults[0]["name"]))
@@ -1664,8 +1659,7 @@ class TVEpisode(object):
         if episode is None:
             episode = self.episode
 
-        logger.log(str(self.show.indexerid) + u": Loading episode details from " + sickbeard.indexerApi(
-            self.show.indexer).name + " for episode " + str(season) + "x" + str(episode), logger.DEBUG)
+        logger.log(u"%s: Loading episode details from %s for episode S%02dE%02d" % (sickbeard.indexerApi(self.show.indexer).name, season, episode) , logger.DEBUG)
 
         indexer_lang = self.show.lang
 
@@ -1711,21 +1705,16 @@ class TVEpisode(object):
             return
 
         if getattr(myEp, 'episodename', None) is None:
-            logger.log(u"This episode (" + self.show.name + " - " + str(season) + "x" + str(
-                episode) + ") has no name on " + sickbeard.indexerApi(self.indexer).name + "")
+            logger.log(u"This episode %s - S%02dE%02d has no name on %s" %(self.show.name, season, episode, sickbeard.indexerApi(self.indexer).name))
             # if I'm incomplete on TVDB but I once was complete then just delete myself from the DB for now
             if self.indexerid != -1:
                 self.deleteEpisode()
             return False
 
         if getattr(myEp, 'absolute_number', None) is None:
-            logger.log(u"This episode (" + self.show.name + " - " + str(season) + "x" + str(
-                episode) + ") has no absolute number on " + sickbeard.indexerApi(
-                self.indexer).name, logger.DEBUG)
+            logger.log(u"This episode %s - S%02dE%02d has no absolute number on %s" %(self.show.name, season, episode, sickbeard.indexerApi(self.indexer).name), logger.DEBUG)
         else:
-            logger.log(
-                str(self.show.indexerid) + ": The absolute_number for " + str(season) + "x" + str(episode) + " is : " +
-                str(myEp["absolute_number"]), logger.DEBUG)
+            logger.log(u"%s: The absolute_number for S%02dE%02d is: %s " % (self.show.indexerid, season, episode, myEp["absolute_number"]), logger.DEBUG)
             self.absolute_number = int(myEp["absolute_number"])
 
         self.name = getattr(myEp, 'episodename', "")
@@ -1756,9 +1745,7 @@ class TVEpisode(object):
         try:
             self.airdate = datetime.date(rawAirdate[0], rawAirdate[1], rawAirdate[2])
         except (ValueError, IndexError):
-            logger.log(u"Malformed air date of " + str(firstaired) + " retrieved from " + sickbeard.indexerApi(
-                self.indexer).name + " for (" + self.show.name + " - " + str(season) + "x" + str(episode) + ")",
-                       logger.WARNING)
+            logger.log(u"Malformed air date of %s retrieved from %s for (%s - S%02dE%02d)" % (firstaired, sickbeard.indexerApi(self.indexer).name, self.show.name, season, episode),logger.WARNING)
             # if I'm incomplete on the indexer but I once was complete then just delete myself from the DB for now
             if self.indexerid != -1:
                 self.deleteEpisode()
@@ -1775,8 +1762,7 @@ class TVEpisode(object):
         # don't update show status if show dir is missing, unless it's missing on purpose
         if not ek.ek(os.path.isdir,
                      self.show._location) and not sickbeard.CREATE_MISSING_SHOW_DIRS and not sickbeard.ADD_SHOWS_WO_DIR:
-            logger.log(
-                u"The show dir " + str(self.show._location) + " is missing, not bothering to change the episode statuses since it'd probably be invalid")
+            logger.log(u"The show dir %s is missing, not bothering to change the episode statuses since it'd probably be invalid" % self.show._location )
             return
 
         if self.location:
@@ -1850,10 +1836,7 @@ class TVEpisode(object):
                     if epDetails.findtext('season') is None or int(epDetails.findtext('season')) != self.season or \
                                     epDetails.findtext('episode') is None or int(
                             epDetails.findtext('episode')) != self.episode:
-                        logger.log(str(
-                            self.show.indexerid) + u": NFO has an <episodedetails> block for a different episode - wanted " + str(
-                            self.season) + "x" + str(self.episode) + " but got " + str(
-                            epDetails.findtext('season')) + "x" + str(epDetails.findtext('episode')), logger.DEBUG)
+                        logger.log(u": NFO has an <episodedetails> block for a different episode - wanted S%02dE%02d but got S%02dE%02d" % (self.show.indexerid, self.season, self.episode, epDetails.findtext('season'), epDetails.findtext('episode') ), logger.DEBUG)
                         continue
 
                     if epDetails.findtext('title') is None or epDetails.findtext('aired') is None:
@@ -1899,8 +1882,7 @@ class TVEpisode(object):
     def __str__(self):
 
         toReturn = ""
-        toReturn += str(self.show.name) + " - " + str(self.season) + "x" + str(self.episode) + " - " + str(
-            self.name) + "\n"
+        toReturn += "%s - S%02dE%02d - %s " % (self.show.name, self.season, self.episode, self.name ) + "\n"
         toReturn += "location: " + str(self.location) + "\n"
         toReturn += "description: " + str(self.description) + "\n"
         toReturn += "subtitles: " + str(",".join(self.subtitles)) + "\n"
@@ -1944,8 +1926,7 @@ class TVEpisode(object):
 
     def deleteEpisode(self):
 
-        logger.log(u"Deleting " + self.show.name + " " + str(self.season) + "x" + str(self.episode) + " from the DB",
-                   logger.DEBUG)
+        logger.log(u"Deleting %s S%02dE%02dfrom the DB" % (self.show.name, self.season, self.episode), logger.DEBUG)
 
         # remove myself from the show dictionary
         if self.show.getEpisode(self.season, self.episode, noCreate=True) == self:
diff --git a/sickbeard/webapi.py b/sickbeard/webapi.py
index 51fb8938a2d3744e5ac5f8cf122c1b8b3aa629f7..d7c90d58cad7049504230deacc58b77ce0d4d1b4 100644
--- a/sickbeard/webapi.py
+++ b/sickbeard/webapi.py
@@ -175,7 +175,7 @@ class ApiHandler(RequestHandler):
                     cmd, cmdIndex = cmd.split("_")  # this gives us the clear cmd and the index
 
                 logger.log(u"API :: " + cmd + ": curKwargs " + str(curKwargs), logger.DEBUG)
-                if not (multiCmds and cmd in ('show.getposter', 'show.getbanner', 'show.getnetworklogo')):  # skip these cmd while chaining
+                if not (multiCmds and cmd in ('show.getbanner', 'show.getfanart', 'show.getnetworklogo', 'show.getposter')):  # skip these cmd while chaining
                     try:
                         if cmd in _functionMaper:
                             # map function
@@ -1100,11 +1100,10 @@ class CMD_SubtitleSearch(ApiCall):
             return _responds(RESULT_FAILURE, msg='Unable to find subtitles')
 
         # return the correct json value
-        if previous_subtitles != epObj.subtitles:
-            status = 'New subtitles downloaded: %s' % ' '.join([
-                "<img src='" + sickbeard.WEB_ROOT + "/images/flags/" + babelfish.language.Language(
-                    x).alpha2 + ".png' alt='" + babelfish.language.Language(x).name + "'/>" for x in
-                sorted(list(set(epObj.subtitles).difference(previous_subtitles)))])
+        newSubtitles = frozenset(ep_obj.subtitles).difference(previous_subtitles)
+        if newSubtitles:
+            newLangs = [subtitles.fromietf(newSub) for newSub in newSubtitles]
+            status = 'New subtitles downloaded: %s' % ', '.join([newLang.name for newLang in newLangs])
             response = _responds(RESULT_SUCCESS, msg='New subtitles found')
         else:
             status = 'No subtitles downloaded'
@@ -2447,6 +2446,7 @@ class CMD_ShowGetBanner(ApiCall):
         """ get the banner for a show in sickrage """
         return {'outputType': 'image', 'image': self.rh.showPoster(self.indexerid, 'banner')}
 
+
 class CMD_ShowGetNetworkLogo(ApiCall):
     _help = {
         "desc": "Get the network logo stored for a show in SickRage",
@@ -2481,6 +2481,34 @@ class CMD_ShowGetNetworkLogo(ApiCall):
             'image': self.rh.showNetworkLogo(self.indexerid)
         }
 
+
+class CMD_ShowGetFanArt(ApiCall):
+    _help = {
+        "desc": "Get the fan art stored for a show in SickRage",
+        "requiredParameters": {
+            "indexerid": {"desc": "Unique id of a show"}
+        },
+        "optionalParameters": {
+            "tvdbid": {"desc": "thetvdb.com unique id of a show"},
+            "tvrageid": {"desc": "tvrage.com unique id of a show"},
+        },
+    }
+
+    def __init__(self, args, kwargs):
+        # required
+        self.indexerid, args = self.check_params(args, kwargs, "indexerid", None, True, "int", [])
+        # optional
+        # super, missing, help
+        ApiCall.__init__(self, args, kwargs)
+
+    def run(self):
+        """ Get the fan art for a show in SickRage """
+        return {
+            'outputType': 'image',
+            'image': self.rh.showPoster(self.indexerid, 'fanart')
+        }
+
+
 class CMD_ShowPause(ApiCall):
     _help = {"desc": "set a show's paused state in sickrage",
              "requiredParameters": {
@@ -3012,6 +3040,7 @@ _functionMaper = {"help": CMD_Help,
                   "show.getposter": CMD_ShowGetPoster,
                   "show.getbanner": CMD_ShowGetBanner,
                   "show.getnetworklogo": CMD_ShowGetNetworkLogo,
+                  "show.getfanart": CMD_ShowGetFanArt,
                   "show.pause": CMD_ShowPause,
                   "show.refresh": CMD_ShowRefresh,
                   "show.seasonlist": CMD_ShowSeasonList,
diff --git a/sickbeard/webserve.py b/sickbeard/webserve.py
index 45060b32bb854c5d73239b752da94ecf2fb0bf9a..1ac8621b1435b260a2bac5e1f60ae3c0ea92ac23 100644
--- a/sickbeard/webserve.py
+++ b/sickbeard/webserve.py
@@ -2157,6 +2157,20 @@ class Home(WebRoot):
 
         return json.dumps({'result': 'failure'})            
 
+@route('/IRC(/?.*)')
+class HomeIRC(Home):
+    def __init__(self, *args, **kwargs):
+        super(HomeIRC, self).__init__(*args, **kwargs)
+
+    def index(self):
+
+        t = PageTemplate(rh=self, file="IRC.tmpl")
+        t.submenu = self.HomeMenu()
+        t.title = "IRC"
+        t.header = "IRC"
+        t.topmenu = "IRC"
+        return t.respond()
+
 @route('/news(/?.*)')
 class HomeNews(Home):
     def __init__(self, *args, **kwargs):
@@ -4928,7 +4942,7 @@ class ConfigSubtitles(Config):
 
     def saveSubtitles(self, use_subtitles=None, subtitles_plugins=None, subtitles_languages=None, subtitles_dir=None,
                       service_order=None, subtitles_history=None, subtitles_finder_frequency=None,
-                      subtitles_multi=None, embedded_subtitles_all=None):
+                      subtitles_multi=None, embedded_subtitles_all=None, subtitles_extra_scripts=None):
 
         results = []
 
@@ -4940,6 +4954,7 @@ class ConfigSubtitles(Config):
         sickbeard.SUBTITLES_HISTORY = config.checkbox_to_value(subtitles_history)
         sickbeard.EMBEDDED_SUBTITLES_ALL = config.checkbox_to_value(embedded_subtitles_all)
         sickbeard.SUBTITLES_MULTI = config.checkbox_to_value(subtitles_multi)
+        sickbeard.SUBTITLES_EXTRA_SCRIPTS = [x.strip() for x in subtitles_extra_scripts.split('|') if x.strip()]
 
         # Subtitles services
         services_str_list = service_order.split()