diff --git a/CHANGES.md b/CHANGES.md index c2304cc4..e1cbb018 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -25,6 +25,13 @@ * Change emails to Unicode aware +### 0.11.4 (2016-01-31 11:30:00 UTC) + +* Fix issue setting some custom name patterns on the "Config/Post Processing/Episode Naming" tab +* Remove Strike torrent provider +* Add network icons + + ### 0.11.3 (2016-01-16 20:00:00 UTC) * Fix Search Settings display fail diff --git a/gui/slick/images/network/bbc hd.png b/gui/slick/images/network/bbc hd.png new file mode 100644 index 00000000..3a6b3c3f Binary files /dev/null and b/gui/slick/images/network/bbc hd.png differ diff --git a/gui/slick/images/network/bravo!.png b/gui/slick/images/network/bravo!.png new file mode 100644 index 00000000..63e75a9c Binary files /dev/null and b/gui/slick/images/network/bravo!.png differ diff --git a/gui/slick/images/network/bravo.png b/gui/slick/images/network/bravo.png index 248dd5e5..63e75a9c 100644 Binary files a/gui/slick/images/network/bravo.png and b/gui/slick/images/network/bravo.png differ diff --git a/gui/slick/images/network/cctv.png b/gui/slick/images/network/cctv.png new file mode 100644 index 00000000..7d62fc50 Binary files /dev/null and b/gui/slick/images/network/cctv.png differ diff --git a/gui/slick/images/network/cnbc.png b/gui/slick/images/network/cnbc.png new file mode 100644 index 00000000..7a77b267 Binary files /dev/null and b/gui/slick/images/network/cnbc.png differ diff --git a/gui/slick/images/network/living.png b/gui/slick/images/network/living.png new file mode 100644 index 00000000..6a696601 Binary files /dev/null and b/gui/slick/images/network/living.png differ diff --git a/gui/slick/images/network/prime.png b/gui/slick/images/network/prime.png new file mode 100644 index 00000000..474f6f6f Binary files /dev/null and b/gui/slick/images/network/prime.png differ diff --git a/gui/slick/images/network/sky living.png b/gui/slick/images/network/sky living.png new file mode 100644 index 00000000..6a696601 Binary files /dev/null and b/gui/slick/images/network/sky living.png differ diff --git a/gui/slick/images/network/sky sports.png b/gui/slick/images/network/sky sports.png new file mode 100644 index 00000000..588e32aa Binary files /dev/null and b/gui/slick/images/network/sky sports.png differ diff --git a/gui/slick/images/network/stv.png b/gui/slick/images/network/stv.png new file mode 100644 index 00000000..6b59979d Binary files /dev/null and b/gui/slick/images/network/stv.png differ diff --git a/gui/slick/images/network/svt.png b/gui/slick/images/network/svt.png new file mode 100644 index 00000000..fb2679b6 Binary files /dev/null and b/gui/slick/images/network/svt.png differ diff --git a/gui/slick/images/network/tvnz.png b/gui/slick/images/network/tvnz.png new file mode 100644 index 00000000..6917d0a3 Binary files /dev/null and b/gui/slick/images/network/tvnz.png differ diff --git a/gui/slick/images/providers/strike.png b/gui/slick/images/providers/strike.png deleted file mode 100644 index a857f5ff..00000000 Binary files a/gui/slick/images/providers/strike.png and /dev/null differ diff --git a/gui/slick/js/configPostProcessing.js b/gui/slick/js/configPostProcessing.js index daf99485..74097149 100644 --- a/gui/slick/js/configPostProcessing.js +++ b/gui/slick/js/configPostProcessing.js @@ -10,7 +10,6 @@ $(document).ready(function () { })(); function israr_supported() { - var pattern = $('#naming_pattern').val(); $.get(sbRoot + '/config/postProcessing/isRarSupported', function (data) { if (data == "supported") { @@ -29,9 +28,8 @@ $(document).ready(function () { function fill_examples() { var pattern = $('#naming_pattern').val(); var multi = $('#naming_multi_ep :selected').val(); - var anime_type = $('input[name="naming_anime"]:checked').val(); - $.get(sbRoot + '/config/postProcessing/testNaming', {pattern: pattern, anime_type: 3}, + $.get(sbRoot + '/config/postProcessing/testNaming', {pattern: pattern}, function (data) { if (data) { $('#naming_example').text(data + '.ext'); @@ -41,7 +39,7 @@ $(document).ready(function () { } }); - $.get(sbRoot + '/config/postProcessing/testNaming', {pattern: pattern, multi: multi, anime_type: 3}, + $.get(sbRoot + '/config/postProcessing/testNaming', {pattern: pattern, multi: multi}, function (data) { if (data) { $('#naming_example_multi').text(data + '.ext'); @@ -51,7 +49,7 @@ $(document).ready(function () { } }); - $.get(sbRoot + '/config/postProcessing/isNamingValid', {pattern: pattern, multi: multi, anime_type: anime_type}, + $.get(sbRoot + '/config/postProcessing/isNamingValid', {pattern: pattern, multi: multi}, function (data) { if (data == "invalid") { $('#naming_pattern').qtip('option', { @@ -80,6 +78,8 @@ $(document).ready(function () { } function fill_abd_examples() { + if (!$('#naming_custom_abd').is(':checked')) + return; var pattern = $('#naming_abd_pattern').val(); $.get(sbRoot + '/config/postProcessing/testNaming', {pattern: pattern, abd: 'True'}, @@ -121,47 +121,8 @@ $(document).ready(function () { } function fill_sports_examples() { - var pattern = $('#naming_sports_pattern').val(); - - $.get(sbRoot + '/config/postProcessing/testNaming', {pattern: pattern, sports: 'True'}, - function (data) { - if (data) { - $('#naming_sports_example').text(data + '.ext'); - $('#naming_sports_example_div').show(); - } else { - $('#naming_sports_example_div').hide(); - } - }); - - $.get(sbRoot + '/config/postProcessing/isNamingValid', {pattern: pattern, sports: 'True'}, - function (data) { - if (data == "invalid") { - $('#naming_sports_pattern').qtip('option', { - 'content.text': 'This pattern is invalid.', - 'style.classes': 'qtip-red qtip-rounded qtip-shadow' - }); - $('#naming_sports_pattern').qtip('toggle', true); - $('#naming_sports_pattern').css('background-color', '#FFDDDD'); - } else if (data == "seasonfolders") { - $('#naming_sports_pattern').qtip('option', { - 'content.text': 'This pattern would be invalid without the folders, using it will force "Flatten" off for all shows.', - 'style.classes': 'qtip-red qtip-rounded qtip-shadow' - }); - $('#naming_sports_pattern').qtip('toggle', true); - $('#naming_sports_pattern').css('background-color', '#FFFFDD'); - } else { - $('#naming_sports_pattern').qtip('option', { - 'content.text': 'This pattern is valid.', - 'style.classes': 'qtip-green qtip-rounded qtip-shadow' - }); - $('#naming_sports_pattern').qtip('toggle', false); - $('#naming_sports_pattern').css('background-color', '#FFFFFF'); - } - }); - - } - - function fill_sports_examples() { + if (!$('#naming_custom_sports').is(':checked')) + return; var pattern = $('#naming_sports_pattern').val(); $.get(sbRoot + '/config/postProcessing/testNaming', {pattern: pattern, sports: 'True'}, @@ -203,6 +164,8 @@ $(document).ready(function () { } function fill_anime_examples() { + if (!$('#naming_custom_anime').is(':checked')) + return; var pattern = $('#naming_anime_pattern').val(); var multi = $('#naming_anime_multi_ep :selected').val(); var anime_type = $('input[name="naming_anime"]:checked').val(); @@ -549,4 +512,4 @@ $(document).ready(function () { } return save_config; })) -}); \ No newline at end of file +}); diff --git a/sickbeard/naming.py b/sickbeard/naming.py index 49d2ed8e..568df682 100644 --- a/sickbeard/naming.py +++ b/sickbeard/naming.py @@ -24,33 +24,37 @@ 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, InvalidNameException +from sickbeard.name_parser.parser import NameParser 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" + self.name = 'Show Name' + self.genre = 'Comedy' self.indexerid = 1 self.air_by_date = 0 self.sports = 0 @@ -58,26 +62,17 @@ class TVShow(): self.scene = 0 def _is_anime(self): - if (self.anime > 0): - return True - else: - return False + return 0 < self.anime is_anime = property(_is_anime) def _is_sports(self): - if (self.sports > 0): - return True - else: - return False + return 0 < self.sports is_sports = property(_is_sports) def _is_scene(self): - if (self.scene > 0): - return True - else: - return False + return 0 < self.scene is_scene = property(_is_scene) @@ -106,16 +101,19 @@ def check_force_season_folders(pattern=None, multi=None, anime_type=None): to be enabled or not. Returns true if season folders need to be forced on or false otherwise. + :param pattern: String Naming Pattern + :param multi: Bool Multi-episode pattern + :param anime_type: Integer Numbering type to use for anime pattern """ - if pattern == None: + if None is pattern: pattern = sickbeard.NAMING_PATTERN - if anime_type == None: + if None is anime_type: anime_type = sickbeard.NAMING_ANIME valid = not validate_name(pattern, None, anime_type, file_only=True) - if multi != None: + if None is not multi: valid = valid or not validate_name(pattern, multi, anime_type, file_only=True) return valid @@ -126,18 +124,21 @@ 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. + :param pattern: String Naming Pattern + :param multi: Bool Multi-episode pattern + :param anime_type: Integer Numbering type to use for anime pattern """ - if pattern == None: + if None is pattern: pattern = sickbeard.NAMING_PATTERN - if anime_type == None: + if None is anime_type: anime_type = sickbeard.NAMING_ANIME - logger.log(u"Checking whether the pattern " + pattern + " is valid for a single episode", logger.DEBUG) + logger.log(u'Checking whether the pattern %s is valid for a single episode' % pattern, logger.DEBUG) valid = validate_name(pattern, None, anime_type) - if multi != None: - logger.log(u"Checking whether the pattern " + pattern + " is valid for a multi episode", logger.DEBUG) + if None is not multi: + logger.log(u'Checking whether the pattern %s is valid for a multi episode' % pattern, logger.DEBUG) valid = valid and validate_name(pattern, multi, anime_type) return valid @@ -148,67 +149,72 @@ 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. + :param pattern: String Naming Pattern """ - if pattern == None: + if None is pattern: pattern = sickbeard.NAMING_PATTERN - logger.log(u"Checking whether the pattern " + pattern + " is valid for an air-by-date episode", logger.DEBUG) + logger.log(u'Checking whether the pattern %s is valid for an air-by-date episode' % pattern, logger.DEBUG) valid = validate_name(pattern, abd=True) 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. + :param pattern: String Naming Pattern """ - if pattern == None: + if None is pattern: pattern = sickbeard.NAMING_PATTERN - logger.log(u"Checking whether the pattern " + pattern + " is valid for an sports episode", logger.DEBUG) + logger.log(u'Checking whether the pattern %s is valid for an sports episode' % pattern, logger.DEBUG) valid = validate_name(pattern, sports=True) return valid -def validate_name(pattern, multi=None, anime_type=None, file_only=False, abd=False, sports=False): - ep = generate_sample_ep(multi, abd, sports, anime_type) - new_name = ep.formatted_filename(pattern, multi, anime_type) + '.ext' +def validate_name(pattern, multi=None, anime_type=None, file_only=False, abd=False, sports=False): + ep = generate_sample_ep(multi, abd, sports, anime_type=anime_type) + + new_name = u'%s.ext' % ep.formatted_filename(pattern, multi, anime_type) new_path = ep.formatted_dir(pattern, multi) if not file_only: new_name = ek.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) + logger.log(u'Unable to create a name out of %s' % pattern, logger.DEBUG) return False - logger.log(u"Trying to parse " + new_name, logger.DEBUG) + logger.log(u'Trying to parse %s' % new_name, logger.DEBUG) parser = NameParser(True, showObj=ep.show, naming_pattern=True) try: result = parser.parse(new_name) except Exception as e: - logger.log(u"Unable to parse " + new_name + ", not valid", logger.DEBUG) + logger.log(u'Unable to parse %s, not valid' % new_name, logger.DEBUG) return False - logger.log("The name " + new_name + " parsed into " + str(result), logger.DEBUG) + logger.log(u'The name %s parsed into %s' % (new_name, result), logger.DEBUG) if abd or sports: if result.air_date != ep.airdate: - logger.log(u"Air date incorrect in parsed episode, pattern isn't valid", logger.DEBUG) + logger.log(u'Air date incorrect in parsed episode, pattern isn\'t valid', logger.DEBUG) return False - elif anime_type != 3: - if len(result.ab_episode_numbers) and result.ab_episode_numbers != [x.absolute_number for x in [ep] + ep.relatedEps]: - logger.log(u"Absolute numbering incorrect in parsed episode, pattern isn't valid", logger.DEBUG) - return False - else: + elif 3 == anime_type: if result.season_number != ep.season: - logger.log(u"Season number incorrect in parsed episode, pattern isn't valid", logger.DEBUG) + logger.log(u'Season number incorrect in parsed episode, pattern isn\'t valid', logger.DEBUG) return False if result.episode_numbers != [x.episode for x in [ep] + ep.relatedEps]: - logger.log(u"Episode numbering incorrect in parsed episode, pattern isn't valid", logger.DEBUG) + logger.log(u'Episode numbering incorrect in parsed episode, pattern isn\'t valid', logger.DEBUG) + return False + else: + if len(result.ab_episode_numbers) and result.ab_episode_numbers != [x.absolute_number for x in + [ep] + ep.relatedEps]: + logger.log(u'Absolute numbering incorrect in parsed episode, pattern isn\'t valid', logger.DEBUG) return False return True @@ -216,14 +222,11 @@ def validate_name(pattern, multi=None, anime_type=None, file_only=False, abd=Fal def generate_sample_ep(multi=None, abd=False, sports=False, anime=False, anime_type=None): # make a fake episode object - ep = TVEpisode(2, 3, 3, "Ep Name") + ep = TVEpisode(2, 3, 3, 'Ep Name') ep._status = Quality.compositeStatus(DOWNLOADED, Quality.HDTV) ep._airdate = datetime.date(2011, 3, 9) - if anime: - ep.show.anime = 1 - if abd: ep._release_name = 'Show.Name.2011.03.09.HDTV.XviD-RLSGROUP' ep.show.air_by_date = 1 @@ -231,38 +234,28 @@ def generate_sample_ep(multi=None, abd=False, sports=False, anime=False, anime_t ep._release_name = 'Show.Name.2011.03.09.HDTV.XviD-RLSGROUP' ep.show.sports = 1 else: - if anime_type != 3: - ep.show.anime = 1 - ep._release_name = 'Show.Name.003.HDTV.XviD-RLSGROUP' - else: + if not anime or 3 == anime_type: ep._release_name = 'Show.Name.S02E03.HDTV.XviD-RLSGROUP' - - if multi != None: - ep._name = "Ep Name (1)" - - if anime_type != 3: + else: + ep._release_name = 'Show.Name.003.HDTV.XviD-RLSGROUP' ep.show.anime = 1 - ep._release_name = 'Show.Name.003-004.HDTV.XviD-RLSGROUP' - - secondEp = TVEpisode(2, 4, 4, "Ep Name (2)") - secondEp._status = Quality.compositeStatus(DOWNLOADED, Quality.HDTV) - secondEp._release_name = ep._release_name - - ep.relatedEps.append(secondEp) - else: + if None is not multi: + ep._name = 'Ep Name (1)' + second_ep = TVEpisode(2, 4, 4, 'Ep Name (2)') + second_ep._status = Quality.compositeStatus(DOWNLOADED, Quality.HDTV) + second_ep._release_name = ep._release_name + ep.relatedEps.append(second_ep) + if not anime or 3 == anime_type: ep._release_name = 'Show.Name.S02E03E04E05.HDTV.XviD-RLSGROUP' - secondEp = TVEpisode(2, 4, 4, "Ep Name (2)") - secondEp._status = Quality.compositeStatus(DOWNLOADED, Quality.HDTV) - secondEp._release_name = ep._release_name - - thirdEp = TVEpisode(2, 5, 5, "Ep Name (3)") - thirdEp._status = Quality.compositeStatus(DOWNLOADED, Quality.HDTV) - thirdEp._release_name = ep._release_name - - ep.relatedEps.append(secondEp) - ep.relatedEps.append(thirdEp) + third_ep = TVEpisode(2, 5, 5, 'Ep Name (3)') + third_ep._status = Quality.compositeStatus(DOWNLOADED, Quality.HDTV) + third_ep._release_name = ep._release_name + ep.relatedEps.append(third_ep) + else: + ep._release_name = 'Show.Name.003-004.HDTV.XviD-RLSGROUP' + ep.show.anime = 1 return ep @@ -270,4 +263,4 @@ def generate_sample_ep(multi=None, abd=False, sports=False, anime=False, anime_t def test_name(pattern, multi=None, abd=False, sports=False, anime=False, anime_type=None): ep = generate_sample_ep(multi, abd, sports, anime, anime_type) - return {'name': ep.formatted_filename(pattern, multi, anime_type), 'dir': ep.formatted_dir(pattern, multi)} \ No newline at end of file + return {'name': ep.formatted_filename(pattern, multi, anime_type), 'dir': ep.formatted_dir(pattern, multi)} diff --git a/sickbeard/providers/__init__.py b/sickbeard/providers/__init__.py index 51f31431..6e1eaad2 100755 --- a/sickbeard/providers/__init__.py +++ b/sickbeard/providers/__init__.py @@ -26,7 +26,7 @@ from sickbeard import logger from . import newznab, omgwtfnzbs, womble # torrent from . import alpharatio, beyondhd, bitmetv, bitsoup, btn, freshontv, funfile, gftracker, grabtheinfo, \ - hdbits, hdspace, iptorrents, kat, morethan, pisexy, pretome, rarbg, scc, scenetime, shazbat, speedcd, strike, \ + hdbits, hdspace, iptorrents, kat, morethan, pisexy, pretome, rarbg, scc, scenetime, shazbat, speedcd, \ thepiratebay, torrentbytes, torrentday, torrenting, torrentleech, torrentshack, transmithe_net, tvchaosuk # anime from . import nyaatorrents, tokyotoshokan @@ -54,7 +54,6 @@ __all__ = ['omgwtfnzbs', 'scenetime', 'shazbat', 'speedcd', - 'strike', 'thepiratebay', 'torrentbytes', 'torrentday', diff --git a/sickbeard/providers/strike.py b/sickbeard/providers/strike.py deleted file mode 100644 index 8b0ffa76..00000000 --- a/sickbeard/providers/strike.py +++ /dev/null @@ -1,84 +0,0 @@ -# coding=utf-8 -# -# This file is part of SickGear. -# -# SickGear 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. -# -# SickGear 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 SickGear. If not, see . - -import re -from . import generic -from sickbeard import helpers -from sickbeard.helpers import tryInt - - -class StrikeProvider(generic.TorrentProvider): - - def __init__(self): - generic.TorrentProvider.__init__(self, 'Strike') - - self.url_base = 'https://getstrike.net/' - self.urls = {'config_provider_home_uri': self.url_base, - 'search': self.url_base + 'api/v2/torrents/search/?category=%s&phrase=%s'} - - self.url = self.urls['config_provider_home_uri'] - - self.minseed, self.minleech = 2 * [None] - - def _search_provider(self, search_params, **kwargs): - - results = [] - items = {'Cache': [], 'Season': [], 'Episode': [], 'Propers': []} - - for mode in search_params.keys(): - search_show = mode in ['Season', 'Episode'] - if not search_show and helpers.has_anime(): - search_params[mode] *= (1, 2)['Cache' == mode] - - for enum, search_string in enumerate(search_params[mode]): - search_url = self.urls['search'] % \ - (('tv', 'anime')[(search_show and bool(self.show and self.show.is_anime)) or bool(enum)], - (re.sub('[\.\s]+', ' ', search_string), 'x264')['Cache' == mode]) - - data_json = self.get_url(search_url, json=True) - - cnt = len(items[mode]) - try: - for item in data_json['torrents']: - seeders, leechers, title, download_magnet, size = [tryInt(n, n) for n in [item.get(x) for x in [ - 'seeds', 'leeches', 'torrent_title', 'magnet_uri', 'size']]] - if self._peers_fail(mode, seeders, leechers): - continue - - if title and download_magnet: - items[mode].append((title, download_magnet, seeders, self._bytesizer(size))) - - except Exception: - pass - self._log_search(mode, len(items[mode]) - cnt, search_url) - - self._sort_seeders(mode, items) - - results = list(set(results + items[mode])) - - return results - - def _season_strings(self, ep_obj, **kwargs): - - return generic.TorrentProvider._season_strings(self, ep_obj, scene=False) - - def _episode_strings(self, ep_obj, **kwargs): - - return generic.TorrentProvider._episode_strings(self, ep_obj, scene=False, **kwargs) - - -provider = StrikeProvider()