diff --git a/SickBeard.py b/SickBeard.py
index ca0115142f2d5d4c029cf2b758d8e7304ff3f8d4..0e309aa6d2a1b768390ab440e0f4cd053024a447 100755
--- a/SickBeard.py
+++ b/SickBeard.py
@@ -18,9 +18,11 @@
 # along with SickRage.  If not, see <http://www.gnu.org/licenses/>.
 
 # Check needed software dependencies to nudge users to fix their setup
+
 from __future__ import with_statement
 
 import codecs
+
 codecs.register(lambda name: codecs.lookup('utf-8') if name == 'cp65001' else None)
 
 import time
@@ -56,7 +58,7 @@ from sickbeard.tv import TVShow
 from sickbeard.webserveInit import SRWebServer
 from sickbeard.event_queue import Events
 from configobj import ConfigObj
-from sickbeard import encodingKludge as ek
+from sickrage.helper.encoding import ek
 
 throwaway = datetime.datetime.strptime('20110101', '%Y%m%d')
 
@@ -112,25 +114,26 @@ class SickRage(object):
 
     def fix_clients_nonsense(self):
 
-        files = ["sickbeard/clients/download_station.py",
-                 "sickbeard/clients/utorrent.py",
-                 "sickbeard/clients/qbittorrent.py",
-                 "sickbeard/clients/transmission.py",
-                 "sickbeard/clients/deluge.py",
-                 "sickbeard/clients/deluged.py",
-                 "sickbeard/clients/rtorrent.py"
-                ]
+        files = [
+            "sickbeard/clients/download_station.py",
+            "sickbeard/clients/utorrent.py",
+            "sickbeard/clients/qbittorrent.py",
+            "sickbeard/clients/transmission.py",
+            "sickbeard/clients/deluge.py",
+            "sickbeard/clients/deluged.py",
+            "sickbeard/clients/rtorrent.py"
+        ]
 
         for file in files:
-            file = ek.ek(os.path.join, sickbeard.PROG_DIR, file)
+            file = ek(os.path.join, sickbeard.PROG_DIR, file)
             try:
-                if ek.ek(os.path.exists, file):
-                    ek.ek(os.remove, file)
+                if ek(os.path.exists, file):
+                    ek(os.remove, file)
             except:
                 pass
             try:
-                if ek.ek(os.path.exists, file + "c"):
-                    ek.ek(os.remove, file + "c")
+                if ek(os.path.exists, file + "c"):
+                    ek(os.remove, file + "c")
             except:
                 pass
 
diff --git a/gui/slick/images/providers/transmitthenet.png b/gui/slick/images/providers/transmitthenet.png
new file mode 100644
index 0000000000000000000000000000000000000000..bcb694d612edde157a2ccb1ab9b1d4c73b4a113d
Binary files /dev/null and b/gui/slick/images/providers/transmitthenet.png differ
diff --git a/gui/slick/images/providers/tvchaosuk.png b/gui/slick/images/providers/tvchaosuk.png
new file mode 100644
index 0000000000000000000000000000000000000000..d6e968a74235769a0eed64a01f171088da00a500
Binary files /dev/null and b/gui/slick/images/providers/tvchaosuk.png differ
diff --git a/gui/slick/js/confirmations.js b/gui/slick/js/confirmations.js
index 577fbfefb8ba9bbaff6034bf8746ce944ab00d9a..c12ff1509657d6c8d18c4e90f2f3cd3a59b3c3db 100644
--- a/gui/slick/js/confirmations.js
+++ b/gui/slick/js/confirmations.js
@@ -41,7 +41,7 @@ $(document).ready(function () {
 		});
 	});
 
-	$('a[href^="/home/deleteShow"]').on('click', function(e) {
+	$('a.removeshow').on('click', function(e) {
 		e.preventDefault();
 		var target = $(this).attr('href');
 		var showname = document.getElementById("showtitle").getAttribute('data-showname');
diff --git a/gui/slick/js/new/comingEpisodes.js b/gui/slick/js/new/comingEpisodes.js
index 35d890d7f6f0ff130d0113e0605c90e43bf457ba..a1c5a2d1fc3ac7c804fc2892ecc1a582dfc52df8 100644
--- a/gui/slick/js/new/comingEpisodes.js
+++ b/gui/slick/js/new/comingEpisodes.js
@@ -29,7 +29,7 @@ if($('meta[data-var="sickbeard.COMING_EPS_LAYOUT"]').data('content') == 'list'){
             return false
         },
         format: function(s) {
-            return s
+            return new Date(s).getTime()
         },
         type: 'numeric'
     });
@@ -45,7 +45,7 @@ $(document).ready(function(){
             widgets: ['stickyHeaders'],
             sortList: sortList,
             textExtraction: {
-                0: function(node) { return $(node).find('span').text().toLowerCase() },
+                0: function(node) { return $(node).find('time').attr('datetime') },
                 5: function(node) { return $(node).find('span').text().toLowerCase() }
             },
             headers: {
diff --git a/gui/slick/views/comingEpisodes.mako b/gui/slick/views/comingEpisodes.mako
index b4f4af2d335e52b81b174d9d737af59501eeec5e..fa1b562f193914fbfbab14f823b0cb448ef8107a 100644
--- a/gui/slick/views/comingEpisodes.mako
+++ b/gui/slick/views/comingEpisodes.mako
@@ -150,7 +150,7 @@
             </td>
 
             <td align="center">
-            ${renderQualityPill(cur_result['quality'])}
+                ${renderQualityPill(cur_result['quality'], showTitle=True)}
             </td>
 
             <td align="center" style="vertical-align: middle;">
@@ -323,7 +323,7 @@
 
                 <div class="clearfix">
                     <span class="title">Quality:</span>
-                ${renderQualityPill(cur_result['quality'])}
+                    ${renderQualityPill(cur_result['quality'], showTitle=True)}
                 </div>
             </td>
         </tr>
diff --git a/gui/slick/views/displayShow.mako b/gui/slick/views/displayShow.mako
index 453a77b3fa9a844a2a63348d5de894256375e375..605e371adf13157854ef38dbab35267244212300 100644
--- a/gui/slick/views/displayShow.mako
+++ b/gui/slick/views/displayShow.mako
@@ -209,10 +209,10 @@ $(document).ready(function(){
                     ${renderQualityPill(show.quality)}
                 % else:
                 % if anyQualities:
-                    <i>Initial:</i> ${", ".join([capture(renderQualityPill, x) for x in sorted(anyQualities)])}${("", "</br>")[bool(bestQualities)]}
+                    <i>Allowed:</i> ${", ".join([capture(renderQualityPill, x) for x in sorted(anyQualities)])}${("", "</br>")[bool(bestQualities)]}
                 % endif
                 % if bestQualities:
-                    <i>Replace with:</i> ${", ".join([capture(renderQualityPill, x) for x in sorted(bestQualities)])}
+                    <i>Preferred:</i> ${", ".join([capture(renderQualityPill, x) for x in sorted(bestQualities)])}
                 % endif
                 % endif
 
diff --git a/gui/slick/views/home.mako b/gui/slick/views/home.mako
index 35ac5b89d85cdf373bb31cffe7080e1b1a594854..a70a6dcd4d855c3f24d866c4eac858d4e6ddc8e5 100644
--- a/gui/slick/views/home.mako
+++ b/gui/slick/views/home.mako
@@ -245,7 +245,7 @@
                 </td>
 
                 <td class="show-table">
-            ${renderQualityPill(curShow.quality, overrideClass="show-quality")}
+                    ${renderQualityPill(curShow.quality, showTitle=True, overrideClass="show-quality")}
                 </td>
             </tr>
         </table>
@@ -437,7 +437,7 @@
         </td>
     % endif
 
-        <td align="center">${renderQualityPill(curShow.quality)}</td>
+        <td align="center">${renderQualityPill(curShow.quality, showTitle=True)}</td>
 
         <td align="center">
             ## This first span is used for sorting and is never displayed to user
diff --git a/gui/slick/views/inc_defs.mako b/gui/slick/views/inc_defs.mako
index 2d44ac5b3e7bd5c313209ba9c82f727a5e3aaaf3..8a339ba4fd52032c923267639f50abbb7c88f540 100644
--- a/gui/slick/views/inc_defs.mako
+++ b/gui/slick/views/inc_defs.mako
@@ -1,7 +1,34 @@
 <%!
+    import cgi
     from sickbeard.common import Quality, qualityPresets, qualityPresetStrings
 %>
-<%def name="renderQualityPill(quality, overrideClass=None)"><%
+<%def name="renderQualityPill(quality, showTitle=False, overrideClass=None)"><%
+    iQuality = quality & 0xFFFF
+    pQuality = quality >> 16
+
+    # If initial and preferred qualities are the same, show pill as initial quality
+    if iQuality == pQuality:
+        quality = iQuality
+
+    # Build a string of quality names to use as title attribute
+    if showTitle:
+        iQuality, pQuality = Quality.splitQuality(quality)
+        title = 'Initial Quality:\n'
+        if iQuality:
+            for curQual in iQuality:
+                title += "  " + Quality.qualityStrings[curQual] + "\n"
+        else:
+            title += "  None\n"
+        title += "\nPreferred Quality:\n"
+        if pQuality:
+            for curQual in pQuality:
+                title += "  " + Quality.qualityStrings[curQual] + "\n"
+        else:
+            title += "  None\n"
+        title = ' title="' + cgi.escape(title.rstrip(), True) + '"'
+    else:
+        title = ""
+
     if quality in qualityPresets:
         cssClass = qualityPresetStrings[quality]
         qualityString = qualityPresetStrings[quality]
@@ -20,4 +47,4 @@
     else:
         cssClass = overrideClass
 
-%><span class="${cssClass}">${qualityString}</span></%def>
+%><span${title} class="${cssClass}">${qualityString}</span></%def>
diff --git a/gui/slick/views/manage.mako b/gui/slick/views/manage.mako
index eada903eecda9e518b8a5c86f1e70a183a3ae576..bf51d4b3a0a55177dcc4985c4fce700b9c2bebc6 100644
--- a/gui/slick/views/manage.mako
+++ b/gui/slick/views/manage.mako
@@ -163,7 +163,7 @@ $(document).ready(function(){
         <tr>
             <td align="center"><input type="checkbox" class="editCheck" id="edit-${curShow.indexerid}" /></td>
             <td class="tvShow"><a href="${sbRoot}/home/displayShow?show=${curShow.indexerid}">${curShow.name}</a></td>
-            <td align="center">${renderQualityPill(curShow.quality)}</td>
+            <td align="center">${renderQualityPill(curShow.quality, showTitle=True)}</td>
             <td align="center"><img src="${sbRoot}/images/${('no16.png" alt="N"', 'yes16.png" alt="Y"')[int(curShow.is_sports) == 1]} width="16" height="16" /></td>
             <td align="center"><img src="${sbRoot}/images/${('no16.png" alt="N"', 'yes16.png" alt="Y"')[int(curShow.is_scene) == 1]} width="16" height="16" /></td>
             <td align="center"><img src="${sbRoot}/images/${('no16.png" alt="N"', 'yes16.png" alt="Y"')[int(curShow.is_anime) == 1]} width="16" height="16" /></td>
diff --git a/gui/slick/views/manage_massEdit.mako b/gui/slick/views/manage_massEdit.mako
index 720cbe131740633d766b6aad955a4154e01fe876..135d0078e616a2c10d46ce4ab4c8f579986b83b7 100644
--- a/gui/slick/views/manage_massEdit.mako
+++ b/gui/slick/views/manage_massEdit.mako
@@ -64,7 +64,7 @@
 
     <div id="customQuality">
         <div class="manageCustom pull-left">
-        <h4>Inital</h4>
+        <h5>Allowed</h5>
             <% anyQualityList = filter(lambda x: x > common.Quality.NONE, common.Quality.qualityStrings) %>
             <select id="anyQualities" name="anyQualities" multiple="multiple" size="${len(anyQualityList)}">
             % for curQuality in sorted(anyQualityList):
@@ -73,9 +73,9 @@
             </select>
         </div>
         <div class="manageCustom pull-left">
-        <h4>Archive</h4>
+        <h5>Preferred</h5>
             <% bestQualityList = filter(lambda x: x >= common.Quality.SDTV, common.Quality.qualityStrings) %>
-            <select id="bestQualities" name="bestQualities" multiple="multiple" size="len(${bestQualityList})">
+            <select id="bestQualities" name="bestQualities" multiple="multiple" size="${len(bestQualityList)}">
             % for curQuality in sorted(bestQualityList):
             <option value="${curQuality}" ${('', 'selected="selected"')[curQuality in bestQualities]}>${common.Quality.qualityStrings[curQuality]}</option>
             % endfor
diff --git a/sickbeard/__init__.py b/sickbeard/__init__.py
index fef229c9a69fe1c0e93435749881ce12174c9e43..bb87c426e6f83299932f2973800582d7402b4acd 100644
--- a/sickbeard/__init__.py
+++ b/sickbeard/__init__.py
@@ -39,7 +39,8 @@ from sickbeard import providers
 from sickbeard.providers.generic import GenericProvider
 from sickbeard.providers import btn, newznab, womble, thepiratebay, torrentleech, kat, iptorrents, \
     omgwtfnzbs, scc, hdtorrents, torrentday, hdbits, hounddawgs, nextgen, speedcd, nyaatorrents, animenzb, bluetigers, cpasbien, fnt, xthor, torrentbytes, \
-    frenchtorrentdb, freshontv, titansoftv, libertalia, morethantv, bitsoup, t411, tokyotoshokan, shazbat, rarbg, alpharatio, tntvillage, binsearch, scenetime, btdigg, strike
+    frenchtorrentdb, freshontv, titansoftv, libertalia, morethantv, bitsoup, t411, tokyotoshokan, shazbat, rarbg, alpharatio, tntvillage, binsearch, \
+    scenetime, btdigg, strike, transmitthenet, tvchaosuk
 from sickbeard.config import CheckSection, check_setting_int, check_setting_str, check_setting_float, ConfigMigrator, \
     naming_ep_type
 from sickbeard import searchBacklog, showUpdater, versionChecker, properFinder, autoPostProcesser, \
diff --git a/sickbeard/autoPostProcesser.py b/sickbeard/autoPostProcesser.py
index 4c43a80e218088f7892a8bd269baea72e937b527..b66e2562796ee405d01c1c0db07fb29e76dbbc52 100644
--- a/sickbeard/autoPostProcesser.py
+++ b/sickbeard/autoPostProcesser.py
@@ -21,8 +21,8 @@ import threading
 import sickbeard
 
 from sickbeard import logger
-from sickbeard import encodingKludge as ek
 from sickbeard import processTV
+from sickrage.helper.encoding import ek
 
 
 class PostProcesser():
@@ -31,24 +31,29 @@ class PostProcesser():
         self.amActive = False
 
     def run(self, force=False):
-
+        """
+        TODO: Rename class to PostProcessor (classname contains a typo)
+        Runs the postprocessor
+        :param force: Forces postprocessing run (reserved for future use)
+        :return: Returns when done without a return state/code
+        """
         self.amActive = True
-        
-        if not ek.ek(os.path.isdir, sickbeard.TV_DOWNLOAD_DIR):
+
+        if not ek(os.path.isdir, sickbeard.TV_DOWNLOAD_DIR):
             logger.log(u"Automatic post-processing attempted but dir " + sickbeard.TV_DOWNLOAD_DIR + " doesn't exist",
                        logger.ERROR)
             self.amActive = False
             return
 
-        if not ek.ek(os.path.isabs, sickbeard.TV_DOWNLOAD_DIR):
+        if not ek(os.path.isabs, sickbeard.TV_DOWNLOAD_DIR):
             logger.log(
                 u"Automatic post-processing attempted but dir " + sickbeard.TV_DOWNLOAD_DIR + " is relative (and probably not what you really want to process)",
                 logger.ERROR)
-            self.amActive = False   
+            self.amActive = False
             return
 
         processTV.processDir(sickbeard.TV_DOWNLOAD_DIR)
-        
+
         self.amActive = False
 
     def __del__(self):
diff --git a/sickbeard/blackandwhitelist.py b/sickbeard/blackandwhitelist.py
index 510daed8e85b238988ff9cd7719965d92b5d89d3..a391d412c32a0d450d1a210eb0f04f8c8e7121d2 100644
--- a/sickbeard/blackandwhitelist.py
+++ b/sickbeard/blackandwhitelist.py
@@ -1,9 +1,10 @@
 # Author: Dennis Lutter <lad1337@gmail.com>
-# URL: http://code.google.com/p/sickbeard/
+# URL: https://sickrage.tv/
+# Git: https://github.com/SiCKRAGETV/SickRage.git
 #
-# This file is part of Sick Beard.
+# This file is part of SickRage.
 #
-# Sick Beard is free software: you can redistribute it and/or modify
+# SickRage is free software: you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
 # the Free Software Foundation, either version 3 of the License, or
 # (at your option) any later version.
@@ -14,7 +15,7 @@
 # GNU General Public License for more details.
 #
 # You should have received a copy of the GNU General Public License
-# along with Sick Beard.  If not, see <http://www.gnu.org/licenses/>.
+# along with SickRage.  If not, see <http://www.gnu.org/licenses/>.
 
 import sickbeard
 from sickbeard import db, logger, helpers
@@ -30,32 +31,63 @@ class BlackAndWhiteList(object):
         self.load()
 
     def load(self):
+        """
+        Builds black and whitelist
+        """
         logger.log(u'Building black and white list for ' + str(self.show_id), logger.DEBUG)
         self.blacklist = self._load_list('blacklist')
         self.whitelist = self._load_list('whitelist')
         
     def _add_keywords(self, table, values):
+        """
+        DB: Adds keywords into database for current show
+
+        :param table: SQL table to add keywords to
+        :param values: Values to be inserted in table
+        """
         myDB = db.DBConnection()
         for value in values:
             myDB.action('INSERT INTO [' + table + '] (show_id, keyword) VALUES (?,?)', [self.show_id, value]) 
 
     def set_black_keywords(self, values):
+        """
+        Sets blacklist to new value
+
+        :param values: Complete list of keywords to be set as blacklist
+        """
         self._del_all_keywords('blacklist')
         self._add_keywords('blacklist', values)
         self.blacklist = values
         logger.log('Blacklist set to: %s' % self.blacklist, logger.DEBUG)
 
     def set_white_keywords(self, values):
+        """
+        Sets whitelist to new value
+
+        :param values: Complete list of keywords to be set as whitelist
+        """
         self._del_all_keywords('whitelist')
         self._add_keywords('whitelist', values)
         self.whitelist = values
         logger.log('Whitelist set to: %s' % self.whitelist, logger.DEBUG)            
 
     def _del_all_keywords(self, table):
+        """
+        DB: Remove all keywords for current show
+
+        :param table: SQL table remove keywords from
+        """
         myDB = db.DBConnection()
         myDB.action('DELETE FROM [' + table + '] WHERE show_id = ?', [self.show_id])        
         
     def _load_list(self, table):
+        """
+        DB: Fetch keywords for current show
+
+        :param table: Table to fetch list of keywords from
+
+        :return: keywords in list
+        """
         myDB = db.DBConnection()
         sqlResults = myDB.select('SELECT keyword FROM [' + table + '] WHERE show_id = ?', [self.show_id])
         if not sqlResults or not len(sqlResults):
@@ -68,6 +100,12 @@ class BlackAndWhiteList(object):
         return groups
 
     def is_valid(self, result):
+        """
+        Check if result is valid according to white/blacklist for current show
+
+        :param result: Result to analyse
+        :return: False if result is not allowed in white/blacklist, True if it is
+        """
         if not result.release_group:
             logger.log('Failed to detect release group, invalid result', logger.DEBUG)
             return False
@@ -97,6 +135,12 @@ class BlackWhitelistNoShowIDException(Exception):
     'No show_id was given'
 
 def short_group_names(groups):
+    """
+    Find AniDB short group names for release groups
+
+    :param groups: list of groups to find short group names for
+    :return: list of shortened group names
+    """
     groups = groups.split(",")
     shortGroupList = []
     if helpers.set_up_anidb_connection():
diff --git a/sickbeard/browser.py b/sickbeard/browser.py
index 2408923928f7e7015544fcee79f408eb634e90db..6d50b8587d27e986526710e0be05d774212c0b61 100644
--- a/sickbeard/browser.py
+++ b/sickbeard/browser.py
@@ -1,5 +1,6 @@
 # Author: Nic Wolfe <nic@wolfeden.ca>
-# URL: http://code.google.com/p/sickbeard/
+# URL: https://sickrage.tv/
+# Git: https://github.com/SiCKRAGETV/SickRage.git
 #
 # This file is part of SickRage.
 #
@@ -19,8 +20,9 @@
 import os
 import string
 
-from sickbeard import encodingKludge as ek
 from sickbeard import logger
+from sickrage.helper.encoding import ek
+
 
 # adapted from http://stackoverflow.com/questions/827371/is-there-a-way-to-list-all-the-available-drive-letters-in-python/827490
 def getWinDrives():
@@ -41,7 +43,11 @@ def getWinDrives():
 def foldersAtPath(path, includeParent=False, includeFiles=False):
     """ Returns a list of dictionaries with the folders contained at the given path
         Give the empty string as the path to list the contents of the root path
-        under Unix this means "/", on Windows this will be a list of drive letters)
+        (under Unix this means "/", on Windows this will be a list of drive letters)
+
+        :param includeParent: boolean, include parent dir in list as well
+        :param includeFiles: boolean, include files or only directories
+        :return: list of folders/files
     """
 
     # walk up the tree until we find a valid path
@@ -71,15 +77,15 @@ def foldersAtPath(path, includeParent=False, includeFiles=False):
         parentPath = ""
 
     try:
-        fileList = [{'name': filename, 'path': ek.ek(os.path.join, path, filename)} for filename in ek.ek(os.listdir, path)]
+        fileList = [{'name': filename, 'path': ek(os.path.join, path, filename)} for filename in ek(os.listdir, path)]
     except OSError, e:
         logger.log(u"Unable to open " + path + ": " + repr(e) + " / " + str(e), logger.WARNING)
-        fileList = [{'name': filename, 'path': ek.ek(os.path.join, parentPath, filename)} for filename in ek.ek(os.listdir, parentPath)]
+        fileList = [{'name': filename, 'path': ek(os.path.join, parentPath, filename)} for filename in ek(os.listdir, parentPath)]
 
     if not includeFiles:
-        fileList = filter(lambda entry: ek.ek(os.path.isdir, entry['path']), fileList)
+        fileList = filter(lambda entry: ek(os.path.isdir, entry['path']), fileList)
 
-    # prune out directories to proect the user from doing stupid things (already lower case the dir to reduce calls)
+    # prune out directories to protect the user from doing stupid things (already lower case the dir to reduce calls)
     hideList = ["boot", "bootmgr", "cache", "msocache", "recovery", "$recycle.bin", "recycler",
                 "system volume information", "temporary internet files"]  # windows specific
     hideList += [".fseventd", ".spotlight", ".trashes", ".vol", "cachedmessages", "caches", "trash"]  # osx specific
diff --git a/sickbeard/bs4_parser.py b/sickbeard/bs4_parser.py
index 4d6887bdc4d1f08988e390c0569f8fd63c3c5acc..e881611a46332feeb79d66fe617bcd05668a6a56 100644
--- a/sickbeard/bs4_parser.py
+++ b/sickbeard/bs4_parser.py
@@ -1,3 +1,22 @@
+# Author: The SickRage Dev Team
+# URL: https://sickrage.tv
+# Repository: https://github.com/SiCKRAGETV/SickRage.git
+#
+# This file is part of SickRage.
+#
+# SickRage is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# SickRage is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with SickRage.  If not, see <http://www.gnu.org/licenses/>.
+
 from bs4 import BeautifulSoup
 
 class BS4Parser:
diff --git a/sickbeard/classes.py b/sickbeard/classes.py
index db93ba1a7c6a298ca9a6ed3f8b9e1bf0c02760eb..05dbfe267830e5c5092eb35a56257c110459c4d9 100644
--- a/sickbeard/classes.py
+++ b/sickbeard/classes.py
@@ -1,5 +1,6 @@
 # Author: Nic Wolfe <nic@wolfeden.ca>
-# URL: http://code.google.com/p/sickbeard/
+# URL: https://sickrage.tv/
+# Git: https://github.com/SiCKRAGETV/SickRage.git
 #
 # This file is part of SickRage.
 #
diff --git a/sickbeard/common.py b/sickbeard/common.py
index c55da517216505d3a13cd8b67bd417afface042a..a43d162f3c48fd46deccc5fa22f68e79ad73c5dc 100644
--- a/sickbeard/common.py
+++ b/sickbeard/common.py
@@ -1,5 +1,6 @@
 # Author: Nic Wolfe <nic@wolfeden.ca>
-# URL: http://code.google.com/p/sickbeard/
+# URL: https://sickrage.tv/
+# Git: https://github.com/SiCKRAGETV/SickRage.git
 #
 # This file is part of SickRage.
 #
@@ -164,6 +165,12 @@ class Quality:
                       ARCHIVED: "Archived"}
     @staticmethod
     def _getStatusStrings(status):
+        """
+        Returns string values associated with Status prefix
+
+        :param status: Status prefix to resolve
+        :return: Human readable status value
+        """
         toReturn = {}
         for x in Quality.qualityStrings.keys():
             toReturn[Quality.compositeStatus(status, x)] = Quality.statusPrefixes[status] + " (" + \
@@ -197,6 +204,9 @@ class Quality:
         """
         Return The quality from an episode File renamed by SickRage
         If no quality is achieved it will try sceneQuality regex
+
+        :param anime: Boolean to indicate if the show we're resolving is Anime
+        :return: Quality prefix
         """
 
         #Try Scene names first
@@ -214,6 +224,10 @@ class Quality:
     def sceneQuality(name, anime=False):
         """
         Return The quality from the scene episode File
+
+        :param name: Episode filename to analyse
+        :param anime: Boolean to indicate if the show we're resolving is Anime
+        :return: Quality prefix
         """
         if not name:
             return Quality.UNKNOWN
@@ -273,6 +287,12 @@ class Quality:
 
     @staticmethod
     def assumeQuality(name):
+        """
+        Assume a quality from file extension if we cannot resolve it otherwise
+
+        :param name: File name of episode to analyse
+        :return: Quality prefix
+        """
         quality = Quality.qualityFromFileMeta(name)
         if quality != Quality.UNKNOWN:
             return quality
@@ -284,6 +304,12 @@ class Quality:
 
     @staticmethod
     def qualityFromFileMeta(filename):
+        """
+        Get quality file file metadata
+
+        :param filename: Filename to analyse
+        :return: Quality prefix
+        """
         from hachoir_parser import createParser
         from hachoir_metadata import extractMetadata
 
@@ -352,6 +378,14 @@ class Quality:
 
     @staticmethod
     def statusFromName(name, assume=True, anime=False):
+        """
+        Get a status object from filename
+
+        :param name: Filename to check
+        :param assume: boolean to assume quality by extension if we can't figure it out
+        :param anime: boolean to enable anime parsing
+        :return: Composite status/quality object
+        """
         quality = Quality.nameQuality(name, anime)
         if assume and quality == Quality.UNKNOWN:
             quality = Quality.assumeQuality(name)
diff --git a/sickbeard/config.py b/sickbeard/config.py
index 1ffddc1c3c8b3cfae1e22a28001bdfd117b30d1c..e956f9e500453c86c0dfb8198d6029f89b01631a 100644
--- a/sickbeard/config.py
+++ b/sickbeard/config.py
@@ -1,5 +1,6 @@
 # Author: Nic Wolfe <nic@wolfeden.ca>
-# URL: http://code.google.com/p/sickbeard/
+# URL: https://sickrage.tv
+# Git: https://github.com/SiCKRAGETV/SickRage.git
 #
 # This file is part of SickRage.
 #
@@ -54,6 +55,12 @@ naming_sep_type_text = (" - ", "space")
 
 
 def change_HTTPS_CERT(https_cert):
+    """
+    Replace HTTPS Certificate file path
+
+    :param https_cert: path to the new certificate file
+    :return: True on success, False on failure
+    """
     if https_cert == '':
         sickbeard.HTTPS_CERT = ''
         return True
@@ -69,6 +76,12 @@ def change_HTTPS_CERT(https_cert):
 
 
 def change_HTTPS_KEY(https_key):
+    """
+    Replace HTTPS Key file path
+
+    :param https_key: path to the new key file
+    :return: True on success, False on failure
+    """
     if https_key == '':
         sickbeard.HTTPS_KEY = ''
         return True
@@ -84,6 +97,13 @@ def change_HTTPS_KEY(https_key):
 
 
 def change_LOG_DIR(log_dir, web_log):
+    """
+    Change logging directory for application and webserver
+
+    :param log_dir: Path to new logging directory
+    :param web_log: Enable/disable web logging
+    :return: True on success, False on failure
+    """
     log_dir_changed = False
     abs_log_dir = os.path.normpath(os.path.join(sickbeard.DATA_DIR, log_dir))
     web_log_value = checkbox_to_value(web_log)
@@ -107,6 +127,12 @@ def change_LOG_DIR(log_dir, web_log):
 
 
 def change_NZB_DIR(nzb_dir):
+    """
+    Change NZB Folder
+
+    :param nzb_dir: New NZB Folder location
+    :return: True on success, False on failure
+    """
     if nzb_dir == '':
         sickbeard.NZB_DIR = ''
         return True
@@ -122,6 +148,12 @@ def change_NZB_DIR(nzb_dir):
 
 
 def change_TORRENT_DIR(torrent_dir):
+    """
+    Change torrent directory
+
+    :param torrent_dir: New torrent directory
+    :return: True on success, False on failure
+    """
     if torrent_dir == '':
         sickbeard.TORRENT_DIR = ''
         return True
@@ -137,6 +169,12 @@ def change_TORRENT_DIR(torrent_dir):
 
 
 def change_TV_DOWNLOAD_DIR(tv_download_dir):
+    """
+    Change TV_DOWNLOAD directory (used by postprocessor)
+
+    :param tv_download_dir: New tv download directory
+    :return: True on success, False on failure
+    """
     if tv_download_dir == '':
         sickbeard.TV_DOWNLOAD_DIR = ''
         return True
@@ -152,6 +190,12 @@ def change_TV_DOWNLOAD_DIR(tv_download_dir):
 
 
 def change_AUTOPOSTPROCESSER_FREQUENCY(freq):
+    """
+    Change frequency of automatic postprocessing thread
+    TODO: Make all thread frequency changers in config.py return True/False status
+
+    :param freq: New frequency
+    """
     sickbeard.AUTOPOSTPROCESSER_FREQUENCY = to_int(freq, default=sickbeard.DEFAULT_AUTOPOSTPROCESSER_FREQUENCY)
 
     if sickbeard.AUTOPOSTPROCESSER_FREQUENCY < sickbeard.MIN_AUTOPOSTPROCESSER_FREQUENCY:
@@ -160,6 +204,11 @@ def change_AUTOPOSTPROCESSER_FREQUENCY(freq):
     sickbeard.autoPostProcesserScheduler.cycleTime = datetime.timedelta(minutes=sickbeard.AUTOPOSTPROCESSER_FREQUENCY)
 
 def change_DAILYSEARCH_FREQUENCY(freq):
+    """
+    Change frequency of daily search thread
+
+    :param freq: New frequency
+    """
     sickbeard.DAILYSEARCH_FREQUENCY = to_int(freq, default=sickbeard.DEFAULT_DAILYSEARCH_FREQUENCY)
 
     if sickbeard.DAILYSEARCH_FREQUENCY < sickbeard.MIN_DAILYSEARCH_FREQUENCY:
@@ -168,6 +217,11 @@ def change_DAILYSEARCH_FREQUENCY(freq):
     sickbeard.dailySearchScheduler.cycleTime = datetime.timedelta(minutes=sickbeard.DAILYSEARCH_FREQUENCY)
 
 def change_BACKLOG_FREQUENCY(freq):
+    """
+    Change frequency of backlog thread
+
+    :param freq: New frequency
+    """
     sickbeard.BACKLOG_FREQUENCY = to_int(freq, default=sickbeard.DEFAULT_BACKLOG_FREQUENCY)
 
     sickbeard.MIN_BACKLOG_FREQUENCY = sickbeard.get_backlog_cycle_time()
@@ -177,6 +231,11 @@ def change_BACKLOG_FREQUENCY(freq):
     sickbeard.backlogSearchScheduler.cycleTime = datetime.timedelta(minutes=sickbeard.BACKLOG_FREQUENCY)
 
 def change_UPDATE_FREQUENCY(freq):
+    """
+    Change frequency of daily updater thread
+
+    :param freq: New frequency
+    """
     sickbeard.UPDATE_FREQUENCY = to_int(freq, default=sickbeard.DEFAULT_UPDATE_FREQUENCY)
 
     if sickbeard.UPDATE_FREQUENCY < sickbeard.MIN_UPDATE_FREQUENCY:
@@ -185,6 +244,11 @@ def change_UPDATE_FREQUENCY(freq):
     sickbeard.versionCheckScheduler.cycleTime = datetime.timedelta(hours=sickbeard.UPDATE_FREQUENCY)
 
 def change_SHOWUPDATE_HOUR(freq):
+    """
+    Change frequency of show updater thread
+
+    :param freq: New frequency
+    """
     sickbeard.SHOWUPDATE_HOUR = to_int(freq, default=sickbeard.DEFAULT_SHOWUPDATE_HOUR)
 
     if sickbeard.SHOWUPDATE_HOUR > 23:
@@ -195,13 +259,22 @@ def change_SHOWUPDATE_HOUR(freq):
     sickbeard.showUpdateScheduler.start_time = datetime.time(hour=sickbeard.SHOWUPDATE_HOUR)
 
 def change_SUBTITLES_FINDER_FREQUENCY(subtitles_finder_frequency):
+    """
+    Change frequency of subtitle thread
 
+    :param subtitles_finder_frequency: New frequency
+    """
     if subtitles_finder_frequency == '' or subtitles_finder_frequency is None:
             subtitles_finder_frequency = 1
 
     sickbeard.SUBTITLES_FINDER_FREQUENCY = to_int(subtitles_finder_frequency, 1)
 
 def change_VERSION_NOTIFY(version_notify):
+    """
+    Change frequency of versioncheck thread
+
+    :param version_notify: New frequency
+    """
     oldSetting = sickbeard.VERSION_NOTIFY
 
     sickbeard.VERSION_NOTIFY = version_notify
@@ -213,6 +286,12 @@ def change_VERSION_NOTIFY(version_notify):
         sickbeard.versionCheckScheduler.forceRun()
 
 def change_DOWNLOAD_PROPERS(download_propers):
+    """
+    Enable/Disable proper download thread
+    TODO: Make this return True/False on success/failure
+
+    :param download_propers: New desired state
+    """
     download_propers = checkbox_to_value(download_propers)
 
     if sickbeard.DOWNLOAD_PROPERS == download_propers:
@@ -232,6 +311,12 @@ def change_DOWNLOAD_PROPERS(download_propers):
         logger.log(u"Stopping PROPERFINDER thread", logger.INFO)
 
 def change_USE_TRAKT(use_trakt):
+    """
+    Enable/disable trakt thread
+    TODO: Make this return true/false on success/failure
+
+    :param use_trakt: New desired state
+    """
     use_trakt = checkbox_to_value(use_trakt)
 
     if sickbeard.USE_TRAKT == use_trakt:
@@ -252,6 +337,12 @@ def change_USE_TRAKT(use_trakt):
 
 
 def change_USE_SUBTITLES(use_subtitles):
+    """
+    Enable/Disable subtitle searcher
+    TODO: Make this return true/false on success/failure
+
+    :param use_subtitles: New desired state
+    """
     use_subtitles = checkbox_to_value(use_subtitles)
 
     if sickbeard.USE_SUBTITLES == use_subtitles:
@@ -271,6 +362,12 @@ def change_USE_SUBTITLES(use_subtitles):
         logger.log(u"Stopping SUBTITLESFINDER thread", logger.INFO)
 
 def change_PROCESS_AUTOMATICALLY(process_automatically):
+    """
+    Enable/Disable postprocessor thread
+    TODO: Make this return True/False on success/failure
+
+    :param process_automatically: New desired state
+    """
     process_automatically = checkbox_to_value(process_automatically)
 
     if sickbeard.PROCESS_AUTOMATICALLY == process_automatically:
@@ -347,6 +444,13 @@ def clean_host(host, default_port=None):
 
 
 def clean_hosts(hosts, default_port=None):
+    """
+    Returns list of cleaned hosts by clean_host
+
+    :param hosts: list of hosts
+    :param default_port: default port to use
+    :return: list of cleaned hosts
+    """
     cleaned_hosts = []
 
     for cur_host in [x.strip() for x in hosts.split(",")]:
diff --git a/sickbeard/dailysearcher.py b/sickbeard/dailysearcher.py
index 2b5421056f09fc3ba553fa8dfb2a717959b4404b..cf12e6f1e3d56d9df217564c5bf29f4647fc59c7 100644
--- a/sickbeard/dailysearcher.py
+++ b/sickbeard/dailysearcher.py
@@ -1,5 +1,6 @@
 # Author: Nic Wolfe <nic@wolfeden.ca>
-# URL: http://code.google.com/p/sickbeard/
+# URL: https://sickrage.tv
+# Git: https://github.com/SiCKRAGETV/SickRage.git
 #
 # This file is part of SickRage.
 #
@@ -36,6 +37,11 @@ class DailySearcher():
         self.amActive = False
 
     def run(self, force=False):
+        """
+        Runs the daily searcher, queuing selected episodes for search
+
+        :param force: Force search
+        """
         if self.amActive:
             return
 
diff --git a/sickbeard/databases/mainDB.py b/sickbeard/databases/mainDB.py
index 42ff879c78084ae327849947748ec67df385d707..abcd93602e82e7d07772e61cc5219fb21940ad2e 100644
--- a/sickbeard/databases/mainDB.py
+++ b/sickbeard/databases/mainDB.py
@@ -23,9 +23,9 @@ import os.path
 
 from sickbeard import db, common, helpers, logger
 
-from sickbeard import encodingKludge as ek
 from sickbeard.name_parser.parser import NameParser, InvalidNameException, InvalidShowException
 from sickrage.helper.common import dateTimeFormat
+from sickrage.helper.encoding import ek
 
 from babelfish import language_converters
 
@@ -346,8 +346,8 @@ class AddSizeAndSceneNameFields(InitialSchema):
                 continue
 
             # if there is no size yet then populate it for us
-            if (not cur_ep["file_size"] or not int(cur_ep["file_size"])) and ek.ek(os.path.isfile, cur_ep["location"]):
-                cur_size = ek.ek(os.path.getsize, cur_ep["location"])
+            if (not cur_ep["file_size"] or not int(cur_ep["file_size"])) and ek(os.path.isfile, cur_ep["location"]):
+                cur_size = ek(os.path.getsize, cur_ep["location"])
                 self.connection.action("UPDATE tv_episodes SET file_size = ? WHERE episode_id = ?",
                                        [cur_size, int(cur_ep["episode_id"])])
 
@@ -366,7 +366,7 @@ class AddSizeAndSceneNameFields(InitialSchema):
                 continue
 
             nzb_name = cur_result["resource"]
-            file_name = ek.ek(os.path.basename, download_results[0]["resource"])
+            file_name = ek(os.path.basename, download_results[0]["resource"])
 
             # take the extension off the filename, it's not needed
             if '.' in file_name:
@@ -411,7 +411,7 @@ class AddSizeAndSceneNameFields(InitialSchema):
         logger.log(u"Adding release name to all episodes with obvious scene filenames")
         for cur_result in empty_results:
 
-            ep_file_name = ek.ek(os.path.basename, cur_result["location"])
+            ep_file_name = ek(os.path.basename, cur_result["location"])
             ep_file_name = os.path.splitext(ep_file_name)[0]
 
             # only want to find real scene names here so anything with a space in it is out
diff --git a/sickbeard/db.py b/sickbeard/db.py
index 25ac95dbd42c5a83c834f13df2d3ae88451358ac..e1eb68c94346ef05abb7c201e0ac325aecc50e30 100644
--- a/sickbeard/db.py
+++ b/sickbeard/db.py
@@ -1,5 +1,6 @@
 # Author: Nic Wolfe <nic@wolfeden.ca>
-# URL: http://code.google.com/p/sickbeard/
+# URL: https://sickrage.tv
+# Git: https://github.com/SiCKRAGETV/SickRage.git
 #
 # This file is part of SickRage.
 #
@@ -25,13 +26,14 @@ import time
 import threading
 import sickbeard
 
-from sickbeard import encodingKludge as ek
 from sickbeard import logger
 from sickbeard.exceptions import ex
+from sickrage.helper.encoding import ek
 
 db_cons = {}
 db_locks = {}
 
+
 def dbFilename(filename="sickbeard.db", suffix=None):
     """
     @param filename: The sqlite database filename to use. If not specified,
@@ -42,7 +44,8 @@ def dbFilename(filename="sickbeard.db", suffix=None):
     """
     if suffix:
         filename = "%s.%s" % (filename, suffix)
-    return ek.ek(os.path.join, sickbeard.DATA_DIR, filename)
+    return ek(os.path.join, sickbeard.DATA_DIR, filename)
+
 
 class DBConnection(object):
     def __init__(self, filename="sickbeard.db", suffix=None, row_type=None):
@@ -79,6 +82,15 @@ class DBConnection(object):
             raise
 
     def execute(self, query, args=None, fetchall=False, fetchone=False):
+        """
+        Executes DB query
+
+        :param query: Query to execute
+        :param args: Arguments in query
+        :param fetchall: Boolean to indicate all results must be fetched
+        :param fetchone: Boolean to indicate one result must be fetched (to walk results for instance)
+        :return: query results
+        """
         try:
             if fetchall:
                 return self._execute(query, args).fetchall()
@@ -90,7 +102,11 @@ class DBConnection(object):
             raise
 
     def checkDBVersion(self):
+        """
+        Fetch database version
 
+        :return: Integer inidicating current DB version
+        """
         result = None
 
         try:
@@ -105,6 +121,14 @@ class DBConnection(object):
             return 0
 
     def mass_action(self, querylist=[], logTransaction=False, fetchall=False):
+        """
+        Execute multiple queries
+
+        :param querylist: list of queries
+        :param logTransaction: Boolean to wrap all in one transaction
+        :param fetchall: Boolean, when using a select query force returning all results
+        :return: list of results
+        """
         # remove None types
         querylist = [i for i in querylist if i is not None and len(i)]
 
@@ -151,6 +175,15 @@ class DBConnection(object):
             return sqlResult
 
     def action(self, query, args=None, fetchall=False, fetchone=False):
+        """
+        Execute single query
+
+        :param query: Query string
+        :param args: Arguments to query string
+        :param fetchall: Boolean to indicate all results must be fetched
+        :param fetchone: Boolean to indicate one result must be fetched (to walk results for instance)
+        :return: query results
+        """
         if query == None:
             return
 
@@ -187,6 +220,13 @@ class DBConnection(object):
             return sqlResult
 
     def select(self, query, args=None):
+        """
+        Perform single select query on database
+
+        :param query: query string
+        :param args:  arguments to query string
+        :return: query results
+        """
 
         sqlResults = self.action(query, args, fetchall=True)
 
@@ -196,7 +236,13 @@ class DBConnection(object):
         return sqlResults
 
     def selectOne(self, query, args=None):
+        """
+        Perform single select query on database, returning one result
 
+        :param query: query string
+        :param args: arguments to query string
+        :return: query results
+        """
         sqlResults = self.action(query, args, fetchone=True)
 
         if sqlResults == None:
@@ -205,6 +251,14 @@ class DBConnection(object):
         return sqlResults
 
     def upsert(self, tableName, valueDict, keyDict):
+        """
+        Update values, or if no updates done, insert values
+        TODO: Make this return true/false on success/error
+
+        :param tableName: table to update/insert
+        :param valueDict: values in table to update/insert
+        :param keyDict:  columns in table to update/insert
+        """
 
         changesBefore = self.connection.total_changes
 
@@ -221,6 +275,12 @@ class DBConnection(object):
             self.action(query, valueDict.values() + keyDict.values())
 
     def tableInfo(self, tableName):
+        """
+        Return information on a database table
+
+        :param tableName: name of table
+        :return: array of name/type info
+        """
         sqlResult = self.select("PRAGMA table_info(%s)" % tableName)
         columns = {}
         for column in sqlResult:
@@ -228,6 +288,12 @@ class DBConnection(object):
         return columns
 
     def _unicode_text_factory(self, x):
+        """
+        Convert text to unicode
+
+        :param x: text to parse
+        :return: unicode result
+        """
         try:
             # Just revert to the old code for now, until we can fix unicode
             return unicode(x, 'utf-8')
@@ -241,12 +307,34 @@ class DBConnection(object):
         return d
 
     def hasTable(self, tableName):
+        """
+        Check if a table exists in database
+
+        :param tableName: table name to check
+        :return: True if table exists, False if it does not
+        """
         return len(self.select("SELECT 1 FROM sqlite_master WHERE name = ?;", (tableName, ))) > 0
 
     def hasColumn(self, tableName, column):
+        """
+        Check if a table has a column
+
+        :param tableName: Table to check
+        :param column: Column to check for
+        :return: True if column exists, False if it does not
+        """
         return column in self.tableInfo(tableName)
 
     def addColumn(self, table, column, type="NUMERIC", default=0):
+        """
+        Adds a column to a table, default column type is NUMERIC
+        TODO: Make this return true/false on success/failure
+
+        :param table: Table to add column too
+        :param column: Column name to add
+        :param type: Column type to add
+        :param default: Default value for column
+        """
         self.action("ALTER TABLE %s ADD %s %s" % (table, column, type))
         self.action("UPDATE %s SET %s = ?" % (table, column), (default,))
 
@@ -266,6 +354,12 @@ class DBSanityCheck(object):
 # ===============
 
 def upgradeDatabase(connection, schema):
+    """
+    Perform database upgrade and provide logging
+
+    :param connection: Existing DB Connection to use
+    :param schema: New schema to upgrade to
+    """
     logger.log(u"Checking database structure..." + connection.filename, logger.DEBUG)
     _processUpgrade(connection, schema)
 
@@ -275,6 +369,12 @@ def prettyName(class_name):
 
 
 def restoreDatabase(version):
+    """
+    Restores a database to a previous version (backup file of version must still exist)
+
+    :param version: Version to restore to
+    :return: True if restore succeeds, False if it fails
+    """
     logger.log(u"Restoring database before trying upgrade again")
     if not sickbeard.helpers.restoreVersionedFile(dbFilename(suffix='v' + str(version)), version):
         logger.log_error_and_exit(u"Database restore failed, abort upgrading database")
diff --git a/sickbeard/encodingKludge.py b/sickbeard/encodingKludge.py
deleted file mode 100644
index 622cfc8aba371da49777df10a1bad3f9eddafda9..0000000000000000000000000000000000000000
--- a/sickbeard/encodingKludge.py
+++ /dev/null
@@ -1,77 +0,0 @@
-# Author: Nic Wolfe <nic@wolfeden.ca>
-# URL: http://code.google.com/p/sickbeard/
-#
-# This file is part of SickRage.
-#
-# SickRage is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# SickRage is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with SickRage.  If not, see <http://www.gnu.org/licenses/>.
-
-import os
-import chardet
-import sickbeard
-
-def _toUnicode(x):
-    if isinstance(x, str):
-        try:
-            x = unicode(x)
-        except Exception:
-            try:
-                x = unicode(x, 'utf-8')
-            except Exception:
-                try:
-                   x = unicode(x, 'latin-1')
-                except Exception:
-                    try:
-                        x = unicode(x, sickbeard.SYS_ENCODING)
-                    except Exception:
-                        try:
-                            # Chardet can be wrong, so try it last
-                            x = unicode(x, chardet.detect(x).get('encoding'))
-                        except Exception:
-                            x = unicode(x, sickbeard.SYS_ENCODING, 'replace')
-    return x
-
-def ss(x):
-    x = _toUnicode(x)
-
-    try:
-        x = x.encode(sickbeard.SYS_ENCODING)
-    except Exception:
-        try:
-            x = x.encode('utf-8')
-        except Exception:
-            try:
-                x = x.encode(sickbeard.SYS_ENCODING, 'replace')
-            except Exception:
-                x = x.encode('utf-8', 'ignore')
-    return x
-
-def fixListEncodings(x):
-    if not isinstance(x, (list, tuple)):
-        return x
-    else:
-        return filter(lambda x: x != None, map(_toUnicode, x))
-
-
-def ek(func, *args, **kwargs):
-    if os.name == 'nt':
-        result = func(*args, **kwargs)
-    else:
-        result = func(*[ss(x) if isinstance(x, (str, unicode)) else x for x in args], **kwargs)
-
-    if isinstance(result, (list, tuple)):
-        return fixListEncodings(result)
-    elif isinstance(result, str):
-        return _toUnicode(result)
-    else:
-        return result
diff --git a/sickbeard/event_queue.py b/sickbeard/event_queue.py
index 8e6d2afc7984e2a6536c5e65b30c91c07aa99674..3b64097c7ba390f91bb2ce56d6b5175219ada33b 100644
--- a/sickbeard/event_queue.py
+++ b/sickbeard/event_queue.py
@@ -27,6 +27,9 @@ class Events(threading.Thread):
         self.queue.put(type)
 
     def run(self):
+        """
+        Actually runs the thread to process events
+        """
         try:
             while (not self.stop.is_set()):
                 try:
diff --git a/sickbeard/exceptions.py b/sickbeard/exceptions.py
index b1040043fa2e3bcb06981b759a1cc95715337978..1ae11922a23ac36c6d2f50145b79967ea9d44572 100644
--- a/sickbeard/exceptions.py
+++ b/sickbeard/exceptions.py
@@ -1,5 +1,6 @@
 # Author: Nic Wolfe <nic@wolfeden.ca>
-# URL: http://code.google.com/p/sickbeard/
+# URL: https://sickrage.tv
+# Git: https://github.com/SiCKRAGETV/SickRage.git
 #
 # This file is part of SickRage.
 #
@@ -16,7 +17,8 @@
 # You should have received a copy of the GNU General Public License
 # along with SickRage.  If not, see <http://www.gnu.org/licenses/>.
 
-from sickbeard import encodingKludge as ek
+from sickrage.helper.encoding import ss
+
 
 def ex(e):
     """
@@ -32,10 +34,10 @@ def ex(e):
 
         if arg is not None:
             if isinstance(arg, (str, unicode)):
-                fixed_arg = ek.ss(arg)
+                fixed_arg = ss(arg)
             else:
                 try:
-                    fixed_arg = u"error " + ek.ss(str(arg))
+                    fixed_arg = u"error " + ss(str(arg))
                 except:
                     fixed_arg = None
 
diff --git a/sickbeard/failedProcessor.py b/sickbeard/failedProcessor.py
index 0b31003d08a892ee4ee6738d36fdc9b1998642d9..155280a9c459947b8ce694f1254df7942df31b27 100644
--- a/sickbeard/failedProcessor.py
+++ b/sickbeard/failedProcessor.py
@@ -1,5 +1,6 @@
 # Author: Tyler Fenby <tylerfenby@gmail.com>
-# URL: http://code.google.com/p/sickbeard/
+# URL: https://sickrage.tv
+# Git: https://github.com/SiCKRAGETV/SickRage.git
 #
 # This file is part of SickRage.
 #
@@ -30,8 +31,8 @@ class FailedProcessor(object):
 
     def __init__(self, dirName, nzbName):
         """
-        dirName: Full path to the folder of the failed download
-        nzbName: Full name of the nzb file that failed
+        :param dirName: Full path to the folder of the failed download
+        :param nzbName: Full name of the nzb file that failed
         """
         self.dir_name = dirName
         self.nzb_name = nzbName
@@ -39,6 +40,11 @@ class FailedProcessor(object):
         self.log = ""
 
     def process(self):
+        """
+        Do the actual work
+
+        :return: True
+        """
         self._log(u"Failed download detected: (" + str(self.nzb_name) + ", " + str(self.dir_name) + ")")
 
         releaseName = show_name_helpers.determineReleaseName(self.dir_name, self.nzb_name)
diff --git a/sickbeard/failed_history.py b/sickbeard/failed_history.py
index cd64abd60e36055834bf9f5667a9bb3d4af81026..14ef0c99cc96c2802ba35e31d8da0c2b7a153b0a 100644
--- a/sickbeard/failed_history.py
+++ b/sickbeard/failed_history.py
@@ -1,5 +1,6 @@
 # Author: Tyler Fenby <tylerfenby@gmail.com>
-# URL: http://code.google.com/p/sickbeard/
+# URL: https://sickrage.tv
+# Git: https://github.com/SiCKRAGETV/SickRage.git
 #
 # This file is part of SickRage.
 #
@@ -25,7 +26,7 @@ from sickbeard import logger
 from sickbeard.exceptions import ex, EpisodeNotFoundException
 from sickbeard.common import Quality
 from sickbeard.common import WANTED, FAILED
-from sickbeard import encodingKludge as ek
+from sickrage.helper.encoding import ss
 from sickrage.show.History import History
 
 
@@ -37,7 +38,7 @@ def prepareFailedName(release):
         fixed = fixed.rpartition(".")[0]
 
     fixed = re.sub("[\.\-\+\ ]", "_", fixed)
-    fixed = ek.ss(fixed)
+    fixed = ss(fixed)
 
     return fixed
 
@@ -99,6 +100,11 @@ def hasFailed(release, size, provider="%"):
     If provider is given, return True only if the release is found
     with that specific provider. Otherwise, return True if the release
     is found with any provider.
+
+    :param release: Release name to record failure
+    :param size: Size of release
+    :param provider: Specific provider to search (defaults to all providers)
+    :return: True if a release has previously failed.
     """
 
     release = prepareFailedName(release)
@@ -137,6 +143,12 @@ def revertEpisode(epObj):
 
 
 def markFailed(epObj):
+    """
+    Mark an episode as failed
+
+    :param epObj: Episode object to mark as failed
+    :return: empty string
+    """
     log_str = u""
 
     try:
@@ -152,6 +164,11 @@ def markFailed(epObj):
 
 
 def logSnatch(searchResult):
+    """
+    Logs a successful snatch
+
+    :param searchResult: Search result that was successful
+    """
     logDate = datetime.datetime.today().strftime(History.date_format)
     release = prepareFailedName(searchResult.name)
 
@@ -173,6 +190,13 @@ def logSnatch(searchResult):
 
 
 def deleteLoggedSnatch(release, size, provider):
+    """
+    Remove a snatch from history
+
+    :param release: release to delete
+    :param size: Size of release
+    :param provider: Provider to delete it from
+    """
     release = prepareFailedName(release)
 
     myDB = db.DBConnection('failed.db')
@@ -181,6 +205,7 @@ def deleteLoggedSnatch(release, size, provider):
 
 
 def trimHistory():
+    """Trims history table to 1 month of history from today"""
     myDB = db.DBConnection('failed.db')
     myDB.action("DELETE FROM history WHERE date < " + str(
         (datetime.datetime.today() - datetime.timedelta(days=30)).strftime(History.date_format)))
diff --git a/sickbeard/generic_queue.py b/sickbeard/generic_queue.py
index 166c8aaa434afc79692ae55b4be6bcc01aef623a..fde0fd0ad5eabe7ad73f86634451a9954e6c4eba 100644
--- a/sickbeard/generic_queue.py
+++ b/sickbeard/generic_queue.py
@@ -1,5 +1,6 @@
 # Author: Nic Wolfe <nic@wolfeden.ca>
-# URL: http://code.google.com/p/sickbeard/
+# URL: https://sickrage.tv
+# Git: https://github.com/SiCKRAGETV/SickRage.git
 #
 # This file is part of SickRage.
 #
@@ -42,14 +43,22 @@ class GenericQueue(object):
         self.lock = threading.Lock()
 
     def pause(self):
+        """Pauses this queue"""
         logger.log(u"Pausing queue")
         self.min_priority = 999999999999
 
     def unpause(self):
+        """Unpauses this queue"""
         logger.log(u"Unpausing queue")
         self.min_priority = 0
 
     def add_item(self, item):
+        """
+        Adds an item to this queue
+
+        :param item: Queue object to add
+        :return: item
+        """
         with self.lock:
             item.added = datetime.datetime.now()
             self.queue.append(item)
@@ -57,6 +66,11 @@ class GenericQueue(object):
             return item
 
     def run(self, force=False):
+        """
+        Process items in this queue
+
+        :param force: Force queue processing (currently not implemented)
+        """
         with self.lock:
             # only start a new task if one isn't already going
             if self.currentItem is None or not self.currentItem.isAlive():
diff --git a/sickbeard/helpers.py b/sickbeard/helpers.py
index 63e1bc23d56756757b86309252a77f00d3b96b39..6348d3ac8811a7a217338c2fff3039a241e36e35 100644
--- a/sickbeard/helpers.py
+++ b/sickbeard/helpers.py
@@ -1,5 +1,6 @@
 # Author: Nic Wolfe <nic@wolfeden.ca>
-# URL: http://code.google.com/p/sickbeard/
+# URL: https://sickrage.tv
+# Git: https://github.com/SiCKRAGETV/SickRage.git
 #
 # This file is part of SickRage.
 #
@@ -68,10 +69,10 @@ from sickbeard.common import USER_AGENT
 from sickbeard.common import mediaExtensions
 from sickbeard.common import subtitleExtensions
 from sickbeard import db
-from sickbeard import encodingKludge as ek
 from sickbeard import notifiers
 from sickbeard import clients
 from sickbeard.subtitles import isValidLanguage
+from sickrage.helper.encoding import ek
 from cachecontrol import CacheControl, caches
 
 from itertools import izip, cycle
@@ -199,9 +200,23 @@ def replaceExtension(filename, newExt):
 
 
 def notTorNZBFile(filename):
+    """
+    Returns true if filename is not a NZB nor Torrent file
+
+    :param filename: Filename to check
+    :return: True if filename is not a NZB nor Torrent
+    """
+
     return not (filename.endswith(".torrent") or filename.endswith(".nzb"))
 
 def isSyncFile(filename):
+    """
+    Returns true if filename is a syncfile, indicating filesystem may be in flux
+
+    :param filename: Filename to check
+    :return: True if this file is a syncfile, False otherwise
+    """
+
     extension = filename.rpartition(".")[2].lower()
     #if extension == '!sync' or extension == 'lftp-pget-status' or extension == 'part' or extension == 'bts':
     syncfiles = sickbeard.SYNC_FILES
@@ -212,6 +227,13 @@ def isSyncFile(filename):
 
 
 def isMediaFile(filename):
+    """
+    Check if named file may contain media
+
+    :param filename: Filename to check
+    :return: True if this is a known media file, False if not
+    """
+
     # ignore samples
     if re.search('(^|[\W_])(sample\d*)[\W_]', filename, re.I):
         return False
@@ -232,6 +254,13 @@ def isMediaFile(filename):
 
 
 def isRarFile(filename):
+    """
+    Check if file is a RAR file, or part of a RAR set
+
+    :param filename: Filename to check
+    :return: True if this is RAR/Part file, False if not
+    """
+
     archive_regex = '(?P<file>^(?P<base>(?:(?!\.part\d+\.rar$).)*)\.(?:(?:part0*1\.)?rar)$)'
 
     if re.search(archive_regex, filename):
@@ -241,8 +270,15 @@ def isRarFile(filename):
 
 
 def isBeingWritten(filepath):
+    """
+    Check if file has been written in last 60 seconds
+
+    :param filepath: Filename to check
+    :return: True if file has been written recently, False if none
+    """
+
     # Return True if file was modified within 60 seconds. it might still be being written to.
-    ctime = max(ek.ek(os.path.getctime, filepath), ek.ek(os.path.getmtime, filepath))
+    ctime = max(ek(os.path.getctime, filepath), ek(os.path.getmtime, filepath))
     if ctime > time.time() - 60:
         return True
 
@@ -273,12 +309,26 @@ def sanitizeFileName(name):
 
 
 def _remove_file_failed(file):
+    """
+    Remove file from filesystem
+
+    :param file: File to remove
+    """
+
     try:
-        ek.ek(os.remove, file)
+        ek(os.remove, file)
     except:
         pass
 
+
 def findCertainShow(showList, indexerid):
+    """
+    Find a show by indexer ID in the show list
+
+    :param showList: List of shows to search in (needle)
+    :param indexerid: Show to look for
+    :return: result list
+    """
 
     results = []
 
@@ -294,9 +344,16 @@ def findCertainShow(showList, indexerid):
         raise MultipleShowObjectsException()
 
 def makeDir(path):
-    if not ek.ek(os.path.isdir, path):
+    """
+    Make a directory on the filesystem
+
+    :param path: directory to make
+    :return: True if success, False if failure
+    """
+
+    if not ek(os.path.isdir, path):
         try:
-            ek.ek(os.makedirs, path)
+            ek(os.makedirs, path)
             # do the library update for synoindex
             notifiers.synoindex_notifier.addFolder(path)
         except OSError:
@@ -305,6 +362,14 @@ def makeDir(path):
 
 
 def searchDBForShow(regShowName, log=False):
+    """
+    Searches if show names are present in the DB
+
+    :param regShowName: list of show names to look for
+    :param log: Boolean, log debug results of search (defaults to False)
+    :return: Indexer ID of found show
+    """
+
     showNames = [re.sub('[. -]', ' ', regShowName)]
 
     yearRegex = "([^()]+?)\s*(\()?(\d{4})(?(2)\))$"
@@ -342,6 +407,16 @@ def searchDBForShow(regShowName, log=False):
 
 
 def searchIndexerForShowID(regShowName, indexer=None, indexer_id=None, ui=None):
+    """
+    Contacts indexer to check for information on shows by showid
+
+    :param regShowName: Name of show
+    :param indexer: Which indexer to use
+    :param indexer_id: Which indexer ID to look for
+    :param ui: Custom UI for indexer use
+    :return:
+    """
+
     showNames = [re.sub('[. -]', ' ', regShowName)]
 
     # Query Indexers for each search term and build the list of results
@@ -404,15 +479,22 @@ def sizeof_fmt(num):
 
 
 def listMediaFiles(path):
-    if not dir or not ek.ek(os.path.isdir, path):
+    """
+    Get a list of files possibly containing media in a path
+
+    :param path: Path to check for files
+    :return: list of files
+    """
+
+    if not dir or not ek(os.path.isdir, path):
         return []
 
     files = []
-    for curFile in ek.ek(os.listdir, path):
-        fullCurFile = ek.ek(os.path.join, path, curFile)
+    for curFile in ek(os.listdir, path):
+        fullCurFile = ek(os.path.join, path, curFile)
 
         # if it's a folder do it recursively
-        if ek.ek(os.path.isdir, fullCurFile) and not curFile.startswith('.') and not curFile == 'Extras':
+        if ek(os.path.isdir, fullCurFile) and not curFile.startswith('.') and not curFile == 'Extras':
             files += listMediaFiles(fullCurFile)
 
         elif isMediaFile(curFile):
@@ -422,23 +504,45 @@ def listMediaFiles(path):
 
 
 def copyFile(srcFile, destFile):
-    ek.ek(shutil.copyfile, srcFile, destFile)
+    """
+    Copy a file from source to destination
+
+    :param srcFile: Path of source file
+    :param destFile: Path of destination file
+    """
+
+    ek(shutil.copyfile, srcFile, destFile)
     try:
-        ek.ek(shutil.copymode, srcFile, destFile)
+        ek(shutil.copymode, srcFile, destFile)
     except OSError:
         pass
 
 
 def moveFile(srcFile, destFile):
+    """
+    Move a file from source to destination
+
+    :param srcFile: Path of source file
+    :param destFile: Path of destination file
+    """
+
     try:
-        ek.ek(shutil.move, srcFile, destFile)
+        ek(shutil.move, srcFile, destFile)
         fixSetGroupID(destFile)
     except OSError:
         copyFile(srcFile, destFile)
-        ek.ek(os.unlink, srcFile)
+        ek(os.unlink, srcFile)
 
 
 def link(src, dst):
+    """
+    Create a file link from source to destination.
+    TODO: Make this unicode proof
+
+    :param src: Source file
+    :param dst: Destination file
+    """
+
     if os.name == 'nt':
         import ctypes
 
@@ -448,8 +552,15 @@ def link(src, dst):
 
 
 def hardlinkFile(srcFile, destFile):
+    """
+    Create a hard-link (inside filesystem link) between source and destination
+
+    :param srcFile: Source file
+    :param destFile: Destination file
+    """
+
     try:
-        ek.ek(link, srcFile, destFile)
+        ek(link, srcFile, destFile)
         fixSetGroupID(destFile)
     except Exception as e:
         logger.log(u"Failed to create hardlink of " + srcFile + " at " + destFile + ": " + ex(e) + ". Copying instead",
@@ -458,6 +569,13 @@ def hardlinkFile(srcFile, destFile):
 
 
 def symlink(src, dst):
+    """
+    Create a soft/symlink between source and destination
+
+    :param src: Source file
+    :param dst: Destination file
+    """
+
     if os.name == 'nt':
         import ctypes
 
@@ -468,10 +586,18 @@ def symlink(src, dst):
 
 
 def moveAndSymlinkFile(srcFile, destFile):
+    """
+    Move a file from source to destination, then create a symlink back from destination from source. If this fails, copy
+    the file from source to destination
+
+    :param srcFile: Source file
+    :param destFile: Destination file
+    """
+
     try:
-        ek.ek(shutil.move, srcFile, destFile)
+        ek(shutil.move, srcFile, destFile)
         fixSetGroupID(destFile)
-        ek.ek(symlink, destFile, srcFile)
+        ek(symlink, destFile, srcFile)
     except:
         logger.log(u"Failed to create symlink of " + srcFile + " at " + destFile + ". Copying instead", logger.ERROR)
         copyFile(srcFile, destFile)
@@ -485,12 +611,12 @@ def make_dirs(path):
 
     logger.log(u"Checking if the path %s already exists" % path, logger.DEBUG)
 
-    if not ek.ek(os.path.isdir, path):
+    if not ek(os.path.isdir, path):
         # Windows, create all missing folders
         if os.name == 'nt' or os.name == 'ce':
             try:
                 logger.log(u"Folder %s didn't exist, creating it" % path, logger.DEBUG)
-                ek.ek(os.makedirs, path)
+                ek(os.makedirs, path)
             except (OSError, IOError) as e:
                 logger.log(u"Failed creating %s : %s" % (path, ex(e)), logger.ERROR)
                 return False
@@ -505,14 +631,14 @@ def make_dirs(path):
                 sofar += cur_folder + os.path.sep
 
                 # if it exists then just keep walking down the line
-                if ek.ek(os.path.isdir, sofar):
+                if ek(os.path.isdir, sofar):
                     continue
 
                 try:
                     logger.log(u"Folder %s didn't exist, creating it" % sofar, logger.DEBUG)
-                    ek.ek(os.mkdir, sofar)
+                    ek(os.mkdir, sofar)
                     # use normpath to remove end separator, otherwise checks permissions against itself
-                    chmodAsParent(ek.ek(os.path.normpath, sofar))
+                    chmodAsParent(ek(os.path.normpath, sofar))
                     # do the library update for synoindex
                     notifiers.synoindex_notifier.addFolder(sofar)
                 except (OSError, IOError) as e:
@@ -527,9 +653,9 @@ def rename_ep_file(cur_path, new_path, old_path_length=0):
     Creates all folders needed to move a file to its new location, renames it, then cleans up any folders
     left that are now empty.
 
-    cur_path: The absolute path to the file you want to move/rename
-    new_path: The absolute path to the destination for the file WITHOUT THE EXTENSION
-    old_path_length: The length of media file path (old name) WITHOUT THE EXTENSION
+    :param  cur_path: The absolute path to the file you want to move/rename
+    :param new_path: The absolute path to the destination for the file WITHOUT THE EXTENSION
+    :param old_path_length: The length of media file path (old name) WITHOUT THE EXTENSION
     """
 
     new_dest_dir, new_dest_name = os.path.split(new_path)  # @UnusedVariable
@@ -558,13 +684,13 @@ def rename_ep_file(cur_path, new_path, old_path_length=0):
     # move the file
     try:
         logger.log(u"Renaming file from %s to %s" % (cur_path, new_path))
-        ek.ek(shutil.move, cur_path, new_path)
+        ek(shutil.move, cur_path, new_path)
     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
-    delete_empty_folders(ek.ek(os.path.dirname, cur_path))
+    delete_empty_folders(ek(os.path.dirname, cur_path))
 
     return True
 
@@ -573,8 +699,8 @@ def delete_empty_folders(check_empty_dir, keep_dir=None):
     """
     Walks backwards up the path and deletes any empty folders found.
 
-    check_empty_dir: The path to clean (absolute path to a folder)
-    keep_dir: Clean until this path is reached
+    :param check_empty_dir: The path to clean (absolute path to a folder)
+    :param keep_dir: Clean until this path is reached
     """
 
     # treat check_empty_dir as empty when it only contains these items
@@ -583,8 +709,8 @@ def delete_empty_folders(check_empty_dir, keep_dir=None):
     logger.log(u"Trying to clean any empty folders under " + check_empty_dir)
 
     # as long as the folder exists and doesn't contain any files, delete it
-    while ek.ek(os.path.isdir, check_empty_dir) and check_empty_dir != keep_dir:
-        check_files = ek.ek(os.listdir, check_empty_dir)
+    while ek(os.path.isdir, check_empty_dir) and check_empty_dir != keep_dir:
+        check_files = ek(os.listdir, check_empty_dir)
 
         if not check_files or (len(check_files) <= len(ignore_items) and all(
                 [check_file in ignore_items for check_file in check_files])):
@@ -592,18 +718,25 @@ def delete_empty_folders(check_empty_dir, keep_dir=None):
             try:
                 logger.log(u"Deleting empty folder: " + check_empty_dir)
                 # need shutil.rmtree when ignore_items is really implemented
-                ek.ek(os.rmdir, check_empty_dir)
+                ek(os.rmdir, check_empty_dir)
                 # do the library update for synoindex
                 notifiers.synoindex_notifier.deleteFolder(check_empty_dir)
             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)
+            check_empty_dir = ek(os.path.dirname, check_empty_dir)
         else:
             break
 
 
 def fileBitFilter(mode):
+    """
+    Strip special filesystem bits from file
+
+    :param mode: mode to check and strip
+    :return: required mode for media file
+    """
+
     for bit in [stat.S_IXUSR, stat.S_IXGRP, stat.S_IXOTH, stat.S_ISUID, stat.S_ISGID]:
         if mode & bit:
             mode -= bit
@@ -612,22 +745,29 @@ def fileBitFilter(mode):
 
 
 def chmodAsParent(childPath):
+    """
+    Retain permissions of parent for childs
+    (Does not work for Windows hosts)
+
+    :param childPath: Child Path to change permissions to sync from parent
+    """
+
     if os.name == 'nt' or os.name == 'ce':
         return
 
-    parentPath = ek.ek(os.path.dirname, childPath)
+    parentPath = ek(os.path.dirname, childPath)
 
     if not parentPath:
         logger.log(u"No parent path provided in " + childPath + ", unable to get permissions from it", logger.DEBUG)
         return
 
-    parentPathStat = ek.ek(os.stat, parentPath)
+    parentPathStat = ek(os.stat, parentPath)
     parentMode = stat.S_IMODE(parentPathStat[stat.ST_MODE])
 
-    childPathStat = ek.ek(os.stat, childPath)
+    childPathStat = ek(os.stat, childPath)
     childPath_mode = stat.S_IMODE(childPathStat[stat.ST_MODE])
 
-    if ek.ek(os.path.isfile, childPath):
+    if ek(os.path.isfile, childPath):
         childMode = fileBitFilter(parentMode)
     else:
         childMode = parentMode
@@ -643,7 +783,7 @@ def chmodAsParent(childPath):
         return
 
     try:
-        ek.ek(os.chmod, childPath, childMode)
+        ek(os.chmod, childPath, childMode)
         logger.log(u"Setting permissions for %s to %o as parent directory has %o" % (childPath, childMode, parentMode),
                    logger.DEBUG)
     except OSError:
@@ -651,16 +791,23 @@ def chmodAsParent(childPath):
 
 
 def fixSetGroupID(childPath):
+    """
+    Inherid SGID from parent
+    (does not work on Windows hosts)
+
+    :param childPath: Path to inherit SGID permissions from parent
+    """
+
     if os.name == 'nt' or os.name == 'ce':
         return
 
-    parentPath = ek.ek(os.path.dirname, childPath)
-    parentStat = ek.ek(os.stat, parentPath)
+    parentPath = ek(os.path.dirname, childPath)
+    parentStat = ek(os.stat, parentPath)
     parentMode = stat.S_IMODE(parentStat[stat.ST_MODE])
 
     if parentMode & stat.S_ISGID:
         parentGID = parentStat[stat.ST_GID]
-        childStat = ek.ek(os.stat, childPath)
+        childStat = ek(os.stat, childPath)
         childGID = childStat[stat.ST_GID]
 
         if childGID == parentGID:
@@ -675,7 +822,7 @@ def fixSetGroupID(childPath):
             return
 
         try:
-            ek.ek(os.chown, childPath, -1, parentGID)  # @UndefinedVariable - only available on UNIX
+            ek(os.chown, childPath, -1, parentGID)  # @UndefinedVariable - only available on UNIX
             logger.log(u"Respecting the set-group-ID bit on the parent directory for %s" % (childPath), logger.DEBUG)
         except OSError:
             logger.log(
@@ -684,6 +831,12 @@ def fixSetGroupID(childPath):
 
 
 def is_anime_in_show_list():
+    """
+    Check if any shows in list contain anime
+
+    :return: True if global showlist contains Anime, False if not
+    """
+
     for show in sickbeard.showList:
         if show.is_anime:
             return True
@@ -691,10 +844,21 @@ def is_anime_in_show_list():
 
 
 def update_anime_support():
+    """Check if we need to support anime, and if we do, enable the feature"""
+
     sickbeard.ANIMESUPPORT = is_anime_in_show_list()
 
 
 def get_absolute_number_from_season_and_episode(show, season, episode):
+    """
+    Find the absolute number for a show episode
+
+    :param show: Show object
+    :param season: Season number
+    :param episode: Episode number
+    :return: The absolute number
+    """
+
     absolute_number = None
 
     if season and episode:
@@ -728,7 +892,7 @@ def get_all_episodes_from_absolute_number(show, absolute_numbers, indexer_id=Non
             ep = show.getEpisode(None, None, absolute_number=absolute_number)
             if ep:
                 episodes.append(ep.episode)
-                season = ep.season  # this will always take the last found seson so eps that cross the season border are not handeled well
+                season = ep.season  # this will always take the last found season so eps that cross the season border are not handeled well
 
     return (season, episodes)
 
@@ -737,9 +901,8 @@ def sanitizeSceneName(name, anime=False):
     """
     Takes a show name and returns the "scenified" version of it.
 
-    anime: Some show have a ' in their name(Kuroko's Basketball) and is needed for search.
-
-    Returns: A string containing the scene version of the show name given.
+    :param anime: Some show have a ' in their name(Kuroko's Basketball) and is needed for search.
+    :return: A string containing the scene version of the show name given.
     """
 
     if not name:
@@ -798,7 +961,12 @@ def arithmeticEval(s):
 def create_https_certificates(ssl_cert, ssl_key):
     """
     Create self-signed HTTPS certificares and store in paths 'ssl_cert' and 'ssl_key'
+
+    :param ssl_cert: Path of SSL certificate file to write
+    :param ssl_key: Path of SSL keyfile to write
+    :return: True on success, False on failure
     """
+
     try:
         from OpenSSL import crypto  # @UnresolvedImport
         from certgen import createKeyPair, createCertRequest, createCertificate, TYPE_RSA, \
@@ -827,13 +995,22 @@ def create_https_certificates(ssl_cert, ssl_key):
 
     return True
 
+
 def backupVersionedFile(old_file, version):
+    """
+    Back up an old version of a file
+
+    :param old_file: Original file, to take a backup from
+    :param version: Version of file to store in backup
+    :return: True if success, False if failure
+    """
+
     numTries = 0
 
     new_file = old_file + '.' + 'v' + str(version)
 
-    while not ek.ek(os.path.isfile, new_file):
-        if not ek.ek(os.path.isfile, old_file):
+    while not ek(os.path.isfile, new_file):
+        if not ek(os.path.isfile, old_file):
             logger.log(u"Not creating backup, %s doesn't exist" % old_file, logger.DEBUG)
             break
 
@@ -856,12 +1033,20 @@ def backupVersionedFile(old_file, version):
 
 
 def restoreVersionedFile(backup_file, version):
+    """
+    Restore a file version to original state
+
+    :param backup_file: File to restore
+    :param version: Version of file to restore
+    :return: True on success, False on failure
+    """
+
     numTries = 0
 
     new_file, backup_version = os.path.splitext(backup_file)
     restore_file = new_file + '.' + 'v' + str(version)
 
-    if not ek.ek(os.path.isfile, new_file):
+    if not ek(os.path.isfile, new_file):
         logger.log(u"Not restoring, %s doesn't exist" % new_file, logger.DEBUG)
         return False
 
@@ -876,8 +1061,8 @@ def restoreVersionedFile(backup_file, version):
             logger.WARNING)
         return False
 
-    while not ek.ek(os.path.isfile, new_file):
-        if not ek.ek(os.path.isfile, restore_file):
+    while not ek(os.path.isfile, new_file):
+        if not ek(os.path.isfile, restore_file):
             logger.log(u"Not restoring, " + restore_file + " doesn't exist", logger.DEBUG)
             break
 
@@ -902,6 +1087,14 @@ def restoreVersionedFile(backup_file, version):
 
 # try to convert to int, if it fails the default will be returned
 def tryInt(s, s_default=0):
+    """
+    Try to convert to int, if it fails, the default will be returned
+
+    :param s: Value to attempt to convert to int
+    :param s_default: Default value to return on failure (defaults to 0)
+    :return: integer, or default value on failure
+    """
+
     try:
         return int(s)
     except:
@@ -910,6 +1103,13 @@ def tryInt(s, s_default=0):
 
 # generates a md5 hash of a file
 def md5_for_file(filename, block_size=2 ** 16):
+    """
+    Generate an md5 hash for a file
+    :param filename: File to generate md5 hash for
+    :param block_size: Block size to use (defaults to 2^16)
+    :return MD5 hexdigest on success, or None on failure
+    """
+
     try:
         with open(filename, 'rb') as f:
             md5 = hashlib.md5()
@@ -925,6 +1125,8 @@ def md5_for_file(filename, block_size=2 ** 16):
 
 
 def get_lan_ip():
+    """Returns IP of system"""
+
     try:return [ip for ip in socket.gethostbyname_ex(socket.gethostname())[2] if not ip.startswith("127.")][0]
     except:return socket.gethostname()
 
@@ -1055,7 +1257,7 @@ def is_hidden_folder(folder):
     """
     Returns True if folder is hidden.
     On Linux based systems hidden folders start with . (dot)
-    folder: Full path of folder to check
+    :param folder: Full path of folder to check
     """
     def is_hidden(filepath):
         name = os.path.basename(os.path.abspath(filepath))
@@ -1070,7 +1272,7 @@ def is_hidden_folder(folder):
             result = False
         return result
 
-    if ek.ek(os.path.isdir, folder):
+    if ek(os.path.isdir, folder):
         if is_hidden(folder):
             return True
 
@@ -1081,7 +1283,7 @@ def real_path(path):
     """
     Returns: the canonicalized absolute pathname. The resulting path will have no symbolic link, '/./' or '/../' components.
     """
-    return ek.ek(os.path.normpath, ek.ek(os.path.normcase, ek.ek(os.path.realpath, path)))
+    return ek(os.path.normpath, ek(os.path.normcase, ek(os.path.realpath, path)))
 
 
 def validateShow(show, season=None, episode=None):
@@ -1106,6 +1308,8 @@ def validateShow(show, season=None, episode=None):
 
 
 def set_up_anidb_connection():
+    """Connect to anidb"""
+
     if not sickbeard.USE_ANIDB:
         logger.log(u"Usage of anidb disabled. Skiping", logger.DEBUG)
         return False
@@ -1136,9 +1340,12 @@ def set_up_anidb_connection():
 
 def makeZip(fileList, archive):
     """
-    'fileList' is a list of file names - full path each name
-    'archive' is the file name for the archive with a full path
+    Create a ZIP of files
+
+    :param fileList: A list of file names - full path each name
+    :param archive: File name for the archive with a full path
     """
+
     try:
         a = zipfile.ZipFile(archive, 'w', zipfile.ZIP_DEFLATED, allowZip64=True)
         for f in fileList:
@@ -1152,9 +1359,12 @@ def makeZip(fileList, archive):
 
 def extractZip(archive, targetDir):
     """
-    'fileList' is a list of file names - full path each name
-    'archive' is the file name for the archive with a full path
+    Unzip a file to a directory
+
+    :param fileList: A list of file names - full path each name
+    :param archive: The file name for the archive with a full path
     """
+
     try:
         if not os.path.exists(targetDir):
             os.mkdir(targetDir)
@@ -1180,6 +1390,15 @@ def extractZip(archive, targetDir):
 
 
 def backupConfigZip(fileList, archive, arcname = None):
+    """
+    Store the config file as a ZIP
+
+    :param fileList: List of files to store
+    :param archive: ZIP file name
+    :param arcname: Archive path
+    :return: True on success, False on failure
+    """
+
     try:
         a = zipfile.ZipFile(archive, 'w', zipfile.ZIP_DEFLATED, allowZip64=True)
         for f in fileList:
@@ -1192,6 +1411,14 @@ def backupConfigZip(fileList, archive, arcname = None):
 
 
 def restoreConfigZip(archive, targetDir):
+    """
+    Restores a Config ZIP file back in place
+
+    :param archive: ZIP filename
+    :param targetDir: Directory to restore to
+    :return: True on success, False on failure
+    """
+
     import ntpath
     try:
         if not os.path.exists(targetDir):
@@ -1272,6 +1499,14 @@ def mapIndexersToShow(showObj):
 
 
 def touchFile(fname, atime=None):
+    """
+    Touch a file (change modification date)
+
+    :param fname: Filename to touch
+    :param atime: Specific access time (defaults to None)
+    :return: True on success, False on failure
+    """
+
     if None != atime:
         try:
             with file(fname, 'a'):
@@ -1289,11 +1524,13 @@ def touchFile(fname, atime=None):
 
 
 def _getTempDir():
-    import getpass
-
-    """Returns the [system temp dir]/tvdb_api-u501 (or
+    """
+    Returns the [system temp dir]/tvdb_api-u501 (or
     tvdb_api-myuser)
     """
+
+    import getpass
+
     if hasattr(os, 'getuid'):
         uid = "u%d" % (os.getuid())
     else:
@@ -1319,7 +1556,12 @@ def codeDescription(status_code):
 def _setUpSession(session, headers):
     """
     Returns a session initialized with default cache and parameter settings
+
+    :param session: session object to (re)use
+    :param headers: Headers to pass to session
+    :return: session object
     """
+
     # request session
     cache_dir = sickbeard.CACHE_DIR or _getTempDir()
     session = CacheControl(sess=session, cache=caches.FileCache(os.path.join(cache_dir, 'sessions')), cache_etags=False)
@@ -1420,6 +1662,15 @@ def getURL(url, post_data=None, params={}, headers={}, timeout=30, session=None,
 
 
 def download_file(url, filename, session=None, headers={}):
+    """
+    Downloads a file specified
+
+    :param url: Source URL
+    :param filename: Target file on filesystem
+    :param session: request session to use
+    :param headers: override existing headers in request session
+    :return: True on success, False on failure
+    """
 
     session = _setUpSession(session, headers)
     session.stream = True
@@ -1467,23 +1718,30 @@ def download_file(url, filename, session=None, headers={}):
 
 
 def get_size(start_path='.'):
-    if not ek.ek(os.path.isdir, start_path):
+    """
+    Find the total dir and filesize of a path
+
+    :param start_path: Path to recursively count size
+    :return: total filesize
+    """
+
+    if not ek(os.path.isdir, start_path):
         return -1
 
     total_size = 0
-    for dirpath, dirnames, filenames in ek.ek(os.walk, start_path):
+    for dirpath, dirnames, filenames in ek(os.walk, start_path):
         for f in filenames:
-            fp = ek.ek(os.path.join, dirpath, f)
+            fp = ek(os.path.join, dirpath, f)
             try:
-                total_size += ek.ek(os.path.getsize, fp)
+                total_size += ek(os.path.getsize, fp)
             except OSError as e:
                 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
 
+
 def generateApiKey():
-    """ Return a new randomized API_KEY
-    """
+    """ Return a new randomized API_KEY"""
 
     try:
         from hashlib import md5
@@ -1505,6 +1763,8 @@ def generateApiKey():
     return m.hexdigest()
 
 def pretty_filesize(file_bytes):
+    """Return humanly formatted sizes from bytes"""
+
     file_bytes = float(file_bytes)
     if file_bytes >= 1099511627776:
         terabytes = file_bytes / 1099511627776
@@ -1528,17 +1788,25 @@ if __name__ == '__main__':
     doctest.testmod()
 
 def remove_article(text=''):
+    """Remove the english articles from a text string"""
+
     return re.sub(r'(?i)^(?:(?:A(?!\s+to)n?)|The)\s(\w)', r'\1', text)
 
 def generateCookieSecret():
+    """Generate a new cookie secret"""
 
     return base64.b64encode(uuid.uuid4().bytes + uuid.uuid4().bytes)
 
 def verify_freespace(src, dest, oldfile=None):
-    """ Checks if the target system has enough free space to copy or move a file,
-    Returns true if there is, False if there isn't.
-    Also returns True if the OS doesn't support this option
     """
+    Checks if the target system has enough free space to copy or move a file.
+
+    :param src: Source filename
+    :param dest: Destination path
+    :param oldfile: File to be replaced (defaults to None)
+    :return: True if there is enough space for the file, False if there isn't. Also returns True if the OS doesn't support this option
+    """
+
     if not isinstance(oldfile, list):
         oldfile = [oldfile]
 
@@ -1569,7 +1837,7 @@ def verify_freespace(src, dest, oldfile=None):
         logger.log("Unable to determine free space on your OS")
         return True
 
-    if not ek.ek(os.path.isfile, src):
+    if not ek(os.path.isfile, src):
         logger.log("A path to a file is required for the source. " + src + " is not a file.", logger.WARNING)
         return True
 
@@ -1579,12 +1847,12 @@ def verify_freespace(src, dest, oldfile=None):
         logger.log("Unable to determine free space, so I will assume there is enough.", logger.WARNING)
         return True
 
-    neededspace = ek.ek(os.path.getsize, src)
+    neededspace = ek(os.path.getsize, src)
 
     if oldfile:
         for file in oldfile:
-            if ek.ek(os.path.isfile, file.location):
-                diskfree += ek.ek(os.path.getsize, file.location)
+            if ek(os.path.isfile, file.location):
+                diskfree += ek(os.path.getsize, file.location)
 
     if diskfree > neededspace:
         return True
@@ -1621,25 +1889,25 @@ def isFileLocked(file, writeLockCheck=False):
         3. If the readLockCheck parameter is True, attempts to rename the file. If this fails the
             file is open by some other process for reading. The file can be read, but not written to
             or deleted.
-    @param file: the file being checked
-    @param writeLockCheck: when true will check if the file is locked for writing (prevents move operations)
+    :param file: the file being checked
+    :param writeLockCheck: when true will check if the file is locked for writing (prevents move operations)
     '''
-    if not ek.ek(os.path.exists, file):
+    if not ek(os.path.exists, file):
         return True
     try:
-        f = ek.ek(open, file, 'r')
+        f = ek(open, file, 'r')
         f.close()
     except IOError:
         return True
 
-    if(writeLockCheck):
+    if writeLockCheck:
         lockFile = file + ".lckchk"
-        if ek.ek(os.path.exists, lockFile):
-            ek.ek(os.remove, lockFile)
+        if ek(os.path.exists, lockFile):
+            ek(os.remove, lockFile)
         try:
-            ek.ek(os.rename, file, lockFile)
+            ek(os.rename, file, lockFile)
             time.sleep(1)
-            ek.ek(os.rename, lockFile, file)
+            ek(os.rename, lockFile, file)
         except (OSError, IOError):
             return True
 
@@ -1648,7 +1916,7 @@ def isFileLocked(file, writeLockCheck=False):
 def getDiskSpaceUsage(diskPath=None):
     '''
     returns the free space in MB for a given path or False if no path given
-    @param diskPath: the filesystem path being checked
+    :param diskPath: the filesystem path being checked
     '''
 
     if diskPath:
diff --git a/sickbeard/history.py b/sickbeard/history.py
index bb49785c18492853c7030f3382dc3d8480accf00..8b96c2d2a9da4ff5387f67360f1eaabcdf58d302 100644
--- a/sickbeard/history.py
+++ b/sickbeard/history.py
@@ -1,5 +1,6 @@
 # Author: Nic Wolfe <nic@wolfeden.ca>
-# URL: http://code.google.com/p/sickbeard/
+# URL: https://sickrage.tv
+# Git: https://github.com/SiCKRAGETV/SickRage.git
 #
 # This file is part of SickRage.
 #
@@ -20,13 +21,25 @@ import db
 import datetime
 
 from sickbeard.common import SNATCHED, SUBTITLED, FAILED, Quality
-from sickbeard import encodingKludge as ek
+from sickrage.helper.encoding import ss
 from sickrage.show.History import History
 
 
 def _logHistoryItem(action, showid, season, episode, quality, resource, provider, version=-1):
+    """
+    Insert a history item in DB
+
+    :param action: action taken (snatch, download, etc)
+    :param showid: showid this entry is about
+    :param season: show season
+    :param episode: show episode
+    :param quality: media quality
+    :param resource: resource used
+    :param provider: provider used
+    :param version: tracked version of file (defaults to -1)
+    """
     logDate = datetime.datetime.today().strftime(History.date_format)
-    resource = ek.ss(resource)
+    resource = ss(resource)
 
     myDB = db.DBConnection()
     myDB.action(
@@ -35,6 +48,11 @@ def _logHistoryItem(action, showid, season, episode, quality, resource, provider
 
 
 def logSnatch(searchResult):
+    """
+    Log history of snatch
+
+    :param searchResult: search result object
+    """
     for curEpObj in searchResult.episodes:
 
         showid = int(curEpObj.show.indexerid)
@@ -57,6 +75,15 @@ def logSnatch(searchResult):
 
 
 def logDownload(episode, filename, new_ep_quality, release_group=None, version=-1):
+    """
+    Log history of download
+
+    :param episode: episode of show
+    :param filename: file on disk where the download is
+    :param new_ep_quality: Quality of download
+    :param release_group: Release group
+    :param version: Version of file (defaults to -1)
+    """
     showid = int(episode.show.indexerid)
     season = int(episode.season)
     epNum = int(episode.episode)
@@ -75,6 +102,15 @@ def logDownload(episode, filename, new_ep_quality, release_group=None, version=-
 
 
 def logSubtitle(showid, season, episode, status, subtitleResult):
+    """
+    Log download of subtitle
+
+    :param showid: Showid of download
+    :param season: Show season
+    :param episode: Show episode
+    :param status: Status of download
+    :param subtitleResult: Result object
+    """
     resource = subtitleResult.language.opensubtitles
     provider = subtitleResult.provider_name
 
@@ -85,6 +121,13 @@ def logSubtitle(showid, season, episode, status, subtitleResult):
 
 
 def logFailed(epObj, release, provider=None):
+    """
+    Log a failed download
+
+    :param epObj: Episode object
+    :param release: Release group
+    :param provider: Provider used for snatch
+    """
     showid = int(epObj.show.indexerid)
     season = int(epObj.season)
     epNum = int(epObj.episode)
diff --git a/sickbeard/image_cache.py b/sickbeard/image_cache.py
index bade105c4fd97dfefd11ef6a241dc1a8a15aadbc..75eb4b40d659811c00cec8801de5bbee1bbab378 100644
--- a/sickbeard/image_cache.py
+++ b/sickbeard/image_cache.py
@@ -1,5 +1,6 @@
 # Author: Nic Wolfe <nic@wolfeden.ca>
-# URL: http://code.google.com/p/sickbeard/
+# URL: https://sickrage.tv
+# Git: https://github.com/SiCKRAGETV/SickRage.git
 #
 # This file is part of SickRage.
 #
@@ -21,9 +22,8 @@ import os.path
 import sickbeard
 
 from sickbeard import helpers, logger, exceptions
-from sickbeard import encodingKludge as ek
-
 from sickbeard.metadata.generic import GenericMetadata
+from sickrage.helper.encoding import ek
 
 from hachoir_parser import createParser
 from hachoir_metadata import extractMetadata
@@ -40,76 +40,71 @@ class ImageCache:
         """
         Builds up the full path to the image cache directory
         """
-        return ek.ek(os.path.abspath, ek.ek(os.path.join, sickbeard.CACHE_DIR, 'images'))
+        return ek(os.path.abspath, ek(os.path.join, sickbeard.CACHE_DIR, 'images'))
 
     def _thumbnails_dir(self):
         """
         Builds up the full path to the thumbnails image cache directory
         """
-        return ek.ek(os.path.abspath, ek.ek(os.path.join, self._cache_dir(), 'thumbnails'))
+        return ek(os.path.abspath, ek(os.path.join, self._cache_dir(), 'thumbnails'))
 
     def poster_path(self, indexer_id):
         """
         Builds up the path to a poster cache for a given Indexer ID
 
-        returns: a full path to the cached poster file for the given Indexer ID
-        
-        indexer_id: ID of the show to use in the file name
+        :param indexer_id: ID of the show to use in the file name
+        :return: a full path to the cached poster file for the given Indexer ID
         """
         poster_file_name = str(indexer_id) + '.poster.jpg'
-        return ek.ek(os.path.join, self._cache_dir(), poster_file_name)
+        return ek(os.path.join, self._cache_dir(), poster_file_name)
 
     def banner_path(self, indexer_id):
         """
         Builds up the path to a banner cache for a given Indexer ID
 
-        returns: a full path to the cached banner file for the given Indexer ID
-        
-        indexer_id: ID of the show to use in the file name
+        :param indexer_id: ID of the show to use in the file name
+        :return: a full path to the cached banner file for the given Indexer ID
         """
         banner_file_name = str(indexer_id) + '.banner.jpg'
-        return ek.ek(os.path.join, self._cache_dir(), banner_file_name)
+        return ek(os.path.join, self._cache_dir(), banner_file_name)
 
     def fanart_path(self, indexer_id):
         """
         Builds up the path to a fanart cache for a given Indexer ID
 
-        returns: a full path to the cached fanart file for the given Indexer ID
-        
-        indexer_id: ID of the show to use in the file name
+        :param indexer_id: ID of the show to use in the file name
+        :return: a full path to the cached fanart file for the given Indexer ID
         """
         fanart_file_name = str(indexer_id) + '.fanart.jpg'
-        return ek.ek(os.path.join, self._cache_dir(), fanart_file_name)
-        
+        return ek(os.path.join, self._cache_dir(), fanart_file_name)
+
     def poster_thumb_path(self, indexer_id):
         """
         Builds up the path to a poster thumb cache for a given Indexer ID
 
-        returns: a full path to the cached poster thumb file for the given Indexer ID
-        
-        indexer_id: ID of the show to use in the file name
+        :param indexer_id: ID of the show to use in the file name
+        :return: a full path to the cached poster thumb file for the given Indexer ID
         """
         posterthumb_file_name = str(indexer_id) + '.poster.jpg'
-        return ek.ek(os.path.join, self._thumbnails_dir(), posterthumb_file_name)
+        return ek(os.path.join, self._thumbnails_dir(), posterthumb_file_name)
 
     def banner_thumb_path(self, indexer_id):
         """
         Builds up the path to a banner thumb cache for a given Indexer ID
 
-        returns: a full path to the cached banner thumb file for the given Indexer ID
-        
-        indexer_id: ID of the show to use in the file name
+        :param indexer_id: ID of the show to use in the file name
+        :return: a full path to the cached banner thumb file for the given Indexer ID
         """
         bannerthumb_file_name = str(indexer_id) + '.banner.jpg'
-        return ek.ek(os.path.join, self._thumbnails_dir(), bannerthumb_file_name)     
-        
+        return ek(os.path.join, self._thumbnails_dir(), bannerthumb_file_name)
+
     def has_poster(self, indexer_id):
         """
         Returns true if a cached poster exists for the given Indexer ID
         """
         poster_path = self.poster_path(indexer_id)
         logger.log(u"Checking if file " + str(poster_path) + " exists", logger.DEBUG)
-        return ek.ek(os.path.isfile, poster_path)
+        return ek(os.path.isfile, poster_path)
 
     def has_banner(self, indexer_id):
         """
@@ -117,7 +112,7 @@ class ImageCache:
         """
         banner_path = self.banner_path(indexer_id)
         logger.log(u"Checking if file " + str(banner_path) + " exists", logger.DEBUG)
-        return ek.ek(os.path.isfile, banner_path)
+        return ek(os.path.isfile, banner_path)
 
     def has_fanart(self, indexer_id):
         """
@@ -125,15 +120,15 @@ class ImageCache:
         """
         fanart_path = self.fanart_path(indexer_id)
         logger.log(u"Checking if file " + str(fanart_path) + " exists", logger.DEBUG)
-        return ek.ek(os.path.isfile, fanart_path)
-        
+        return ek(os.path.isfile, fanart_path)
+
     def has_poster_thumbnail(self, indexer_id):
         """
         Returns true if a cached poster thumbnail exists for the given Indexer ID
         """
         poster_thumb_path = self.poster_thumb_path(indexer_id)
         logger.log(u"Checking if file " + str(poster_thumb_path) + " exists", logger.DEBUG)
-        return ek.ek(os.path.isfile, poster_thumb_path)
+        return ek(os.path.isfile, poster_thumb_path)
 
     def has_banner_thumbnail(self, indexer_id):
         """
@@ -141,7 +136,7 @@ class ImageCache:
         """
         banner_thumb_path = self.banner_thumb_path(indexer_id)
         logger.log(u"Checking if file " + str(banner_thumb_path) + " exists", logger.DEBUG)
-        return ek.ek(os.path.isfile, banner_thumb_path)
+        return ek(os.path.isfile, banner_thumb_path)
 
     BANNER = 1
     POSTER = 2
@@ -152,13 +147,12 @@ class ImageCache:
     def which_type(self, path):
         """
         Analyzes the image provided and attempts to determine whether it is a poster or banner.
-        
-        returns: BANNER, POSTER if it concluded one or the other, or None if the image was neither (or didn't exist)
-        
-        path: full path to the image
+
+        :param path: full path to the image
+        :return: BANNER, POSTER if it concluded one or the other, or None if the image was neither (or didn't exist)
         """
 
-        if not ek.ek(os.path.isfile, path):
+        if not ek(os.path.isfile, path):
             logger.log(u"Couldn't check the type of " + str(path) + " cause it doesn't exist", logger.WARNING)
             return None
 
@@ -181,7 +175,7 @@ class ImageCache:
         # most banners are around 5.4 width/height ratio (eg. 758/140)
         elif 5 < img_ratio < 6:
             return self.BANNER
-        
+
         # most fanart are around 1.77777 width/height ratio (eg. 1280/720 and 1920/1080)
         elif 1.7 < img_ratio < 1.8:
             return self.FANART
@@ -192,12 +186,11 @@ class ImageCache:
     def _cache_image_from_file(self, image_path, img_type, indexer_id):
         """
         Takes the image provided and copies it to the cache folder
-        
-        returns: bool representing success
-        
-        image_path: path to the image we're caching
-        img_type: BANNER or POSTER or FANART
-        indexer_id: id of the show this image belongs to
+
+        :param image_path: path to the image we're caching
+        :param img_type: BANNER or POSTER or FANART
+        :param indexer_id: id of the show this image belongs to
+        :return: bool representing success
         """
 
         # generate the path based on the type & indexer_id
@@ -206,19 +199,19 @@ class ImageCache:
         elif img_type == self.BANNER:
             dest_path = self.banner_path(indexer_id)
         elif img_type == self.FANART:
-            dest_path = self.fanart_path(indexer_id)            
+            dest_path = self.fanart_path(indexer_id)
         else:
             logger.log(u"Invalid cache image type: " + str(img_type), logger.ERROR)
             return False
 
         # make sure the cache folder exists before we try copying to it
-        if not ek.ek(os.path.isdir, self._cache_dir()):
+        if not ek(os.path.isdir, self._cache_dir()):
             logger.log(u"Image cache dir didn't exist, creating it at " + str(self._cache_dir()))
-            ek.ek(os.makedirs, self._cache_dir())
+            ek(os.makedirs, self._cache_dir())
 
-        if not ek.ek(os.path.isdir, self._thumbnails_dir()):
+        if not ek(os.path.isdir, self._thumbnails_dir()):
             logger.log(u"Thumbnails cache dir didn't exist, creating it at " + str(self._thumbnails_dir()))
-            ek.ek(os.makedirs, self._thumbnails_dir())
+            ek(os.makedirs, self._thumbnails_dir())
 
         logger.log(u"Copying from " + image_path + " to " + dest_path)
         helpers.copyFile(image_path, dest_path)
@@ -228,11 +221,10 @@ class ImageCache:
     def _cache_image_from_indexer(self, show_obj, img_type):
         """
         Retrieves an image of the type specified from indexer and saves it to the cache folder
-        
-        returns: bool representing success
-        
-        show_obj: TVShow object that we want to cache an image for
-        img_type: BANNER or POSTER or FANART
+
+        :param show_obj: TVShow object that we want to cache an image for
+        :param img_type: BANNER or POSTER or FANART
+        :return: bool representing success
         """
 
         # generate the path based on the type & indexer_id
@@ -250,7 +242,7 @@ class ImageCache:
             dest_path = self.banner_thumb_path(show_obj.indexerid)
         elif img_type == self.FANART:
             img_type_name = 'fanart'
-            dest_path = self.fanart_path(show_obj.indexerid)           
+            dest_path = self.fanart_path(show_obj.indexerid)
         else:
             logger.log(u"Invalid cache image type: " + str(img_type), logger.ERROR)
             return False
@@ -267,8 +259,8 @@ class ImageCache:
         """
         Caches all images for the given show. Copies them from the show dir if possible, or
         downloads them from indexer if they aren't in the show dir.
-        
-        show_obj: TVShow object to cache images for
+
+        :param show_obj: TVShow object to cache images for
         """
 
         logger.log(u"Checking if we need any cache images for show " + str(show_obj.indexerid), logger.DEBUG)
@@ -291,7 +283,7 @@ class ImageCache:
                 for cur_provider in sickbeard.metadata_provider_dict.values():
                     logger.log(u"Checking if we can use the show image from the " + cur_provider.name + " metadata",
                                logger.DEBUG)
-                    if ek.ek(os.path.isfile, cur_provider.get_poster_path(show_obj)):
+                    if ek(os.path.isfile, cur_provider.get_poster_path(show_obj)):
                         cur_file_name = os.path.abspath(cur_provider.get_poster_path(show_obj))
                         cur_file_type = self.which_type(cur_file_name)
 
diff --git a/sickbeard/imdbPopular.py b/sickbeard/imdbPopular.py
index 44643242b246b932a0cab5f552c48fe7dc7269b9..6249ce5a4be6c6d0aaef99d39fe4affd90283a88 100644
--- a/sickbeard/imdbPopular.py
+++ b/sickbeard/imdbPopular.py
@@ -6,9 +6,10 @@ from datetime import date
 
 import sickbeard
 from sickbeard import helpers
-from sickbeard import encodingKludge as ek
+from sickrage.helper.encoding import ek
 
-class imdbPopular():
+
+class imdbPopular:
     def __init__(self):
 
         self.url = "http://www.imdb.com/search/title?at=0&sort=moviemeter&title_type=tv_series&year=%s,%s" % \
@@ -17,6 +18,8 @@ class imdbPopular():
         self.session = requests.Session()
 
     def fetch_popular_shows(self):
+        """Get popular show information from IMDB"""
+
         popular_shows = []
 
         data = helpers.getURL(self.url, session=self.session)
@@ -83,7 +86,11 @@ class imdbPopular():
             return image_url
 
     def cache_image(self, image_url):
-        path = ek.ek(os.path.abspath, ek.ek(os.path.join, sickbeard.CACHE_DIR, 'images', 'imdb_popular'))
+        """
+        Store cache of image in cache dir
+        :param image_url: Source URL
+        """
+        path = ek(os.path.abspath, ek(os.path.join, sickbeard.CACHE_DIR, 'images', 'imdb_popular'))
 
         if not os.path.exists(path):
             os.makedirs(path)
diff --git a/sickbeard/indexers/test/__init__.py b/sickbeard/indexers/test/__init__.py
deleted file mode 100644
index 1f47cffeca0eb214cc2745b71a3f0777534c3f09..0000000000000000000000000000000000000000
--- a/sickbeard/indexers/test/__init__.py
+++ /dev/null
@@ -1 +0,0 @@
-__author__ = 'Justin'
diff --git a/sickbeard/logger.py b/sickbeard/logger.py
index e3161d008fbc71ae86bbab20eb8aff22543e3d17..f2febe7c96f73d5bb870b78555b9470506415a30 100644
--- a/sickbeard/logger.py
+++ b/sickbeard/logger.py
@@ -1,5 +1,6 @@
 # Author: Nic Wolfe <nic@wolfeden.ca>
-# URL: http://code.google.com/p/sickbeard/
+# URL: https://sickrage.tv
+# Git: https://github.com/SiCKRAGETV/SickRage.git
 #
 # This file is part of SickRage.
 #
@@ -27,8 +28,9 @@ import platform
 import locale
 
 import sickbeard
-from sickbeard import classes, encodingKludge as ek
+from sickbeard import classes
 from sickrage.helper.common import dateTimeFormat
+from sickrage.helper.encoding import ek, ss
 from github import Github, InputFileContent
 import codecs
 
@@ -39,11 +41,13 @@ INFO = logging.INFO
 DEBUG = logging.DEBUG
 DB = 5
 
-reverseNames = {u'ERROR': ERROR,
-                u'WARNING': WARNING,
-                u'INFO': INFO,
-                u'DEBUG': DEBUG,
-                u'DB': DB}
+reverseNames = {
+    u'ERROR': ERROR,
+    u'WARNING': WARNING,
+    u'INFO': INFO,
+    u'DEBUG': DEBUG,
+    u'DB': DB
+}
 
 censoredItems = {}
 
@@ -58,6 +62,7 @@ class CensoredFormatter(logging.Formatter, object):
         super(CensoredFormatter, self).__init__(*args, **kwargs)
 
     def format(self, record):
+        """Strips censored items from string"""
         msg = super(CensoredFormatter, self).format(record)
         for k, v in censoredItems.iteritems():
             if v and len(v) > 0 and v in msg:
@@ -185,12 +190,12 @@ class Logger(object):
             log_data = None
 
             if os.path.isfile(self.logFile):
-                with ek.ek(codecs.open, *[self.logFile, 'r', 'utf-8']) as f:
+                with ek(codecs.open, *[self.logFile, 'r', 'utf-8']) as f:
                     log_data = f.readlines()
 
             for i in range (1 , int(sickbeard.LOG_NR)):
                 if os.path.isfile(self.logFile + "." + str(i)) and (len(log_data) <= 500):
-                    with ek.ek(codecs.open, *[self.logFile + "." + str(i), 'r', 'utf-8']) as f:
+                    with ek(codecs.open, *[self.logFile + "." + str(i), 'r', 'utf-8']) as f:
                             log_data += f.readlines()
 
             log_data = [line for line in reversed(log_data)]
@@ -200,7 +205,7 @@ class Logger(object):
                 try:
                     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)
+                        title_Error = re.match("^[A-Z0-9\-\[\] :]+::\s*(.*)$", ss(str(curError.message))).group(1)
 
                     # if len(title_Error) > (1024 - len(u"[APP SUBMITTED]: ")):
                     # 1000 just looks better than 1007 and adds some buffer
@@ -212,7 +217,7 @@ class Logger(object):
                 gist = None
                 regex = "^(%s)\s+([A-Z]+)\s+([0-9A-Z\-]+)\s*(.*)$" % curError.time
                 for i, x in enumerate(log_data):
-                    x = ek.ss(x)
+                    x = ss(x)
                     match = re.match(regex, x)
                     if match:
                         level = match.group(2)
diff --git a/sickbeard/metadata/generic.py b/sickbeard/metadata/generic.py
index b816e93e78dec992c294dc0b55fc4d762095dffd..33f59e93b91744e192b3a87a69264f4e9ae28c7d 100644
--- a/sickbeard/metadata/generic.py
+++ b/sickbeard/metadata/generic.py
@@ -29,15 +29,16 @@ import sickbeard
 from sickbeard import helpers
 from sickbeard.metadata import helpers as metadata_helpers
 from sickbeard import logger
-from sickbeard import encodingKludge as ek
 from sickbeard.exceptions import ex
 from sickbeard.show_name_helpers import allPossibleShowNames
+from sickrage.helper.encoding import ek, ss
 
 from tmdb_api.tmdb_api import TMDB
 
 import fanart
 from fanart.core import Request as fanartRequest
 
+
 class GenericMetadata():
     """
     Base class for all metadata providers. Default behavior is meant to mostly
@@ -118,84 +119,84 @@ class GenericMetadata():
         self.season_all_banner = config_list[9]
 
     def _has_show_metadata(self, show_obj):
-        result = ek.ek(os.path.isfile, self.get_show_file_path(show_obj))
+        result = ek(os.path.isfile, self.get_show_file_path(show_obj))
         logger.log(u"Checking if " + self.get_show_file_path(show_obj) + " exists: " + str(result), logger.DEBUG)
         return result
 
     def _has_episode_metadata(self, ep_obj):
-        result = ek.ek(os.path.isfile, self.get_episode_file_path(ep_obj))
+        result = ek(os.path.isfile, self.get_episode_file_path(ep_obj))
         logger.log(u"Checking if " + self.get_episode_file_path(ep_obj) + " exists: " + str(result), logger.DEBUG)
         return result
 
     def _has_fanart(self, show_obj):
-        result = ek.ek(os.path.isfile, self.get_fanart_path(show_obj))
+        result = ek(os.path.isfile, self.get_fanart_path(show_obj))
         logger.log(u"Checking if " + self.get_fanart_path(show_obj) + " exists: " + str(result), logger.DEBUG)
         return result
 
     def _has_poster(self, show_obj):
-        result = ek.ek(os.path.isfile, self.get_poster_path(show_obj))
+        result = ek(os.path.isfile, self.get_poster_path(show_obj))
         logger.log(u"Checking if " + self.get_poster_path(show_obj) + " exists: " + str(result), logger.DEBUG)
         return result
 
     def _has_banner(self, show_obj):
-        result = ek.ek(os.path.isfile, self.get_banner_path(show_obj))
+        result = ek(os.path.isfile, self.get_banner_path(show_obj))
         logger.log(u"Checking if " + self.get_banner_path(show_obj) + " exists: " + str(result), logger.DEBUG)
         return result
 
     def _has_episode_thumb(self, ep_obj):
         location = self.get_episode_thumb_path(ep_obj)
-        result = location != None and ek.ek(os.path.isfile, location)
+        result = location != None and ek(os.path.isfile, location)
         if location:
             logger.log(u"Checking if " + location + " exists: " + str(result), logger.DEBUG)
         return result
 
     def _has_season_poster(self, show_obj, season):
         location = self.get_season_poster_path(show_obj, season)
-        result = location != None and ek.ek(os.path.isfile, location)
+        result = location != None and ek(os.path.isfile, location)
         if location:
             logger.log(u"Checking if " + location + " exists: " + str(result), logger.DEBUG)
         return result
 
     def _has_season_banner(self, show_obj, season):
         location = self.get_season_banner_path(show_obj, season)
-        result = location != None and ek.ek(os.path.isfile, location)
+        result = location != None and ek(os.path.isfile, location)
         if location:
             logger.log(u"Checking if " + location + " exists: " + str(result), logger.DEBUG)
         return result
 
     def _has_season_all_poster(self, show_obj):
-        result = ek.ek(os.path.isfile, self.get_season_all_poster_path(show_obj))
+        result = ek(os.path.isfile, self.get_season_all_poster_path(show_obj))
         logger.log(u"Checking if " + self.get_season_all_poster_path(show_obj) + " exists: " + str(result),
                    logger.DEBUG)
         return result
 
     def _has_season_all_banner(self, show_obj):
-        result = ek.ek(os.path.isfile, self.get_season_all_banner_path(show_obj))
+        result = ek(os.path.isfile, self.get_season_all_banner_path(show_obj))
         logger.log(u"Checking if " + self.get_season_all_banner_path(show_obj) + " exists: " + str(result),
                    logger.DEBUG)
         return result
 
     def get_show_file_path(self, show_obj):
-        return ek.ek(os.path.join, show_obj.location, self._show_metadata_filename)
+        return ek(os.path.join, show_obj.location, self._show_metadata_filename)
 
     def get_episode_file_path(self, ep_obj):
         return helpers.replaceExtension(ep_obj.location, self._ep_nfo_extension)
 
     def get_fanart_path(self, show_obj):
-        return ek.ek(os.path.join, show_obj.location, self.fanart_name)
+        return ek(os.path.join, show_obj.location, self.fanart_name)
 
     def get_poster_path(self, show_obj):
-        return ek.ek(os.path.join, show_obj.location, self.poster_name)
+        return ek(os.path.join, show_obj.location, self.poster_name)
 
     def get_banner_path(self, show_obj):
-        return ek.ek(os.path.join, show_obj.location, self.banner_name)
+        return ek(os.path.join, show_obj.location, self.banner_name)
 
     def get_episode_thumb_path(self, ep_obj):
         """
         Returns the path where the episode thumbnail should be stored.
         ep_obj: a TVEpisode instance for which to create the thumbnail
         """
-        if ek.ek(os.path.isfile, ep_obj.location):
+        if ek(os.path.isfile, ep_obj.location):
 
             tbn_filename = ep_obj.location.rpartition(".")
 
@@ -223,7 +224,7 @@ class GenericMetadata():
         else:
             season_poster_filename = 'season' + str(season).zfill(2)
 
-        return ek.ek(os.path.join, show_obj.location, season_poster_filename + '-poster.jpg')
+        return ek(os.path.join, show_obj.location, season_poster_filename + '-poster.jpg')
 
     def get_season_banner_path(self, show_obj, season):
         """
@@ -240,13 +241,13 @@ class GenericMetadata():
         else:
             season_banner_filename = 'season' + str(season).zfill(2)
 
-        return ek.ek(os.path.join, show_obj.location, season_banner_filename + '-banner.jpg')
+        return ek(os.path.join, show_obj.location, season_banner_filename + '-banner.jpg')
 
     def get_season_all_poster_path(self, show_obj):
-        return ek.ek(os.path.join, show_obj.location, self.season_all_poster_name)
+        return ek(os.path.join, show_obj.location, self.season_all_poster_name)
 
     def get_season_all_banner_path(self, show_obj):
-        return ek.ek(os.path.join, show_obj.location, self.season_all_banner_name)
+        return ek(os.path.join, show_obj.location, self.season_all_banner_name)
 
     def _show_data(self, show_obj):
         """
@@ -283,7 +284,7 @@ class GenericMetadata():
 
             nfo_file_path = self.get_show_file_path(show_obj)
             try:
-                with ek.ek(open, nfo_file_path, 'r') as xmlFileObj:
+                with ek(open, nfo_file_path, 'r') as xmlFileObj:
                     showXML = etree.ElementTree(file=xmlFileObj)
 
                 indexerid = showXML.find('id')
@@ -414,17 +415,17 @@ class GenericMetadata():
             return False
 
         nfo_file_path = self.get_show_file_path(show_obj)
-        nfo_file_dir = ek.ek(os.path.dirname, nfo_file_path)
+        nfo_file_dir = ek(os.path.dirname, nfo_file_path)
 
         try:
-            if not ek.ek(os.path.isdir, nfo_file_dir):
+            if not ek(os.path.isdir, nfo_file_dir):
                 logger.log(u"Metadata dir didn't exist, creating it at " + nfo_file_dir, logger.DEBUG)
-                ek.ek(os.makedirs, nfo_file_dir)
+                ek(os.makedirs, nfo_file_dir)
                 helpers.chmodAsParent(nfo_file_dir)
 
             logger.log(u"Writing show nfo file to " + nfo_file_path, logger.DEBUG)
 
-            nfo_file = ek.ek(open, nfo_file_path, 'w')
+            nfo_file = ek(open, nfo_file_path, 'w')
 
             data.write(nfo_file, encoding="utf-8")
             nfo_file.close()
@@ -459,17 +460,17 @@ class GenericMetadata():
             return False
 
         nfo_file_path = self.get_episode_file_path(ep_obj)
-        nfo_file_dir = ek.ek(os.path.dirname, nfo_file_path)
+        nfo_file_dir = ek(os.path.dirname, nfo_file_path)
 
         try:
-            if not ek.ek(os.path.isdir, nfo_file_dir):
+            if not ek(os.path.isdir, nfo_file_dir):
                 logger.log(u"Metadata dir didn't exist, creating it at " + nfo_file_dir, logger.DEBUG)
-                ek.ek(os.makedirs, nfo_file_dir)
+                ek(os.makedirs, nfo_file_dir)
                 helpers.chmodAsParent(nfo_file_dir)
 
             logger.log(u"Writing episode nfo file to " + nfo_file_path, logger.DEBUG)
 
-            nfo_file = ek.ek(open, nfo_file_path, 'w')
+            nfo_file = ek(open, nfo_file_path, 'w')
 
             data.write(nfo_file, encoding="utf-8")
             nfo_file.close()
@@ -704,23 +705,23 @@ class GenericMetadata():
         """
 
         # don't bother overwriting it
-        if ek.ek(os.path.isfile, image_path):
+        if ek(os.path.isfile, image_path):
             logger.log(u"Image already exists, not downloading", logger.DEBUG)
             return False
 
-        image_dir = ek.ek(os.path.dirname, image_path)
+        image_dir = ek(os.path.dirname, image_path)
 
         if not image_data:
-            logger.log(u"Unable to retrieve image to save in %s, skipping" % (ek.ss(image_path)), logger.DEBUG)
+            logger.log(u"Unable to retrieve image to save in %s, skipping" % (ss(image_path)), logger.DEBUG)
             return False
 
         try:
-            if not ek.ek(os.path.isdir, image_dir):
+            if not ek(os.path.isdir, image_dir):
                 logger.log(u"Metadata dir didn't exist, creating it at " + image_dir, logger.DEBUG)
-                ek.ek(os.makedirs, image_dir)
+                ek(os.makedirs, image_dir)
                 helpers.chmodAsParent(image_dir)
 
-            outFile = ek.ek(open, image_path, 'wb')
+            outFile = ek(open, image_path, 'wb')
             outFile.write(image_data)
             outFile.close()
             helpers.chmodAsParent(image_path)
@@ -921,16 +922,16 @@ class GenericMetadata():
 
         empty_return = (None, None, None)
 
-        metadata_path = ek.ek(os.path.join, folder, self._show_metadata_filename)
+        metadata_path = ek(os.path.join, folder, self._show_metadata_filename)
 
-        if not ek.ek(os.path.isdir, folder) or not ek.ek(os.path.isfile, metadata_path):
+        if not ek(os.path.isdir, folder) or not ek(os.path.isfile, metadata_path):
             logger.log(u"Can't load the metadata file from " + repr(metadata_path) + ", it doesn't exist", logger.DEBUG)
             return empty_return
 
         logger.log(u"Loading show info from metadata file in " + folder, logger.DEBUG)
 
         try:
-            with ek.ek(open, metadata_path, 'r') as xmlFileObj:
+            with ek(open, metadata_path, 'r') as xmlFileObj:
                 showXML = etree.ElementTree(file=xmlFileObj)
 
             if showXML.findtext('title') == None \
diff --git a/sickbeard/metadata/kodi.py b/sickbeard/metadata/kodi.py
index 71d1eedf8c41bbfb15ab23fd433429001bf82ae7..7c902f2307084f850ac8d53bb1af627a1bf946c1 100644
--- a/sickbeard/metadata/kodi.py
+++ b/sickbeard/metadata/kodi.py
@@ -22,7 +22,7 @@ import kodi_12plus
 import os
 
 from sickbeard import helpers
-from sickbeard import encodingKludge as ek
+from sickrage.helper.encoding import ek
 
 
 class KODIMetadata(kodi_12plus.KODI_12PlusMetadata):
@@ -97,7 +97,7 @@ class KODIMetadata(kodi_12plus.KODI_12PlusMetadata):
 
         ep_obj: a TVEpisode instance for which to create the thumbnail
         """
-        if ek.ek(os.path.isfile, ep_obj.location):
+        if ek(os.path.isfile, ep_obj.location):
             tbn_filename = helpers.replaceExtension(ep_obj.location, 'tbn')
         else:
             return None
@@ -119,7 +119,7 @@ class KODIMetadata(kodi_12plus.KODI_12PlusMetadata):
         else:
             season_poster_filename = 'season' + str(season).zfill(2)
 
-        return ek.ek(os.path.join, show_obj.location, season_poster_filename + '.tbn')
+        return ek(os.path.join, show_obj.location, season_poster_filename + '.tbn')
 
 
 # present a standard "interface" from the module
diff --git a/sickbeard/metadata/mede8er.py b/sickbeard/metadata/mede8er.py
index 45e30e9b420d61720b9b9b22d50f5b1f39d61cc7..c352ab48e1a2dcc9a5a6cce305e18d0635b1c3d3 100644
--- a/sickbeard/metadata/mede8er.py
+++ b/sickbeard/metadata/mede8er.py
@@ -25,8 +25,8 @@ import mediabrowser
 
 from sickbeard import logger, exceptions, helpers
 from sickbeard.exceptions import ex
-from sickbeard import encodingKludge as ek
 from sickrage.helper.common import dateFormat
+from sickrage.helper.encoding import ek
 
 try:
     import xml.etree.cElementTree as etree
@@ -379,17 +379,17 @@ class Mede8erMetadata(mediabrowser.MediaBrowserMetadata):
             return False
 
         nfo_file_path = self.get_show_file_path(show_obj)
-        nfo_file_dir = ek.ek(os.path.dirname, nfo_file_path)
+        nfo_file_dir = ek(os.path.dirname, nfo_file_path)
 
         try:
-            if not ek.ek(os.path.isdir, nfo_file_dir):
+            if not ek(os.path.isdir, nfo_file_dir):
                 logger.log(u"Metadata dir didn't exist, creating it at " + nfo_file_dir, logger.DEBUG)
-                ek.ek(os.makedirs, nfo_file_dir)
+                ek(os.makedirs, nfo_file_dir)
                 helpers.chmodAsParent(nfo_file_dir)
 
             logger.log(u"Writing show nfo file to " + nfo_file_path, logger.DEBUG)
 
-            nfo_file = ek.ek(open, nfo_file_path, 'w')
+            nfo_file = ek(open, nfo_file_path, 'w')
 
             data.write(nfo_file, encoding="UTF-8")
             nfo_file.close()
@@ -424,17 +424,17 @@ class Mede8erMetadata(mediabrowser.MediaBrowserMetadata):
             return False
 
         nfo_file_path = self.get_episode_file_path(ep_obj)
-        nfo_file_dir = ek.ek(os.path.dirname, nfo_file_path)
+        nfo_file_dir = ek(os.path.dirname, nfo_file_path)
 
         try:
-            if not ek.ek(os.path.isdir, nfo_file_dir):
+            if not ek(os.path.isdir, nfo_file_dir):
                 logger.log(u"Metadata dir didn't exist, creating it at " + nfo_file_dir, logger.DEBUG)
-                ek.ek(os.makedirs, nfo_file_dir)
+                ek(os.makedirs, nfo_file_dir)
                 helpers.chmodAsParent(nfo_file_dir)
 
             logger.log(u"Writing episode nfo file to " + nfo_file_path, logger.DEBUG)
 
-            nfo_file = ek.ek(open, nfo_file_path, 'w')
+            nfo_file = ek(open, nfo_file_path, 'w')
 
             data.write(nfo_file, encoding="UTF-8")
             nfo_file.close()
diff --git a/sickbeard/metadata/mediabrowser.py b/sickbeard/metadata/mediabrowser.py
index 7ed50b75add56156809233dea93e4f6947fa8779..e9bffeade0a403f505c76c2c092b4bdeaae02c1d 100644
--- a/sickbeard/metadata/mediabrowser.py
+++ b/sickbeard/metadata/mediabrowser.py
@@ -25,10 +25,9 @@ import sickbeard
 import generic
 
 from sickbeard import logger, exceptions, helpers
-from sickbeard import encodingKludge as ek
-
 from sickbeard.exceptions import ex
 from sickrage.helper.common import dateFormat
+from sickrage.helper.encoding import ek
 
 import xml.etree.cElementTree as etree
 
@@ -111,10 +110,10 @@ class MediaBrowserMetadata(generic.GenericMetadata):
         ep_obj: a TVEpisode object to get the path for
         """
 
-        if ek.ek(os.path.isfile, ep_obj.location):
-            xml_file_name = helpers.replaceExtension(ek.ek(os.path.basename, ep_obj.location), self._ep_nfo_extension)
-            metadata_dir_name = ek.ek(os.path.join, ek.ek(os.path.dirname, ep_obj.location), 'metadata')
-            xml_file_path = ek.ek(os.path.join, metadata_dir_name, xml_file_name)
+        if ek(os.path.isfile, ep_obj.location):
+            xml_file_name = helpers.replaceExtension(ek(os.path.basename, ep_obj.location), self._ep_nfo_extension)
+            metadata_dir_name = ek(os.path.join, ek(os.path.dirname, ep_obj.location), 'metadata')
+            xml_file_path = ek(os.path.join, metadata_dir_name, xml_file_name)
         else:
             logger.log(u"Episode location doesn't exist: " + str(ep_obj.location), logger.DEBUG)
             return ''
@@ -129,10 +128,10 @@ class MediaBrowserMetadata(generic.GenericMetadata):
         ep_obj: a TVEpisode object to get the path from
         """
 
-        if ek.ek(os.path.isfile, ep_obj.location):
-            tbn_file_name = helpers.replaceExtension(ek.ek(os.path.basename, ep_obj.location), 'jpg')
-            metadata_dir_name = ek.ek(os.path.join, ek.ek(os.path.dirname, ep_obj.location), 'metadata')
-            tbn_file_path = ek.ek(os.path.join, metadata_dir_name, tbn_file_name)
+        if ek(os.path.isfile, ep_obj.location):
+            tbn_file_name = helpers.replaceExtension(ek(os.path.basename, ep_obj.location), 'jpg')
+            metadata_dir_name = ek(os.path.join, ek(os.path.dirname, ep_obj.location), 'metadata')
+            tbn_file_path = ek(os.path.join, metadata_dir_name, tbn_file_name)
         else:
             return None
 
@@ -145,8 +144,8 @@ class MediaBrowserMetadata(generic.GenericMetadata):
         If no season folder exists, None is returned
         """
 
-        dir_list = [x for x in ek.ek(os.listdir, show_obj.location) if
-                    ek.ek(os.path.isdir, ek.ek(os.path.join, show_obj.location, x))]
+        dir_list = [x for x in ek(os.listdir, show_obj.location) if
+                    ek(os.path.isdir, ek(os.path.join, show_obj.location, x))]
 
         season_dir_regex = '^Season\s+(\d+)$'
 
@@ -176,7 +175,7 @@ class MediaBrowserMetadata(generic.GenericMetadata):
 
         logger.log(u"Using " + str(season_dir) + "/folder.jpg as season dir for season " + str(season), logger.DEBUG)
 
-        return ek.ek(os.path.join, show_obj.location, season_dir, 'folder.jpg')
+        return ek(os.path.join, show_obj.location, season_dir, 'folder.jpg')
 
     def get_season_banner_path(self, show_obj, season):
         """
@@ -185,8 +184,8 @@ class MediaBrowserMetadata(generic.GenericMetadata):
         If no season folder exists, None is returned
         """
 
-        dir_list = [x for x in ek.ek(os.listdir, show_obj.location) if
-                    ek.ek(os.path.isdir, ek.ek(os.path.join, show_obj.location, x))]
+        dir_list = [x for x in ek(os.listdir, show_obj.location) if
+                    ek(os.path.isdir, ek(os.path.join, show_obj.location, x))]
 
         season_dir_regex = '^Season\s+(\d+)$'
 
@@ -216,7 +215,7 @@ class MediaBrowserMetadata(generic.GenericMetadata):
 
         logger.log(u"Using " + str(season_dir) + "/banner.jpg as season dir for season " + str(season), logger.DEBUG)
 
-        return ek.ek(os.path.join, show_obj.location, season_dir, 'banner.jpg')
+        return ek(os.path.join, show_obj.location, season_dir, 'banner.jpg')
 
     def _show_data(self, show_obj):
         """
diff --git a/sickbeard/metadata/ps3.py b/sickbeard/metadata/ps3.py
index b1e578c840e4685fd6dd2ce30e41e4ac0b259e9c..eb0c0131c3ef3a6ebe73da5d368fa4b2722857cf 100644
--- a/sickbeard/metadata/ps3.py
+++ b/sickbeard/metadata/ps3.py
@@ -20,7 +20,7 @@ import os
 
 import generic
 
-from sickbeard import encodingKludge as ek
+from sickrage.helper.encoding import ek
 
 
 class PS3Metadata(generic.GenericMetadata):
@@ -116,7 +116,7 @@ class PS3Metadata(generic.GenericMetadata):
 
         ep_obj: a TVEpisode instance for which to create the thumbnail
         """
-        if ek.ek(os.path.isfile, ep_obj.location):
+        if ek(os.path.isfile, ep_obj.location):
             tbn_filename = ep_obj.location + ".cover.jpg"
         else:
             return None
diff --git a/sickbeard/metadata/tivo.py b/sickbeard/metadata/tivo.py
index 7744c585154e068e2852a7aff542806176a6642a..0d2b53828b3fad605d3c6c2e837ac2fdf7cfb389 100644
--- a/sickbeard/metadata/tivo.py
+++ b/sickbeard/metadata/tivo.py
@@ -26,8 +26,8 @@ import sickbeard
 
 from sickbeard import logger, exceptions, helpers
 from sickbeard.metadata import generic
-from sickbeard import encodingKludge as ek
 from sickbeard.exceptions import ex
+from sickrage.helper.encoding import ek
 
 
 class TIVOMetadata(generic.GenericMetadata):
@@ -135,10 +135,10 @@ class TIVOMetadata(generic.GenericMetadata):
 
         ep_obj: a TVEpisode object to get the path for
         """
-        if ek.ek(os.path.isfile, ep_obj.location):
-            metadata_file_name = ek.ek(os.path.basename, ep_obj.location) + "." + self._ep_nfo_extension
-            metadata_dir_name = ek.ek(os.path.join, ek.ek(os.path.dirname, ep_obj.location), '.meta')
-            metadata_file_path = ek.ek(os.path.join, metadata_dir_name, metadata_file_name)
+        if ek(os.path.isfile, ep_obj.location):
+            metadata_file_name = ek(os.path.basename, ep_obj.location) + "." + self._ep_nfo_extension
+            metadata_dir_name = ek(os.path.join, ek(os.path.dirname, ep_obj.location), '.meta')
+            metadata_file_path = ek(os.path.join, metadata_dir_name, metadata_file_name)
         else:
             logger.log(u"Episode location doesn't exist: " + str(ep_obj.location), logger.DEBUG)
             return ''
@@ -311,17 +311,17 @@ class TIVOMetadata(generic.GenericMetadata):
             return False
 
         nfo_file_path = self.get_episode_file_path(ep_obj)
-        nfo_file_dir = ek.ek(os.path.dirname, nfo_file_path)
+        nfo_file_dir = ek(os.path.dirname, nfo_file_path)
 
         try:
-            if not ek.ek(os.path.isdir, nfo_file_dir):
+            if not ek(os.path.isdir, nfo_file_dir):
                 logger.log(u"Metadata dir didn't exist, creating it at " + nfo_file_dir, logger.DEBUG)
-                ek.ek(os.makedirs, nfo_file_dir)
+                ek(os.makedirs, nfo_file_dir)
                 helpers.chmodAsParent(nfo_file_dir)
 
             logger.log(u"Writing episode nfo file to " + nfo_file_path, logger.DEBUG)
 
-            with ek.ek(open, nfo_file_path, 'w') as nfo_file:
+            with ek(open, nfo_file_path, 'w') as nfo_file:
                 # Calling encode directly, b/c often descriptions have wonky characters.
                 nfo_file.write(data.encode("utf-8"))
 
diff --git a/sickbeard/metadata/wdtv.py b/sickbeard/metadata/wdtv.py
index bcc625d47587e918097932b0df1b354932dbc04c..530340ac45fc60cd42ed886ef0160125a75b4dc5 100644
--- a/sickbeard/metadata/wdtv.py
+++ b/sickbeard/metadata/wdtv.py
@@ -25,10 +25,9 @@ import sickbeard
 import generic
 
 from sickbeard import logger, exceptions, helpers
-from sickbeard import encodingKludge as ek
-
 from sickbeard.exceptions import ex
 from sickrage.helper.common import dateFormat
+from sickrage.helper.encoding import ek
 
 import xml.etree.cElementTree as etree
 
@@ -124,7 +123,7 @@ class WDTVMetadata(generic.GenericMetadata):
 
         ep_obj: a TVEpisode instance for which to create the thumbnail
         """
-        if ek.ek(os.path.isfile, ep_obj.location):
+        if ek(os.path.isfile, ep_obj.location):
             tbn_filename = helpers.replaceExtension(ep_obj.location, 'metathumb')
         else:
             return None
@@ -138,8 +137,8 @@ class WDTVMetadata(generic.GenericMetadata):
         If no season folder exists, None is returned
         """
 
-        dir_list = [x for x in ek.ek(os.listdir, show_obj.location) if
-                    ek.ek(os.path.isdir, ek.ek(os.path.join, show_obj.location, x))]
+        dir_list = [x for x in ek(os.listdir, show_obj.location) if
+                    ek(os.path.isdir, ek(os.path.join, show_obj.location, x))]
 
         season_dir_regex = '^Season\s+(\d+)$'
 
@@ -166,7 +165,7 @@ class WDTVMetadata(generic.GenericMetadata):
 
         logger.log(u"Using " + str(season_dir) + "/folder.jpg as season dir for season " + str(season), logger.DEBUG)
 
-        return ek.ek(os.path.join, show_obj.location, season_dir, 'folder.jpg')
+        return ek(os.path.join, show_obj.location, season_dir, 'folder.jpg')
 
     def _ep_data(self, ep_obj):
         """
diff --git a/sickbeard/name_cache.py b/sickbeard/name_cache.py
index 0429bff57805e5387ad20078fb0bc7f948ac7a12..8b0af37e8c3f4c497d18c68e23a90d65704362c0 100644
--- a/sickbeard/name_cache.py
+++ b/sickbeard/name_cache.py
@@ -1,5 +1,6 @@
 # Author: Nic Wolfe <nic@wolfeden.ca>
-# URL: http://code.google.com/p/sickbeard/
+# URL: https://sickrage.tv
+# Git: https://github.com/SiCKRAGETV/SickRage.git
 #
 # This file is part of SickRage.
 #
@@ -27,8 +28,8 @@ def addNameToCache(name, indexer_id=0):
     """
     Adds the show & tvdb id to the scene_names table in cache.db.
 
-    name: The show name to cache
-    indexer_id: the TVDB id that this show should be cached with (can be None/0 for unknown)
+    :param name: The show name to cache
+    :param indexer_id: the TVDB id that this show should be cached with (can be None/0 for unknown)
     """
 
     global nameCache
@@ -46,9 +47,8 @@ def retrieveNameFromCache(name):
     """
     Looks up the given name in the scene_names table in cache.db.
 
-    name: The show name to look up.
-
-    Returns: the TVDB id that resulted from the cache lookup or None if the show wasn't found in the cache
+    :param name: The show name to look up.
+    :return: the TVDB id that resulted from the cache lookup or None if the show wasn't found in the cache
     """
     global nameCache
 
@@ -75,6 +75,7 @@ def clearCache(indexerid=0):
 
 
 def saveNameCacheToDb():
+    """Commit cache to database file"""
     cacheDB = db.DBConnection('cache.db')
 
     for name, indexer_id in nameCache.iteritems():
@@ -82,6 +83,10 @@ def saveNameCacheToDb():
 
 
 def buildNameCache(show=None):
+    """Build internal name cache
+
+    :param show: Specify show to build name cache for, if None, just do all shows
+    """
     global nameCache
     with nameCacheLock:
         sickbeard.scene_exceptions.retrieve_exceptions()
diff --git a/sickbeard/name_parser/parser.py b/sickbeard/name_parser/parser.py
index 76b142d14d1ce5959588f9398cea6e758d7cd7b7..512aa2a221fda5028ba74f0da0c749e814e6b05e 100644
--- a/sickbeard/name_parser/parser.py
+++ b/sickbeard/name_parser/parser.py
@@ -25,8 +25,9 @@ import os.path
 import regexes
 import sickbeard
 
-from sickbeard import logger, helpers, scene_numbering, common, scene_exceptions, encodingKludge as ek, db
+from sickbeard import logger, helpers, scene_numbering, common, scene_exceptions, db
 from sickbeard.exceptions import ex
+from sickrage.helper.encoding import ek
 from dateutil import parser
 
 
@@ -225,7 +226,7 @@ class NameParser(object):
                 if sql_result:
                     season_number = int(sql_result[0][0])
                     episode_numbers = [int(sql_result[0][1])]
-                
+
                 if not season_number or not len(episode_numbers):
                     try:
                         lINDEXER_API_PARMS = sickbeard.indexerApi(bestResult.show.indexer).api_params.copy()
@@ -401,7 +402,7 @@ class NameParser(object):
             return cached
 
         # break it into parts if there are any (dirname, file name, extension)
-        dir_name, file_name = ek.ek(os.path.split, name)
+        dir_name, file_name = ek(os.path.split, name)
 
         if self.file_name:
             base_file_name = helpers.remove_extension(file_name)
diff --git a/sickbeard/naming.py b/sickbeard/naming.py
index 693d72ecb8dbe7ef41e5f9515dd1ad709d45d4e6..d2e3723bc83ea3a232d9ee70ab12ddfcd4652781 100644
--- a/sickbeard/naming.py
+++ b/sickbeard/naming.py
@@ -1,5 +1,6 @@
 # Author: Nic Wolfe <nic@wolfeden.ca>
-# URL: http://code.google.com/p/sickbeard/
+# URL: https://sickrage.tv
+# Git: https://github.com/SiCKRAGETV/SickRage.git
 #
 # This file is part of SickRage.
 #
@@ -20,34 +21,38 @@ import datetime
 import os
 
 import sickbeard
-from sickbeard import encodingKludge as ek
 from sickbeard import tv
 from sickbeard import common
 from sickbeard import logger
 from sickbeard.name_parser.parser import NameParser
+from sickrage.helper.encoding import ek
 
 from common import Quality, DOWNLOADED
 
-name_presets = ('%SN - %Sx%0E - %EN',
-                '%S.N.S%0SE%0E.%E.N',
-                '%Sx%0E - %EN',
-                'S%0SE%0E - %EN',
-                'Season %0S/%S.N.S%0SE%0E.%Q.N-%RG'
+name_presets = (
+    '%SN - %Sx%0E - %EN',
+    '%S.N.S%0SE%0E.%E.N',
+    '%Sx%0E - %EN',
+    'S%0SE%0E - %EN',
+    'Season %0S/%S.N.S%0SE%0E.%Q.N-%RG'
 )
 
 name_anime_presets = name_presets
 
-name_abd_presets = ('%SN - %A-D - %EN',
-                    '%S.N.%A.D.%E.N.%Q.N',
-                    '%Y/%0M/%S.N.%A.D.%E.N-%RG'
+name_abd_presets = (
+    '%SN - %A-D - %EN',
+    '%S.N.%A.D.%E.N.%Q.N',
+    '%Y/%0M/%S.N.%A.D.%E.N-%RG'
 )
 
-name_sports_presets = ('%SN - %A-D - %EN',
-                    '%S.N.%A.D.%E.N.%Q.N',
-                    '%Y/%0M/%S.N.%A.D.%E.N-%RG'
+name_sports_presets = (
+    '%SN - %A-D - %EN',
+    '%S.N.%A.D.%E.N.%Q.N',
+    '%Y/%0M/%S.N.%A.D.%E.N-%RG'
 )
 
-class TVShow():
+
+class TVShow:
     def __init__(self):
         self.name = "Show Name"
         self.genre = "Comedy"
@@ -58,7 +63,11 @@ class TVShow():
         self.scene = 0
 
     def _is_anime(self):
-        if (self.anime > 0):
+        """
+        Find out if show is anime
+        :return: True if show is anime, False if not
+        """
+        if self.anime > 0:
             return True
         else:
             return False
@@ -66,7 +75,11 @@ class TVShow():
     is_anime = property(_is_anime)
 
     def _is_sports(self):
-        if (self.sports > 0):
+        """
+        Find out if show is sports
+        :return: True if show is sports, False if not
+        """
+        if self.sports > 0:
             return True
         else:
             return False
@@ -74,7 +87,11 @@ class TVShow():
     is_sports = property(_is_sports)
 
     def _is_scene(self):
-        if (self.scene > 0):
+        """
+        Find out if show is scene numbering
+        :return: True if show is scene numbering, False if not
+        """
+        if self.scene > 0:
             return True
         else:
             return False
@@ -103,8 +120,8 @@ def check_force_season_folders(pattern=None, multi=None, anime_type=None):
     """
     Checks if the name can still be parsed if you strip off the folders to determine if we need to force season folders
     to be enabled or not.
-    
-    Returns true if season folders need to be forced on or false otherwise.
+
+    :return: true if season folders need to be forced on or false otherwise.
     """
     if pattern == None:
         pattern = sickbeard.NAMING_PATTERN
@@ -123,8 +140,8 @@ def check_force_season_folders(pattern=None, multi=None, anime_type=None):
 def check_valid_naming(pattern=None, multi=None, anime_type=None):
     """
     Checks if the name is can be parsed back to its original form for both single and multi episodes.
-    
-    Returns true if the naming is valid, false if not.
+
+    :return: true if the naming is valid, false if not.
     """
     if pattern == None:
         pattern = sickbeard.NAMING_PATTERN
@@ -145,8 +162,8 @@ def check_valid_naming(pattern=None, multi=None, anime_type=None):
 def check_valid_abd_naming(pattern=None):
     """
     Checks if the name is can be parsed back to its original form for an air-by-date format.
-    
-    Returns true if the naming is valid, false if not.
+
+    :return: true if the naming is valid, false if not.
     """
     if pattern == None:
         pattern = sickbeard.NAMING_PATTERN
@@ -156,11 +173,12 @@ def check_valid_abd_naming(pattern=None):
 
     return valid
 
+
 def check_valid_sports_naming(pattern=None):
     """
     Checks if the name is can be parsed back to its original form for an sports format.
 
-    Returns true if the naming is valid, false if not.
+    :return: true if the naming is valid, false if not.
     """
     if pattern == None:
         pattern = sickbeard.NAMING_PATTERN
@@ -170,13 +188,25 @@ def check_valid_sports_naming(pattern=None):
 
     return valid
 
+
 def validate_name(pattern, multi=None, anime_type=None, file_only=False, abd=False, sports=False):
+    """
+    See if we understand a name
+
+    :param pattern: Name to analyse
+    :param multi: Is this a multi-episode name
+    :param anime_type: Is this anime
+    :param file_only: Is this just a file or a dir
+    :param abd: Is air-by-date enabled
+    :param sports: Is this sports
+    :return: True if valid name, False if not
+    """
     ep = generate_sample_ep(multi, abd, sports, anime_type)
 
     new_name = ep.formatted_filename(pattern, multi, anime_type) + '.ext'
     new_path = ep.formatted_dir(pattern, multi)
     if not file_only:
-        new_name = ek.ek(os.path.join, new_path, new_name)
+        new_name = ek(os.path.join, new_path, new_name)
 
     if not new_name:
         logger.log(u"Unable to create a name out of " + pattern, logger.DEBUG)
diff --git a/sickbeard/network_timezones.py b/sickbeard/network_timezones.py
index 7f7c7d70676111570197307f77f88f64f75fcdb5..deb5ebe07bbf54f25b544f2ef7507c218577d119 100644
--- a/sickbeard/network_timezones.py
+++ b/sickbeard/network_timezones.py
@@ -1,5 +1,6 @@
 # Author: Nic Wolfe <nic@wolfeden.ca>
-# URL: http://code.google.com/p/sickbeard/
+# URL: https://sickrage.tv
+# Git: https://github.com/SiCKRAGETV/SickRage.git
 #
 # This file is part of SickRage.
 #
@@ -22,7 +23,7 @@ from dateutil import zoneinfo
 from sickbeard import db
 from sickbeard import helpers
 from sickbeard import logger
-from sickbeard import encodingKludge as ek
+from sickrage.helper.encoding import ek
 from os.path import basename, join, isfile
 import os
 import re
@@ -42,26 +43,29 @@ sb_timezone = tz.tzlocal()
 # helper to remove failed temp download
 def _remove_zoneinfo_failed(filename):
     try:
-        ek.ek(os.remove, filename)
+        ek(os.remove, filename)
     except:
         pass
 
 
 # helper to remove old unneeded zoneinfo files
 def _remove_old_zoneinfo():
+    """
+    Removes zoneinfo tar.gz file from repository, as we do not need it
+    """
     if zoneinfo.ZONEINFOFILE is not None:
-        cur_zoneinfo = ek.ek(basename, zoneinfo.ZONEINFOFILE)
+        cur_zoneinfo = ek(basename, zoneinfo.ZONEINFOFILE)
     else:
         return
 
-    cur_file = helpers.real_path(ek.ek(join, ek.ek(os.path.dirname, zoneinfo.__file__), cur_zoneinfo))
-    for (path, dirs, files) in ek.ek(os.walk, helpers.real_path(ek.ek(os.path.dirname, zoneinfo.__file__))):
+    cur_file = helpers.real_path(ek(join, ek(os.path.dirname, zoneinfo.__file__), cur_zoneinfo))
+    for (path, dirs, files) in ek(os.walk, helpers.real_path(ek(os.path.dirname, zoneinfo.__file__))):
         for filename in files:
             if filename.endswith('.tar.gz'):
-                file_w_path = ek.ek(join, path, filename)
-                if file_w_path != cur_file and ek.ek(isfile, file_w_path):
+                file_w_path = ek(join, path, filename)
+                if file_w_path != cur_file and ek(isfile, file_w_path):
                     try:
-                        ek.ek(os.remove, file_w_path)
+                        ek(os.remove, file_w_path)
                         logger.log(u'Delete unneeded old zoneinfo File: %s' % file_w_path)
                     except:
                         logger.log(u'Unable to delete: %s' % file_w_path, logger.WARNING)
@@ -69,6 +73,9 @@ def _remove_old_zoneinfo():
 
 # update the dateutil zoneinfo
 def _update_zoneinfo():
+    """
+    Request new zoneinfo directly from repository
+    """
     global sb_timezone
     sb_timezone = tz.tzlocal()
     url_zv = 'http://sickragetv.github.io/sb_network_timezones/zoneinfo.txt'
@@ -79,7 +86,7 @@ def _update_zoneinfo():
 
         # Filename of existing zoneinfo
         if zoneinfo.ZONEINFOFILE is not None:
-            cur_zoneinfo = ek.ek(basename, zoneinfo.ZONEINFOFILE)
+            cur_zoneinfo = ek(basename, zoneinfo.ZONEINFOFILE)
         else:
             cur_zoneinfo = None
 
@@ -96,12 +103,12 @@ def _update_zoneinfo():
     # now load the new zoneinfo
     url_tar = u'http://sickragetv.github.io/sb_network_timezones/%s' % new_zoneinfo
 
-    zonefile = helpers.real_path(ek.ek(join, ek.ek(os.path.dirname, zoneinfo.__file__), new_zoneinfo))
+    zonefile = helpers.real_path(ek(join, ek(os.path.dirname, zoneinfo.__file__), new_zoneinfo))
     zonefile_tmp = re.sub(r'\.tar\.gz$', '.tmp', zonefile)
 
-    if ek.ek(os.path.exists, zonefile_tmp):
+    if ek(os.path.exists, zonefile_tmp):
         try:
-            ek.ek(os.remove, zonefile_tmp)
+            ekk(os.remove, zonefile_tmp)
         except:
             logger.log(u'Unable to delete: %s' % zonefile_tmp, logger.WARNING)
             return
@@ -109,7 +116,7 @@ def _update_zoneinfo():
     if not helpers.download_file(url_tar, zonefile_tmp, session=requests.Session()):
         return
 
-    if not ek.ek(os.path.exists, zonefile_tmp):
+    if not ek(os.path.exists, zonefile_tmp):
         logger.log(u'Download of %s failed.' % zonefile_tmp, logger.WARNING)
         return
 
@@ -121,11 +128,11 @@ def _update_zoneinfo():
             # remove the old zoneinfo file
             if cur_zoneinfo is not None:
                 old_file = helpers.real_path(
-                    ek.ek(join, ek.ek(os.path.dirname, zoneinfo.__file__), cur_zoneinfo))
-                if ek.ek(os.path.exists, old_file):
-                    ek.ek(os.remove, old_file)
+                    ek(join, ek(os.path.dirname, zoneinfo.__file__), cur_zoneinfo))
+                if ek(os.path.exists, old_file):
+                    ek(os.remove, old_file)
             # rename downloaded file
-            ek.ek(os.rename, zonefile_tmp, zonefile)
+            ek(os.rename, zonefile_tmp, zonefile)
             # load the new zoneinfo
             reload(zoneinfo)
             sb_timezone = tz.tzlocal()
@@ -140,6 +147,7 @@ def _update_zoneinfo():
 
 # update the network timezone table
 def update_network_dict():
+    """Update timezone information from SR repositories"""
     _remove_old_zoneinfo()
     _update_zoneinfo()
 
@@ -186,6 +194,9 @@ def update_network_dict():
 
 # load network timezones from db into dict
 def load_network_dict():
+    """
+    Load network timezones from db into dict network_dict (global dict)
+    """
     try:
         my_db = db.DBConnection('cache.db')
         cur_network_list = my_db.select('SELECT * FROM network_timezones;')
@@ -201,6 +212,13 @@ def load_network_dict():
 
 # get timezone of a network or return default timezone
 def get_network_timezone(network, network_dict):
+    """
+    Get a timezone of a network from a given network dict
+
+    :param network: network to look up (needle)
+    :param network_dict: dict to look up in (haystack)
+    :return:
+    """
     if network is None:
         return sb_timezone
 
@@ -223,6 +241,14 @@ def get_network_timezone(network, network_dict):
 
 # parse date and time string into local time
 def parse_date_time(d, t, network):
+    """
+    Parse date and time string into local time
+
+    :param d: date string
+    :param t: time string
+    :param network: network to use as base
+    :return: datetime object containing local time
+    """
     if network_dict is None:
         load_network_dict()
     mo = time_regex.search(t)
diff --git a/sickbeard/notifiers/emailnotify.py b/sickbeard/notifiers/emailnotify.py
index 41b32f8d0049d7eed84d908e81225be57afd61dc..f6c9633597249207975a451f54159328d2bdc974 100644
--- a/sickbeard/notifiers/emailnotify.py
+++ b/sickbeard/notifiers/emailnotify.py
@@ -31,7 +31,7 @@ import sickbeard
 
 from sickbeard import logger
 from sickbeard import db
-from sickbeard import encodingKludge as ek
+from sickrage.helper.encoding import ss
 
 
 class EmailNotifier:
@@ -53,7 +53,7 @@ class EmailNotifier:
         ep_name: The name of the episode that was snatched
         title: The title of the notification (optional)
         """
-        ep_name = ek.ss(ep_name)
+        ep_name = ss(ep_name)
 
         if sickbeard.EMAIL_NOTIFY_ONSNATCH:
             show = self._parseEp(ep_name)
@@ -88,11 +88,11 @@ class EmailNotifier:
     def notify_download(self, ep_name, title="Completed:"):
         """
         Send a notification that an episode was downloaded
-        
+
         ep_name: The name of the episode that was downloaded
         title: The title of the notification (optional)
         """
-        ep_name = ek.ss(ep_name)
+        ep_name = ss(ep_name)
 
         if sickbeard.EMAIL_NOTIFY_ONDOWNLOAD:
             show = self._parseEp(ep_name)
@@ -127,11 +127,11 @@ class EmailNotifier:
     def notify_subtitle_download(self, ep_name, lang, title="Downloaded subtitle:"):
         """
         Send a notification that an subtitle was downloaded
-        
+
         ep_name: The name of the episode that was downloaded
         lang: Subtitle language wanted
         """
-        ep_name = ek.ss(ep_name)
+        ep_name = ss(ep_name)
 
         if sickbeard.EMAIL_NOTIFY_ONSUBTITLEDOWNLOAD:
             show = self._parseEp(ep_name)
@@ -196,7 +196,7 @@ class EmailNotifier:
             logger.log(u"Exception generated while sending e-mail: " + str(e), logger.ERROR)
             logger.log(traceback.format_exc(), logger.DEBUG)
             return False
-            
+
         if smtpDebug:
             srv.set_debuglevel(1)
         try:
@@ -217,7 +217,7 @@ class EmailNotifier:
             return False
 
     def _parseEp(self, ep_name):
-        ep_name = ek.ss(ep_name)
+        ep_name = ss(ep_name)
 
         sep = " - "
         titles = ep_name.split(sep)
diff --git a/sickbeard/notifiers/kodi.py b/sickbeard/notifiers/kodi.py
index 1da53717d0754498096f10945745291fa14caca5..8c0720768ef67b3f65a4e2322d88e2e3f4539ad9 100644
--- a/sickbeard/notifiers/kodi.py
+++ b/sickbeard/notifiers/kodi.py
@@ -27,8 +27,7 @@ import sickbeard
 from sickbeard import logger
 from sickbeard import common
 from sickbeard.exceptions import ex
-from sickbeard import encodingKludge as ek
-
+from sickrage.helper.encoding import ss
 
 try:
     import xml.etree.cElementTree as etree
@@ -40,6 +39,7 @@ try:
 except ImportError:
     import simplejson as json
 
+
 class KODINotifier:
     sr_logo_url = 'https://raw.githubusercontent.com/SiCKRAGETV/SickRage/master/gui/slick/images/sickrage-shark-mascot.png'
 
@@ -236,9 +236,9 @@ class KODINotifier:
                 base64string = base64.encodestring('%s:%s' % (username, password))[:-1]
                 authheader = "Basic %s" % base64string
                 req.add_header("Authorization", authheader)
-                logger.log(u"Contacting KODI (with auth header) via url: " + ek.ss(url), logger.DEBUG)
+                logger.log(u"Contacting KODI (with auth header) via url: " + ss(url), logger.DEBUG)
             else:
-                logger.log(u"Contacting KODI via url: " + ek.ss(url), logger.DEBUG)
+                logger.log(u"Contacting KODI via url: " + ss(url), logger.DEBUG)
 
             response = urllib2.urlopen(req)
             result = response.read().decode(sickbeard.SYS_ENCODING)
@@ -248,7 +248,7 @@ class KODINotifier:
             return result
 
         except Exception as e:
-            logger.log(u"Warning: Couldn't contact KODI HTTP at " + ek.ss(url) + " " + str(e),
+            logger.log(u"Warning: Couldn't contact KODI HTTP at " + ss(url) + " " + str(e),
                        logger.WARNING)
             return False
 
@@ -379,9 +379,9 @@ class KODINotifier:
                 base64string = base64.encodestring('%s:%s' % (username, password))[:-1]
                 authheader = "Basic %s" % base64string
                 req.add_header("Authorization", authheader)
-                logger.log(u"Contacting KODI (with auth header) via url: " + ek.ss(url), logger.DEBUG)
+                logger.log(u"Contacting KODI (with auth header) via url: " + ss(url), logger.DEBUG)
             else:
-                logger.log(u"Contacting KODI via url: " + ek.ss(url), logger.DEBUG)
+                logger.log(u"Contacting KODI via url: " + ss(url), logger.DEBUG)
 
             try:
                 response = urllib2.urlopen(req)
@@ -401,7 +401,7 @@ class KODINotifier:
                 return False
 
         except IOError, e:
-            logger.log(u"Warning: Couldn't contact KODI JSON API at " + ek.ss(url) + " " + ex(e),
+            logger.log(u"Warning: Couldn't contact KODI JSON API at " + ss(url) + " " + ex(e),
                        logger.WARNING)
             return False
 
@@ -531,7 +531,7 @@ class KODINotifier:
     def notify_subtitle_download(self, ep_name, lang):
         if sickbeard.KODI_NOTIFY_ONSUBTITLEDOWNLOAD:
             self._notify_kodi(ep_name + ": " + lang, common.notifyStrings[common.NOTIFY_SUBTITLE_DOWNLOAD])
-            
+
     def notify_git_update(self, new_version = "??"):
         if sickbeard.USE_KODI:
             update_text=common.notifyStrings[common.NOTIFY_GIT_UPDATE_TEXT]
diff --git a/sickbeard/notifiers/pytivo.py b/sickbeard/notifiers/pytivo.py
index a38accb2bc9fe60bc470bd2dbabe7f859fcde3c6..5734e6bc1d5cbd9bd30796b21560cc7e16bd3901 100644
--- a/sickbeard/notifiers/pytivo.py
+++ b/sickbeard/notifiers/pytivo.py
@@ -24,7 +24,7 @@ from urllib2 import Request, urlopen, HTTPError
 
 from sickbeard import logger
 from sickbeard.exceptions import ex
-from sickbeard import encodingKludge as ek
+from sickrage.helper.encoding import ek
 
 
 class pyTivoNotifier:
@@ -36,7 +36,7 @@ class pyTivoNotifier:
 
     def notify_subtitle_download(self, ep_name, lang):
         pass
-        
+
     def notify_git_update(self, new_version):
         pass
 
@@ -52,14 +52,14 @@ class pyTivoNotifier:
         tsn = sickbeard.PYTIVO_TIVO_NAME
 
         # There are two more values required, the container and file.
-        # 
+        #
         # container: The share name, show name and season
         #
         # file: The file name
-        # 
+        #
         # Some slicing and dicing of variables is required to get at these values.
         #
-        # There might be better ways to arrive at the values, but this is the best I have been able to 
+        # There might be better ways to arrive at the values, but this is the best I have been able to
         # come up with.
         #
 
@@ -68,7 +68,7 @@ class pyTivoNotifier:
 
         showPath = ep_obj.show.location
         showName = ep_obj.show.name
-        rootShowAndSeason = ek.ek(os.path.dirname, ep_obj.location)
+        rootShowAndSeason = ek(os.path.dirname, ep_obj.location)
         absPath = ep_obj.location
 
         # Some show names have colons in them which are illegal in a path location, so strip them out.
diff --git a/sickbeard/notifiers/synoindex.py b/sickbeard/notifiers/synoindex.py
index 626c0771b3dcb1b76175627f44ea82cb24b4b13a..58d696a2811141903122602f27abee11ee1eb5ab 100644
--- a/sickbeard/notifiers/synoindex.py
+++ b/sickbeard/notifiers/synoindex.py
@@ -16,16 +16,14 @@
 # You should have received a copy of the GNU General Public License
 # along with SickRage.  If not, see <http://www.gnu.org/licenses/>.
 
-
-
 import os
 import subprocess
 
 import sickbeard
 
 from sickbeard import logger
-from sickbeard import encodingKludge as ek
 from sickbeard.exceptions import ex
+from sickrage.helper.encoding import ek
 
 
 class synoIndexNotifier:
@@ -37,7 +35,7 @@ class synoIndexNotifier:
 
     def notify_subtitle_download(self, ep_name, lang):
         pass
-        
+
     def notify_git_update(self, new_version):
         pass
 
@@ -49,10 +47,10 @@ class synoIndexNotifier:
 
     def moveObject(self, old_path, new_path):
         if sickbeard.USE_SYNOINDEX:
-            synoindex_cmd = ['/usr/syno/bin/synoindex', '-N', ek.ek(os.path.abspath, new_path),
-                             ek.ek(os.path.abspath, old_path)]
+            synoindex_cmd = ['/usr/syno/bin/synoindex', '-N', ek(os.path.abspath, new_path),
+                             ek(os.path.abspath, old_path)]
             logger.log(u"Executing command " + str(synoindex_cmd), logger.DEBUG)
-            logger.log(u"Absolute path to command: " + ek.ek(os.path.abspath, synoindex_cmd[0]), logger.DEBUG)
+            logger.log(u"Absolute path to command: " + ek(os.path.abspath, synoindex_cmd[0]), logger.DEBUG)
             try:
                 p = subprocess.Popen(synoindex_cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
                                      cwd=sickbeard.PROG_DIR)
@@ -75,9 +73,9 @@ class synoIndexNotifier:
 
     def makeObject(self, cmd_arg, cur_path):
         if sickbeard.USE_SYNOINDEX:
-            synoindex_cmd = ['/usr/syno/bin/synoindex', cmd_arg, ek.ek(os.path.abspath, cur_path)]
+            synoindex_cmd = ['/usr/syno/bin/synoindex', cmd_arg, ek(os.path.abspath, cur_path)]
             logger.log(u"Executing command " + str(synoindex_cmd), logger.DEBUG)
-            logger.log(u"Absolute path to command: " + ek.ek(os.path.abspath, synoindex_cmd[0]), logger.DEBUG)
+            logger.log(u"Absolute path to command: " + ek(os.path.abspath, synoindex_cmd[0]), logger.DEBUG)
             try:
                 p = subprocess.Popen(synoindex_cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
                                      cwd=sickbeard.PROG_DIR)
diff --git a/sickbeard/notifiers/synologynotifier.py b/sickbeard/notifiers/synologynotifier.py
index a67c769fdcfd56fd3f557e04101f04bd8f2b02e3..16d38ab12f7ba07d599ba9a62ed3cfd24b2044b1 100644
--- a/sickbeard/notifiers/synologynotifier.py
+++ b/sickbeard/notifiers/synologynotifier.py
@@ -15,17 +15,15 @@
 # You should have received a copy of the GNU General Public License
 # along with SickRage.  If not, see <http://www.gnu.org/licenses/>.
 
-
-
 import os
 import subprocess
 
 import sickbeard
 
 from sickbeard import logger
-from sickbeard import encodingKludge as ek
 from sickbeard.exceptions import ex
 from sickbeard import common
+from sickrage.helper.encoding import ek
 
 
 class synologyNotifier:
@@ -40,7 +38,7 @@ class synologyNotifier:
     def notify_subtitle_download(self, ep_name, lang):
         if sickbeard.SYNOLOGYNOTIFIER_NOTIFY_ONSUBTITLEDOWNLOAD:
             self._send_synologyNotifier(ep_name + ": " + lang, common.notifyStrings[common.NOTIFY_SUBTITLE_DOWNLOAD])
-            
+
     def notify_git_update(self, new_version = "??"):
         if sickbeard.USE_SYNOLOGYNOTIFIER:
             update_text=common.notifyStrings[common.NOTIFY_GIT_UPDATE_TEXT]
@@ -50,7 +48,7 @@ class synologyNotifier:
     def _send_synologyNotifier(self, message, title):
         synodsmnotify_cmd = ["/usr/syno/bin/synodsmnotify", "@administrators", title, message]
         logger.log(u"Executing command " + str(synodsmnotify_cmd))
-        logger.log(u"Absolute path to command: " + ek.ek(os.path.abspath, synodsmnotify_cmd[0]), logger.DEBUG)
+        logger.log(u"Absolute path to command: " + ek(os.path.abspath, synodsmnotify_cmd[0]), logger.DEBUG)
         try:
             p = subprocess.Popen(synodsmnotify_cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
                                  cwd=sickbeard.PROG_DIR)
diff --git a/sickbeard/nzbSplitter.py b/sickbeard/nzbSplitter.py
index 079c16b75680a4d87738a1a8a644bf85ebbfac1b..4713cff07ed98e5c588607c8e0dd1c3c98e19785 100644
--- a/sickbeard/nzbSplitter.py
+++ b/sickbeard/nzbSplitter.py
@@ -1,5 +1,6 @@
 # Author: Nic Wolfe <nic@wolfeden.ca>
-# URL: http://code.google.com/p/sickbeard/
+# URL: https://sickrage.tv
+# Git: https://github.com/SiCKRAGETV/SickRage.git
 #
 # This file is part of SickRage.
 #
@@ -26,12 +27,21 @@ import re
 
 from sickbeard import logger, classes, helpers
 from sickbeard.common import Quality
-from sickbeard import encodingKludge as ek
 from sickbeard.exceptions import ex
+from sickrage.helper.encoding import ek, ss
 
 from name_parser.parser import NameParser, InvalidNameException, InvalidShowException
 
+
 def getSeasonNZBs(name, urlData, season):
+    """
+    Split a season NZB into episodes
+
+    :param name: NZB name
+    :param urlData: URL to get data from
+    :param season: Season to check
+    :return: dict of (episode files, xml matches)
+    """
     try:
         showXML = etree.ElementTree(etree.XML(urlData))
     except SyntaxError:
@@ -84,12 +94,18 @@ def createNZBString(fileElements, xmlns):
     for curFile in fileElements:
         rootElement.append(stripNS(curFile, xmlns))
 
-    return xml.etree.ElementTree.tostring(ek.ss(rootElement))
+    return xml.etree.ElementTree.tostring(ss(rootElement))
 
 
 def saveNZB(nzbName, nzbString):
+    """
+    Save NZB to disk
+
+    :param nzbName: Filename/path to write to
+    :param nzbString: Content to write in file
+    """
     try:
-        with ek.ek(open, nzbName + ".nzb", 'w') as nzb_fh:
+        with ek(open, nzbName + ".nzb", 'w') as nzb_fh:
             nzb_fh.write(nzbString)
 
     except EnvironmentError, e:
@@ -105,6 +121,12 @@ def stripNS(element, ns):
 
 
 def splitResult(result):
+    """
+    Split result into seperate episodes
+
+    :param result: search result object
+    :return: False upon failure, a list of episode objects otherwise
+    """
     urlData = helpers.getURL(result.url, session=requests.Session())
     if urlData is None:
         logger.log(u"Unable to load url " + result.url + ", can't download season NZB", logger.ERROR)
diff --git a/sickbeard/nzbget.py b/sickbeard/nzbget.py
index e4d914e36baefacab535b38289559cc1e85bd4ef..077f57de470be9231c93f4e5f06740c56f88ba1d 100644
--- a/sickbeard/nzbget.py
+++ b/sickbeard/nzbget.py
@@ -1,5 +1,6 @@
 # Author: Nic Wolfe <nic@wolfeden.ca>
-# URL: http://code.google.com/p/sickbeard/
+# URL: https://sickrage.tv
+# Git: https://github.com/SiCKRAGETV/SickRage.git
 #
 # This file is part of SickRage.
 #
@@ -34,6 +35,12 @@ from common import Quality
 
 
 def sendNZB(nzb, proper=False):
+    """
+    Sends NZB to NZBGet client
+
+    :param nzb: nzb object
+    :param proper: True if this is a Proper download, False if not. Defaults to False
+    """
     addToTop = False
     nzbgetprio = 0
     category = sickbeard.NZBGET_CATEGORY
diff --git a/sickbeard/postProcessor.py b/sickbeard/postProcessor.py
index b57a4e3dbddbf4bc2652546509b113f00b8efaf4..54bc70c7a49ac208a1f93f718f7e71434c8ad8f4 100644
--- a/sickbeard/postProcessor.py
+++ b/sickbeard/postProcessor.py
@@ -1,5 +1,6 @@
 # Author: Nic Wolfe <nic@wolfeden.ca>
-# URL: http://code.google.com/p/sickbeard/
+# URL: https://sickrage.tv
+# Git: https://github.com/SiCKRAGETV/SickRage.git
 #
 # This file is part of SickRage.
 #
@@ -36,10 +37,9 @@ from sickbeard import logger
 from sickbeard import notifiers
 from sickbeard import show_name_helpers
 from sickbeard import failed_history
-from sickbeard import encodingKludge as ek
 from sickbeard.exceptions import ex
-
 from sickbeard.name_parser.parser import NameParser, InvalidNameException, InvalidShowException
+from sickrage.helper.encoding import ek
 
 import adba
 from sickbeard.helpers import verify_freespace
@@ -65,16 +65,16 @@ class PostProcessor(object):
         nzb_name: The name of the NZB which resulted in this file being downloaded (optional)
         """
         # absolute path to the folder that is being processed
-        self.folder_path = ek.ek(os.path.dirname, ek.ek(os.path.abspath, file_path))
+        self.folder_path = ek(os.path.dirname, ek(os.path.abspath, file_path))
 
         # full path to file
         self.file_path = file_path
 
         # file name only
-        self.file_name = ek.ek(os.path.basename, file_path)
+        self.file_name = ek(os.path.basename, file_path)
 
         # the name of the folder only
-        self.folder_name = ek.ek(os.path.basename, self.folder_path)
+        self.folder_name = ek(os.path.basename, self.folder_path)
 
         # name of the NZB that resulted in this folder
         self.nzb_name = nzb_name
@@ -99,8 +99,8 @@ class PostProcessor(object):
         """
         A wrapper for the internal logger which also keeps track of messages and saves them to a string for later.
 
-        message: The string to log (unicode)
-        level: The log level to use (optional)
+        :param message: The string to log (unicode)
+        :param level: The log level to use (optional)
         """
         logger.log(message, level)
         self.log += message + '\n'
@@ -110,9 +110,9 @@ class PostProcessor(object):
         Checks if a file exists already and if it does whether it's bigger or smaller than
         the file we are post processing
 
-        existing_file: The file to compare to
+        ;param existing_file: The file to compare to
 
-        Returns:
+        :return:
             DOESNT_EXIST if the file doesn't exist
             EXISTS_LARGER if the file exists and is larger than the file we are post processing
             EXISTS_SMALLER if the file exists and is smaller than the file we are post processing
@@ -124,14 +124,14 @@ class PostProcessor(object):
             return PostProcessor.DOESNT_EXIST
 
         # if the new file exists, return the appropriate code depending on the size
-        if ek.ek(os.path.isfile, existing_file):
+        if ek(os.path.isfile, existing_file):
 
             # see if it's bigger than our old file
-            if ek.ek(os.path.getsize, existing_file) > ek.ek(os.path.getsize, self.file_path):
+            if ek(os.path.getsize, existing_file) > ek(os.path.getsize, self.file_path):
                 self._log(u"File " + existing_file + " is larger than " + self.file_path, logger.DEBUG)
                 return PostProcessor.EXISTS_LARGER
 
-            elif ek.ek(os.path.getsize, existing_file) == ek.ek(os.path.getsize, self.file_path):
+            elif ek(os.path.getsize, existing_file) == ek(os.path.getsize, self.file_path):
                 self._log(u"File " + existing_file + " is the same size as " + self.file_path, logger.DEBUG)
                 return PostProcessor.EXISTS_SAME
 
@@ -148,11 +148,11 @@ class PostProcessor(object):
         """
         For a given file path searches for files with the same name but different extension and returns their absolute paths
 
-        file_path: The file to check for associated files
+        :param file_path: The file to check for associated files
 
-        base_name_only: False add extra '.' (conservative search) to file_path minus extension
+        :param base_name_only: False add extra '.' (conservative search) to file_path minus extension
 
-        Returns: A list containing all files which are associated to the given file
+        :return: A list containing all files which are associated to the given file
         """
         def recursive_glob(treeroot, pattern):
             results = []
@@ -167,7 +167,7 @@ class PostProcessor(object):
         file_path_list = []
 
         if subfolders:
-            base_name = ek.ek(os.path.basename, file_path).rpartition('.')[0]
+            base_name = ek(os.path.basename, file_path).rpartition('.')[0]
         else:
             base_name = file_path.rpartition('.')[0]
 
@@ -182,11 +182,11 @@ class PostProcessor(object):
         base_name = re.sub(r'[\[\]\*\?]', r'[\g<0>]', base_name)
 
         if subfolders: # subfolders are only checked in show folder, so names will always be exactly alike
-            filelist = ek.ek(recursive_glob, ek.ek(os.path.dirname, file_path), base_name + '*') # just create the list of all files starting with the basename
+            filelist = ek(recursive_glob, ek(os.path.dirname, file_path), base_name + '*') # just create the list of all files starting with the basename
         else: # this is called when PP, so we need to do the filename check case-insensitive
             filelist = []
 
-            checklist = ek.ek(glob.glob, helpers.fixGlob(ek.ek(os.path.join, ek.ek(os.path.dirname, file_path), '*'))) # get a list of all the files in the folder
+            checklist = ek(glob.glob, helpers.fixGlob(ek(os.path.join, ek(os.path.dirname, file_path), '*'))) # get a list of all the files in the folder
             for filefound in checklist: # loop through all the files in the folder, and check if they are the same name even when the cases don't match
                 file_name = filefound.rpartition('.')[0]
                 if not base_name_only:
@@ -194,7 +194,6 @@ class PostProcessor(object):
                 if file_name.lower() == base_name.lower(): # if there's no difference in the filename add it to the filelist
                     filelist.append(filefound)
 
-
         for associated_file_path in filelist:
             # only add associated to list
             if associated_file_path == file_path:
@@ -207,7 +206,7 @@ class PostProcessor(object):
             if re.search('(^.+\.(rar|r\d+)$)', associated_file_path):
                 continue
 
-            if ek.ek(os.path.isfile, associated_file_path):
+            if ek(os.path.isfile, associated_file_path):
                 file_path_list.append(associated_file_path)
 
         if file_path_list:
@@ -221,8 +220,8 @@ class PostProcessor(object):
         """
         Deletes the file and optionally all associated files.
 
-        file_path: The file to delete
-        associated_files: True to delete all files which differ only by extension, False to leave them
+        :param file_path: The file to delete
+        :param associated_files: True to delete all files which differ only by extension, False to leave them
         """
 
         if not file_path:
@@ -239,19 +238,19 @@ class PostProcessor(object):
 
         # delete the file and any other files which we want to delete
         for cur_file in file_list:
-            if ek.ek(os.path.isfile, cur_file):
+            if ek(os.path.isfile, cur_file):
                 self._log(u"Deleting file " + cur_file, logger.DEBUG)
                 # check first the read-only attribute
-                file_attribute = ek.ek(os.stat, cur_file)[0]
-                if (not file_attribute & stat.S_IWRITE):
+                file_attribute = ek(os.stat, cur_file)[0]
+                if not file_attribute & stat.S_IWRITE:
                     # File is read-only, so make it writeable
                     self._log('Read only mode on file ' + cur_file + ' Will try to make it writeable', logger.DEBUG)
                     try:
-                        ek.ek(os.chmod, cur_file, stat.S_IWRITE)
+                        ek(os.chmod, cur_file, stat.S_IWRITE)
                     except:
                         self._log(u'Cannot change permissions of ' + cur_file, logger.WARNING)
 
-                ek.ek(os.remove, cur_file)
+                ek(os.remove, cur_file)
 
                 # do the library update for synoindex
                 notifiers.synoindex_notifier.deleteFile(cur_file)
@@ -262,11 +261,12 @@ class PostProcessor(object):
         Performs a generic operation (move or copy) on a file. Can rename the file as well as change its location,
         and optionally move associated files too.
 
-        file_path: The full path of the media file to act on
-        new_path: Destination path where we want to move/copy the file to
-        new_base_name: The base filename (no extension) to use during the copy. Use None to keep the same name.
-        associated_files: Boolean, whether we should copy similarly-named files too
-        action: function that takes an old path and new path and does an operation with them (move/copy)
+        :param file_path: The full path of the media file to act on
+        :param new_path: Destination path where we want to move/copy the file to
+        :param new_base_name: The base filename (no extension) to use during the copy. Use None to keep the same name.
+        :param associated_files: Boolean, whether we should copy similarly-named files too
+        :param action: function that takes an old path and new path and does an operation with them (move/copy)
+        :param subtitles: Boolean, whether we should process subtitles too
         """
 
         if not action:
@@ -290,7 +290,7 @@ class PostProcessor(object):
         # deal with all files
         for cur_file_path in file_list:
 
-            cur_file_name = ek.ek(os.path.basename, cur_file_path)
+            cur_file_name = ek(os.path.basename, cur_file_path)
 
             # get the extension without .
             cur_extension = cur_file_path[old_base_name_length + 1:]
@@ -313,24 +313,26 @@ class PostProcessor(object):
                 new_file_name = helpers.replaceExtension(cur_file_name, cur_extension)
 
             if sickbeard.SUBTITLES_DIR and cur_extension in common.subtitleExtensions:
-                subs_new_path = ek.ek(os.path.join, new_path, sickbeard.SUBTITLES_DIR)
+                subs_new_path = ek(os.path.join, new_path, sickbeard.SUBTITLES_DIR)
                 dir_exists = helpers.makeDir(subs_new_path)
                 if not dir_exists:
                     logger.log(u"Unable to create subtitles folder " + subs_new_path, logger.ERROR)
                 else:
                     helpers.chmodAsParent(subs_new_path)
-                new_file_path = ek.ek(os.path.join, subs_new_path, new_file_name)
+                new_file_path = ek(os.path.join, subs_new_path, new_file_name)
             else:
-                new_file_path = ek.ek(os.path.join, new_path, new_file_name)
+                new_file_path = ek(os.path.join, new_path, new_file_name)
 
             action(cur_file_path, new_file_path)
 
     def _move(self, file_path, new_path, new_base_name, associated_files=False, subtitles=False):
         """
-        file_path: The full path of the media file to move
-        new_path: Destination path where we want to move the file to
-        new_base_name: The base filename (no extension) to use during the move. Use None to keep the same name.
-        associated_files: Boolean, whether we should move similarly-named files too
+        Move file and set proper permissions
+
+        :param file_path: The full path of the media file to move
+        :param new_path: Destination path where we want to move the file to
+        :param new_base_name: The base filename (no extension) to use during the move. Use None to keep the same name.
+        :param associated_files: Boolean, whether we should move similarly-named files too
         """
 
         def _int_move(cur_file_path, new_file_path):
@@ -348,10 +350,12 @@ class PostProcessor(object):
 
     def _copy(self, file_path, new_path, new_base_name, associated_files=False, subtitles=False):
         """
-        file_path: The full path of the media file to copy
-        new_path: Destination path where we want to copy the file to
-        new_base_name: The base filename (no extension) to use during the copy. Use None to keep the same name.
-        associated_files: Boolean, whether we should copy similarly-named files too
+        Copy file and set proper permissions
+
+        :param file_path: The full path of the media file to copy
+        :param new_path: Destination path where we want to copy the file to
+        :param new_base_name: The base filename (no extension) to use during the copy. Use None to keep the same name.
+        :param associated_files: Boolean, whether we should copy similarly-named files too
         """
 
         def _int_copy(cur_file_path, new_file_path):
@@ -370,10 +374,12 @@ class PostProcessor(object):
 
     def _hardlink(self, file_path, new_path, new_base_name, associated_files=False, subtitles=False):
         """
-        file_path: The full path of the media file to move
-        new_path: Destination path where we want to create a hard linked file
-        new_base_name: The base filename (no extension) to use during the link. Use None to keep the same name.
-        associated_files: Boolean, whether we should move similarly-named files too
+        Hardlink file and set proper permissions
+
+        :param file_path: The full path of the media file to move
+        :param new_path: Destination path where we want to create a hard linked file
+        :param new_base_name: The base filename (no extension) to use during the link. Use None to keep the same name.
+        :param associated_files: Boolean, whether we should move similarly-named files too
         """
 
         def _int_hard_link(cur_file_path, new_file_path):
@@ -390,10 +396,12 @@ class PostProcessor(object):
 
     def _moveAndSymlink(self, file_path, new_path, new_base_name, associated_files=False, subtitles=False):
         """
-        file_path: The full path of the media file to move
-        new_path: Destination path where we want to move the file to create a symbolic link to
-        new_base_name: The base filename (no extension) to use during the link. Use None to keep the same name.
-        associated_files: Boolean, whether we should move similarly-named files too
+        Move file, symlink source location back to destination, and set proper permissions
+
+        :param file_path: The full path of the media file to move
+        :param new_path: Destination path where we want to move the file to create a symbolic link to
+        :param new_base_name: The base filename (no extension) to use during the link. Use None to keep the same name.
+        :param associated_files: Boolean, whether we should move similarly-named files too
         """
 
         def _int_move_and_sym_link(cur_file_path, new_file_path):
@@ -413,7 +421,7 @@ class PostProcessor(object):
         """
         Look up the NZB name in the history and see if it contains a record for self.nzb_name
 
-        Returns a (indexer_id, season, [], quality, version) tuple. The first two may be None if none were found.
+        :return: A (indexer_id, season, [], quality, version) tuple. The first two may be None if none were found.
         """
 
         to_return = (None, None, [], None, None)
@@ -462,6 +470,11 @@ class PostProcessor(object):
         return to_return
 
     def _finalize(self, parse_result):
+        """
+        Store parse result if it is complete and final
+
+        :param parse_result: Result of parsers
+        """
         self.release_group = parse_result.release_group
 
         # remember whether it's a proper
@@ -474,7 +487,7 @@ class PostProcessor(object):
                                          or parse_result.air_date) and parse_result.release_group:
 
             if not self.release_name:
-                self.release_name = helpers.remove_extension(ek.ek(os.path.basename, parse_result.original_name))
+                self.release_name = helpers.remove_extension(ek(os.path.basename, parse_result.original_name))
 
         else:
             logger.log(u"Parse result not sufficient (all following have to be set). will not save release name",
@@ -485,14 +498,13 @@ class PostProcessor(object):
             logger.log(u" or Parse result(air_date): " + str(parse_result.air_date), logger.DEBUG)
             logger.log(u"Parse result(release_group): " + str(parse_result.release_group), logger.DEBUG)
 
-
     def _analyze_name(self, name, file=True):
         """
         Takes a name and tries to figure out a show, season, and episode from it.
 
-        name: A string which we want to analyze to determine show info from (unicode)
+        :param name: A string which we want to analyze to determine show info from (unicode)
 
-        Returns a (indexer_id, season, [episodes]) tuple. The first two may be None and episodes may be []
+        :return: A (indexer_id, season, [episodes]) tuple. The first two may be None and episodes may be []
         if none were found.
         """
 
@@ -525,6 +537,13 @@ class PostProcessor(object):
         return to_return
 
     def _build_anidb_episode(self, connection, filePath):
+        """
+        Look up anidb properties for an episode
+
+        :param connection: anidb connection handler
+        :param filePath: file to check
+        :return: episode object
+        """
         ep = adba.Episode(connection, filePath=filePath,
                           paramsF=["quality", "anidb_file_name", "crc32"],
                           paramsA=["epno", "english_name", "short_name_list", "other_name", "synonym_list"])
@@ -532,8 +551,13 @@ class PostProcessor(object):
         return ep
 
     def _add_to_anidb_mylist(self, filePath):
+        """
+        Adds an episode to anidb mylist
+
+        :param filePath: file to add to mylist
+        """
         if helpers.set_up_anidb_connection():
-            if not self.anidbEpisode:  # seams like we could parse the name before, now lets build the anidb object
+            if not self.anidbEpisode:  # seems like we could parse the name before, now lets build the anidb object
                 self.anidbEpisode = self._build_anidb_episode(sickbeard.ADBA_CONNECTION, filePath)
 
             self._log(u"Adding the file to the anidb mylist", logger.DEBUG)
@@ -545,6 +569,8 @@ class PostProcessor(object):
     def _find_info(self):
         """
         For a given file try to find the showid, season, and episode.
+
+        :return: A (show, season, episodes, quality, version) tuple
         """
 
         show = season = quality = version = None
@@ -646,11 +672,11 @@ class PostProcessor(object):
         """
         Retrieve the TVEpisode object requested.
 
-        show: The show object belonging to the show we want to process
-        season: The season of the episode (int)
-        episodes: A list of episodes to find (list of ints)
+        :param show: The show object belonging to the show we want to process
+        :param season: The season of the episode (int)
+        :param episodes: A list of episodes to find (list of ints)
 
-        If the episode(s) can be found then a TVEpisode object with the correct related eps will
+        :return: If the episode(s) can be found then a TVEpisode object with the correct related eps will
         be instantiated and returned. If the episode can't be found then None will be returned.
         """
 
@@ -681,9 +707,8 @@ class PostProcessor(object):
         Determines the quality of the file that is being post processed, first by checking if it is directly
         available in the TVEpisode's status or otherwise by parsing through the data available.
 
-        ep_obj: The TVEpisode object related to the file we are post processing
-
-        Returns: A quality value found in common.Quality
+        :param ep_obj: The TVEpisode object related to the file we are post processing
+        :return: A quality value found in common.Quality
         """
 
         ep_quality = common.Quality.UNKNOWN
@@ -744,13 +769,13 @@ class PostProcessor(object):
         """
         Executes any extra scripts defined in the config.
 
-        ep_obj: The object to use when calling the extra script
+        :param ep_obj: The object to use when calling the extra script
         """
         for curScriptName in sickbeard.EXTRA_SCRIPTS:
 
             # generate a safe command line string to execute the script and provide all the parameters
             script_cmd = [piece for piece in re.split("( |\\\".*?\\\"|'.*?')", curScriptName) if piece.strip()]
-            script_cmd[0] = ek.ek(os.path.abspath, script_cmd[0])
+            script_cmd[0] = ek(os.path.abspath, script_cmd[0])
             self._log(u"Absolute path to script: " + script_cmd[0], logger.DEBUG)
 
             script_cmd = script_cmd + [ep_obj.location, self.file_path, str(ep_obj.show.indexerid), str(ep_obj.season),
@@ -775,10 +800,9 @@ class PostProcessor(object):
         Determines if the episode is a priority download or not (if it is expected). Episodes which are expected
         (snatched) or larger than the existing episode are priority, others are not.
 
-        ep_obj: The TVEpisode object in question
-        new_ep_quality: The quality of the episode that is being processed
-
-        Returns: True if the episode is priority, False otherwise.
+        :param ep_obj: The TVEpisode object in question
+        :param new_ep_quality: The quality of the episode that is being processed
+        :return: True if the episode is priority, False otherwise.
         """
 
         if self.is_priority:
@@ -819,11 +843,13 @@ class PostProcessor(object):
     def process(self):
         """
         Post-process a given file
+
+        :return: True on success, False on failure
         """
 
         self._log(u"Processing " + self.file_path + " (" + str(self.nzb_name) + ")")
 
-        if ek.ek(os.path.isdir, self.file_path):
+        if ek(os.path.isdir, self.file_path):
             self._log(u"File " + self.file_path + " seems to be a directory")
             return False
 
@@ -924,8 +950,7 @@ class PostProcessor(object):
 
                 # clean up any left over folders
                 if cur_ep.location:
-                    helpers.delete_empty_folders(ek.ek(os.path.dirname, cur_ep.location),
-                                                 keep_dir=ep_obj.show._location)
+                    helpers.delete_empty_folders(ek(os.path.dirname, cur_ep.location), keep_dir=ep_obj.show._location)
             except (OSError, IOError):
                 raise exceptions.PostProcessingFailed("Unable to delete the existing files")
 
@@ -934,10 +959,10 @@ class PostProcessor(object):
             #    curEp.status = common.Quality.compositeStatus(common.SNATCHED, new_ep_quality)
 
         # if the show directory doesn't exist then make it if allowed
-        if not ek.ek(os.path.isdir, ep_obj.show._location) and sickbeard.CREATE_MISSING_SHOW_DIRS:
+        if not ek(os.path.isdir, ep_obj.show._location) and sickbeard.CREATE_MISSING_SHOW_DIRS:
             self._log(u"Show directory doesn't exist, creating it", logger.DEBUG)
             try:
-                ek.ek(os.mkdir, ep_obj.show._location)
+                ek(os.mkdir, ep_obj.show._location)
                 helpers.chmodAsParent(ep_obj.show._location)
 
                 # do the library update for synoindex
@@ -992,9 +1017,9 @@ class PostProcessor(object):
         # find the destination folder
         try:
             proper_path = ep_obj.proper_path()
-            proper_absolute_path = ek.ek(os.path.join, ep_obj.show.location, proper_path)
+            proper_absolute_path = ek(os.path.join, ep_obj.show.location, proper_path)
 
-            dest_path = ek.ek(os.path.dirname, proper_absolute_path)
+            dest_path = ek(os.path.dirname, proper_absolute_path)
         except exceptions.ShowDirNotFoundException:
             raise exceptions.PostProcessingFailed(
                 u"Unable to post-process an episode if the show dir doesn't exist, quitting")
@@ -1007,7 +1032,7 @@ class PostProcessor(object):
         # figure out the base name of the resulting episode file
         if sickbeard.RENAME_EPISODES:
             orig_extension = self.file_name.rpartition('.')[-1]
-            new_base_name = ek.ek(os.path.basename, proper_path)
+            new_base_name = ek(os.path.basename, proper_path)
             new_file_name = new_base_name + '.' + orig_extension
 
         else:
@@ -1049,7 +1074,7 @@ class PostProcessor(object):
         if sickbeard.USE_SUBTITLES and ep_obj.show.subtitles:
             for cur_ep in [ep_obj] + ep_obj.relatedEps:
                 with cur_ep.lock:
-                    cur_ep.location = ek.ek(os.path.join, dest_path, new_file_name)
+                    cur_ep.location = ek(os.path.join, dest_path, new_file_name)
                     cur_ep.downloadSubtitles(force=True)
 
         # now that processing has finished, we can put the info in the DB. If we do it earlier, then when processing fails, it won't try again.
@@ -1061,7 +1086,7 @@ class PostProcessor(object):
         sql_l = []
         for cur_ep in [ep_obj] + ep_obj.relatedEps:
             with cur_ep.lock:
-                cur_ep.location = ek.ek(os.path.join, dest_path, new_file_name)
+                cur_ep.location = ek(os.path.join, dest_path, new_file_name)
                 sql_l.append(cur_ep.get_sql())
 
         if len(sql_l) > 0:
diff --git a/sickbeard/processTV.py b/sickbeard/processTV.py
index 821992a42f879bedb14776ae5bc7e83283c1c6f8..b4dfc42b4b7705d95c485e2c0644dc7f31e85418 100644
--- a/sickbeard/processTV.py
+++ b/sickbeard/processTV.py
@@ -1,5 +1,6 @@
 # Author: Nic Wolfe <nic@wolfeden.ca>
-# URL: http://code.google.com/p/sickbeard/
+# URL: https://sickrage.tv/
+# Git: https://github.com/SiCKRAGETV/SickRage.git
 #
 # This file is part of SickRage.
 #
@@ -24,13 +25,12 @@ import stat
 import sickbeard
 from sickbeard import postProcessor
 from sickbeard import db, helpers, exceptions
-from sickbeard import encodingKludge as ek
 from sickbeard.exceptions import ex
 from sickbeard import logger
 from sickbeard.name_parser.parser import NameParser, InvalidNameException, InvalidShowException
 from sickbeard import common
-
 from sickbeard import failedProcessor
+from sickrage.helper.encoding import ek
 
 from unrar2 import RarFile
 from unrar2.rar_exceptions import *
@@ -48,10 +48,18 @@ class ProcessResult:
         self.missedfiles = []
         self.aggresult = True
 
+
 def delete_folder(folder, check_empty=True):
+    """
+    Removes a folder from the filesystem
+
+    :param folder: Path to folder to remove
+    :param check_empty: Boolean, check if the folder is empty before removing it, defaults to True
+    :return: True on success, False on failure
+    """
 
     # check if it's a folder
-    if not ek.ek(os.path.isdir, folder):
+    if not ek(os.path.isdir, folder):
         return False
 
     # check if it isn't TV_DOWNLOAD_DIR
@@ -61,11 +69,11 @@ def delete_folder(folder, check_empty=True):
 
     # check if it's empty folder when wanted checked
     if check_empty:
-        check_files = ek.ek(os.listdir, folder)
+        check_files = ek(os.listdir, folder)
         if check_files:
             logger.log(u"Not deleting folder " + folder + " found the following files: " + str(check_files), logger.INFO)
             return False
-        
+
         try:
             logger.log(u"Deleting folder (if it's empty): " + folder)
             os.rmdir(folder)
@@ -82,38 +90,48 @@ def delete_folder(folder, check_empty=True):
 
     return True
 
+
 def delete_files(processPath, notwantedFiles, result, force=False):
+    """
+    Remove files from filesystem
+
+    :param processPath: path to process
+    :param notwantedFiles: files we do not want
+    :param result: Processor results
+    :param force: Boolean, force deletion, defaults to false
+    """
 
     if not result.result and force:
         result.output += logHelper(u"Forcing deletion of files, even though last result was not success", logger.DEBUG)
     elif not result.result:
         return
 
-    #Delete all file not needed
+    # Delete all file not needed
     for cur_file in notwantedFiles:
 
-        cur_file_path = ek.ek(os.path.join, processPath, cur_file)
+        cur_file_path = ek(os.path.join, processPath, cur_file)
 
-        if not ek.ek(os.path.isfile, cur_file_path):
-            continue  #Prevent error when a notwantedfiles is an associated files
+        if not ek(os.path.isfile, cur_file_path):
+            continue  # Prevent error when a notwantedfiles is an associated files
 
         result.output += logHelper(u"Deleting file " + cur_file, logger.DEBUG)
 
-        #check first the read-only attribute
-        file_attribute = ek.ek(os.stat, cur_file_path)[0]
-        if (not file_attribute & stat.S_IWRITE):
+        # check first the read-only attribute
+        file_attribute = ek(os.stat, cur_file_path)[0]
+        if not file_attribute & stat.S_IWRITE:
             # File is read-only, so make it writeable
             result.output += logHelper(u"Changing ReadOnly Flag for file " + cur_file, logger.DEBUG)
             try:
-                ek.ek(os.chmod, cur_file_path, stat.S_IWRITE)
+                ek(os.chmod, cur_file_path, stat.S_IWRITE)
             except OSError, e:
                 result.output += logHelper(u"Cannot change permissions of " + cur_file_path + ': ' + str(e.strerror),
                                        logger.DEBUG)
         try:
-            ek.ek(os.remove, cur_file_path)
+            ek(os.remove, cur_file_path)
         except OSError, e:
             result.output += logHelper(u"Unable to delete file " + cur_file + ': ' + str(e.strerror), logger.DEBUG)
 
+
 def logHelper(logMessage, logLevel=logger.INFO):
     logger.log(logMessage, logLevel)
     return logMessage + u"\n"
@@ -123,11 +141,11 @@ def processDir(dirName, nzbName=None, process_method=None, force=False, is_prior
     """
     Scans through the files in dirName and processes whatever media files it finds
 
-    dirName: The folder name to look in
-    nzbName: The NZB name which resulted in this folder being downloaded
-    force: True to postprocess already postprocessed files
-    failed: Boolean for whether or not the download failed
-    type: Type of postprocessing auto or manual
+    :param dirName: The folder name to look in
+    :param nzbName: The NZB name which resulted in this folder being downloaded
+    :param force: True to postprocess already postprocessed files
+    :param failed: Boolean for whether or not the download failed
+    :param type: Type of postprocessing auto or manual
     """
 
     result = ProcessResult()
@@ -137,17 +155,17 @@ def processDir(dirName, nzbName=None, process_method=None, force=False, is_prior
     result.output += logHelper(u"TV_DOWNLOAD_DIR: " + sickbeard.TV_DOWNLOAD_DIR, logger.DEBUG)
     postpone = False
     # if they passed us a real dir then assume it's the one we want
-    if ek.ek(os.path.isdir, dirName):
-        dirName = ek.ek(os.path.realpath, dirName)
+    if ek(os.path.isdir, dirName):
+        dirName = ek(os.path.realpath, dirName)
 
     # if the client and SickRage are not on the same machine translate the Dir in a network dir
-    elif sickbeard.TV_DOWNLOAD_DIR and ek.ek(os.path.isdir, sickbeard.TV_DOWNLOAD_DIR) \
-            and ek.ek(os.path.normpath, dirName) != ek.ek(os.path.normpath, sickbeard.TV_DOWNLOAD_DIR):
-        dirName = ek.ek(os.path.join, sickbeard.TV_DOWNLOAD_DIR, ek.ek(os.path.abspath, dirName).split(os.path.sep)[-1])
+    elif sickbeard.TV_DOWNLOAD_DIR and ek(os.path.isdir, sickbeard.TV_DOWNLOAD_DIR) \
+            and ek(os.path.normpath, dirName) != ek(os.path.normpath, sickbeard.TV_DOWNLOAD_DIR):
+        dirName = ek(os.path.join, sickbeard.TV_DOWNLOAD_DIR, ek(os.path.abspath, dirName).split(os.path.sep)[-1])
         result.output += logHelper(u"Trying to use folder " + dirName, logger.DEBUG)
 
     # if we didn't find a real dir then quit
-    if not ek.ek(os.path.isdir, dirName):
+    if not ek(os.path.isdir, dirName):
         result.output += logHelper(
             u"Unable to figure out what folder to process. If your downloader and SickRage aren't on the same PC make sure you fill out your TV download dir in the config.",
             logger.DEBUG)
@@ -185,9 +203,9 @@ def processDir(dirName, nzbName=None, process_method=None, force=False, is_prior
 
         if not process_method:
             process_method = sickbeard.PROCESS_METHOD
-    
+
         result.result = True
-    
+
         #Don't Link media when the media is extracted from a rar in the same path
         if process_method in ('hardlink', 'symlink') and videoInRar:
             process_media(path, videoInRar, nzbName, 'move', force, is_priority, result)
@@ -202,24 +220,24 @@ def processDir(dirName, nzbName=None, process_method=None, force=False, is_prior
         else:
             for video in videoFiles:
                 process_media(path, [video], nzbName, process_method, force, is_priority, result)
-        
+
     else:
         result.output += logHelper(u"Found temporary sync files, skipping post processing for folder " + str(path), logger.WARNING)
         result.output += logHelper(u"Sync Files: " + str(SyncFiles) + " in path: " + path, logger.WARNING)
         result.missedfiles.append(path + " : Syncfiles found")
-        
+
     #Process Video File in all TV Subdir
     for dir in [x for x in dirs if validateDir(path, x, nzbNameOriginal, failed, result)]:
 
         result.result = True
 
-        for processPath, processDir, fileList in ek.ek(os.walk, ek.ek(os.path.join, path, dir), topdown=False):
-            
+        for processPath, processDir, fileList in ek(os.walk, ek(os.path.join, path, dir), topdown=False):
+
             if (not validateDir(path, processPath, nzbNameOriginal, failed, result)):
                 continue
-            
+
             postpone = False
-            
+
             SyncFiles = filter(helpers.isSyncFile, fileList)
 
             # Don't post process if files are still being synced and option is activated
@@ -235,7 +253,7 @@ def processDir(dirName, nzbName=None, process_method=None, force=False, is_prior
                 notwantedFiles = [x for x in fileList if x not in videoFiles]
                 if notwantedFiles:
                     result.output += logHelper(u"Found unwanted files: " + str(notwantedFiles), logger.DEBUG)
-    
+
                 #Don't Link media when the media is extracted from a rar in the same path
                 if process_method in ('hardlink', 'symlink') and videoInRar:
                     process_media(processPath, videoInRar, nzbName, 'move', force, is_priority, result)
@@ -249,16 +267,16 @@ def processDir(dirName, nzbName=None, process_method=None, force=False, is_prior
                     delete_files(processPath, rarContent, result, True)
                 else:
                     process_media(processPath, videoFiles, nzbName, process_method, force, is_priority, result)
-    
+
                     #Delete all file not needed
                     if process_method != "move" or not result.result \
                             or (type == "manual" and not delete_on):  #Avoid to delete files if is Manual PostProcessing
                         continue
-    
+
                     delete_files(processPath, notwantedFiles, result)
-    
+
                     if (not sickbeard.NO_DELETE or type == "manual") and process_method == "move" and \
-                                    ek.ek(os.path.normpath, processPath) != ek.ek(os.path.normpath,
+                                    ek(os.path.normpath, processPath) != ek(os.path.normpath,
                                                                                   sickbeard.TV_DOWNLOAD_DIR):
                         if delete_folder(processPath, check_empty=True):
                             result.output += logHelper(u"Deleted folder: " + processPath, logger.DEBUG)
@@ -266,7 +284,7 @@ def processDir(dirName, nzbName=None, process_method=None, force=False, is_prior
                 result.output += logHelper(u"Found temporary sync files, skipping post processing for folder: " + str(processPath), logger.WARNING)
                 result.output += logHelper(u"Sync Files: " + str(SyncFiles) + " in path: " + processPath, logger.WARNING)
                 result.missedfiles.append(processPath + " : Syncfiles found")
-                                
+
     if result.aggresult:
         result.output += logHelper(u"Processing completed")
         if result.missedfiles:
@@ -282,17 +300,27 @@ def processDir(dirName, nzbName=None, process_method=None, force=False, is_prior
 
 
 def validateDir(path, dirName, nzbNameOriginal, failed, result):
+    """
+    Check if directory is valid for processing
+
+    :param path: Path to use
+    :param dirName: Directory to check
+    :param nzbNameOriginal: Original NZB name
+    :param failed: Previously failed objects
+    :param result: Previous results
+    :return: True if dir is valid for processing, False if not
+    """
 
     result.output += logHelper(u"Processing folder " + dirName, logger.DEBUG)
 
-    if ek.ek(os.path.basename, dirName).startswith('_FAILED_'):
+    if ek(os.path.basename, dirName).startswith('_FAILED_'):
         result.output += logHelper(u"The directory name indicates it failed to extract.", logger.DEBUG)
         failed = True
-    elif ek.ek(os.path.basename, dirName).startswith('_UNDERSIZED_'):
+    elif ek(os.path.basename, dirName).startswith('_UNDERSIZED_'):
         result.output += logHelper(u"The directory name indicates that it was previously rejected for being undersized.",
                                logger.DEBUG)
         failed = True
-    elif ek.ek(os.path.basename, dirName).upper().startswith('_UNPACK'):
+    elif ek(os.path.basename, dirName).upper().startswith('_UNPACK'):
         result.output += logHelper(u"The directory name indicates that this release is in the process of being unpacked.",
                                logger.DEBUG)
         result.missedfiles.append(dirName + " : Being unpacked")
@@ -314,7 +342,7 @@ def validateDir(path, dirName, nzbNameOriginal, failed, result):
 
     for sqlShow in sqlResults:
         if dirName.lower().startswith(
-                        ek.ek(os.path.realpath, sqlShow["location"]).lower() + os.sep) or dirName.lower() == ek.ek(
+                        ek(os.path.realpath, sqlShow["location"]).lower() + os.sep) or dirName.lower() == ek(
                 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,
@@ -324,7 +352,7 @@ def validateDir(path, dirName, nzbNameOriginal, failed, result):
     # Get the videofile list for the next checks
     allFiles = []
     allDirs = []
-    for processPath, processDir, fileList in ek.ek(os.walk, ek.ek(os.path.join, path, dirName), topdown=False):
+    for processPath, processDir, fileList in ek(os.walk, ek(os.path.join, path, dirName), topdown=False):
         allDirs += processDir
         allFiles += fileList
 
@@ -356,11 +384,20 @@ def validateDir(path, dirName, nzbNameOriginal, failed, result):
                 return True
             except (InvalidNameException, InvalidShowException):
                 pass
-            
+
     result.output += logHelper(dirName + " : No processable items found in folder", logger.DEBUG)
     return False
 
 def unRAR(path, rarFiles, force, result):
+    """
+    Extracts RAR files
+
+    :param path: Path to look for files in
+    :param rarFiles: Names of RAR files
+    :param force: process currently processing items
+    :param result: Previous results
+    :return: List of unpacked file names
+    """
 
     unpacked_files = []
 
@@ -433,7 +470,15 @@ def unRAR(path, rarFiles, force, result):
 
 
 def already_postprocessed(dirName, videofile, force, result):
+    """
+    Check if we already post processed a file
 
+    :param dirName: Directory a file resides in
+    :param videofile: File name
+    :param force: Force checking when already checking (currently unused)
+    :param result: True if file is already postprocessed, False if not
+    :return:
+    """
     if force:
         return False
 
@@ -449,7 +494,7 @@ def already_postprocessed(dirName, videofile, force, result):
         if sqlResult:
             #result.output += logHelper(u"You're trying to post process a video that's already been processed, skipping", logger.DEBUG)
             return True
-        
+
         #Needed if we have downloaded the same episode @ different quality
         #But we need to make sure we check the history of the episode we're going to PP, and not others
         np = NameParser(dirName, tryIndexers=True, trySceneExceptions=True)
@@ -457,14 +502,14 @@ def already_postprocessed(dirName, videofile, force, result):
             parse_result = np.parse(dirName)
         except: #ignore the exception, because we kind of expected it, but create parse_result anyway so we can perform a check on it.
             parse_result = False
-        
-        
+
+
         search_sql = "SELECT tv_episodes.indexerid, history.resource FROM tv_episodes INNER JOIN history ON history.showid=tv_episodes.showid" #This part is always the same
         search_sql += " WHERE history.season=tv_episodes.season and history.episode=tv_episodes.episode"
         #If we find a showid, a season number, and one or more episode numbers then we need to use those in the query
         if parse_result and (parse_result.show.indexerid and parse_result.episode_numbers and parse_result.season_number):
             search_sql += " and tv_episodes.showid = '" + str(parse_result.show.indexerid) + "' and tv_episodes.season = '" + str(parse_result.season_number) + "' and tv_episodes.episode = '" + str(parse_result.episode_numbers[0]) + "'"
-        
+
         search_sql += " and tv_episodes.status IN (" + ",".join([str(x) for x in common.Quality.DOWNLOADED]) + ")"
         search_sql += " and history.resource LIKE ?"
         sqlResult = myDB.select(search_sql, [u'%' + videofile])
@@ -476,10 +521,21 @@ def already_postprocessed(dirName, videofile, force, result):
 
 
 def process_media(processPath, videoFiles, nzbName, process_method, force, is_priority, result):
+    """
+    Postprocess mediafiles
+
+    :param processPath: Path to postprocess in
+    :param videoFiles: Filenames to look for and postprocess
+    :param nzbName: Name of NZB file related
+    :param process_method: auto/manual
+    :param force: Postprocess currently postprocessing file
+    :param is_priority: Boolean, is this a priority download
+    :param result: Previous results
+    """
 
     processor = None
     for cur_video_file in videoFiles:
-        cur_video_file_path = ek.ek(os.path.join, processPath, cur_video_file)
+        cur_video_file_path = ek(os.path.join, processPath, cur_video_file)
 
         if already_postprocessed(processPath, cur_video_file, force, result):
             result.output += logHelper(u"Already Processed " + cur_video_file_path + " : Skipping", logger.DEBUG)
@@ -506,18 +562,26 @@ def process_media(processPath, videoFiles, nzbName, process_method, force, is_pr
 
 
 def get_path_dir_files(dirName, nzbName, type):
+    """
+    Get files in a path
+
+    :param dirName: Directory to start in
+    :param nzbName: NZB file, if present
+    :param type: auto/manual
+    :return: a tuple of (path,dirs,files)
+    """
     path = ""
     dirs = []
     files = []
 
-    if dirName == sickbeard.TV_DOWNLOAD_DIR and not nzbName or type == "manual":  #Scheduled Post Processing Active
-        #Get at first all the subdir in the dirName
-        for path, dirs, files in ek.ek(os.walk, dirName):
+    if dirName == sickbeard.TV_DOWNLOAD_DIR and not nzbName or type == "manual":  # Scheduled Post Processing Active
+        # Get at first all the subdir in the dirName
+        for path, dirs, files in ek(os.walk, dirName):
             break
     else:
-        path, dirs = ek.ek(os.path.split, dirName)  #Script Post Processing
+        path, dirs = ek(os.path.split, dirName)  # Script Post Processing
         if not nzbName is None and not nzbName.endswith('.nzb') and os.path.isfile(
-                os.path.join(dirName, nzbName)):  #For single torrent file without Dir
+                os.path.join(dirName, nzbName)):  # For single torrent file without Dir
             dirs = []
             files = [os.path.join(dirName, nzbName)]
         else:
diff --git a/sickbeard/properFinder.py b/sickbeard/properFinder.py
index 2b98188476a078c9ab0084ef7b5aeeae6cb2a231..9a8e11b987619028e375edc6c25ead2c76c93c52 100644
--- a/sickbeard/properFinder.py
+++ b/sickbeard/properFinder.py
@@ -1,5 +1,6 @@
 # Author: Nic Wolfe <nic@wolfeden.ca>
-# URL: http://code.google.com/p/sickbeard/
+# URL: https://sickrage.tv
+# Git: https://github.com/SiCKRAGETV/SickRage.git
 #
 # This file is part of SickRage.
 #
@@ -44,6 +45,11 @@ class ProperFinder():
         self.amActive = False
 
     def run(self, force=False):
+        """
+        Start looking for new propers
+
+        :param force: Start even if already running (currently not used, defaults to False)
+        """
         logger.log(u"Beginning the search for new propers")
 
         self.amActive = True
@@ -68,6 +74,9 @@ class ProperFinder():
         self.amActive = False
 
     def _getProperList(self):
+        """
+        Walk providers for propers
+        """
         propers = {}
 
         search_date = datetime.datetime.today() - datetime.timedelta(days=2)
@@ -201,6 +210,11 @@ class ProperFinder():
         return finalPropers
 
     def _downloadPropers(self, properList):
+        """
+        Download proper (snatch it)
+
+        :param properList:
+        """
 
         for curProper in properList:
 
@@ -256,6 +270,11 @@ class ProperFinder():
         return name.replace(".", " ").replace("-", " ").replace("_", " ").lower()
 
     def _set_lastProperSearch(self, when):
+        """
+        Record last propersearch in DB
+
+        :param when: When was the last proper search
+        """
 
         logger.log(u"Setting the last Proper search in the DB to " + str(when), logger.DEBUG)
 
@@ -269,6 +288,9 @@ class ProperFinder():
             myDB.action("UPDATE info SET last_proper_search=" + str(when))
 
     def _get_lastProperSearch(self):
+        """
+        Find last propersearch from DB
+        """
 
         myDB = db.DBConnection()
         sqlResults = myDB.select("SELECT * FROM info")
diff --git a/sickbeard/providers/__init__.py b/sickbeard/providers/__init__.py
index d30caaede43f352f0220782a6ac7201e6974fe55..8314f0467776b8d49f196ed411bdfba50e6e622b 100644
--- a/sickbeard/providers/__init__.py
+++ b/sickbeard/providers/__init__.py
@@ -52,7 +52,9 @@ __all__ = ['womble',
            'xthor',
            'scenetime',
            'btdigg',
-		   'strike',
+           'strike',
+           'transmitthenet',
+           'tvchaosuk'
 ]
 
 import sickbeard
diff --git a/sickbeard/providers/generic.py b/sickbeard/providers/generic.py
index cd0eb802f545fe659d8f243081c0a57c340b9d5f..0c1c91f7c1d75133e71e2ad65f731433a77c1ac4 100644
--- a/sickbeard/providers/generic.py
+++ b/sickbeard/providers/generic.py
@@ -32,14 +32,13 @@ from hachoir_parser import createParser
 
 import sickbeard
 from sickbeard import helpers, classes, logger, db
-from sickbeard.common import MULTI_EP_RESULT, SEASON_RESULT, USER_AGENT
+from sickbeard.common import MULTI_EP_RESULT, SEASON_RESULT
 from sickbeard import tvcache
-from sickbeard import encodingKludge as ek
 from sickbeard.exceptions import ex
 from sickbeard.name_parser.parser import NameParser, InvalidNameException, InvalidShowException
 from sickbeard.common import Quality
 from sickbeard.common import user_agents
-
+from sickrage.helper.encoding import ek
 
 
 class GenericProvider:
@@ -168,25 +167,24 @@ class GenericProvider:
 
                 if not torrent_hash:
                     logger.log("Unable to extract torrent hash from magnet: " + ex(result.url), logger.ERROR)
-                    return (urls, filename)
+                    return urls, filename
 
                 urls = [x.format(torrent_hash=torrent_hash, torrent_name=torrent_name) for x in self.btCacheURLS]
             except:
                 logger.log("Unable to extract torrent hash or name from magnet: " + ex(result.url), logger.ERROR)
-                return (urls, filename)
+                return urls, filename
         else:
             urls = [result.url]
 
         if self.providerType == GenericProvider.TORRENT:
-            filename = ek.ek(os.path.join, sickbeard.TORRENT_DIR,
-                             helpers.sanitizeFileName(result.name) + '.' + self.providerType)
+            filename = ek(os.path.join, sickbeard.TORRENT_DIR,
+                          helpers.sanitizeFileName(result.name) + '.' + self.providerType)
 
         elif self.providerType == GenericProvider.NZB:
-            filename = ek.ek(os.path.join, sickbeard.NZB_DIR,
-                             helpers.sanitizeFileName(result.name) + '.' + self.providerType)
-
-        return (urls, filename)
+            filename = ek(os.path.join, sickbeard.NZB_DIR,
+                          helpers.sanitizeFileName(result.name) + '.' + self.providerType)
 
+        return urls, filename
 
     def downloadResult(self, result):
         """
diff --git a/sickbeard/providers/newznab.py b/sickbeard/providers/newznab.py
index 838bedff56b435c348180d983ef2f902d1b920f8..f52925d910c5f745f90f1bfdfa079671d5ea7958 100644
--- a/sickbeard/providers/newznab.py
+++ b/sickbeard/providers/newznab.py
@@ -28,11 +28,12 @@ from sickbeard.common import Quality
 from sickbeard import classes
 from sickbeard import helpers
 from sickbeard import scene_exceptions
-from sickbeard import encodingKludge as ek
 from sickbeard import logger
 from sickbeard import tvcache
 from sickbeard import db
 from sickbeard.exceptions import AuthException
+from sickrage.helper.encoding import ek
+
 
 class NewznabProvider(generic.NZBProvider):
     def __init__(self, name, url, key='0', catIDs='5030,5040', search_mode='eponly', search_fallback=False,
@@ -76,8 +77,8 @@ class NewznabProvider(generic.NZBProvider):
             int(self.enable_daily)) + '|' + str(int(self.enable_backlog))
 
     def imageName(self):
-        if ek.ek(os.path.isfile,
-                 ek.ek(os.path.join, sickbeard.PROG_DIR, 'gui', sickbeard.GUI_NAME, 'images', 'providers',
+        if ek(os.path.isfile,
+                 ek(os.path.join, sickbeard.PROG_DIR, 'gui', sickbeard.GUI_NAME, 'images', 'providers',
                        self.getID() + '.png')):
             return self.getID() + '.png'
         return 'newznab.png'
diff --git a/sickbeard/providers/rsstorrent.py b/sickbeard/providers/rsstorrent.py
index 0fc185a91d38cd01eb8265246a2cc5bb437ba8e5..13f5c64ae014edefddfaec7ef9dc5d14bf482ffd 100644
--- a/sickbeard/providers/rsstorrent.py
+++ b/sickbeard/providers/rsstorrent.py
@@ -15,7 +15,6 @@
 # You should have received a copy of the GNU General Public License
 # along with SickRage.  If not, see <http://www.gnu.org/licenses/>.
 
-
 import os
 import re
 
@@ -23,10 +22,10 @@ import sickbeard
 import generic
 
 from sickbeard import helpers
-from sickbeard import encodingKludge as ek
 from sickbeard import logger
 from sickbeard import tvcache
 from sickbeard.exceptions import ex
+from sickrage.helper.encoding import ek
 
 import requests
 from bencode import bdecode
@@ -65,8 +64,8 @@ class TorrentRssProvider(generic.TorrentProvider):
                                             self.enable_backlog)
 
     def imageName(self):
-        if ek.ek(os.path.isfile,
-                 ek.ek(os.path.join, sickbeard.PROG_DIR, 'gui', sickbeard.GUI_NAME, 'images', 'providers',
+        if ek(os.path.isfile,
+                 ek(os.path.join, sickbeard.PROG_DIR, 'gui', sickbeard.GUI_NAME, 'images', 'providers',
                        self.getID() + '.png')):
             return self.getID() + '.png'
         return 'torrentrss.png'
@@ -137,8 +136,7 @@ class TorrentRssProvider(generic.TorrentProvider):
             return (False, 'Error when trying to load RSS: ' + ex(e))
 
     def dumpHTML(self, data):
-
-        dumpName = ek.ek(os.path.join, sickbeard.CACHE_DIR, 'custom_torrent.html')
+        dumpName = ek(os.path.join, sickbeard.CACHE_DIR, 'custom_torrent.html')
 
         try:
             fileOut = open(dumpName, 'wb')
diff --git a/sickbeard/providers/transmitthenet.py b/sickbeard/providers/transmitthenet.py
new file mode 100644
index 0000000000000000000000000000000000000000..ec35943724a6b189cf9143fe2fbdd4d566ae7e6c
--- /dev/null
+++ b/sickbeard/providers/transmitthenet.py
@@ -0,0 +1,276 @@
+# This file is part of SickRage.
+#
+# SickRage is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# SickRage is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with SickRage.  If not, see <http://www.gnu.org/licenses/>.
+
+import re
+import traceback
+import datetime
+import sickbeard
+import generic
+import requests
+
+from sickbeard.common import Quality
+from sickbeard import logger
+from sickbeard import tvcache
+from sickbeard import db
+from sickbeard import classes
+from sickbeard import helpers
+from sickbeard import show_name_helpers
+from sickbeard.exceptions import ex, AuthException
+from sickbeard.helpers import sanitizeSceneName
+from sickbeard.bs4_parser import BS4Parser
+from unidecode import unidecode
+from urllib import urlencode
+
+
+class TransmitTheNetProvider(generic.TorrentProvider):
+    def __init__(self):
+        generic.TorrentProvider.__init__(self, "TransmitTheNet")
+
+        self.urls = {
+            'base_url': 'https://transmithe.net/',
+            'index': 'https://transmithe.net/index.php',
+            }
+
+        self.url = self.urls['base_url']
+
+        self.supportsBacklog = True
+        self.enabled = False
+        self.username = None
+        self.password = None
+        self.ratio = None
+        self.minseed = None
+        self.minleech = None
+
+        self.cache = TransmitTheNetCache(self)
+
+        self.search_params = {
+            'page': 'torrents', "category": 1, "active": 1
+        }
+
+    def isEnabled(self):
+        return self.enabled
+
+    def imageName(self):
+        return 'transmitthenet.png'
+
+    def getQuality(self, item, anime=False):
+
+        quality = Quality.sceneQuality(item[0], anime)
+        return quality
+
+    def _checkAuth(self):
+        if not self.username or not self.password:
+            raise AuthException("Your authentication credentials for " + self.name + " are missing, check your config.")
+
+        return True
+
+    def _doLogin(self):
+
+        login_params = {
+             'uid': self.username,
+             'pwd': self.password,
+             'remember_me': 'on',
+             'login': 'submit'
+            }
+
+        response = self.getURL(self.urls['index'], params={'page': 'login'}, post_data=login_params, timeout=30)
+        if not response:
+            logger.log(u'Unable to connect to ' + self.name + ' provider.', logger.ERROR)
+            return False
+
+        if re.search('Username Incorrect', response) or re.search('Password Incorrect', response):
+            logger.log(u'Invalid username or password for ' + self.name + ' Check your settings', logger.ERROR)
+            return False
+        else:
+            logger.log(u'Login successful for ' + self.name, logger.DEBUG)
+
+        return True
+
+    def _get_season_search_strings(self, ep_obj):
+
+        search_string = {'Season': []}
+        for show_name in set(show_name_helpers.allPossibleShowNames(self.show)):
+            if ep_obj.show.air_by_date or ep_obj.show.sports:
+                ep_string = show_name + ' ' + str(ep_obj.airdate).split('-')[0]
+            elif ep_obj.show.anime:
+                ep_string = show_name + ' ' + "%d" % ep_obj.scene_absolute_number
+            else:
+                ep_string = show_name + ' S%02d' % int(ep_obj.scene_season)  #1) showName SXX
+
+            search_string['Season'].append(ep_string.strip())
+
+        return [search_string]
+
+    def _get_episode_search_strings(self, ep_obj, add_string=''):
+
+        search_string = {'Episode': []}
+
+        if not ep_obj:
+            return []
+
+        if self.show.air_by_date:
+            for show_name in set(show_name_helpers.allPossibleShowNames(self.show)):
+                ep_string = sanitizeSceneName(show_name) + ' ' + \
+                            str(ep_obj.airdate).replace('-', '|')
+                search_string['Episode'].append(ep_string)
+        elif self.show.sports:
+            for show_name in set(show_name_helpers.allPossibleShowNames(self.show)):
+                ep_string = sanitizeSceneName(show_name) + ' ' + \
+                            str(ep_obj.airdate).replace('-', '|') + '|' + \
+                            ep_obj.airdate.strftime('%b')
+                search_string['Episode'].append(ep_string)
+        elif self.show.anime:
+            for show_name in set(show_name_helpers.allPossibleShowNames(self.show)):
+                ep_string = sanitizeSceneName(show_name) + ' ' + \
+                            "%i" % int(ep_obj.scene_absolute_number)
+                search_string['Episode'].append(ep_string)
+        else:
+            for show_name in set(show_name_helpers.allPossibleShowNames(self.show)):
+                ep_string = sanitizeSceneName(show_name) + ' ' + \
+                            sickbeard.config.naming_ep_type[2] % {'seasonnumber': ep_obj.scene_season,
+                                                                  'episodenumber': ep_obj.scene_episode} + ' %s' % add_string
+
+                search_string['Episode'].append(re.sub('\s+', ' ', ep_string))
+
+        return [search_string]
+
+    def _doSearch(self, search_strings, search_mode='eponly', epcount=0, age=0, epObj=None):
+
+        results = []
+        items = {'Season': [], 'Episode': [], 'RSS': []}
+
+        if not self._doLogin():
+            return results
+
+        for mode in search_strings.keys():
+            for search_string in search_strings[mode]:
+
+                self.search_params['search'] = search_string.strip()
+                logger.log(u"Search string: " + self.search_params['search'] + " for " + self.name, logger.DEBUG)
+
+                data = self.getURL(self.urls['index'], params=self.search_params)
+                url_searched = self.urls['index'] + "?" + urlencode(self.search_params)
+
+                if not data:
+                    logger.log(u"The response from (" + url_searched + ") is empty.",logger.DEBUG)
+                    continue
+
+                logger.log(u"Search query from (" + url_searched + ") returned data.",logger.DEBUG)
+
+                try:
+                    with BS4Parser(data) as html:
+
+                        torrent_rows = []
+                        
+                        down_elems = html.findAll("img", {"alt": "Download Torrent"})
+                        for down_elem in down_elems:
+                            if down_elem:
+                                torr_row = down_elem.findParent('tr')
+                                if torr_row:
+                                    torrent_rows.append(torr_row)
+
+                        #Continue only if one Release is found
+                        if len(torrent_rows) < 1:
+                             logger.log(u"The Data returned from " + self.name + " did not contain any torrent", logger.DEBUG)
+                             continue
+
+                        for torrent_row in torrent_rows:
+
+                            title = torrent_row.find('a',{"data-src": True})['data-src'].rsplit('.', 1)[0]
+                            download_href = torrent_row.find('img', {"alt": 'Download Torrent'}).findParent()['href']
+                            id = torrent_row.find('a',{"data-src": True})['href'].split("&id=", 1)[1]
+                            seeders = int(torrent_row.findAll('a', {'title': 'Click here to view peers details'})[0].text.strip())
+                            leechers = int(torrent_row.findAll('a', {'title': 'Click here to view peers details'})[1].text.strip())
+
+                            #Filter unseeded torrent
+                            if seeders < self.minseed:
+                                continue
+
+                            if not title or not download_href:
+                                continue
+
+                            download_url = self.urls['base_url'] + download_href
+
+                            item = title, download_url, id, seeders, leechers
+                            logger.log(u"Found result: " + title.replace(' ','.') + " (" + download_url + ")", logger.DEBUG)
+
+                            items[mode].append(item)
+
+                except:
+                    logger.log(u"Failed parsing " + self.name + " Traceback: " + traceback.format_exc(), logger.ERROR)
+
+            #For each search mode sort all the items by seeders
+            items[mode].sort(key=lambda tup: tup[3], reverse=True)
+
+            results += items[mode]
+
+        return results
+
+    def _get_title_and_url(self, item):
+
+        title, url, id, seeders, leechers = item
+
+        if title:
+            title = self._clean_title_from_provider(title)
+
+        if url:
+            url = str(url).replace('&amp;', '&')
+
+        return (title, url)
+
+    def findPropers(self, search_date=datetime.datetime.today()):
+
+        results = []
+
+        myDB = db.DBConnection()
+        sqlResults = myDB.select(
+            'SELECT s.show_name, e.showid, e.season, e.episode, e.status, e.airdate FROM tv_episodes AS e' +
+            ' INNER JOIN tv_shows AS s ON (e.showid = s.indexer_id)' +
+            ' WHERE e.airdate >= ' + str(search_date.toordinal()) +
+            ' AND (e.status IN (' + ','.join([str(x) for x in Quality.DOWNLOADED]) + ')' +
+            ' OR (e.status IN (' + ','.join([str(x) for x in Quality.SNATCHED]) + ')))'
+        )
+
+        for sqlshow in sqlResults or []:
+            self.show = helpers.findCertainShow(sickbeard.showList, int(sqlshow["showid"]))
+            if self.show:
+                curEp = self.show.getEpisode(int(sqlshow["season"]), int(sqlshow["episode"]))
+
+                searchString = self._get_episode_search_strings(curEp, add_string='PROPER|REPACK')
+
+                for item in self._doSearch(searchString[0]):
+                    title, url = self._get_title_and_url(item)
+                    results.append(classes.Proper(title, url, datetime.datetime.today(), self.show))
+
+        return results
+
+    def seedRatio(self):
+        return self.ratio
+
+
+class TransmitTheNetCache(tvcache.TVCache):
+    def __init__(self, provider):
+
+        tvcache.TVCache.__init__(self, provider)
+
+        # only poll TorrentBytes every 20 minutes max
+        self.minTime = 20
+
+    def _getRSSData(self):
+        search_strings = {'RSS': ['']}
+        return {'entries': self.provider._doSearch(search_strings)}
+
+
+provider = TransmitTheNetProvider()
\ No newline at end of file
diff --git a/sickbeard/providers/tvchaosuk.py b/sickbeard/providers/tvchaosuk.py
new file mode 100644
index 0000000000000000000000000000000000000000..66406b665eb074bf829ed8ef90bb75ea44cc1238
--- /dev/null
+++ b/sickbeard/providers/tvchaosuk.py
@@ -0,0 +1,261 @@
+# This file is part of SickRage.
+#
+# SickRage is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# SickRage is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with SickRage.  If not, see <http://www.gnu.org/licenses/>.
+
+import re
+import traceback
+import datetime
+import sickbeard
+import generic
+
+from sickbeard.common import Quality
+from sickbeard import logger
+from sickbeard import tvcache
+from sickbeard import db
+from sickbeard import classes
+from sickbeard import helpers
+from sickbeard import show_name_helpers
+from sickbeard.exceptions import ex, AuthException
+from sickbeard.helpers import sanitizeSceneName
+from sickbeard.bs4_parser import BS4Parser
+
+from urllib import urlencode
+
+
+class TVChaosUKProvider(generic.TorrentProvider):
+    def __init__(self):
+        generic.TorrentProvider.__init__(self, 'TvChaosUK')
+
+        self.urls = {
+            'base_url': 'https://tvchaosuk.com/',
+            'login': 'https://tvchaosuk.com/takelogin.php',
+            'index': 'https://tvchaosuk.com/index.php',
+            'search': 'https://tvchaosuk.com/browse.php'
+            }
+
+        self.url = self.urls['base_url']
+
+        self.supportsBacklog = True
+        self.enabled = False
+        self.username = None
+        self.password = None
+        self.ratio = None
+        self.minseed = None
+        self.minleech = None
+
+        self.cache = TVChaosUKCache(self)
+
+        self.search_params = {
+            'do': 'search',
+            'keywords':  '',
+            'search_type': 't_name',
+            'category': 0,
+            'include_dead_torrents': 'no',
+        }
+
+    def isEnabled(self):
+        return self.enabled
+
+    def imageName(self):
+        return 'tvchaosuk.png'
+
+    def getQuality(self, item, anime=False):
+        return Quality.sceneQuality(item[0], anime)
+
+    def _checkAuth(self):
+        if self.username and self.password:
+            return True
+
+        raise AuthException('Your authentication credentials for ' + self.name + ' are missing, check your config.')
+
+    def _doLogin(self):
+
+        login_params = {'username': self.username, 'password': self.password}
+        response = self.getURL(self.urls['login'], post_data=login_params, timeout=30)
+        if not response:
+            logger.log(u'Unable to connect to ' + self.name + ' provider.', logger.ERROR)
+            return False
+
+        if re.search('Error: Username or password incorrect!', response):
+            logger.log(u'Invalid username or password for ' + self.name + ' Check your settings', logger.ERROR)
+            return False
+
+        logger.log(u'Login successful for ' + self.name, logger.DEBUG)
+        return True
+
+    def _get_season_search_strings(self, ep_obj):
+
+        search_string = {'Season': []}
+
+        for show_name in set(show_name_helpers.allPossibleShowNames(self.show)):
+            for sep in ' ', ' - ':
+                season_string = show_name + sep + 'Series '
+                if ep_obj.show.air_by_date or ep_obj.show.sports:
+                    season_string += str(ep_obj.airdate).split('-')[0]
+                elif ep_obj.show.anime:
+                    season_string += '%d' % ep_obj.scene_absolute_number
+                else:
+                    season_string += '%d' % int(ep_obj.scene_season)
+
+                search_string['Season'].append(re.sub(r'\s+', ' ', season_string.replace('.', ' ').strip()))
+
+        return [search_string]
+
+    def _get_episode_search_strings(self, ep_obj, add_string=''):
+
+        search_string = {'Episode': []}
+
+        if not ep_obj:
+            return []
+
+        for show_name in set(show_name_helpers.allPossibleShowNames(self.show)):
+            for sep in ' ', ' - ':
+                ep_string = sanitizeSceneName(show_name) + sep
+                if self.show.air_by_date:
+                    ep_string += str(ep_obj.airdate).replace('-', '|')
+                elif self.show.sports:
+                    ep_string += str(ep_obj.airdate).replace('-', '|') + '|' + ep_obj.airdate.strftime('%b')
+                elif self.show.anime:
+                    ep_string += '%i' % int(ep_obj.scene_absolute_number)
+                else:
+                    ep_string += sickbeard.config.naming_ep_type[2] % {'seasonnumber': ep_obj.scene_season, 'episodenumber': ep_obj.scene_episode}
+
+                if add_string:
+                    ep_string += ' %s' % add_string
+
+                search_string['Episode'].append(re.sub(r'\s+', ' ', ep_string.replace('.', ' ').strip()))
+
+        return [search_string]
+
+    def _doSearch(self, search_strings, search_mode='eponly', epcount=0, age=0, epObj=None):
+
+        results = []
+        items = {'Season': [], 'Episode': [], 'RSS': []}
+
+        if not self._doLogin():
+            return results
+
+        for mode in search_strings.keys():
+            for search_string in search_strings[mode]:
+                self.search_params['keywords'] = search_string.strip()
+                logger.log(u'Search string: ' + self.search_params['keywords'] + ' for ' + self.name, logger.DEBUG)
+
+                data = self.getURL(self.urls['search'], params=self.search_params)
+                url_searched = self.urls['search'] + '?' + urlencode(self.search_params)
+
+                if not data:
+                    logger.log(u'The response from (' + url_searched + ') is empty.',logger.DEBUG)
+                    continue
+
+                logger.log(u'Search query from (' + url_searched + ') returned data.',logger.DEBUG)
+
+                with BS4Parser(data) as html:
+                    torrent_table = html.find(id='listtorrents').find_all('tr')
+                    for torrent in torrent_table:
+                        try:
+                            title = torrent.find(attrs={'class':'tooltip-content'}).text.strip()
+                            url = torrent.find(title="Click to Download this Torrent!").parent['href'].strip()
+                            seeders = int(torrent.find(title='Seeders').text.strip())
+                            leechers = int(torrent.find(title='Leechers').text.strip())
+
+                            #Filter unseeded torrent
+                            if not seeders or seeders < self.minseed or leechers < self.minleech:
+                                continue
+
+                            if not title or not url:
+                                continue
+
+                            # Chop off tracker/channel prefix or we cant parse the result!
+                            show_name_first_word = re.search(r'^[^ .]+', self.search_params['keywords']).group()
+                            if not title.startswith(show_name_first_word):
+                                title = re.match(r'(.*)(' + show_name_first_word + '.*)', title).group(2)
+
+                            # Change title from Series to Season, or we can't parse
+                            if 'Series' in self.search_params['keywords']:
+                                title = re.sub(r'(?i)series', 'Season', title)
+
+                            # Strip year from the end or we can't parse it!
+                            title = re.sub(r' \(\d{4}\)$', '', title)
+
+                            item = title, url, seeders, leechers
+                            logger.log(u'Found result: ' + title.replace(' ', '.') + ' (' + url + ')', logger.DEBUG)
+
+                            items[mode].append(item)
+
+                        except:
+                            continue
+
+            #For each search mode sort all the items by seeders
+            items[mode].sort(key=lambda tup: tup[3], reverse=True)
+
+            results += items[mode]
+
+        return results
+
+    def _get_title_and_url(self, item):
+
+        title, url, seeders, leechers = item
+
+        if title:
+            title = self._clean_title_from_provider(title)
+
+        if url:
+            url = str(url).replace('&amp;', '&')
+
+        return (title, url)
+
+    def findPropers(self, search_date=datetime.datetime.today()):
+
+        results = []
+
+        myDB = db.DBConnection()
+        sqlResults = myDB.select(
+            'SELECT s.show_name, e.showid, e.season, e.episode, e.status, e.airdate FROM tv_episodes AS e' +
+            ' INNER JOIN tv_shows AS s ON (e.showid = s.indexer_id)' +
+            ' WHERE e.airdate >= ' + str(search_date.toordinal()) +
+            ' AND (e.status IN (' + ','.join([str(x) for x in Quality.DOWNLOADED]) + ')' +
+            ' OR (e.status IN (' + ','.join([str(x) for x in Quality.SNATCHED]) + ')))'
+        )
+
+        for sqlshow in sqlResults or []:
+            self.show = helpers.findCertainShow(sickbeard.showList, int(sqlshow['showid']))
+            if self.show:
+                curEp = self.show.getEpisode(int(sqlshow['season']), int(sqlshow['episode']))
+
+                searchString = self._get_episode_search_strings(curEp, add_string='PROPER|REPACK')
+
+                for item in self._doSearch(searchString[0]):
+                    title, url = self._get_title_and_url(item)
+                    results.append(classes.Proper(title, url, datetime.datetime.today(), self.show))
+
+        return results
+
+    def seedRatio(self):
+        return self.ratio
+
+
+class TVChaosUKCache(tvcache.TVCache):
+    def __init__(self, provider):
+
+        tvcache.TVCache.__init__(self, provider)
+
+        # only poll TVChaosUK every 20 minutes max
+        self.minTime = 20
+
+    def _getRSSData(self):
+        search_strings = {'RSS': ['']}
+        return {'entries': self.provider._doSearch(search_strings)}
+
+
+provider = TVChaosUKProvider()
diff --git a/sickbeard/rssfeeds.py b/sickbeard/rssfeeds.py
index 0a06c49fa0fa6988be975f9d91a9378b64f08ac3..e117568b473e5d5011f803fa8e2fbdf55948af84 100644
--- a/sickbeard/rssfeeds.py
+++ b/sickbeard/rssfeeds.py
@@ -6,8 +6,8 @@ import urllib
 import sickbeard
 
 from sickbeard import logger
-from sickbeard import encodingKludge as ek
 from sickbeard.exceptions import ex
+from sickrage.helper.encoding import ek
 
 from feedcache.cache import Cache
 
@@ -17,7 +17,7 @@ from sqliteshelf import SQLiteShelf
 class RSSFeeds:
     def __init__(self, db_name='feeds'):
         try:
-            db_name = ek.ek(os.path.join, sickbeard.CACHE_DIR, 'rss', db_name) + '.db'
+            db_name = ek(os.path.join, sickbeard.CACHE_DIR, 'rss', db_name) + '.db'
             if not os.path.exists(os.path.dirname(db_name)):
                 sickbeard.helpers.makeDir(os.path.dirname(db_name))
 
@@ -33,7 +33,6 @@ class RSSFeeds:
 
     def getFeed(self, url, post_data=None, request_headers=None, items=None, handlers=[]):
 
-
         if post_data:
             url += urllib.urlencode(post_data)
 
diff --git a/sickbeard/sab.py b/sickbeard/sab.py
index 639dfe8095e36a936705025bb5c2592aa9a5ef86..458863987a03d2f8c302d22f688d9bf1bf79cae0 100644
--- a/sickbeard/sab.py
+++ b/sickbeard/sab.py
@@ -1,5 +1,6 @@
 # Author: Nic Wolfe <nic@wolfeden.ca>
-# URL: http://code.google.com/p/sickbeard/
+# URL: https://sickrage.tv
+# Git: https://github.com/SiCKRAGETV/SickRage
 #
 # This file is part of SickRage.
 #
@@ -39,7 +40,7 @@ def sendNZB(nzb):
     """
     Sends an NZB to SABnzbd via the API.
     
-    nzb: The NZBSearchResult object to send to SAB
+    :param nzb: The NZBSearchResult object to send to SAB
     """
 
     # set up a dict with the URL params in it
@@ -146,6 +147,12 @@ def sendNZB(nzb):
 
 
 def _checkSabResponse(f):
+    """
+    Check response from SAB
+
+    :param f: Response from SAV
+    :return: a list of (Boolean, string) which is True if SAB is not reporting an error
+    """
     try:
         result = f.readlines()
     except Exception, e:
@@ -174,6 +181,12 @@ def _checkSabResponse(f):
 
 
 def _sabURLOpenSimple(url):
+    """
+    Open a connection to SAB
+
+    :param url: URL where SAB is at
+    :return: (boolean, string) list, True if connection can be made
+    """
     try:
         f = urllib.urlopen(url)
     except (EOFError, IOError), e:
@@ -190,6 +203,15 @@ def _sabURLOpenSimple(url):
 
 
 def getSabAccesMethod(host=None, username=None, password=None, apikey=None):
+    """
+    Find out how we should connect to SAB
+
+    :param host: hostname where SAB lives
+    :param username: username to use
+    :param password: password to use
+    :param apikey: apikey to use
+    :return: (boolean, string) with True if method was successful
+    """
     url = host + "api?mode=auth"
 
     result, f = _sabURLOpenSimple(url)
@@ -207,12 +229,11 @@ def testAuthentication(host=None, username=None, password=None, apikey=None):
     """
     Sends a simple API request to SAB to determine if the given connection information is connect
     
-    host: The host where SAB is running (incl port)
-    username: The username to use for the HTTP request
-    password: The password to use for the HTTP request
-    apikey: The API key to provide to SAB
-    
-    Returns: A tuple containing the success boolean and a message
+    :param host: The host where SAB is running (incl port)
+    :param username: The username to use for the HTTP request
+    :param password: The password to use for the HTTP request
+    :param apikey: The API key to provide to SAB
+    :return: A tuple containing the success boolean and a message
     """
 
     # build up the URL parameters
diff --git a/sickbeard/sbdatetime.py b/sickbeard/sbdatetime.py
index c3c34cdad68ef4575c84650607fb479adab8d57f..1240df9296e3e2ef98960c49294126f41efc58a4 100644
--- a/sickbeard/sbdatetime.py
+++ b/sickbeard/sbdatetime.py
@@ -1,5 +1,6 @@
 # Author: Nic Wolfe <nic@wolfeden.ca>
-# URL: http://code.google.com/p/sickbeard/
+# URL: https://sickrage.tv
+# Git: https://github.com/SiCKRAGETV/SickRage.git
 #
 # This file is part of SickRage.
 #
@@ -125,6 +126,15 @@ class sbdatetime(datetime.datetime):
     # display Time in SickRage Format
     @static_or_instance
     def sbftime(self, dt=None, show_seconds=False, t_preset=None):
+        """
+        Display time in SR format
+        TODO: Rename this to srftime
+
+        :param dt: datetime object
+        :param show_seconds: Boolean, show seconds
+        :param t_preset: Preset time format
+        :return: time string
+        """
 
         try:locale.setlocale(locale.LC_TIME, '')
         except:pass
@@ -168,6 +178,14 @@ class sbdatetime(datetime.datetime):
     # display Date in SickRage Format
     @static_or_instance
     def sbfdate(self, dt=None, d_preset=None):
+        """
+        Display date in SR format
+        TODO: Rename this to srfdate
+
+        :param dt: datetime object
+        :param d_preset: Preset date format
+        :return: date string
+        """
 
         try:
             locale.setlocale(locale.LC_TIME, '')
@@ -199,6 +217,16 @@ class sbdatetime(datetime.datetime):
     # display Datetime in SickRage Format
     @static_or_instance
     def sbfdatetime(self, dt=None, show_seconds=False, d_preset=None, t_preset=None):
+        """
+        Show datetime in SR format
+        TODO: Rename this to srfdatetime
+
+        :param dt: datetime object
+        :param show_seconds: Boolean, show seconds as well
+        :param d_preset: Preset date format
+        :param t_preset: Preset time format
+        :return: datetime string
+        """
 
         try:
             locale.setlocale(locale.LC_TIME, '')
diff --git a/sickbeard/scene_exceptions.py b/sickbeard/scene_exceptions.py
index fc70d2f8539fd8d17431af033cd7f8061ab7ce4b..dbf7b665e4f78c736f72c4d791b0e8c53cfe73ea 100644
--- a/sickbeard/scene_exceptions.py
+++ b/sickbeard/scene_exceptions.py
@@ -1,5 +1,6 @@
 # Author: Nic Wolfe <nic@wolfeden.ca>
-# URL: http://code.google.com/p/sickbeard/
+# URL: https://sickrage.tv
+# Git: https://github.com/SiCKRAGETV/SickRage.git
 #
 # This file is part of SickRage.
 #
@@ -38,6 +39,12 @@ exceptionsSeasonCache = {}
 exceptionLock = threading.Lock()
 
 def shouldRefresh(list):
+    """
+    Check if we should refresh cache for items in list
+
+    :param list: list to check
+    :return: True if refresh is needed
+    """
     MAX_REFRESH_AGE_SECS = 86400  # 1 day
 
     myDB = db.DBConnection('cache.db')
@@ -49,6 +56,11 @@ def shouldRefresh(list):
         return True
 
 def setLastRefresh(list):
+    """
+    Update last cache update time for shows in list
+
+    :param list: list to check
+    """
     myDB = db.DBConnection('cache.db')
     myDB.upsert("scene_exceptions_refresh",
                 {'last_refreshed': int(time.mktime(datetime.datetime.today().timetuple()))},
@@ -81,6 +93,12 @@ def get_scene_exceptions(indexer_id, season=-1):
 
 
 def get_all_scene_exceptions(indexer_id):
+    """
+    Get all scene exceptions for a show ID
+
+    :param indexer_id: ID to check
+    :return: dict of exceptions
+    """
     exceptionsDict = {}
 
     myDB = db.DBConnection('cache.db')
@@ -316,8 +334,7 @@ def _xem_exceptions_fetcher():
 
 
 def getSceneSeasons(indexer_id):
-    """get a list of season numbers that have scene exceptions
-    """
+    """get a list of season numbers that have scene exceptions"""
     myDB = db.DBConnection('cache.db')
     seasons = myDB.select("SELECT DISTINCT season FROM scene_exceptions WHERE indexer_id = ?", [indexer_id])
     return [cur_exception["season"] for cur_exception in seasons]
diff --git a/sickbeard/scene_numbering.py b/sickbeard/scene_numbering.py
index 11f7a9cd2b5776b7f50c873a1886f35901c78894..ffb3d0fdb2667b92b771ec4caa11577797636455 100644
--- a/sickbeard/scene_numbering.py
+++ b/sickbeard/scene_numbering.py
@@ -1,5 +1,6 @@
 # Author: Nic Wolfe <nic@wolfeden.ca>
-# URL: http://code.google.com/p/sickbeard/
+# URL: https://sickrage.tv
+# Git: https://github.com/SiCKRAGETV/SickRage.git
 #
 # This file is part of SickRage.
 #
@@ -39,11 +40,11 @@ def get_scene_numbering(indexer_id, indexer, season, episode, fallback_to_xem=Tr
     returns the TVDB numbering.
     (so the return values will always be set)
 
-    @param indexer_id: int
-    @param season: int
-    @param episode: int
-    @param fallback_to_xem: bool If set (the default), check xem for matches if there is no local scene numbering
-    @return: (int, int) a tuple with (season, episode)
+    :param indexer_id: int
+    :param season: int
+    :param episode: int
+    :param fallback_to_xem: bool If set (the default), check xem for matches if there is no local scene numbering
+    :return: (int, int) a tuple with (season, episode)
     """
     if indexer_id is None or season is None or episode is None:
         return (season, episode)
@@ -89,10 +90,10 @@ def get_scene_absolute_numbering(indexer_id, indexer, absolute_number, fallback_
     returns the TVDB numbering.
     (so the return values will always be set)
 
-    @param indexer_id: int
-    @param absolute_number: int
-    @param fallback_to_xem: bool If set (the default), check xem for matches if there is no local scene numbering
-    @return: (int, int) a tuple with (season, episode)
+    :param indexer_id: int
+    ;param absolute_number: int
+    :param fallback_to_xem: bool If set (the default), check xem for matches if there is no local scene numbering
+    :return: (int, int) a tuple with (season, episode)
     """
     if indexer_id is None or absolute_number is None:
         return absolute_number
@@ -192,7 +193,6 @@ def set_scene_numbering(indexer_id, indexer, season=None, episode=None, absolute
     """
     Set scene numbering for a season/episode.
     To clear the scene numbering, leave both sceneSeason and sceneEpisode as None.
-
     """
     if indexer_id is None:
         return
@@ -228,10 +228,10 @@ def find_xem_numbering(indexer_id, indexer, season, episode):
     Returns the scene numbering, as retrieved from xem.
     Refreshes/Loads as needed.
 
-    @param indexer_id: int
-    @param season: int
-    @param episode: int
-    @return: (int, int) a tuple of scene_season, scene_episode, or None if there is no special mapping.
+    :param indexer_id: int
+    :param season: int
+    :param episode: int
+    :return: (int, int) a tuple of scene_season, scene_episode, or None if there is no special mapping.
     """
     if indexer_id is None or season is None or episode is None:
         return (season, episode)
@@ -255,9 +255,9 @@ def find_xem_absolute_numbering(indexer_id, indexer, absolute_number):
     Returns the scene numbering, as retrieved from xem.
     Refreshes/Loads as needed.
 
-    @param indexer_id: int
-    @param absolute_number: int
-    @return: int
+    :param indexer_id: int
+    :param absolute_number: int
+    :return: int
     """
     if indexer_id is None or absolute_number is None:
         return absolute_number
@@ -280,10 +280,10 @@ def get_indexer_numbering_for_xem(indexer_id, indexer, sceneSeason, sceneEpisode
     """
     Reverse of find_xem_numbering: lookup a tvdb season and episode using scene numbering
 
-    @param indexer_id: int
-    @param sceneSeason: int
-    @param sceneEpisode: int
-    @return: (int, int) a tuple of (season, episode)
+    :param indexer_id: int
+    :param sceneSeason: int
+    :param sceneEpisode: int
+    :return: (int, int) a tuple of (season, episode)
     """
     if indexer_id is None or sceneSeason is None or sceneEpisode is None:
         return (sceneSeason, sceneEpisode)
@@ -308,9 +308,9 @@ def get_indexer_absolute_numbering_for_xem(indexer_id, indexer, sceneAbsoluteNum
     """
     Reverse of find_xem_numbering: lookup a tvdb season and episode using scene numbering
 
-    @param indexer_id: int
-    @param sceneAbsoluteNumber: int
-    @return: int
+    :param indexer_id: int
+    :param sceneAbsoluteNumber: int
+    :return: int
     """
     if indexer_id is None or sceneAbsoluteNumber is None:
         return sceneAbsoluteNumber
@@ -456,7 +456,7 @@ def xem_refresh(indexer_id, indexer, force=False):
     """
     Refresh data from xem for a tv show
 
-    @param indexer_id: int
+    :param indexer_id: int
     """
     if not indexer_id or indexer_id < 1:
         return
diff --git a/sickbeard/scheduler.py b/sickbeard/scheduler.py
index 32c08ffa69b647ba386917d1a77f8b057cf95f8d..f95f1ecaa8465e57268ddd97a82479a411050044 100644
--- a/sickbeard/scheduler.py
+++ b/sickbeard/scheduler.py
@@ -1,5 +1,6 @@
 # Author: Nic Wolfe <nic@wolfeden.ca>
-# URL: http://code.google.com/p/sickbeard/
+# URL: https://sickrage.tv
+# Git: https://github.com/SiCKRAGETV/SickRage.git
 #
 # This file is part of SickRage.
 #
@@ -48,6 +49,10 @@ class Scheduler(threading.Thread):
         self.enable = False
 
     def timeLeft(self):
+        """
+        Check how long we have until we run again
+        :return: timedelta
+        """
         if self.isAlive():
             if self.start_time is None:
                 return self.cycleTime - (datetime.datetime.now() - self.lastRun)
@@ -69,6 +74,9 @@ class Scheduler(threading.Thread):
         return False
 
     def run(self):
+        """
+        Runs the thread
+        """
         try:
             while not self.stop.is_set():
                 if self.enable:
diff --git a/sickbeard/search.py b/sickbeard/search.py
index 79c0b8900a1ab0a4f2fa036496842ead870ad590..b11bd24662322d5ed082e70def54bf5df992f68b 100644
--- a/sickbeard/search.py
+++ b/sickbeard/search.py
@@ -1,5 +1,6 @@
 # Author: Nic Wolfe <nic@wolfeden.ca>
-# URL: http://code.google.com/p/sickbeard/
+# URL: https://sickrage.tv
+# Git: https://github.com/SiCKRAGETV/SickRage.git
 #
 # This file is part of SickRage.
 #
@@ -36,19 +37,19 @@ from sickbeard import history
 from sickbeard import notifiers
 from sickbeard import nzbSplitter
 from sickbeard import ui
-from sickbeard import encodingKludge as ek
 from sickbeard import failed_history
 from sickbeard.exceptions import ex
 from sickbeard.providers.generic import GenericProvider
 from sickbeard import common
+from sickrage.helper.encoding import ek
+
 
 def _downloadResult(result):
     """
     Downloads a result to the appropriate black hole folder.
 
-    Returns a bool representing success.
-
-    result: SearchResult instance to download.
+    :param result: SearchResult instance to download.
+    :return: boolean, True on success
     """
 
     resProvider = result.provider
@@ -63,7 +64,7 @@ def _downloadResult(result):
     elif result.resultType == "nzbdata":
 
         # get the final file path to the nzb
-        fileName = ek.ek(os.path.join, sickbeard.NZB_DIR, result.name + ".nzb")
+        fileName = ek(os.path.join, sickbeard.NZB_DIR, result.name + ".nzb")
 
         logger.log(u"Saving NZB to " + fileName)
 
@@ -71,7 +72,7 @@ def _downloadResult(result):
 
         # save the data to disk
         try:
-            with ek.ek(open, fileName, 'w') as fileOut:
+            with ek(open, fileName, 'w') as fileOut:
                 fileOut.write(result.extraInfo[0])
 
             helpers.chmodAsParent(fileName)
@@ -92,10 +93,9 @@ def snatchEpisode(result, endStatus=SNATCHED):
     Contains the internal logic necessary to actually "snatch" a result that
     has been found.
 
-    Returns a bool representing success.
-
-    result: SearchResult instance to be snatched.
-    endStatus: the episode status that should be used for the episode object once it's snatched.
+    :param result: SearchResult instance to be snatched.
+    :param endStatus: the episode status that should be used for the episode object once it's snatched.
+    :return: boolean, True on success
     """
 
     if result is None:
@@ -184,6 +184,13 @@ def snatchEpisode(result, endStatus=SNATCHED):
 
 
 def pickBestResult(results, show):
+    """
+    Find the best result out of a list of search results for a show
+
+    :param results: list of result objects
+    :param show: Shows we check for
+    :return: best result object
+    """
     results = results if isinstance(results, list) else [results]
 
     logger.log(u"Picking the best result out of " + str([x.name for x in results]), logger.DEBUG)
@@ -259,7 +266,6 @@ def isFinalResult(result):
 
     If the result is the highest quality in both the any/best quality lists then this function
     returns True, if not then it's False
-
     """
 
     logger.log(u"Checking if we should keep searching after we've found " + result.name, logger.DEBUG)
@@ -308,6 +314,12 @@ def isFirstBestMatch(result):
     return False
 
 def wantedEpisodes(show, fromDate):
+    """
+    Get a list of episodes that we want to download
+    :param show: Show these episodes are from
+    :param fromDate: Search from a certain date
+    :return: list of wanted episodes
+    """
 
     anyQualities, bestQualities = common.Quality.splitQuality(show.quality) # @UnusedVariable
     allQualities = list(set(anyQualities + bestQualities))
@@ -338,6 +350,11 @@ def wantedEpisodes(show, fromDate):
     return wanted
 
 def searchForNeededEpisodes():
+    """
+    Check providers for details on wanted episodes
+
+    :return: episodes we have a search hit for
+    """
     foundResults = {}
 
     didSearch = False
@@ -410,6 +427,15 @@ def searchForNeededEpisodes():
 
 
 def searchProviders(show, episodes, manualSearch=False, downCurQuality=False):
+    """
+    Walk providers for information on shows
+
+    :param show: Show we are looking for
+    :param episodes: Episodes we hope to find
+    :param manualSearch: Boolean, is this a manual search?
+    :param downCurQuality: Boolean, should we redownload currently avaialble quality file
+    :return: results for search
+    """
     foundResults = {}
     finalResults = []
 
@@ -592,7 +618,7 @@ def searchProviders(show, episodes, manualSearch=False, downCurQuality=False):
 
                 logger.log(u"Seeing if we want to bother with multi-episode result " + _multiResult.name, logger.DEBUG)
 
-		# Filter result by ignore/required/whitelist/blacklist/quality, etc
+                # Filter result by ignore/required/whitelist/blacklist/quality, etc
                 multiResult = pickBestResult(_multiResult, show)
                 if not multiResult:
                     continue
diff --git a/sickbeard/show_name_helpers.py b/sickbeard/show_name_helpers.py
index c5097235e94481541b18f3e73010eb14d4a4dce3..9fe166c3b01976b864e263ee74d048075e2b2c41 100644
--- a/sickbeard/show_name_helpers.py
+++ b/sickbeard/show_name_helpers.py
@@ -15,6 +15,7 @@
 #
 # You should have received a copy of the GNU General Public License
 # along with SickRage.  If not, see <http://www.gnu.org/licenses/>.
+
 import fnmatch
 import os
 
@@ -28,12 +29,17 @@ from sickbeard.helpers import sanitizeSceneName
 from sickbeard.scene_exceptions import get_scene_exceptions
 from sickbeard import logger
 from sickbeard import db
-from sickbeard import encodingKludge as ek
+from sickrage.helper.encoding import ek, ss
 from name_parser.parser import NameParser, InvalidNameException, InvalidShowException
 
-resultFilters = ["sub(bed|ed|pack|s)", "(dk|fin|heb|kor|nor|nordic|pl|swe)sub(bed|ed|s)?",
-                 "(dir|sample|sub|nfo)fix", "sample", "(dvd)?extras",
-                 "dub(bed)?"]
+resultFilters = [
+    "sub(bed|ed|pack|s)",
+    "(dk|fin|heb|kor|nor|nordic|pl|swe)sub(bed|ed|s)?",
+    "(dir|sample|sub|nfo)fix",
+    "sample",
+    "(dvd)?extras",
+    "dub(bed)?"
+]
 
 
 def containsAtLeastOneWord(name, words):
@@ -58,9 +64,9 @@ def filterBadReleases(name, parse=True):
     """
     Filters out non-english and just all-around stupid releases by comparing them
     to the resultFilters contents.
-    
+
     name: the release name to check
-    
+
     Returns: True if the release name is OK, False if it's bad.
     """
 
@@ -98,9 +104,9 @@ def filterBadReleases(name, parse=True):
 def sceneToNormalShowNames(name):
     """
         Takes a show name from a scene dirname and converts it to a more "human-readable" format.
-    
+
     name: The show name to convert
-    
+
     Returns: a list of all the possible "normal" names
     """
 
@@ -255,7 +261,7 @@ def isGoodResult(name, show, log=True, season=-1):
 
     all_show_names = allPossibleShowNames(show, season=season)
     showNames = map(sanitizeSceneName, all_show_names) + all_show_names
-    showNames += map(ek.ss, all_show_names)
+    showNames += map(ss, all_show_names)
 
     for curName in set(showNames):
         if not show.is_anime:
@@ -286,9 +292,9 @@ def allPossibleShowNames(show, season=-1):
     """
     Figures out every possible variation of the name for a particular show. Includes TVDB name, TVRage name,
     country codes on the end, eg. "Show Name (AU)", and any scene exception names.
-    
+
     show: a TVShow object that we should get the names of
-    
+
     Returns: a list of all the possible show names
     """
 
@@ -340,19 +346,19 @@ def determineReleaseName(dir_name=None, nzb_name=None):
     for search in file_types:
 
         reg_expr = re.compile(fnmatch.translate(search), re.IGNORECASE)
-        files = [file_name for file_name in ek.ek(os.listdir, dir_name) if
-                 ek.ek(os.path.isfile, ek.ek(os.path.join, dir_name, file_name))]
+        files = [file_name for file_name in ek(os.listdir, dir_name) if
+                 ek(os.path.isfile, ek(os.path.join, dir_name, file_name))]
         results = filter(reg_expr.search, files)
 
         if len(results) == 1:
-            found_file = ek.ek(os.path.basename, results[0])
+            found_file = ek(os.path.basename, results[0])
             found_file = found_file.rpartition('.')[0]
             if filterBadReleases(found_file):
                 logger.log(u"Release name (" + found_file + ") found from file (" + results[0] + ")")
                 return found_file.rpartition('.')[0]
 
     # If that fails, we try the folder
-    folder = ek.ek(os.path.basename, dir_name)
+    folder = ek(os.path.basename, dir_name)
     if filterBadReleases(folder):
         # NOTE: Multiple failed downloads will change the folder name.
         # (e.g., appending #s)
diff --git a/sickbeard/subtitles.py b/sickbeard/subtitles.py
index 92bb826d02fda167aa688a446d206b9136e81519..3ad8e467873a67e20a2447c216951f2041e87272 100644
--- a/sickbeard/subtitles.py
+++ b/sickbeard/subtitles.py
@@ -21,23 +21,26 @@ import sickbeard
 from sickbeard.common import *
 from sickbeard.exceptions import ex
 from sickbeard import logger
-from sickbeard import encodingKludge as ek
 from sickbeard import db
 from sickrage.helper.common import dateTimeFormat
+from sickrage.helper.encoding import ek
 import subliminal
 import babelfish
 import subprocess
 
 subliminal.cache_region.configure('dogpile.cache.memory')
 
-provider_urls = {'addic7ed': 'http://www.addic7ed.com',
-                 'opensubtitles': 'http://www.opensubtitles.org',
-                 'podnapisi': 'http://www.podnapisi.net',
-                 'thesubdb': 'http://www.thesubdb.com',
-                 'tvsubtitles': 'http://www.tvsubtitles.net'
-                }
+provider_urls = {
+    'addic7ed': 'http://www.addic7ed.com',
+    'opensubtitles': 'http://www.opensubtitles.org',
+    'podnapisi': 'http://www.podnapisi.net',
+    'thesubdb': 'http://www.thesubdb.com',
+    'tvsubtitles': 'http://www.tvsubtitles.net'
+}
 
 SINGLE = 'und'
+
+
 def sortedServiceList():
     newList = []
     lmgtfy = 'http://lmgtfy.com/?q=%s'
@@ -94,11 +97,11 @@ def subtitlesLanguages(video_path):
     embedded_languages = subliminal.video.scan_video(video_path, subtitles=False, embedded_subtitles=not sickbeard.EMBEDDED_SUBTITLES_ALL)
 
     # Search subtitles in the absolute path
-    if sickbeard.SUBTITLES_DIR and ek.ek(os.path.exists, sickbeard.SUBTITLES_DIR):
-        video_path = ek.ek(os.path.join, sickbeard.SUBTITLES_DIR, ek.ek(os.path.basename, video_path))
+    if sickbeard.SUBTITLES_DIR and ek(os.path.exists, sickbeard.SUBTITLES_DIR):
+        video_path = ek(os.path.join, sickbeard.SUBTITLES_DIR, ek(os.path.basename, video_path))
     # Search subtitles in the relative path
     elif sickbeard.SUBTITLES_DIR:
-        video_path = ek.ek(os.path.join, ek.ek(os.path.dirname, video_path), sickbeard.SUBTITLES_DIR, ek.ek(os.path.basename, video_path))
+        video_path = ek(os.path.join, ek(os.path.dirname, video_path), sickbeard.SUBTITLES_DIR, ek(os.path.basename, video_path))
 
     languages = subliminal.video.scan_subtitle_languages(video_path)
 
@@ -170,7 +173,7 @@ class SubtitlesFinder():
         now = datetime.datetime.now()
         for epToSub in sqlResults:
 
-            if not ek.ek(os.path.isfile, epToSub['location']):
+            if not ek(os.path.isfile, epToSub['location']):
                 logger.log('Episode file does not exist, cannot download subtitles for episode %dx%d of show %s' % (epToSub['season'], epToSub['episode'], epToSub['show_name']), logger.DEBUG)
                 continue
 
@@ -219,17 +222,17 @@ 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])
+        script_cmd[0] = 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))
+                if sickbeard.SUBTITLES_DIR and ek(os.path.exists, sickbeard.SUBTITLES_DIR):
+                    subpath = ek(os.path.join, sickbeard.SUBTITLES_DIR, ek(os.path.basename, subpath))
                 elif sickbeard.SUBTITLES_DIR:
-                    subpath = ek.ek(os.path.join, ek.ek(os.path.dirname, subpath), sickbeard.SUBTITLES_DIR, ek.ek(os.path.basename, subpath))
+                    subpath = ek(os.path.join, ek(os.path.dirname, subpath), sickbeard.SUBTITLES_DIR, ek(os.path.basename, subpath))
 
                 inner_cmd = script_cmd + [video.name, subpath, sub.language.opensubtitles, epObj.show.name,
                                          str(epObj.season), str(epObj.episode), epObj.name, str(epObj.show.indexerid)]
diff --git a/sickbeard/traktChecker.py b/sickbeard/traktChecker.py
index 9ebab41fdf3167351f2f9d1dede61deaba2c5754..f19dc994df320713cd7aa8ef7079d230cbce2e8c 100644
--- a/sickbeard/traktChecker.py
+++ b/sickbeard/traktChecker.py
@@ -21,7 +21,6 @@ import traceback
 import datetime
 
 import sickbeard
-from sickbeard import encodingKludge as ek
 from sickbeard.exceptions import ex
 from sickbeard import logger
 from sickbeard import helpers
@@ -31,6 +30,7 @@ from sickbeard.common import ARCHIVED
 from sickbeard.common import SKIPPED
 from sickbeard.common import UNKNOWN
 from sickbeard.common import WANTED
+from sickrage.helper.encoding import ek
 from common import Quality
 from libtrakt import *
 from libtrakt.exceptions import traktException
@@ -101,7 +101,7 @@ class TraktChecker():
             library = self.trakt_api.traktRequest("sync/collection/shows") or []
 
             if not library:
-                logger.log(u"Could not connect to trakt service, aborting library check", logger.ERROR)
+                logger.log(u"Could not connect to trakt service, aborting library check", logger.WARNING)
                 return
 
             if not len(library):
@@ -417,7 +417,7 @@ class TraktChecker():
                 location = None
 
             if location:
-                showPath = ek.ek(os.path.join, location, helpers.sanitizeFileName(name))
+                showPath = ek(os.path.join, location, helpers.sanitizeFileName(name))
                 dir_exists = helpers.makeDir(showPath)
                 if not dir_exists:
                     logger.log(u"Unable to create the folder " + showPath + ", can't add the show", logger.ERROR)
diff --git a/sickbeard/tv.py b/sickbeard/tv.py
index fb7627b109c0089f073e6ff1626ed5667955eb22..d7329b217501e3fd65671f265f24ddc9b6b18df8 100644
--- a/sickbeard/tv.py
+++ b/sickbeard/tv.py
@@ -53,10 +53,9 @@ from sickbeard import sbdatetime
 from sickbeard import network_timezones
 from sickbeard.indexers.indexer_config import INDEXER_TVRAGE
 from sickrage.helper.common import dateTimeFormat
+from sickrage.helper.encoding import ek
 from dateutil.tz import *
 
-from sickbeard import encodingKludge as ek
-
 from common import Quality, Overview, statusStrings
 from common import DOWNLOADED, SNATCHED, SNATCHED_PROPER, SNATCHED_BEST, ARCHIVED, IGNORED, UNAIRED, WANTED, SKIPPED, \
     UNKNOWN, FAILED
@@ -182,7 +181,7 @@ class TVShow(object):
         if sickbeard.CREATE_MISSING_SHOW_DIRS:
             return self._location
 
-        if ek.ek(os.path.isdir, self._location):
+        if ek(os.path.isdir, self._location):
             return self._location
         else:
             raise exceptions.ShowDirNotFoundException("Show folder doesn't exist, you shouldn't be using it")
@@ -190,7 +189,7 @@ class TVShow(object):
     def _setLocation(self, newLocation):
         logger.log(u"Setter sets location to " + newLocation, logger.DEBUG)
         # Don't validate dir if user wants to add shows without creating a dir
-        if sickbeard.ADD_SHOWS_WO_DIR or ek.ek(os.path.isdir, newLocation):
+        if sickbeard.ADD_SHOWS_WO_DIR or ek(os.path.isdir, newLocation):
             dirty_setter("_location")(self, newLocation)
             self._isDirGood = True
         else:
@@ -338,7 +337,7 @@ class TVShow(object):
 
         result = False
 
-        if not ek.ek(os.path.isdir, self._location):
+        if not ek(os.path.isdir, self._location):
             logger.log(str(self.indexerid) + u": Show dir doesn't exist, skipping NFO generation")
             return False
 
@@ -350,7 +349,7 @@ class TVShow(object):
 
     def writeMetadata(self, show_only=False):
 
-        if not ek.ek(os.path.isdir, self._location):
+        if not ek(os.path.isdir, self._location):
             logger.log(str(self.indexerid) + u": Show dir doesn't exist, skipping NFO generation")
             return
 
@@ -363,7 +362,7 @@ class TVShow(object):
 
     def writeEpisodeNFOs(self):
 
-        if not ek.ek(os.path.isdir, self._location):
+        if not ek(os.path.isdir, self._location):
             logger.log(str(self.indexerid) + u": Show dir doesn't exist, skipping NFO generation")
             return
 
@@ -380,10 +379,9 @@ class TVShow(object):
 
             curEp.createMetaFiles()
 
-
     def updateMetadata(self):
 
-        if not ek.ek(os.path.isdir, self._location):
+        if not ek(os.path.isdir, self._location):
             logger.log(str(self.indexerid) + u": Show dir doesn't exist, skipping NFO generation")
             return
 
@@ -393,7 +391,7 @@ class TVShow(object):
 
         result = False
 
-        if not ek.ek(os.path.isdir, self._location):
+        if not ek(os.path.isdir, self._location):
             logger.log(str(self.indexerid) + u": Show dir doesn't exist, skipping NFO generation")
             return False
 
@@ -406,7 +404,7 @@ class TVShow(object):
     # find all media files in the show folder and create episodes for as many as possible
     def loadEpisodesFromDir(self):
 
-        if not ek.ek(os.path.isdir, self._location):
+        if not ek(os.path.isdir, self._location):
             logger.log(str(self.indexerid) + u": Show dir doesn't exist, not loading episodes from disk", logger.DEBUG)
             return
 
@@ -425,7 +423,7 @@ class TVShow(object):
 
             logger.log(str(self.indexerid) + u": Creating episode from " + mediaFile, logger.DEBUG)
             try:
-                curEpisode = self.makeEpFromFile(ek.ek(os.path.join, self._location, mediaFile))
+                curEpisode = self.makeEpFromFile(ek(os.path.join, self._location, mediaFile))
             except (exceptions.ShowNotFoundException, exceptions.EpisodeNotFoundException), e:
                 logger.log(u"Episode " + mediaFile + " returned an exception: " + ex(e), logger.ERROR)
                 continue
@@ -436,8 +434,8 @@ class TVShow(object):
                 continue
 
             # see if we should save the release name in the db
-            ep_file_name = ek.ek(os.path.basename, curEpisode.location)
-            ep_file_name = ek.ek(os.path.splitext, ep_file_name)[0]
+            ep_file_name = ek(os.path.basename, curEpisode.location)
+            ep_file_name = ek(os.path.splitext, ep_file_name)[0]
 
             try:
                 parse_result = None
@@ -626,7 +624,7 @@ class TVShow(object):
     # make a TVEpisode object from a media file
     def makeEpFromFile(self, file):
 
-        if not ek.ek(os.path.isfile, file):
+        if not ek(os.path.isfile, file):
             logger.log(str(self.indexerid) + u": That isn't even a real file dude... " + file)
             return None
 
@@ -675,7 +673,7 @@ class TVShow(object):
 
             else:
                 # if there is a new file associated with this ep then re-check the quality
-                if curEp.location and ek.ek(os.path.normpath, curEp.location) != ek.ek(os.path.normpath, file):
+                if curEp.location and ek(os.path.normpath, curEp.location) != ek(os.path.normpath, file):
                     logger.log(
                         u"The old episode had a different file associated with it, I will re-check the quality based on the new filename " + file,
                         logger.DEBUG)
@@ -692,7 +690,7 @@ class TVShow(object):
 
                     curEp.checkForMetaFiles()
 
-            if rootEp == None:
+            if rootEp is None:
                 rootEp = curEp
             else:
                 if curEp not in rootEp.relatedEps:
@@ -1009,8 +1007,8 @@ class TVShow(object):
         sickbeard.showList = [x for x in sickbeard.showList if int(x.indexerid) != self.indexerid]
 
         # clear the cache
-        image_cache_dir = ek.ek(os.path.join, sickbeard.CACHE_DIR, 'images')
-        for cache_file in ek.ek(glob.glob, ek.ek(os.path.join, image_cache_dir, str(self.indexerid) + '.*')):
+        image_cache_dir = ek(os.path.join, sickbeard.CACHE_DIR, 'images')
+        for cache_file in ek(glob.glob, ek(os.path.join, image_cache_dir, str(self.indexerid) + '.*')):
             logger.log(u'Attempt to %s cache file %s' % (action, cache_file))
             try:
                 if sickbeard.TRASH_REMOVE_SHOW:
@@ -1026,19 +1024,19 @@ class TVShow(object):
             try:
                 logger.log(u'Attempt to %s show folder %s' % (action, self._location))
                 # check first the read-only attribute
-                file_attribute = ek.ek(os.stat, self.location)[0]
-                if (not file_attribute & stat.S_IWRITE):
+                file_attribute = ek(os.stat, self.location)[0]
+                if not file_attribute & stat.S_IWRITE:
                     # File is read-only, so make it writeable
                     logger.log('Attempting to make writeable the read only folder %s' % self._location, logger.DEBUG)
                     try:
-                        ek.ek(os.chmod, self.location, stat.S_IWRITE)
+                        ek(os.chmod, self.location, stat.S_IWRITE)
                     except:
                         logger.log(u'Unable to change permissions of %s' % self._location, logger.WARNING)
 
                 if sickbeard.TRASH_REMOVE_SHOW:
                     send2trash(self.location)
                 else:
-                    ek.ek(shutil.rmtree, self.location)
+                    ek(shutil.rmtree, self.location)
 
                 logger.log(u'%s show folder %s' %
                            (('Deleted', 'Trashed')[sickbeard.TRASH_REMOVE_SHOW],
@@ -1062,7 +1060,7 @@ class TVShow(object):
     def refreshDir(self):
 
         # make sure the show dir is where we think it is unless dirs are created on the fly
-        if not ek.ek(os.path.isdir, self._location) and not sickbeard.CREATE_MISSING_SHOW_DIRS:
+        if not ek(os.path.isdir, self._location) and not sickbeard.CREATE_MISSING_SHOW_DIRS:
             return False
 
         # load from dir
@@ -1090,7 +1088,7 @@ class TVShow(object):
                 continue
 
             # if the path doesn't exist or if it's not in our show dir
-            if not ek.ek(os.path.isfile, curLoc) or not os.path.normpath(curLoc).startswith(
+            if not ek(os.path.isfile, curLoc) or not os.path.normpath(curLoc).startswith(
                     os.path.normpath(self.location)):
 
                 # check if downloaded files still exist, update our data if this has changed
@@ -1122,7 +1120,7 @@ class TVShow(object):
 
     def downloadSubtitles(self, force=False):
         # TODO: Add support for force option
-        if not ek.ek(os.path.isdir, self._location):
+        if not ek(os.path.isdir, self._location):
             logger.log(str(self.indexerid) + ": Show dir doesn't exist, can't download subtitles", logger.DEBUG)
             return
 
@@ -1418,8 +1416,8 @@ class TVEpisode(object):
         # self._location = newLocation
         dirty_setter("_location")(self, new_location)
 
-        if new_location and ek.ek(os.path.isfile, new_location):
-            self.file_size = ek.ek(os.path.getsize, new_location)
+        if new_location and ek(os.path.isfile, new_location):
+            self.file_size = ek(os.path.getsize, new_location)
         else:
             self.file_size = 0
 
@@ -1430,7 +1428,7 @@ class TVEpisode(object):
         self.subtitles = subtitles.subtitlesLanguages(self.location)
 
     def downloadSubtitles(self, force=False):
-        if not ek.ek(os.path.isfile, self.location):
+        if not ek(os.path.isfile, self.location):
             logger.log(u"%s: Episode file doesn't exist, can't download subtitles for S%02dE%02d" %
                     (self.show.indexerid, self.season, self.episode), logger.DEBUG)
             return
@@ -1463,7 +1461,7 @@ class TVEpisode(object):
                 logger.log(u'%s: Exception caught in subliminal.scan_video for S%02dE%02d' %
                     (self.show.indexerid, self.season, self.episode), logger.DEBUG)
                 return
-            
+
             if not video:
                 return
 
@@ -1474,17 +1472,17 @@ class TVEpisode(object):
                 return
 
             # Select the correct subtitles path
-            if sickbeard.SUBTITLES_DIR and ek.ek(os.path.exists, sickbeard.SUBTITLES_DIR):
+            if sickbeard.SUBTITLES_DIR and ek(os.path.exists, sickbeard.SUBTITLES_DIR):
                 subs_new_path = sickbeard.SUBTITLES_DIR
             elif sickbeard.SUBTITLES_DIR:
-                subs_new_path = ek.ek(os.path.join, ek.ek(os.path.dirname, self.location), sickbeard.SUBTITLES_DIR)
+                subs_new_path = ek(os.path.join, ek(os.path.dirname, self.location), sickbeard.SUBTITLES_DIR)
                 dir_exists = helpers.makeDir(subs_new_path)
                 if not dir_exists:
 	                logger.log(u'Unable to create subtitles folder ' + subs_new_path, logger.ERROR)
                 else:
 	                helpers.chmodAsParent(subs_new_path)
             else:
-                subs_new_path = ek.ek(os.path.join, ek.ek(os.path.dirname, self.location))
+                subs_new_path = ek(os.path.join, ek(os.path.dirname, self.location))
 
             subliminal.save_subtitles(foundSubs, directory=subs_new_path, single=not sickbeard.SUBTITLES_MULTI)
 
@@ -1539,7 +1537,7 @@ class TVEpisode(object):
         cur_tbn = False
 
         # check for nfo and tbn
-        if ek.ek(os.path.isfile, self.location):
+        if ek(os.path.isfile, self.location):
             for cur_provider in sickbeard.metadata_provider_dict.values():
                 if cur_provider.episode_metadata:
                     new_result = cur_provider._has_episode_metadata(self)
@@ -1565,7 +1563,7 @@ class TVEpisode(object):
 
         if not sqlResult:
             # only load from NFO if we didn't load from DB
-            if ek.ek(os.path.isfile, self.location):
+            if ek(os.path.isfile, self.location):
                 try:
                     self.loadFromNFO(self.location)
                 except exceptions.NoNFOException:
@@ -1779,7 +1777,7 @@ class TVEpisode(object):
             return False
 
         # don't update show status if show dir is missing, unless it's missing on purpose
-        if not ek.ek(os.path.isdir,
+        if not ek(os.path.isdir,
                      self.show._location) and not sickbeard.CREATE_MISSING_SHOW_DIRS and not sickbeard.ADD_SHOWS_WO_DIR:
             logger.log(u"The show dir %s is missing, not bothering to change the episode statuses since it'd probably be invalid" % self.show._location )
             return
@@ -1788,8 +1786,8 @@ class TVEpisode(object):
             logger.log(u"%s: Setting status for S%02dE%02d based on status %s and location %s" %
                     (self.show.indexerid, season, episode, statusStrings[self.status], self.location), logger.DEBUG)
 
-        if not ek.ek(os.path.isfile, self.location):
-            if  self.airdate >= datetime.date.today() or self.airdate == datetime.date.fromordinal(1):
+        if not ek(os.path.isfile, self.location):
+            if self.airdate >= datetime.date.today() or self.airdate == datetime.date.fromordinal(1):
                 logger.log(u"Episode airs in the future or has no airdate, marking it %s" % statusStrings[UNAIRED], logger.DEBUG)
                 self.status = UNAIRED
             elif self.status in [UNAIRED, UNKNOWN]:
@@ -1815,7 +1813,7 @@ class TVEpisode(object):
 
     def loadFromNFO(self, location):
 
-        if not ek.ek(os.path.isdir, self.show._location):
+        if not ek(os.path.isdir, self.show._location):
             logger.log(
                 str(self.show.indexerid) + u": The show dir is missing, not bothering to try loading the episode NFO")
             return
@@ -1837,14 +1835,14 @@ class TVEpisode(object):
             nfoFile = sickbeard.helpers.replaceExtension(self.location, "nfo")
             logger.log(str(self.show.indexerid) + u": Using NFO name " + nfoFile, logger.DEBUG)
 
-            if ek.ek(os.path.isfile, nfoFile):
+            if ek(os.path.isfile, nfoFile):
                 try:
                     showXML = etree.ElementTree(file=nfoFile)
                 except (SyntaxError, ValueError), e:
                     logger.log(u"Error loading the NFO, backing up the NFO and skipping for now: " + ex(e),
                                logger.ERROR)  # TODO: figure out what's wrong and fix it
                     try:
-                        ek.ek(os.rename, nfoFile, nfoFile + ".old")
+                        ek(os.rename, nfoFile, nfoFile + ".old")
                     except Exception, e:
                         logger.log(
                             u"Failed to rename your episode's NFO file - you need to delete it or fix it: " + ex(e),
@@ -1894,7 +1892,7 @@ class TVEpisode(object):
             else:
                 self.hasnfo = False
 
-            if ek.ek(os.path.isfile, sickbeard.helpers.replaceExtension(nfoFile, "tbn")):
+            if ek(os.path.isfile, sickbeard.helpers.replaceExtension(nfoFile, "tbn")):
                 self.hastbn = True
             else:
                 self.hastbn = False
@@ -1916,7 +1914,7 @@ class TVEpisode(object):
 
     def createMetaFiles(self):
 
-        if not ek.ek(os.path.isdir, self.show._location):
+        if not ek(os.path.isdir, self.show._location):
             logger.log(str(self.show.indexerid) + u": The show dir is missing, not bothering to try to create metadata")
             return
 
@@ -2070,10 +2068,10 @@ class TVEpisode(object):
         myDB.upsert("tv_episodes", newValueDict, controlValueDict)
 
     def fullPath(self):
-        if self.location == None or self.location == "":
+        if self.location is None or self.location == "":
             return None
         else:
-            return ek.ek(os.path.join, self.show.location, self.location)
+            return ek(os.path.join, self.show.location, self.location)
 
     def createStrings(self, pattern=None):
         patterns = [
@@ -2446,7 +2444,7 @@ class TVEpisode(object):
 
         # if not we append the folder on and use that
         else:
-            result = ek.ek(os.path.join, self.formatted_dir(), result)
+            result = ek(os.path.join, self.formatted_dir(), result)
 
         return result
 
@@ -2455,7 +2453,7 @@ class TVEpisode(object):
         Just the folder name of the episode
         """
 
-        if pattern == None:
+        if pattern is None:
             # we only use ABD if it's enabled, this is an ABD show, AND this is not a multi-ep
             if self.show.air_by_date and sickbeard.NAMING_CUSTOM_ABD and not self.relatedEps:
                 pattern = sickbeard.NAMING_ABD_PATTERN
@@ -2501,13 +2499,13 @@ class TVEpisode(object):
         in the naming settings.
         """
 
-        if not ek.ek(os.path.isfile, self.location):
+        if not ek(os.path.isfile, self.location):
             logger.log(u"Can't perform rename on " + self.location + " when it doesn't exist, skipping", logger.WARNING)
             return
 
         proper_path = self.proper_path()
-        absolute_proper_path = ek.ek(os.path.join, self.show.location, proper_path)
-        absolute_current_path_no_ext, file_ext = ek.ek(os.path.splitext, self.location)
+        absolute_proper_path = ek(os.path.join, self.show.location, proper_path)
+        absolute_current_path_no_ext, file_ext = ek(os.path.splitext, self.location)
         absolute_current_path_no_ext_length = len(absolute_current_path_no_ext)
 
         related_subs = []
@@ -2533,7 +2531,7 @@ class TVEpisode(object):
         if self.show.subtitles and sickbeard.SUBTITLES_DIR != '':
             related_subs = postProcessor.PostProcessor(self.location).list_associated_files(sickbeard.SUBTITLES_DIR,
                                                                                             subtitles_only=True, subfolders=True)
-            absolute_proper_subs_path = ek.ek(os.path.join, sickbeard.SUBTITLES_DIR, self.formatted_filename())
+            absolute_proper_subs_path = ek(os.path.join, sickbeard.SUBTITLES_DIR, self.formatted_filename())
 
         logger.log(u"Files associated to " + self.location + ": " + str(related_files), logger.DEBUG)
 
@@ -2543,11 +2541,11 @@ class TVEpisode(object):
         # move related files
         for cur_related_file in related_files:
             #We need to fix something here because related files can be in subfolders and the original code doesn't handle this (at all)
-            cur_related_dir = ek.ek(os.path.dirname, ek.ek(os.path.abspath, cur_related_file))
-            subfolder = cur_related_dir.replace(ek.ek(os.path.dirname, ek.ek(os.path.abspath, self.location)), '')
+            cur_related_dir = ek(os.path.dirname, ek(os.path.abspath, cur_related_file))
+            subfolder = cur_related_dir.replace(ek(os.path.dirname, ek(os.path.abspath, self.location)), '')
             #We now have a subfolder. We need to add that to the absolute_proper_path.
             #First get the absolute proper-path dir
-            proper_related_dir = ek.ek(os.path.dirname, ek.ek(os.path.abspath, absolute_proper_path + file_ext))
+            proper_related_dir = ek(os.path.dirname, ek(os.path.abspath, absolute_proper_path + file_ext))
             proper_related_path = absolute_proper_path.replace(proper_related_dir, proper_related_dir + subfolder)
 
 
@@ -2557,7 +2555,7 @@ class TVEpisode(object):
                 logger.log(str(self.indexerid) + u": Unable to rename file " + cur_related_file, logger.ERROR)
 
         for cur_related_sub in related_subs:
-            absolute_proper_subs_path = ek.ek(os.path.join, sickbeard.SUBTITLES_DIR, self.formatted_filename())
+            absolute_proper_subs_path = ek(os.path.join, sickbeard.SUBTITLES_DIR, self.formatted_filename())
             cur_result = helpers.rename_ep_file(cur_related_sub, absolute_proper_subs_path,
                                                 absolute_current_path_no_ext_length)
             if not cur_result:
diff --git a/sickbeard/tvcache.py b/sickbeard/tvcache.py
index 974e78e66ae4fd05b4a113eb867c435331407d9c..a7ed5ee91cee84000ebf349fc57d0e6aa86415c5 100644
--- a/sickbeard/tvcache.py
+++ b/sickbeard/tvcache.py
@@ -33,8 +33,9 @@ from sickbeard.exceptions import ex
 from sickbeard.exceptions import AuthException
 from sickbeard.rssfeeds import RSSFeeds
 from name_parser.parser import NameParser, InvalidNameException, InvalidShowException
-from sickbeard import encodingKludge as ek
 from sickbeard import show_name_helpers
+from sickrage.helper.encoding import ss
+
 
 class CacheDBConnection(db.DBConnection):
     def __init__(self, providerName):
@@ -279,7 +280,7 @@ class TVCache():
             # get quality of release
             quality = parse_result.quality
 
-            name = ek.ss(name)
+            name = ss(name)
 
             # get release group
             release_group = parse_result.release_group
diff --git a/sickbeard/versionChecker.py b/sickbeard/versionChecker.py
index a106aaeacd6b2a836f14fb77aa19fd91c2f7c8b7..dc60962d9b375bf0600805a77969de3031227b46 100644
--- a/sickbeard/versionChecker.py
+++ b/sickbeard/versionChecker.py
@@ -32,7 +32,7 @@ from sickbeard import notifiers
 from sickbeard import ui
 from sickbeard import logger, helpers
 from sickbeard.exceptions import ex
-from sickbeard import encodingKludge as ek
+from sickrage.helper.encoding import ek
 import requests
 
 import shutil
@@ -41,7 +41,7 @@ import shutil_custom
 shutil.copyfile = shutil_custom.copyfile_custom
 
 
-class CheckVersion():
+class CheckVersion:
     """
     Version check class meant to run as a thread object with the sr scheduler.
     """
@@ -232,7 +232,7 @@ class CheckVersion():
         # check if we're a windows build
         if sickbeard.BRANCH.startswith('build '):
             install_type = 'win'
-        elif os.path.isdir(ek.ek(os.path.join, sickbeard.PROG_DIR, u'.git')):
+        elif os.path.isdir(ek(os.path.join, sickbeard.PROG_DIR, u'.git')):
             install_type = 'git'
         else:
             install_type = 'source'
@@ -757,7 +757,7 @@ class SourceUpdateManager(UpdateManager):
 
         try:
             # prepare the update dir
-            sr_update_dir = ek.ek(os.path.join, sickbeard.PROG_DIR, u'sr-update')
+            sr_update_dir = ek(os.path.join, sickbeard.PROG_DIR, u'sr-update')
 
             if os.path.isdir(sr_update_dir):
                 logger.log(u"Clearing out update folder " + sr_update_dir + " before extracting")
@@ -771,11 +771,11 @@ class SourceUpdateManager(UpdateManager):
             tar_download_path = os.path.join(sr_update_dir, u'sr-update.tar')
             helpers.download_file(tar_download_url, tar_download_path, session=self.session)
 
-            if not ek.ek(os.path.isfile, tar_download_path):
+            if not ek(os.path.isfile, tar_download_path):
                 logger.log(u"Unable to retrieve new version from " + tar_download_url + ", can't update", logger.WARNING)
                 return False
 
-            if not ek.ek(tarfile.is_tarfile, tar_download_path):
+            if not ek(tarfile.is_tarfile, tar_download_path):
                 logger.log(u"Retrieved version from " + tar_download_url + " is corrupt, can't update", logger.ERROR)
                 return False
 
diff --git a/sickbeard/webapi.py b/sickbeard/webapi.py
index a2eae8507d735210edce81a50f788c0e98e9258c..ea72436c942bf3f53710a2112a5c4404e55f79a3 100644
--- a/sickbeard/webapi.py
+++ b/sickbeard/webapi.py
@@ -28,6 +28,7 @@ import traceback
 
 import sickbeard
 from sickrage.helper.common import dateFormat, dateTimeFormat, timeFormat
+from sickrage.helper.encoding import ek
 from sickrage.helper.quality import get_quality_string
 from sickrage.media.ShowFanArt import ShowFanArt
 from sickrage.media.ShowNetworkLogo import ShowNetworkLogo
@@ -35,12 +36,12 @@ from sickrage.media.ShowPoster import ShowPoster
 from sickrage.media.ShowBanner import ShowBanner
 from sickrage.show.ComingEpisodes import ComingEpisodes
 from sickrage.show.History import History
+from sickrage.show.Show import Show
 from sickrage.system.Restart import Restart
 from sickrage.system.Shutdown import Shutdown
 
 from versionChecker import CheckVersion
 from sickbeard import db, logger, exceptions, ui, helpers
-from sickbeard import encodingKludge as ek
 from sickbeard import search_queue
 from sickbeard import image_cache
 from sickbeard import classes
@@ -594,7 +595,7 @@ def _getRootDirs():
     for root_dir in root_dirs:
         valid = 1
         try:
-            ek.ek(os.listdir, root_dir)
+            ek(os.listdir, root_dir)
         except:
             valid = 0
         default = 0
@@ -1196,7 +1197,7 @@ class CMD_Logs(ApiCall):
 
         data = []
         if os.path.isfile(logger.logFile):
-            with ek.ek(codecs.open, *[logger.logFile, 'r', 'utf-8']) as f:
+            with ek(codecs.open, *[logger.logFile, 'r', 'utf-8']) as f:
                 data = f.readlines()
 
         regex = "^(\d\d\d\d)\-(\d\d)\-(\d\d)\s*(\d\d)\:(\d\d):(\d\d)\s*([A-Z]+)\s*(.+?)\s*\:\:\s*(.*)$"
@@ -1322,7 +1323,7 @@ class CMD_SickBeardAddRootDir(ApiCall):
         index = 0
 
         # dissallow adding/setting an invalid dir
-        if not ek.ek(os.path.isdir, self.location):
+        if not ek(os.path.isdir, self.location):
             return _responds(RESULT_FAILURE, msg="Location is invalid")
 
         root_dirs = []
@@ -1932,7 +1933,7 @@ class CMD_ShowAddExisting(ApiCall):
         if showObj:
             return _responds(RESULT_FAILURE, msg="An existing indexerid already exists in the database")
 
-        if not ek.ek(os.path.isdir, self.location):
+        if not ek(os.path.isdir, self.location):
             return _responds(RESULT_FAILURE, msg='Not a valid location')
 
         indexerName = None
@@ -2052,7 +2053,7 @@ class CMD_ShowAddNew(ApiCall):
             else:
                 return _responds(RESULT_FAILURE, msg="Root directory is not set, please provide a location")
 
-        if not ek.ek(os.path.isdir, self.location):
+        if not ek(os.path.isdir, self.location):
             return _responds(RESULT_FAILURE, msg="'" + self.location + "' is not a valid location")
 
         quality_map = {'sdtv': Quality.SDTV,
@@ -2129,7 +2130,7 @@ class CMD_ShowAddNew(ApiCall):
         indexer = indexerResult['data']['results'][0]['indexer']
 
         # moved the logic check to the end in an attempt to eliminate empty directory being created from previous errors
-        showPath = ek.ek(os.path.join, self.location, helpers.sanitizeFileName(indexerName))
+        showPath = ek(os.path.join, self.location, helpers.sanitizeFileName(indexerName))
 
         # don't create show dir if config says not to
         if sickbeard.ADD_SHOWS_WO_DIR:
@@ -2182,45 +2183,42 @@ class CMD_ShowCache(ApiCall):
         has_poster = 0
         has_banner = 0
 
-        if ek.ek(os.path.isfile, cache_obj.poster_path(showObj.indexerid)):
+        if ek(os.path.isfile, cache_obj.poster_path(showObj.indexerid)):
             has_poster = 1
-        if ek.ek(os.path.isfile, cache_obj.banner_path(showObj.indexerid)):
+        if ek(os.path.isfile, cache_obj.banner_path(showObj.indexerid)):
             has_banner = 1
 
         return _responds(RESULT_SUCCESS, {"poster": has_poster, "banner": has_banner})
 
 
 class CMD_ShowDelete(ApiCall):
-    _help = {"desc": "delete a show in sickrage",
-             "requiredParameters": {
-                 "indexerid": {"desc": "unique id of a show"},
-             },
-             "optionalParameters": {
-                 "tvdbid": {"desc": "thetvdb.com unique id of a show"},
-                 "removefiles":{"desc": "Deletes the files, there is no going back!"},
-             }
+    _help = {
+        "desc": "Delete a show in SickRage",
+        "requiredParameters": {
+            "indexerid": {"desc": "Unique id of a show"},
+        },
+        "optionalParameters": {
+            "tvdbid": {"desc": "thetvdb.com unique id of a show"},
+            "removefiles": {"desc": "Deletes the files, there is no going back! Default if false"},
+        }
     }
 
     def __init__(self, args, kwargs):
         # required
         self.indexerid, args = self.check_params(args, kwargs, "indexerid", None, True, "int", [])
         # optional
-        self.removefiles, args = self.check_params(args, kwargs, "removefiles", 0, False, "int", [0,1])
+        self.removefiles, args = self.check_params(args, kwargs, "removefiles", 0, False, "int", [0, 1])
         # super, missing, help
         ApiCall.__init__(self, args, kwargs)
 
     def run(self):
-        """ delete a show in sickrage """
-        showObj = sickbeard.helpers.findCertainShow(sickbeard.showList, int(self.indexerid))
-        if not showObj:
-            return _responds(RESULT_FAILURE, msg="Show not found")
+        """ Delete a show in SickRage """
+        error, show = Show.delete(self.indexerid, self.removefiles)
 
-        try:
-            sickbeard.showQueueScheduler.action.removeShow(showObj, bool(self.removefiles))
-        except sickbeard.exceptions.CantRemoveException as e:
-            return _responds(RESULT_FAILURE, msg=ex(e))
+        if error is not None:
+            return _responds(RESULT_FAILURE, msg=error)
 
-        return _responds(RESULT_SUCCESS, msg=showObj.name + " has been queued to be deleted")
+        return _responds(RESULT_SUCCESS, msg='%s has been queued to be deleted' % show.name)
 
 
 class CMD_ShowGetQuality(ApiCall):
@@ -2362,14 +2360,15 @@ class CMD_ShowGetFanArt(ApiCall):
 
 
 class CMD_ShowPause(ApiCall):
-    _help = {"desc": "set a show's paused state in sickrage",
-             "requiredParameters": {
-                 "indexerid": {"desc": "unique id of a show"},
-             },
-             "optionalParameters": {
-                 "tvdbid": {"desc": "thetvdb.com unique id of a show"},
-                 "pause": {"desc": "set the pause state of the show"}
-             }
+    _help = {
+        "desc": "Set a show's paused state in SickRage",
+        "requiredParameters": {
+            "indexerid": {"desc": "Unique id of a show"},
+        },
+        "optionalParameters": {
+            "tvdbid": {"desc": "thetvdb.com unique id of a show"},
+            "pause": {"desc": "1 to pause the show, 0 to resume the show"}
+        }
     }
 
     def __init__(self, args, kwargs):
@@ -2381,28 +2380,24 @@ class CMD_ShowPause(ApiCall):
         ApiCall.__init__(self, args, kwargs)
 
     def run(self):
-        """ set a show's paused state in sickrage """
-        showObj = sickbeard.helpers.findCertainShow(sickbeard.showList, int(self.indexerid))
-        if not showObj:
-            return _responds(RESULT_FAILURE, msg="Show not found")
+        """ Set a show's paused state in SickRage """
+        error, show = Show.pause(self.indexerid, self.pause)
+
+        if error is not None:
+            return _responds(RESULT_FAILURE, msg=error)
+
+        return _responds(RESULT_SUCCESS, msg='%s has been %s' % (show.name, ('resumed', 'paused')[show.paused]))
 
-        if self.pause:
-            showObj.paused = 1
-            showObj.saveToDB()
-            return _responds(RESULT_SUCCESS, msg=str(showObj.name) + " has been paused")
-        else:
-            showObj.paused = 0
-            showObj.saveToDB()
-            return _responds(RESULT_SUCCESS, msg=str(showObj.name) + " has been unpaused")
 
 class CMD_ShowRefresh(ApiCall):
-    _help = {"desc": "refresh a show in sickrage",
-             "requiredParameters": {
-                 "indexerid": {"desc": "unique id of a show"},
-             },
-             "optionalParameters": {
-                 "tvdbid": {"desc": "thetvdb.com unique id of a show"},
-             }
+    _help = {
+        "desc": "Refresh a show in SickRage",
+        "requiredParameters": {
+            "indexerid": {"desc": "Unique id of a show"},
+        },
+        "optionalParameters": {
+            "tvdbid": {"desc": "thetvdb.com unique id of a show"},
+        }
     }
 
     def __init__(self, args, kwargs):
@@ -2413,17 +2408,13 @@ class CMD_ShowRefresh(ApiCall):
         ApiCall.__init__(self, args, kwargs)
 
     def run(self):
-        """ refresh a show in sickrage """
-        showObj = sickbeard.helpers.findCertainShow(sickbeard.showList, int(self.indexerid))
-        if not showObj:
-            return _responds(RESULT_FAILURE, msg="Show not found")
+        """ Refresh a show in SickRage """
+        error, show = Show.refresh(self.indexerid)
 
-        try:
-            sickbeard.showQueueScheduler.action.refreshShow(showObj)  # @UndefinedVariable
-            return _responds(RESULT_SUCCESS, msg=str(showObj.name) + " has queued to be refreshed")
-        except exceptions.CantRefreshException:
-            # TODO: log the excption
-            return _responds(RESULT_FAILURE, msg="Unable to refresh " + str(showObj.name))
+        if error is not None:
+            return _responds(RESULT_FAILURE, msg=error)
+
+        return _responds(RESULT_SUCCESS, msg='%s has queued to be refreshed' % show.name)
 
 
 class CMD_ShowSeasonList(ApiCall):
diff --git a/sickbeard/webserve.py b/sickbeard/webserve.py
index ae7e2868070d6ecbb9c313b1925b2c813d5ad08a..a40d30a7bb051f86b0495dcc4b4c03e735e61286 100644
--- a/sickbeard/webserve.py
+++ b/sickbeard/webserve.py
@@ -30,7 +30,6 @@ from sickbeard import clients
 from sickbeard import notifiers, processTV
 from sickbeard import ui
 from sickbeard import logger, helpers, exceptions, classes, db
-from sickbeard import encodingKludge as ek
 from sickbeard import search_queue
 from sickbeard import naming
 from sickbeard import subtitles
@@ -53,12 +52,14 @@ from unrar2 import RarFile
 import adba
 from libtrakt import TraktAPI
 from libtrakt.exceptions import traktException
+from sickrage.helper.encoding import ek, ss
 from sickrage.media.ShowBanner import ShowBanner
 from sickrage.media.ShowFanArt import ShowFanArt
 from sickrage.media.ShowNetworkLogo import ShowNetworkLogo
 from sickrage.media.ShowPoster import ShowPoster
 from sickrage.show.ComingEpisodes import ComingEpisodes
 from sickrage.show.History import History as HistoryTool
+from sickrage.show.Show import Show
 from sickrage.system.Restart import Restart
 from sickrage.system.Shutdown import Shutdown
 from versionChecker import CheckVersion
@@ -1199,7 +1200,7 @@ class Home(WebRoot):
                 else:
                     submenu.append({'title': 'Pause', 'path': 'home/togglePause?show=%d' % showObj.indexerid, 'icon': 'ui-icon ui-icon-pause'})
 
-                submenu.append({'title': 'Remove', 'path': 'home/deleteShow?show=%d' % showObj.indexerid, 'class':'remove', 'confirm': True, 'icon': 'ui-icon ui-icon-trash'})
+                submenu.append({'title': 'Remove', 'path': 'home/deleteShow?show=%d' % showObj.indexerid, 'class':'removeshow', 'confirm': True, 'icon': 'ui-icon ui-icon-trash'})
                 submenu.append({'title': 'Re-scan files', 'path': 'home/refreshShow?show=%d' % showObj.indexerid, 'icon': 'ui-icon ui-icon-refresh'})
                 submenu.append({'title': 'Force Full Update', 'path': 'home/updateShow?show=%d&amp;force=1' % showObj.indexerid, 'icon': 'ui-icon ui-icon-transfer-e-w'})
                 submenu.append({'title': 'Update show in KODI','path': 'home/updateKODI?show=%d' % showObj.indexerid, 'requires': self.haveKODI(), 'icon': 'submenu-icon-kodi'})
@@ -1429,7 +1430,7 @@ class Home(WebRoot):
             # if we change location clear the db of episodes, change it, write to db, and rescan
             if os.path.normpath(showObj._location) != os.path.normpath(location):
                 logger.log(os.path.normpath(showObj._location) + " != " + os.path.normpath(location), logger.DEBUG)
-                if not ek.ek(os.path.isdir, location) and not sickbeard.CREATE_MISSING_SHOW_DIRS:
+                if not ek(os.path.isdir, location) and not sickbeard.CREATE_MISSING_SHOW_DIRS:
                     errors.append("New location <tt>%s</tt> does not exist" % location)
 
                 # don't bother if we're going to update anyway
@@ -1482,73 +1483,50 @@ class Home(WebRoot):
 
         return self.redirect("/home/displayShow?show=" + show)
 
-
     def togglePause(self, show=None):
-        if show is None:
-            return self._genericMessage("Error", "Invalid show ID")
-
-        showObj = sickbeard.helpers.findCertainShow(sickbeard.showList, int(show))
+        error, show = Show.pause(show)
 
-        if showObj is None:
-            return self._genericMessage("Error", "Unable to find the specified show")
-
-        if showObj.paused:
-            showObj.paused = 0
-        else:
-            showObj.paused = 1
+        if error is not None:
+            return self._genericMessage('Error', error)
 
-        showObj.saveToDB()
+        ui.notifications.message('%s has been %s' % (show.name, ('resumed', 'paused')[show.paused]))
 
-        ui.notifications.message('%s has been %s' % (showObj.name,('resumed', 'paused')[showObj.paused]))
         return self.redirect("/home/displayShow?show=" + show)
 
     def deleteShow(self, show=None, full=0):
-
-        if show is None:
-            return self._genericMessage("Error", "Invalid show ID")
-
-        showObj = sickbeard.helpers.findCertainShow(sickbeard.showList, int(show))
-
-        if showObj is None:
-            return self._genericMessage("Error", "Unable to find the specified show")
-
-        try:
-            sickbeard.showQueueScheduler.action.removeShow(showObj, bool(full))
-        except Exception as e:
-            logger.log(u"Unable to delete show: %s. Error: %s" % (showObj.name, ex(e)),logger.WARNING)
-            return self._genericMessage("Error", "Unable to delete show: %s" % showObj.name)
-
-        ui.notifications.message('%s has been %s %s' %
-                                 (showObj.name,
-                                  ('deleted', 'trashed')[bool(sickbeard.TRASH_REMOVE_SHOW)],
-                                  ('(media untouched)', '(with all related media)')[bool(full)]))
+        error, show = Show.delete(show, full)
+
+        if error is not None:
+            return self._genericMessage('Error', error)
+
+        ui.notifications.message(
+            '%s has been %s %s' %
+            (
+                show.name,
+                ('deleted', 'trashed')[bool(sickbeard.TRASH_REMOVE_SHOW)],
+                ('(media untouched)', '(with all related media)')[bool(full)]
+            )
+        )
 
         time.sleep(cpu_presets[sickbeard.CPU_PRESET])
-        #Dont redirect to default page so user can confirm show was deleted
-        return self.redirect('/home/')
 
+        # Don't redirect to the default page, so the user can confirm that the show was deleted
+        return self.redirect('/home/')
 
     def refreshShow(self, show=None):
+        error, show = Show.refresh(show)
 
-        if show is None:
-            return self._genericMessage("Error", "Invalid show ID")
+        # This is a show validation error
+        if error is not None and show is None:
+            return self._genericMessage('Error', error)
 
-        showObj = sickbeard.helpers.findCertainShow(sickbeard.showList, int(show))
-
-        if showObj is None:
-            return self._genericMessage("Error", "Unable to find the specified show")
-
-        # force the update from the DB
-        try:
-            sickbeard.showQueueScheduler.action.refreshShow(showObj)
-        except exceptions.CantRefreshException, e:
-            ui.notifications.error("Unable to refresh this show.",
-                                   ex(e))
+        # This is a refresh error
+        if error is not None:
+            ui.notifications.error('Unable to refresh this show.', ex(error))
 
         time.sleep(cpu_presets[sickbeard.CPU_PRESET])
 
-        return self.redirect("/home/displayShow?show=" + str(showObj.indexerid))
-
+        return self.redirect("/home/displayShow?show=" + str(show.indexerid))
 
     def updateShow(self, show=None, force=0):
 
@@ -1706,7 +1684,7 @@ class Home(WebRoot):
                         continue
 
                     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):
+                        IGNORED] and not 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)
@@ -2275,22 +2253,22 @@ class HomeAddShows(Home):
         myDB = db.DBConnection()
         for root_dir in root_dirs:
             try:
-                file_list = ek.ek(os.listdir, root_dir)
+                file_list = ek(os.listdir, root_dir)
             except:
                 continue
 
             for cur_file in file_list:
 
                 try:
-                    cur_path = ek.ek(os.path.normpath, ek.ek(os.path.join, root_dir, cur_file))
-                    if not ek.ek(os.path.isdir, cur_path):
+                    cur_path = ek(os.path.normpath, ek(os.path.join, root_dir, cur_file))
+                    if not ek(os.path.isdir, cur_path):
                         continue
                 except:
                     continue
 
                 cur_dir = {
                     'dir': cur_path,
-                    'display_dir': '<b>' + ek.ek(os.path.dirname, cur_path) + os.sep + '</b>' + ek.ek(
+                    'display_dir': '<b>' + ek(os.path.dirname, cur_path) + os.sep + '</b>' + ek(
                         os.path.basename,
                         cur_path),
                 }
@@ -2353,7 +2331,7 @@ class HomeAddShows(Home):
 
         elif not show_name:
             default_show_name = re.sub(' \(\d{4}\)', '',
-                                         ek.ek(os.path.basename, ek.ek(os.path.normpath, show_dir)).replace('.', ' '))
+                                         ek(os.path.basename, ek(os.path.normpath, show_dir)).replace('.', ' '))
         else:
             default_show_name = show_name
 
@@ -2533,7 +2511,7 @@ class HomeAddShows(Home):
             location = None
 
         if location:
-            show_dir = ek.ek(os.path.join, location, helpers.sanitizeFileName(showName))
+            show_dir = ek(os.path.join, location, helpers.sanitizeFileName(showName))
             dir_exists = helpers.makeDir(show_dir)
             if not dir_exists:
                 logger.log(u"Unable to create the folder " + show_dir + ", can't add the show", logger.ERROR)
@@ -2621,12 +2599,12 @@ class HomeAddShows(Home):
 
         # use the whole path if it's given, or else append the show name to the root dir to get the full show path
         if fullShowPath:
-            show_dir = ek.ek(os.path.normpath, fullShowPath)
+            show_dir = ek(os.path.normpath, fullShowPath)
         else:
-            show_dir = ek.ek(os.path.join, rootDir, helpers.sanitizeFileName(show_name))
+            show_dir = ek(os.path.join, rootDir, helpers.sanitizeFileName(show_name))
 
         # blanket policy - if the dir exists you should have used "add existing show" numbnuts
-        if ek.ek(os.path.isdir, show_dir) and not fullShowPath:
+        if ek(os.path.isdir, show_dir) and not fullShowPath:
             ui.notifications.error("Unable to add show", "Folder " + show_dir + " exists already")
             return self.redirect('/home/addShows/existingShows/')
 
@@ -3088,7 +3066,7 @@ class Manage(Home, WebRoot):
 
         for curShow in showList:
 
-            cur_root_dir = ek.ek(os.path.dirname, curShow._location)
+            cur_root_dir = ek(os.path.dirname, curShow._location)
             if cur_root_dir not in root_dir_list:
                 root_dir_list.append(cur_root_dir)
 
@@ -3195,10 +3173,10 @@ class Manage(Home, WebRoot):
             if not showObj:
                 continue
 
-            cur_root_dir = ek.ek(os.path.dirname, showObj._location)
-            cur_show_dir = ek.ek(os.path.basename, showObj._location)
+            cur_root_dir = ek(os.path.dirname, showObj._location)
+            cur_show_dir = ek(os.path.basename, showObj._location)
             if cur_root_dir in dir_map and cur_root_dir != dir_map[cur_root_dir]:
-                new_show_dir = ek.ek(os.path.join, dir_map[cur_root_dir], cur_show_dir)
+                new_show_dir = ek(os.path.join, dir_map[cur_root_dir], cur_show_dir)
                 logger.log(
                     u"For show " + showObj.name + " changing dir from " + showObj._location + " to " + new_show_dir)
             else:
@@ -3759,7 +3737,7 @@ class ConfigGeneral(Config):
             ui.notifications.error('Error(s) Saving Configuration',
                                    '<br />\n'.join(results))
         else:
-            ui.notifications.message('Configuration Saved', ek.ek(os.path.join, sickbeard.CONFIG_FILE))
+            ui.notifications.message('Configuration Saved', ek(os.path.join, sickbeard.CONFIG_FILE))
 
         return self.redirect("/config/general/")
 
@@ -3916,7 +3894,7 @@ class ConfigSearch(Config):
             ui.notifications.error('Error(s) Saving Configuration',
                                    '<br />\n'.join(results))
         else:
-            ui.notifications.message('Configuration Saved', ek.ek(os.path.join, sickbeard.CONFIG_FILE))
+            ui.notifications.message('Configuration Saved', ek(os.path.join, sickbeard.CONFIG_FILE))
 
         return self.redirect("/config/search/")
 
@@ -4038,7 +4016,7 @@ class ConfigPostProcessing(Config):
             ui.notifications.error('Error(s) Saving Configuration',
                                    '<br />\n'.join(results))
         else:
-            ui.notifications.message('Configuration Saved', ek.ek(os.path.join, sickbeard.CONFIG_FILE))
+            ui.notifications.message('Configuration Saved', ek(os.path.join, sickbeard.CONFIG_FILE))
 
         return self.redirect("/config/postProcessing/")
 
@@ -4052,7 +4030,7 @@ class ConfigPostProcessing(Config):
 
         result = naming.test_name(pattern, multi, abd, sports, anime_type)
 
-        result = ek.ek(os.path.join, result['dir'], result['name'])
+        result = ek(os.path.join, result['dir'], result['name'])
 
         return result
 
@@ -4580,7 +4558,7 @@ class ConfigProviders(Config):
             ui.notifications.error('Error(s) Saving Configuration',
                                    '<br />\n'.join(results))
         else:
-            ui.notifications.message('Configuration Saved', ek.ek(os.path.join, sickbeard.CONFIG_FILE))
+            ui.notifications.message('Configuration Saved', ek(os.path.join, sickbeard.CONFIG_FILE))
 
         return self.redirect("/config/providers/")
 
@@ -4812,7 +4790,7 @@ class ConfigNotifications(Config):
             ui.notifications.error('Error(s) Saving Configuration',
                                    '<br />\n'.join(results))
         else:
-            ui.notifications.message('Configuration Saved', ek.ek(os.path.join, sickbeard.CONFIG_FILE))
+            ui.notifications.message('Configuration Saved', ek(os.path.join, sickbeard.CONFIG_FILE))
 
         return self.redirect("/config/notifications/")
 
@@ -4863,7 +4841,7 @@ class ConfigSubtitles(Config):
             ui.notifications.error('Error(s) Saving Configuration',
                                    '<br />\n'.join(results))
         else:
-            ui.notifications.message('Configuration Saved', ek.ek(os.path.join, sickbeard.CONFIG_FILE))
+            ui.notifications.message('Configuration Saved', ek(os.path.join, sickbeard.CONFIG_FILE))
 
         return self.redirect("/config/subtitles/")
 
@@ -4898,7 +4876,7 @@ class ConfigAnime(Config):
             ui.notifications.error('Error(s) Saving Configuration',
                                    '<br />\n'.join(results))
         else:
-            ui.notifications.message('Configuration Saved', ek.ek(os.path.join, sickbeard.CONFIG_FILE))
+            ui.notifications.message('Configuration Saved', ek(os.path.join, sickbeard.CONFIG_FILE))
 
         return self.redirect("/config/anime/")
 
@@ -4940,8 +4918,7 @@ class ErrorLogs(WebRoot):
             finalData = []
 
             for x in reversed(data_in):
-
-                x = ek.ss(x)
+                x = ss(x)
                 match = re.match(regex, x)
 
                 if match:
@@ -5006,12 +4983,12 @@ class ErrorLogs(WebRoot):
         data = []
 
         if os.path.isfile(logger.logFile):
-            with ek.ek(codecs.open, *[logger.logFile, 'r', 'utf-8']) as f:
+            with ek(codecs.open, *[logger.logFile, 'r', 'utf-8']) as f:
                 data = Get_Data(minLevel, f.readlines(), 0, regex, logFilter, logSearch, maxLines)
 
         for i in range (1 , int(sickbeard.LOG_NR)):
             if os.path.isfile(logger.logFile + "." + str(i)) and (len(data) <= maxLines):
-                with ek.ek(codecs.open, *[logger.logFile + "." + str(i), 'r', 'utf-8']) as f:
+                with ek(codecs.open, *[logger.logFile + "." + str(i), 'r', 'utf-8']) as f:
                         data += Get_Data(minLevel, f.readlines(), len(data), regex, logFilter, logSearch, maxLines)
 
         return t.render(header="Log File", title="Logs", topmenu="errorlogs", submenu=self.ErrorLogsMenu(),
diff --git a/sickrage/helper/common.py b/sickrage/helper/common.py
index bf8bd35317afb2303a703b864d3ffdbab69a7149..9fe374e1ce2ed89894e4ad5dd049afd1d163ee1e 100644
--- a/sickrage/helper/common.py
+++ b/sickrage/helper/common.py
@@ -1,3 +1,21 @@
+# This file is part of SickRage.
+#
+# URL: https://www.sickrage.tv
+# Git: https://github.com/SiCKRAGETV/SickRage.git
+#
+# SickRage is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# SickRage is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with SickRage.  If not, see <http://www.gnu.org/licenses/>.
+
 dateFormat = '%Y-%m-%d'
 dateTimeFormat = '%Y-%m-%d %H:%M:%S'
 timeFormat = '%A %I:%M %p'
diff --git a/sickrage/helper/encoding.py b/sickrage/helper/encoding.py
new file mode 100644
index 0000000000000000000000000000000000000000..def98bba76ca8b1799e6005e6f92308f8ce3da9f
--- /dev/null
+++ b/sickrage/helper/encoding.py
@@ -0,0 +1,115 @@
+# Author: Nic Wolfe <nic@wolfeden.ca>
+# URL: https://sickrage.tv
+# Git: https://github.com/SiCKRAGETV/SickRage.git
+#
+# This file is part of SickRage.
+#
+# SickRage is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# SickRage is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with SickRage.  If not, see <http://www.gnu.org/licenses/>.
+
+import sickbeard
+
+from chardet import detect
+from os import name
+
+
+def ek(function, *args, **kwargs):
+    """
+    Encoding Kludge: Call function with arguments and unicode-encode output
+
+    :param function:  Function to call
+    :param args:  Arguments for function
+    :param kwargs:  Arguments for function
+    :return: Unicode-converted function output (string, list or tuple, depends on input)
+    """
+
+    if name == 'nt':
+        result = function(*args, **kwargs)
+    else:
+        result = function(*[ss(x) if isinstance(x, (str, unicode)) else x for x in args], **kwargs)
+
+    if isinstance(result, (list, tuple)):
+        return _fix_list_encoding(result)
+
+    if isinstance(result, str):
+        return _to_unicode(result)
+
+    return result
+
+
+def ss(var):
+    """
+    Converts string to Unicode, fallback encoding is forced UTF-8
+
+    :param var: String to convert
+    :return: Converted string
+    """
+
+    var = _to_unicode(var)
+
+    try:
+        var = var.encode(sickbeard.SYS_ENCODING)
+    except Exception:
+        try:
+            var = var.encode('utf-8')
+        except Exception:
+            try:
+                var = var.encode(sickbeard.SYS_ENCODING, 'replace')
+            except Exception:
+                var = var.encode('utf-8', 'ignore')
+
+    return var
+
+
+def _fix_list_encoding(var):
+    """
+    Converts each item in a list to Unicode
+
+    :param var: List or tuple to convert to Unicode
+    :return: Unicode converted input
+    """
+
+    if isinstance(var, (list, tuple)):
+        return filter(lambda x: x is not None, map(_to_unicode, var))
+
+    return var
+
+
+def _to_unicode(var):
+    """
+    Converts string to Unicode, using in order: UTF-8, Latin-1, System encoding or finally what chardet wants
+
+    :param var: String to convert
+    :return: Converted string as unicode, fallback is System encoding
+    """
+
+    if isinstance(var, str):
+        try:
+            var = unicode(var)
+        except Exception:
+            try:
+                var = unicode(var, 'utf-8')
+            except Exception:
+                try:
+                    var = unicode(var, 'latin-1')
+                except Exception:
+                    try:
+                        var = unicode(var, sickbeard.SYS_ENCODING)
+                    except Exception:
+                        try:
+                            # Chardet can be wrong, so try it last
+                            var = unicode(var, detect(var).get('encoding'))
+                        except Exception:
+                            var = unicode(var, sickbeard.SYS_ENCODING, 'replace')
+
+    return var
diff --git a/sickrage/helper/quality.py b/sickrage/helper/quality.py
index ebdc1c48719ce151803d9b7345e6959a08b7bda9..cc757cb89ac71f1eccef97358719e94722f5c14b 100644
--- a/sickrage/helper/quality.py
+++ b/sickrage/helper/quality.py
@@ -1,3 +1,21 @@
+# This file is part of SickRage.
+#
+# URL: https://www.sickrage.tv
+# Git: https://github.com/SiCKRAGETV/SickRage.git
+#
+# SickRage is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# SickRage is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with SickRage.  If not, see <http://www.gnu.org/licenses/>.
+
 from sickbeard.common import Quality, qualityPresetStrings
 
 
diff --git a/sickrage/media/GenericMedia.py b/sickrage/media/GenericMedia.py
index df57fb19b6ba57f06d7a1770e6f791692bdc3ba1..43b5a10c892b2b1670a3326f5b14c833799ecaa3 100644
--- a/sickrage/media/GenericMedia.py
+++ b/sickrage/media/GenericMedia.py
@@ -1,11 +1,29 @@
+# This file is part of SickRage.
+#
+# URL: https://www.sickrage.tv
+# Git: https://github.com/SiCKRAGETV/SickRage.git
+#
+# SickRage is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# SickRage is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with SickRage.  If not, see <http://www.gnu.org/licenses/>.
+
 import sickbeard
 
 from abc import abstractmethod
 from mimetypes import guess_type
 from os.path import isfile, join, normpath
-from sickbeard.encodingKludge import ek
 from sickbeard.exceptions import MultipleShowObjectsException
 from sickbeard.helpers import findCertainShow
+from sickrage.helper.encoding import ek
 
 
 class GenericMedia:
diff --git a/sickrage/media/ShowBanner.py b/sickrage/media/ShowBanner.py
index e2ec5980f43a7fb7cafeb96e5932b611545b00d1..9d370274d4d03f85022770658103c159bda6d46c 100644
--- a/sickrage/media/ShowBanner.py
+++ b/sickrage/media/ShowBanner.py
@@ -1,3 +1,21 @@
+# This file is part of SickRage.
+#
+# URL: https://www.sickrage.tv
+# Git: https://github.com/SiCKRAGETV/SickRage.git
+#
+# SickRage is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# SickRage is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with SickRage.  If not, see <http://www.gnu.org/licenses/>.
+
 from sickbeard.image_cache import ImageCache
 from sickrage.media.GenericMedia import GenericMedia
 
diff --git a/sickrage/media/ShowFanArt.py b/sickrage/media/ShowFanArt.py
index b027def87297fb991648b28a43585a681513e818..bdf991a2fde3e59ff705a163f44b577b8dbc4d35 100644
--- a/sickrage/media/ShowFanArt.py
+++ b/sickrage/media/ShowFanArt.py
@@ -1,3 +1,21 @@
+# This file is part of SickRage.
+#
+# URL: https://www.sickrage.tv
+# Git: https://github.com/SiCKRAGETV/SickRage.git
+#
+# SickRage is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# SickRage is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with SickRage.  If not, see <http://www.gnu.org/licenses/>.
+
 from sickbeard.image_cache import ImageCache
 from sickrage.media.GenericMedia import GenericMedia
 
diff --git a/sickrage/media/ShowNetworkLogo.py b/sickrage/media/ShowNetworkLogo.py
index 296aec1bd9d02278c423dcc91282cc647a9d4daa..e86435af9d1dda77bd242df821b976d8392abf12 100644
--- a/sickrage/media/ShowNetworkLogo.py
+++ b/sickrage/media/ShowNetworkLogo.py
@@ -1,5 +1,23 @@
+# This file is part of SickRage.
+#
+# URL: https://www.sickrage.tv
+# Git: https://github.com/SiCKRAGETV/SickRage.git
+#
+# SickRage is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# SickRage is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with SickRage.  If not, see <http://www.gnu.org/licenses/>.
+
 from os.path import join
-from sickbeard.encodingKludge import ek
+from sickrage.helper.encoding import ek
 from sickrage.media.GenericMedia import GenericMedia
 
 
diff --git a/sickrage/media/ShowPoster.py b/sickrage/media/ShowPoster.py
index f19d582651ff79f2aac93c0e88da1c9520ac7d39..bb890882da4a47c24d3d002c13bbfc24c0d70eb7 100644
--- a/sickrage/media/ShowPoster.py
+++ b/sickrage/media/ShowPoster.py
@@ -1,3 +1,21 @@
+# This file is part of SickRage.
+#
+# URL: https://www.sickrage.tv
+# Git: https://github.com/SiCKRAGETV/SickRage.git
+#
+# SickRage is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# SickRage is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with SickRage.  If not, see <http://www.gnu.org/licenses/>.
+
 from sickbeard.image_cache import ImageCache
 from sickrage.media.GenericMedia import GenericMedia
 
diff --git a/sickrage/show/ComingEpisodes.py b/sickrage/show/ComingEpisodes.py
index 2026a9cf9ccdabd678a3bbe4a4b105bf3cccc05a..2077fe564eeb9cd4ad1cf1d2eaa7f6be94b58bcb 100644
--- a/sickrage/show/ComingEpisodes.py
+++ b/sickrage/show/ComingEpisodes.py
@@ -1,3 +1,21 @@
+# This file is part of SickRage.
+#
+# URL: https://www.sickrage.tv
+# Git: https://github.com/SiCKRAGETV/SickRage.git
+#
+# SickRage is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# SickRage is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with SickRage.  If not, see <http://www.gnu.org/licenses/>.
+
 import sickbeard
 
 from datetime import date, timedelta
diff --git a/sickrage/show/History.py b/sickrage/show/History.py
index d1b69555550b60f0fe5fad6dbaab9f569653fc64..31870516ec4c04ed7aeeb92133f634efc7756a9a 100644
--- a/sickrage/show/History.py
+++ b/sickrage/show/History.py
@@ -1,3 +1,21 @@
+# This file is part of SickRage.
+#
+# URL: https://www.sickrage.tv
+# Git: https://github.com/SiCKRAGETV/SickRage.git
+#
+# SickRage is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# SickRage is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with SickRage.  If not, see <http://www.gnu.org/licenses/>.
+
 from datetime import datetime
 from datetime import timedelta
 from sickbeard.common import Quality
diff --git a/sickrage/show/Show.py b/sickrage/show/Show.py
new file mode 100644
index 0000000000000000000000000000000000000000..fadd77ee24d0eace6255fa74689d24365773331f
--- /dev/null
+++ b/sickrage/show/Show.py
@@ -0,0 +1,118 @@
+# This file is part of SickRage.
+#
+# URL: https://www.sickrage.tv
+# Git: https://github.com/SiCKRAGETV/SickRage.git
+#
+# SickRage is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# SickRage is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with SickRage.  If not, see <http://www.gnu.org/licenses/>.
+
+import sickbeard
+
+from sickbeard import showQueueScheduler
+from sickbeard.exceptions import CantRefreshException, CantRemoveException, ex, MultipleShowObjectsException
+from sickbeard.helpers import findCertainShow
+
+
+class Show:
+    def __init__(self):
+        pass
+
+    @staticmethod
+    def delete(indexer_id, remove_files=False):
+        """
+        Try to delete a show
+        :param indexer_id: The unique id of the show to delete
+        :param remove_files: ``True`` to remove the files associated with the show, ``False`` otherwise
+        :return: A tuple containing:
+         - an error message if the show could not be deleted, ``None`` otherwise
+         - the show object that was deleted, if it exists, ``None`` otherwise
+        """
+
+        error, show = Show._validate_indexer_id(indexer_id)
+
+        if error is not None:
+            return error, show
+
+        try:
+            showQueueScheduler.action.removeShow(show, bool(remove_files))
+        except CantRemoveException as exception:
+            return ex(exception), show
+
+        return None, show
+
+    @staticmethod
+    def pause(indexer_id, pause=None):
+        """
+        Change the pause state of a show
+        :param indexer_id: The unique id of the show to update
+        :param pause: ``True`` to pause the show, ``False`` to resume the show, ``None`` to toggle the pause state
+        :return: A tuple containing:
+         - an error message if the pause state could not be changed, ``None`` otherwise
+         - the show object that was updated, if it exists, ``None`` otherwise
+        """
+
+        error, show = Show._validate_indexer_id(indexer_id)
+
+        if error is not None:
+            return error, show
+
+        if pause is None:
+            show.paused = not show.paused
+        else:
+            show.paused = pause
+
+        show.saveToDB()
+
+        return None, show
+
+    @staticmethod
+    def refresh(indexer_id):
+        """
+        Try to refresh a show
+        :param indexer_id: The unique id of the show to refresh
+        :return: A tuple containing:
+         - an error message if the show could not be refreshed, ``None`` otherwise
+         - the show object that was refreshed, if it exists, ``None`` otherwise
+        """
+
+        error, show = Show._validate_indexer_id(indexer_id)
+
+        if error is not None:
+            return error, show
+
+        try:
+            showQueueScheduler.action.refreshShow(show)
+        except CantRefreshException as exception:
+            return ex(exception), show
+
+        return None, show
+
+    @staticmethod
+    def _validate_indexer_id(indexer_id):
+        """
+        Check that the provided indexer_id is valid and corresponds with a known show
+        :param indexer_id: The indexer id to check
+        :return: A tuple containing:
+         - an error message if the indexer id is not correct, ``None`` otherwise
+         - the show object corresponding to ``indexer_id`` if it exists, ``None`` otherwise
+        """
+
+        if indexer_id is None:
+            return 'Invalid show ID', None
+
+        try:
+            show = findCertainShow(sickbeard.showList, int(indexer_id))
+        except MultipleShowObjectsException:
+            return 'Unable to find the specified show', None
+
+        return None, show
diff --git a/sickrage/show/__init__.py b/sickrage/show/__init__.py
index 6a2173ff8b45d1709c6ca6d68d5be027c582602d..48b7f8852e4976f82e435201301eb9fc999d77d0 100644
--- a/sickrage/show/__init__.py
+++ b/sickrage/show/__init__.py
@@ -1 +1 @@
-__all__ = ['ComingEpisodes', 'History']
+__all__ = ['ComingEpisodes', 'History', 'Show']
diff --git a/sickrage/system/Restart.py b/sickrage/system/Restart.py
index e8674d592ed53f32e5deb3de2b52c74ac6997e6f..25372da9054a8dad5f37a1c039e179814ff970aa 100644
--- a/sickrage/system/Restart.py
+++ b/sickrage/system/Restart.py
@@ -1,3 +1,21 @@
+# This file is part of SickRage.
+#
+# URL: https://www.sickrage.tv
+# Git: https://github.com/SiCKRAGETV/SickRage.git
+#
+# SickRage is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# SickRage is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with SickRage.  If not, see <http://www.gnu.org/licenses/>.
+
 import sickbeard
 
 from sickbeard.event_queue import Events
diff --git a/sickrage/system/Shutdown.py b/sickrage/system/Shutdown.py
index 40d0231b51371b4f540876ce374e232289ba8ea7..a5ec702c502c75db91bb558556f96f03ea07b3f1 100644
--- a/sickrage/system/Shutdown.py
+++ b/sickrage/system/Shutdown.py
@@ -1,3 +1,21 @@
+# This file is part of SickRage.
+#
+# URL: https://www.sickrage.tv
+# Git: https://github.com/SiCKRAGETV/SickRage.git
+#
+# SickRage is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# SickRage is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with SickRage.  If not, see <http://www.gnu.org/licenses/>.
+
 import sickbeard
 
 from sickbeard.event_queue import Events
diff --git a/tests/encoding_tests.py b/tests/encoding_tests.py
index 0084458178aca381571b3267fbea3fcba044a7dc..fddb33e4f58c4dbb0694db7e15042d36726b2cb7 100644
--- a/tests/encoding_tests.py
+++ b/tests/encoding_tests.py
@@ -1,4 +1,5 @@
 # coding=utf-8
+
 import locale
 import unittest
 import sys, os.path
@@ -7,9 +8,10 @@ sys.path.insert(1, os.path.abspath(os.path.join(os.path.dirname(__file__), '../l
 sys.path.insert(1, os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))
 
 import sickbeard
-from sickbeard import encodingKludge as ek
 from sickbeard.exceptions import ex
 from sickbeard.helpers import sanitizeFileName
+from sickrage.helper.encoding import ek
+
 
 class EncodingTests(unittest.TestCase):
     def test_encoding(self):
@@ -30,7 +32,7 @@ class EncodingTests(unittest.TestCase):
 
         for s in strings:
             try:
-                show_dir = ek.ek(os.path.join, rootDir, sanitizeFileName(s))
+                show_dir = ek(os.path.join, rootDir, sanitizeFileName(s))
                 self.assertTrue(isinstance(show_dir, unicode))
             except Exception, e:
                 ex(e)