diff --git a/gui/slick/js/core.js b/gui/slick/js/core.js
index aeb979d2f0087a5b7d03837a46523d962aca7b6a..91cd9741fc4d5a7c7d8e97198594a588536584e0 100644
--- a/gui/slick/js/core.js
+++ b/gui/slick/js/core.js
@@ -2859,8 +2859,6 @@ var SICKRAGE = {
             });
         },
         editShow: function() {
-            let allExceptions = [];
-
             $('#location').fileBrowser({title: _('Select Show Location')});
 
             SICKRAGE.common.QualityChooser.init();
@@ -2871,13 +2869,20 @@ var SICKRAGE = {
             }); */
 
             $('#submit').on('click', function() {
-                allExceptions = [];
+                const allExceptions = $('#exceptions_list').find('optgroup').get().map(function(group) {
+                    const season = $(group).data('season');
+                    const exceptions = $(group).find('option:enabled').get().map(function(option) {
+                        const exception = $(option).val();
+
+                        return encodeURIComponent(exception);
+                    }).join('|');
 
-                $('#exceptions_list option').each(function() {
-                    allExceptions.push($(this).val());
+                    return [season, exceptions].join(':');
+                }).filter(function(item) {
+                    return item;
                 });
 
-                $('#exceptions_list').val(allExceptions);
+                $('#exceptions').val(allExceptions);
 
                 if (metaToBool('show.is_anime')) {
                     generateBlackWhiteList(); // eslint-disable-line no-undef
@@ -2885,48 +2890,43 @@ var SICKRAGE = {
             });
 
             $('#addSceneName').on('click', function() {
+                const season = $('#SceneSeason').find(':selected').data('season');
                 const sceneEx = $('#SceneName').val();
-                const option = $('<option>');
-                allExceptions = [];
 
-                $('#exceptions_list option').each(function() {
-                    allExceptions.push($(this).val());
-                });
+                const group = $('#exceptions_list').find('[data-season="' + season + '"]').get()[0];
+                const placeholder = $(group).find('option.empty');
 
-                $('#SceneName').val('');
+                const exceptions = $(group).find('option:not(.empty)').get().map(function(el) {
+                    return $(el).val();
+                });
 
-                if ($.inArray(sceneEx, allExceptions) > -1 || (sceneEx === '')) {
+                // If we already have the exception or the field is empty return
+                if (exceptions.indexOf(sceneEx) > -1 || sceneEx.trim() === '') {
+                    $('#SceneName').val('');
                     return;
                 }
 
-                $('#SceneException').show();
-
-                option.attr('value', sceneEx);
-                option.html(sceneEx);
-                return option.appendTo('#exceptions_list');
-            });
+                const newException = $('<option data-season=' + season + '>').text(sceneEx).val(sceneEx);
 
-            $('#removeSceneName').on('click', function(event) {
-                $('#exceptions_list option:selected').remove();
+                $(group).append(newException);
+                placeholder.remove();
 
-                $(event.currentTarget).toggleSceneException();
+                $('#SceneName').val('');
             });
 
-            $.fn.toggleSceneException = function() {
-                allExceptions = [];
+            $('#removeSceneName').on('click', function() {
+                const option = $('#exceptions_list').find('option:selected');
+                const group = option.closest('optgroup');
 
-                $('#exceptions_list option').each(function() {
-                    allExceptions.push($(this).val());
-                });
+                if (group.find('option').length < 2) {
+                    const newOption = $('<option disabled class="empty">');
+                    newOption.text(_('None'));
 
-                if (allExceptions === '') {
-                    $('#SceneException').hide();
-                } else {
-                    $('#SceneException').show();
+                    group.append(newOption);
                 }
-            };
 
-            $(this).toggleSceneException();
+                option.remove();
+            });
         },
         postProcess: function() {
             $('#episodeDir').fileBrowser({
diff --git a/gui/slick/views/editShow.mako b/gui/slick/views/editShow.mako
index c692be0322e09f7a6b6f7f35768fdd54ce85417c..62fee40737a4c0b3f338e8c134a9dfb213ca8b5e 100644
--- a/gui/slick/views/editShow.mako
+++ b/gui/slick/views/editShow.mako
@@ -330,17 +330,38 @@
                                     <div class="col-lg-9 col-md-8 col-sm-7 col-xs-12 component-desc">
                                         <div class="row">
                                             <div class="col-md-12">
-                                                <input type="text" id="SceneName"
-                                                       class="form-control input-sm input200" autocapitalize="off"/>
+                                                <input type="text" id="SceneName" class="form-control input-sm input250" autocapitalize="off"/>
+                                                <select id="SceneSeason" class="form-control input-sm" style="width: 95px">
+                                                    % for season in range(0, len(seasonResults)):
+                                                        %if season == 0:
+                                                            <% season = -1 %>
+                                                        %endif
+                                                        <option data-season="${season}">${_('Show') if season == -1 else _('Season ') + str(season)}</option>
+                                                    %endfor
+                                                </select>
                                                 <input class="btn btn-inline" type="button" value="${_('Add')}" id="addSceneName"/>
                                             </div>
                                         </div>
                                         <div class="row">
                                             <div class="col-md-12">
-                                                <select id="exceptions_list" name="exceptions_list" multiple="multiple"
-                                                        style="height:99px;width:200px;" title="exceptions_list">
-                                                    % for cur_exception in show.exceptions:
-                                                        <option value="${cur_exception}">${cur_exception}</option>
+                                                <input type="hidden" id="exceptions" name="exceptions_list"/>
+                                                <select id="exceptions_list" multiple
+                                                        style="height:200px;" class="form-control input350" title="exceptions_list">
+                                                    % for season in range(0, len(seasonResults)):
+                                                        %if season == 0:
+                                                            <% season = -1 %>
+                                                        %endif
+                                                        <optgroup data-season="${season}" label="${_('Show') if season == -1 else _('Season ') + str(season)}">
+                                                            %if season in scene_exceptions:
+                                                                %for exception in scene_exceptions[season]:
+                                                                    <option ${'disabled' if exception["custom"] == False else ''} value="${exception["show_name"]}">
+                                                                        ${exception["show_name"]}
+                                                                    </option>
+                                                                %endfor
+                                                            % else:
+                                                            <option class="empty" disabled>${_('None')}</option>
+                                                        %endif
+                                                        </optgroup>
                                                     % endfor
                                                 </select>
                                                 <div>
@@ -358,6 +379,11 @@
                                                 <label>${_('this list appends to the original show name.')}</label>
                                             </div>
                                         </div>
+                                        <div class="row">
+                                            <div class="col-md-12">
+                                                <label>${_('disabled entries come from a central file on github,<br/> if you think something is wrong please make an issue <a href="//github.com/sickrage/sickrage.github.io/issues">here</a>.')}</label>
+                                            </div>
+                                        </div>
                                     </div>
                                 </div>
 
diff --git a/sickbeard/scene_exceptions.py b/sickbeard/scene_exceptions.py
index c7ca1f5e73b3dac08d6fef6fe107ed934a0cf8d7..8ea0469add82ea96ec720fd38d182ae2b669e79a 100644
--- a/sickbeard/scene_exceptions.py
+++ b/sickbeard/scene_exceptions.py
@@ -110,13 +110,16 @@ def get_all_scene_exceptions(indexer_id):
     exceptionsDict = {}
 
     cache_db_con = db.DBConnection('cache.db')
-    exceptions = cache_db_con.select("SELECT show_name,season FROM scene_exceptions WHERE indexer_id = ?", [indexer_id])
+    exceptions = cache_db_con.select("SELECT show_name,season,custom FROM scene_exceptions WHERE indexer_id = ?", [indexer_id])
 
     if exceptions:
         for cur_exception in exceptions:
             if not cur_exception[b"season"] in exceptionsDict:
                 exceptionsDict[cur_exception[b"season"]] = []
-            exceptionsDict[cur_exception[b"season"]].append(cur_exception[b"show_name"])
+            exceptionsDict[cur_exception[b"season"]].append({
+                "show_name": cur_exception[b"show_name"],
+                "custom": bool(cur_exception[b"custom"])
+            })
 
     return exceptionsDict
 
@@ -271,23 +274,21 @@ def retrieve_exceptions():  # pylint:disable=too-many-locals, too-many-branches
     xem_exception_dict.clear()
 
 
-def update_scene_exceptions(indexer_id, scene_exceptions, season=-1):
+def update_scene_exceptions(indexer_id, scene_exceptions):
     """
     Given a indexer_id, and a list of all show scene exceptions, update the db.
     """
     cache_db_con = db.DBConnection('cache.db')
-    cache_db_con.action('DELETE FROM scene_exceptions WHERE indexer_id=? and season=?', [indexer_id, season])
+    cache_db_con.action('DELETE FROM scene_exceptions WHERE indexer_id=? and custom=1', [indexer_id])
 
     logger.log("Updating scene exceptions", logger.INFO)
 
-    # A change has been made to the scene exception list. Let's clear the cache, to make this visible
-    if indexer_id in exceptionsCache:
-        exceptionsCache[indexer_id] = {}
-        exceptionsCache[indexer_id][season] = scene_exceptions
+    for season in scene_exceptions:
+        for cur_exception in scene_exceptions[season]:
+            cache_db_con.action("INSERT INTO scene_exceptions (indexer_id, show_name, season, custom) VALUES (?,?,?,?)",
+                                [indexer_id, cur_exception["show_name"], season, cur_exception["custom"]])
 
-    for cur_exception in scene_exceptions:
-        cache_db_con.action("INSERT INTO scene_exceptions (indexer_id, show_name, season) VALUES (?,?,?)",
-                            [indexer_id, cur_exception, season])
+    rebuild_exception_cache(indexer_id)
 
 
 def _anidb_exceptions_fetcher():
@@ -342,3 +343,17 @@ def getSceneSeasons(indexer_id):
     cache_db_con = db.DBConnection('cache.db')
     seasons = cache_db_con.select("SELECT DISTINCT season FROM scene_exceptions WHERE indexer_id = ?", [indexer_id])
     return [cur_exception[b"season"] for cur_exception in seasons]
+
+
+def rebuild_exception_cache(indexer_id):
+    if indexer_id in exceptionsCache:
+        exceptionsCache[indexer_id] = {}
+
+    cache_db_con = db.DBConnection('cache.db')
+    results = cache_db_con.action('SELECT show_name, season FROM scene_exceptions WHERE indexer_id=?', [indexer_id])
+
+    for result in results:
+        if result[b"season"] not in exceptionsCache[indexer_id]:
+            exceptionsCache[indexer_id][result[b"season"]] = []
+
+        exceptionsCache[indexer_id][result[b"season"]].append(result[b"show_name"])
diff --git a/sickbeard/webserve.py b/sickbeard/webserve.py
index ce7d98735980fd7bea85115c744d6d0f97f6ad81..5537bf2d3f12a626d9f5a3cba05fd0185a38b896 100644
--- a/sickbeard/webserve.py
+++ b/sickbeard/webserve.py
@@ -1521,10 +1521,10 @@ class Home(WebRoot):
             return _("No scene exceptions")
 
         out = []
-        for season, names in iter(sorted(six.iteritems(exceptionsList))):
+        for season, object in iter(sorted(six.iteritems(exceptionsList))):
             if season == -1:
                 season = "*"
-            out.append("S" + str(season) + ": " + ", ".join(names))
+            out.append("S" + str(season) + ": " + ", ".join(object.names))
         return "<br>".join(out)
 
     def editShow(self, show=None, location=None, anyQualities=None, bestQualities=None,
@@ -1551,7 +1551,13 @@ class Home(WebRoot):
             else:
                 return self._genericMessage(_("Error"), errString)
 
-        show_obj.exceptions = sickbeard.scene_exceptions.get_scene_exceptions(show_obj.indexerid)
+        show_obj.exceptions = sickbeard.scene_exceptions.get_all_scene_exceptions(show_obj.indexerid)
+
+        main_db_con = db.DBConnection()
+        seasonResults = main_db_con.select(
+            "SELECT DISTINCT season FROM tv_episodes WHERE showid = ? AND season IS NOT NULL ORDER BY season DESC",
+            [show_obj.indexerid]
+        )
 
         if try_int(quality_preset, None):
             bestQualities = []
@@ -1575,14 +1581,14 @@ class Home(WebRoot):
 
             with show_obj.lock:
                 show = show_obj
-                scene_exceptions = sickbeard.scene_exceptions.get_scene_exceptions(show_obj.indexerid)
 
             if show_obj.is_anime:
-                return t.render(show=show, scene_exceptions=scene_exceptions, groups=groups, whitelist=whitelist,
-                                blacklist=blacklist, title=_('Edit Show'), header=_('Edit Show'), controller="home", action="editShow")
+                return t.render(show=show, scene_exceptions=show_obj.exceptions, seasonResults=seasonResults,
+                                groups=groups, whitelist=whitelist, blacklist=blacklist,
+                                title=_('Edit Show'), header=_('Edit Show'), controller="home", action="editShow")
             else:
-                return t.render(show=show, scene_exceptions=scene_exceptions, title=_('Edit Show'), header=_('Edit Show'),
-                                controller="home", action="editShow")
+                return t.render(show=show, scene_exceptions=show_obj.exceptions, seasonResults=seasonResults,
+                                title=_('Edit Show'), header=_('Edit Show'), controller="home", action="editShow")
 
         season_folders = config.checkbox_to_value(season_folders)
         dvdorder = config.checkbox_to_value(dvdorder)
@@ -1618,18 +1624,28 @@ class Home(WebRoot):
         if not isinstance(bestQualities, list):
             bestQualities = [bestQualities]
 
-        if not isinstance(exceptions_list, list):
-            exceptions_list = [exceptions_list]
-
-        # If directCall from mass_edit_update no scene exceptions handling or blackandwhite list handling
-        if directCall:
-            do_update_exceptions = False
-        else:
-            if set(exceptions_list) == set(show_obj.exceptions):
-                do_update_exceptions = False
+        if isinstance(exceptions_list, list):
+            if len(exceptions_list) > 0:
+                exceptions_list = exceptions_list[0]
             else:
-                do_update_exceptions = True
+                exceptions_list = None
+
+        # Map custom exceptions
+        exceptions = {}
 
+        if exceptions_list is not None:
+            for season in exceptions_list.split(','):
+                (season, shows) = season.split(':')
+
+                show_list = []
+
+                for cur_show in shows.split('|'):
+                    show_list.append({'show_name': unquote_plus(cur_show), 'custom': True})
+
+                exceptions[int(season)] = show_list
+
+        # If directCall from mass_edit_update no scene exceptions handling or blackandwhite list handling
+        if not directCall:
             with show_obj.lock:
                 if anime:
                     if not show_obj.release_groups:
@@ -1710,12 +1726,11 @@ class Home(WebRoot):
             except CantUpdateShowException as e:
                 errors.append(_("Unable to update show: {error}").format(error=e))
 
-        if do_update_exceptions:
-            try:
-                sickbeard.scene_exceptions.update_scene_exceptions(show_obj.indexerid, exceptions_list)  # @UndefinedVdexerid)
-                time.sleep(cpu_presets[sickbeard.CPU_PRESET])
-            except CantUpdateShowException as e:
-                errors.append(_("Unable to force an update on scene exceptions of the show."))
+        try:
+            sickbeard.scene_exceptions.update_scene_exceptions(show_obj.indexerid, exceptions)  # @UndefinedVdexerid)
+            time.sleep(cpu_presets[sickbeard.CPU_PRESET])
+        except CantUpdateShowException as e:
+            errors.append(_("Unable to force an update on scene exceptions of the show."))
 
         if do_update_scene_numbering:
             try: