diff --git a/gui/slick/images/providers/torrentz.png b/gui/slick/images/providers/torrentz.png new file mode 100644 index 0000000000000000000000000000000000000000..8d3493e7b6ec4e610489d2853fcd0e795a5c2e4a Binary files /dev/null and b/gui/slick/images/providers/torrentz.png differ diff --git a/gui/slick/views/displayShow.mako b/gui/slick/views/displayShow.mako index 1f2af7939aab76c5fae37b753e8a810118574629..0e57871c52d29a8fb2968a29608c259e27430425 100644 --- a/gui/slick/views/displayShow.mako +++ b/gui/slick/views/displayShow.mako @@ -214,7 +214,7 @@ % if sickbeard.USE_SUBTITLES: <tr><td class="showLegend">Subtitles: </td><td><img src="${srRoot}/images/${("no16.png", "yes16.png")[bool(show.subtitles)]}" alt="${("N", "Y")[bool(show.subtitles)]}" width="16" height="16" /></td></tr> % endif - <tr><td class="showLegend">Flat Folders: </td><td><img src="${srRoot}/images/${("no16.png", "yes16.png")[bool(show.flatten_folders or sickbeard.NAMING_FORCE_FOLDERS)]}" alt=="${("N", "Y")[bool(show.flatten_folders or sickbeard.NAMING_FORCE_FOLDERS)]}" width="16" height="16" /></td></tr> + <tr><td class="showLegend">Season Folders: </td><td><img src="${srRoot}/images/${("no16.png", "yes16.png")[bool(not show.flatten_folders or sickbeard.NAMING_FORCE_FOLDERS)]}" alt=="${("N", "Y")[bool(not show.flatten_folders or sickbeard.NAMING_FORCE_FOLDERS)]}" width="16" height="16" /></td></tr> <tr><td class="showLegend">Paused: </td><td><img src="${srRoot}/images/${("no16.png", "yes16.png")[bool(show.paused)]}" alt="${("N", "Y")[bool(show.paused)]}" width="16" height="16" /></td></tr> <tr><td class="showLegend">Air-by-Date: </td><td><img src="${srRoot}/images/${("no16.png", "yes16.png")[bool(show.air_by_date)]}" alt="${("N", "Y")[bool(show.air_by_date)]}" width="16" height="16" /></td></tr> <tr><td class="showLegend">Sports: </td><td><img src="${srRoot}/images/${("no16.png", "yes16.png")[bool(show.is_sports)]}" alt="${("N", "Y")[bool(show.is_sports)]}" width="16" height="16" /></td></tr> diff --git a/gui/slick/views/manage.mako b/gui/slick/views/manage.mako index 9f001a3d6bed6859328daf996482a4f8caab6bcf..e7f0ba82301e6a6eec793c5d8513645be6465fb8 100644 --- a/gui/slick/views/manage.mako +++ b/gui/slick/views/manage.mako @@ -27,7 +27,7 @@ <th class="col-legend">Sports</th> <th class="col-legend">Scene</th> <th class="col-legend">Anime</th> - <th class="col-legend">Flat Folders</th> + <th class="col-legend">Season folders</th> <th class="col-legend">Archive first match</th> <th class="col-legend">Paused</th> <th class="col-legend">Subtitle</th> @@ -107,7 +107,7 @@ <td align="center"><img src="${srRoot}/images/${('no16.png" alt="N"', 'yes16.png" alt="Y"')[int(curShow.is_sports) == 1]} width="16" height="16" /></td> <td align="center"><img src="${srRoot}/images/${('no16.png" alt="N"', 'yes16.png" alt="Y"')[int(curShow.is_scene) == 1]} width="16" height="16" /></td> <td align="center"><img src="${srRoot}/images/${('no16.png" alt="N"', 'yes16.png" alt="Y"')[int(curShow.is_anime) == 1]} width="16" height="16" /></td> - <td align="center"><img src="${srRoot}/images/${('no16.png" alt="N"', 'yes16.png" alt="Y"')[int(curShow.flatten_folders) == 1]} width="16" height="16" /></td> + <td align="center"><img src="${srRoot}/images/${('no16.png" alt="N"', 'yes16.png" alt="Y"')[not int(curShow.flatten_folders) == 1]} width="16" height="16" /></td> <td align="center"><img src="${srRoot}/images/${('no16.png" alt="N"', 'yes16.png" alt="Y"')[int(curShow.archive_firstmatch) == 1]} width="16" height="16" /></td> <td align="center"><img src="${srRoot}/images/${('no16.png" alt="N"', 'yes16.png" alt="Y"')[int(curShow.paused) == 1]} width="16" height="16" /></td> <td align="center"><img src="${srRoot}/images/${('no16.png" alt="N"', 'yes16.png" alt="Y"')[int(curShow.subtitles) == 1]} width="16" height="16" /></td> diff --git a/gui/slick/views/manage_massEdit.mako b/gui/slick/views/manage_massEdit.mako index d372f3c007228336add59648d57f94081d8d1ad6..cb18db9b4dfdd10bf5631823bfc37bff633cb528 100644 --- a/gui/slick/views/manage_massEdit.mako +++ b/gui/slick/views/manage_massEdit.mako @@ -33,14 +33,26 @@ <form action="massEditSubmit" method="post"> <input type="hidden" name="toEdit" value="${showList}" /> +<div class="optionWrapper"> +<h5>Selected shows</h5> + <select id="showNames" name="showNames" size="${len(showNames)}"> + % for curName in sorted(showNames): + <option disabled value="${curName}">${curName}</option> + % endfor + </select> +</div> + <div class="optionWrapper"> <span class="selectTitle">Root Directories <span class="separator">*</span></span><br /> % for cur_dir in root_dir_list: <% cur_index = root_dir_list.index(cur_dir) %> + <div> + From: ${cur_dir}<br /> + To:     <span id="display_new_root_dir_${cur_index}">${cur_dir}</span> + </div> <div> <input class="btn edit_root_dir" type="button" class="edit_root_dir" id="edit_root_dir_${cur_index}" value="Edit" /> <input class="btn delete_root_dir" type="button" class="delete_root_dir" id="delete_root_dir_${cur_index}" value="Delete" /> - ${cur_dir} => <span id="display_new_root_dir_${cur_index}">${cur_dir}</span> </div> <input type="hidden" name="orig_root_dir_${cur_index}" value="${cur_dir}" /> <input type="text" style="display: none" name="new_root_dir_${cur_index}" id="new_root_dir_${cur_index}" class="new_root_dir" value="${cur_dir}" /> @@ -95,12 +107,12 @@ </div> <div class="optionWrapper clearfix"> -<span class="selectTitle">Flatten Folders <span class="separator">*</span></span> +<span class="selectTitle">Season folders<span class="separator">*</span></span> <div class="selectChoices"> <select id="edit_flatten_folders" name="flatten_folders" class="form-control form-control-inline input-sm"> <option value="keep" ${('', 'selected="selected"')[flatten_folders_value == None]}>< keep ></option> - <option value="enable" ${('', 'selected="selected"')[flatten_folders_value == 1]}>enable</option> - <option value="disable" ${('', 'selected="selected"')[flatten_folders_value == 0]}>disable</option> + <option value="disable" ${('', 'selected="selected"')[flatten_folders_value == 1]}>disable</option> + <option value="enable" ${('', 'selected="selected"')[flatten_folders_value == 0]}>enable</option> </select> </div> </div> diff --git a/readme.md b/readme.md index 1028d1a027f64c363395112386c88981164f68b5..47a9e38b34a423621e22dd4567a143da934d69b2 100644 --- a/readme.md +++ b/readme.md @@ -49,7 +49,7 @@ We HIGHLY recommend starting out with no database files at all to make this a fr A full list can be found here: [Link](https://github.com/SiCKRAGETV/sickrage-issues/wiki/SickRage-Search-Providers) ###Special Thanks to: -[RARBG](rarbg.to) +[RARBG](https://rarbg.to) [TorrentProject](https://torrentproject.se/about) [ThePirateBay](https://thepiratebay.la/) [KickAssTorrents](https://kat.cr) diff --git a/sickbeard/__init__.py b/sickbeard/__init__.py index 5a41da479d5e1a48570ccb9e2e51967ab12c8b0c..3ed5cbfbbd88be03395b76fd54558de576d17383 100644 --- a/sickbeard/__init__.py +++ b/sickbeard/__init__.py @@ -37,7 +37,7 @@ from github import Github from sickbeard import metadata from sickbeard import providers from sickbeard.providers.generic import GenericProvider -from sickbeard.providers import btn, newznab, womble, thepiratebay, torrentleech, kat, iptorrents, \ +from sickbeard.providers import btn, newznab, womble, thepiratebay, torrentleech, kat, iptorrents, torrentz, \ 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, torrentproject, extratorrent, \ scenetime, btdigg, strike, transmitthenet, tvchaosuk, bitcannon diff --git a/sickbeard/common.py b/sickbeard/common.py index a4086734f165d3e6cba0729ad92b4d1b10f44d92..fc0eecf48fa0f713fae23f672cea632aaba1244e 100644 --- a/sickbeard/common.py +++ b/sickbeard/common.py @@ -141,7 +141,7 @@ class Quality: sceneQualityStrings = {NONE: "N/A", UNKNOWN: "Unknown", SDTV: "HDTV", - SDDVD: "BDRip", + SDDVD: "", HDTV: "720p HDTV", RAWHDTV: "1080i HDTV", FULLHDTV: "1080p HDTV", @@ -406,6 +406,67 @@ class Quality: return (status, Quality.NONE) + @staticmethod + def sceneQualityFromName(name, quality): + """ + Get scene naming parameters from filename and quality + + :param name: Filename to check + :param quality: int of quality to make sure we get the right rip type + :return: encoder type for scene quality naming + """ + codecList = ['xvid', 'divx'] + x264List = ['x264', 'x 264', 'x.264'] + h264List = ['h264', 'h 264', 'h.264', 'avc'] + x265List = ['x265', 'x 265', 'x.265'] + h265List = ['h265', 'h 265', 'h.265', 'hevc'] + codecList.extend(x264List + h264List + x265List + h265List) + + found_codecs = {} + found_codec = None + + for codec in codecList: + if codec in name.lower(): + found_codecs[name.lower().rfind(codec)] = codec + + if found_codecs: + sorted_codecs = sorted(found_codecs, reverse=True) + found_codec = found_codecs[list(sorted_codecs)[0]] + + # 2 corresponds to SDDVD quality + if quality == 2: + if re.search(r"bd(|.|-| )(rip|mux)", name.lower()): + rip_type = " BDRip" + elif re.search(r"dvd(|.|-| )(rip|mux)", name.lower()): + rip_type = " DVDRip" + elif re.search(r"web(|.|-| )(rip|mux)", name.lower()): + rip_type = " WEBRip" + else: + rip_type = "" + + if found_codec: + if codecList[0] in found_codec: + found_codec = 'XviD' + elif codecList[1] in found_codec: + found_codec = 'DivX' + elif found_codec in x264List: + found_codec = x264List[0] + elif found_codec in h264List: + found_codec = h264List[0] + elif found_codec in x265List: + found_codec = x265List[0] + elif found_codec in h265List: + found_codec = h265List[0] + + if quality == 2: + return rip_type + " " + found_codec + else: + return " " + found_codec + elif quality == 2: + return rip_type + else: + return "" + @staticmethod def statusFromName(name, assume=True, anime=False): """ diff --git a/sickbeard/helpers.py b/sickbeard/helpers.py index 8b27416b9eaff36d8c3b103274d9189c627cead4..2f6d5fc391ed9008ee8e0194fd0e62f7a588ad13 100644 --- a/sickbeard/helpers.py +++ b/sickbeard/helpers.py @@ -151,6 +151,7 @@ def remove_non_release_groups(name): r'\.Renc$': 'searchre', r'-NZBGEEK$': 'searchre', r'-Siklopentan$': 'searchre', + r'-\SpastikusTV\]$': 'searchre', r'-RP$': 'searchre', r'-20-40$': 'searchre', r'\.\[www\.usabit\.com\]$': 'searchre', diff --git a/sickbeard/logger.py b/sickbeard/logger.py index b85d7382233562fe025eb53c8fd87a65cb8dd2b2..7dd0ababe5df36ce0b6c3db0d9ed5b54efc70ebe 100644 --- a/sickbeard/logger.py +++ b/sickbeard/logger.py @@ -269,19 +269,30 @@ class Logger(object): reports = gh.get_organization(gh_org).get_repo(gh_repo).get_issues(state="all") def is_mako_error(title): - return re.search(r'Loaded module.*not found in sys\.modules', title) is not None + #[APP SUBMITTED]: Loaded module _home_pi_SickRage_gui_slick_views_home_mako not found in sys.modules + #[APP SUBMITTED]: Loaded module _opt_sickbeard_gui_slick_views_home_mako not found in sys.modules + #[APP SUBMITTED]: Loaded module D__TV_SickRage_gui_slick_views_home_mako not found in sys.modules + return re.search(r".* Loaded module .* not found in sys\.modules", title) is not None def is_ascii_error(title): - return re.search(r"'.*' codec can't encode character .* in position .*:", title) is not None + #[APP SUBMITTED]: 'ascii' codec can't encode characters in position 00-00: ordinal not in range(128) + #[APP SUBMITTED]: 'charmap' codec can't decode byte 0x00 in position 00: character maps to <undefined> + return re.search(r".* codec can't .*code .* in position .*:", title) is not None + + def is_malformed_error(title): + #[APP SUBMITTED]: not well-formed (invalid token): line 0, column 0 + re.search(r".* not well-formed \(invalid token\): line .* column .*", title) is not None mako_error = is_mako_error(title_Error) ascii_error = is_ascii_error(title_Error) + malformed_error = is_malformed_error(title_Error) issue_found = False for report in reports: if title_Error.rsplit(' :: ')[-1] in report.title or \ (mako_error and is_mako_error(report.title)) or \ - (ascii_error and is_ascii_error(report.title)): + (malformed_error and is_malformed_error(report.title)) or \ + (ascii_error and is_ascii_error(report.title)): issue_id = report.number if not report.raw_data['locked']: diff --git a/sickbeard/providers/__init__.py b/sickbeard/providers/__init__.py index 75c87703d76d02744e820bf472ebeef44ee1332c..2880981f61157049b6b477f6a17412787cd9fddf 100644 --- a/sickbeard/providers/__init__.py +++ b/sickbeard/providers/__init__.py @@ -57,7 +57,8 @@ __all__ = ['womble', 'tvchaosuk', 'torrentproject', 'extratorrent', - 'bitcannon' + 'bitcannon', + 'torrentz' ] import sickbeard diff --git a/sickbeard/providers/btdigg.py b/sickbeard/providers/btdigg.py index fdced9764084354541e7555ecaff18f1491db988..648f8612ce175113d3bfd3445f2211cb82aa57ee 100644 --- a/sickbeard/providers/btdigg.py +++ b/sickbeard/providers/btdigg.py @@ -30,7 +30,7 @@ class BTDIGGProvider(generic.TorrentProvider): self.supportsBacklog = True self.public = True - + self.ratio = 0 self.urls = {'url': u'https://btdigg.org/', 'api': u'https://api.btdigg.org/'} @@ -92,6 +92,9 @@ class BTDIGGProvider(generic.TorrentProvider): return results + def seedRatio(self): + return self.ratio + class BTDiggCache(tvcache.TVCache): def __init__(self, provider_obj): diff --git a/sickbeard/providers/hdtorrents.py b/sickbeard/providers/hdtorrents.py index 5155139e7661e5856e9038e99f123e57f58daa8f..a2470be4362248a6d68ea35a5beb06e190ee58b6 100644 --- a/sickbeard/providers/hdtorrents.py +++ b/sickbeard/providers/hdtorrents.py @@ -20,6 +20,7 @@ import re import urllib import requests +import traceback from bs4 import BeautifulSoup from sickbeard import logger diff --git a/sickbeard/providers/morethantv.py b/sickbeard/providers/morethantv.py index 5b16ab01828c8abd6dbd12d9a98a10f3238a1dc8..a4e55cbcdc5d03fa2aafe62107b5d5ea8e4a3b83 100644 --- a/sickbeard/providers/morethantv.py +++ b/sickbeard/providers/morethantv.py @@ -46,7 +46,7 @@ class MoreThanTVProvider(generic.TorrentProvider): self.ratio = None self.minseed = None self.minleech = None - self.freeleech = False + # self.freeleech = False self.urls = {'base_url': 'https://www.morethan.tv/', 'login': 'https://www.morethan.tv/login.php', @@ -81,7 +81,8 @@ class MoreThanTVProvider(generic.TorrentProvider): else: login_params = {'username': self.username, 'password': self.password, - 'login': 'submit'} + 'login': 'Log in', + 'keeplogged': '1'} response = self.getURL(self.urls['login'], post_data=login_params, timeout=30) if not response: @@ -99,7 +100,7 @@ class MoreThanTVProvider(generic.TorrentProvider): results = [] items = {'Season': [], 'Episode': [], 'RSS': []} - freeleech = '3' if self.freeleech else '0' + # freeleech = '3' if self.freeleech else '0' if not self._doLogin(): return results @@ -111,7 +112,7 @@ class MoreThanTVProvider(generic.TorrentProvider): if mode != 'RSS': logger.log(u"Search string: %s " % search_string, logger.DEBUG) - searchURL = self.urls['search'] % (search_string) + searchURL = self.urls['search'] % (search_string.replace('(', '').replace(')', '')) logger.log(u"Search URL: %s" % searchURL, logger.DEBUG) # returns top 15 results by default, expandable in user profile to 100 @@ -151,8 +152,9 @@ class MoreThanTVProvider(generic.TorrentProvider): leechers = cells[7].contents[0] - #FIXME size = -1 + if re.match(r'\d+([,\.]\d+)?\s*[KkMmGgTt]?[Bb]', cells[4].contents[0]): + size = self._convertSize(cells[4].text.strip()) except (AttributeError, TypeError): continue @@ -186,6 +188,22 @@ class MoreThanTVProvider(generic.TorrentProvider): def seedRatio(self): return self.ratio + def _convertSize(self, sizeString): + size = sizeString[:-2].strip() + modifier = sizeString[-2:].upper() + try: + size = float(size) + if modifier in 'KB': + size = size * 1024 + elif modifier in 'MB': + size = size * 1024**2 + elif modifier in 'GB': + size = size * 1024**3 + elif modifier in 'TB': + size = size * 1024**4 + except Exception: + size = -1 + return int(size) class MoreThanTVCache(tvcache.TVCache): def __init__(self, provider_obj): diff --git a/sickbeard/providers/strike.py b/sickbeard/providers/strike.py index 0b339fdc9726097b2a3b9a8d55209d43488854ea..0ee96b147b54557f8ea912b2caa134aa05ab3301 100644 --- a/sickbeard/providers/strike.py +++ b/sickbeard/providers/strike.py @@ -28,7 +28,7 @@ class STRIKEProvider(generic.TorrentProvider): self.supportsBacklog = True self.public = True self.url = 'https://getstrike.net/' - + self.ratio = 0 self.cache = StrikeCache(self) self.minseed, self.minleech = 2 * [None] @@ -86,6 +86,10 @@ class STRIKEProvider(generic.TorrentProvider): return results + def seedRatio(self): + return self.ratio + + class StrikeCache(tvcache.TVCache): def __init__(self, provider_obj): diff --git a/sickbeard/providers/torrentproject.py b/sickbeard/providers/torrentproject.py index 7a8625c8c6ba3d44525b230207dc683de04665f5..1aa69aa1d4966725ad2f5516995f4758ef2caa8c 100644 --- a/sickbeard/providers/torrentproject.py +++ b/sickbeard/providers/torrentproject.py @@ -31,7 +31,7 @@ class TORRENTPROJECTProvider(generic.TorrentProvider): self.supportsBacklog = True self.public = True - + self.ratio = 0 self.urls = {'api': u'https://torrentproject.se/',} self.url = self.urls['api'] self.headers.update({'User-Agent': USER_AGENT}) @@ -113,6 +113,10 @@ class TORRENTPROJECTProvider(generic.TorrentProvider): return results + def seedRatio(self): + return self.ratio + + class TORRENTPROJECTCache(tvcache.TVCache): def __init__(self, provider_obj): diff --git a/sickbeard/providers/torrentz.py b/sickbeard/providers/torrentz.py new file mode 100644 index 0000000000000000000000000000000000000000..6f2c2895ba8dc32f8fcf01508e7a41a2c94a0863 --- /dev/null +++ b/sickbeard/providers/torrentz.py @@ -0,0 +1,140 @@ +# Author: Dustyn Gibson <miigotu@gmail.com> +# URL: https://github.com/SiCKRAGETV/SickRage +# +# 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 time +import traceback +import xmltodict +import HTMLParser +from six.moves import urllib +from xml.parsers.expat import ExpatError + +import sickbeard +from sickbeard import logger +from sickbeard import tvcache +from sickbeard.providers import generic +from sickbeard.common import cpu_presets + +class TORRENTZProvider(generic.TorrentProvider): + + def __init__(self): + + generic.TorrentProvider.__init__(self, "Torrentz") + self.public = True + self.supportsBacklog = True + self.confirmed = True + self.ratio = None + self.minseed = None + self.minleech = None + self.cache = TORRENTZCache(self) + self.urls = {'verified': 'https://torrentz.eu/feed_verified', + 'feed': 'https://torrentz.eu/feed', + 'base': 'https://torrentz.eu/'} + self.url = self.urls['base'] + + def isEnabled(self): + return self.enabled + + def seedRatio(self): + return self.ratio + + @staticmethod + def _split_description(description): + match = re.findall(r'[0-9]+', description) + return (int(match[0]) * 1024**2, int(match[1]), int(match[2])) + + def _doSearch(self, search_strings, search_mode='eponly', epcount=0, age=0, epObj=None): + results = [] + items = {'Season': [], 'Episode': [], 'RSS': []} + + for mode in search_strings: + for search_string in search_strings[mode]: + search_url = self.urls['verified'] if self.confirmed else self.urls['feed'] + if mode != 'RSS': + search_url += '?q=' + urllib.parse.quote_plus(search_string) + + logger.log(search_url) + data = self.getURL(search_url) + if not data: + logger.log('Seems to be down right now!') + continue + + time.sleep(cpu_presets[sickbeard.CPU_PRESET]) + + if not data.startswith("<?xml"): + logger.log('Wrong data returned from: ' + search_url, logger.DEBUG) + continue + + try: + data = xmltodict.parse(HTMLParser.HTMLParser().unescape(data.encode('utf-8')).replace('&', '&')) + except ExpatError: + logger.log(u"Failed parsing provider. Traceback: %r\n%r" % (traceback.format_exc(), data), logger.ERROR) + continue + + if not all([data, 'rss' in data, 'channel' in data['rss'], 'item' in data['rss']['channel']]): + logger.log(u"Malformed rss returned, skipping", logger.DEBUG) + continue + + # https://github.com/martinblech/xmltodict/issues/111 + entries = data['rss']['channel']['item'] + entries = entries if isinstance(entries, list) else [entries] + + for item in entries: + if 'tv' not in item['category']: + continue + + title = item['title'].rsplit(' ', 1)[0].replace(' ', '.') + t_hash = item['guid'].rsplit('/', 1)[-1] + + if not all([title, t_hash]): + continue + + # TODO: Add method to generic provider for building magnet from hash. + download_url = "magnet:?xt=urn:btih:" + t_hash + "&dn=" + title + "&tr=udp://tracker.openbittorrent.com:80&tr=udp://tracker.coppersurfer.tk:6969&tr=udp://open.demonii.com:1337&tr=udp://tracker.leechers-paradise.org:6969&tr=udp://exodus.desync.com:6969" + size, seeders, leechers = self._split_description(item['description']) + + #Filter unseeded torrent + if seeders < self.minseed or leechers < self.minleech: + if mode != 'RSS': + logger.log(u"Discarding torrent because it doesn't meet the minimum seeders or leechers: {0} (S:{1} L:{2})".format(title, seeders, leechers), logger.DEBUG) + continue + + items[mode].append((title, download_url, size, seeders, leechers)) + + del data + + #For each search mode sort all the items by seeders if available + items[mode].sort(key=lambda tup: tup[3], reverse=True) + results += items[mode] + + return results + +class TORRENTZCache(tvcache.TVCache): + + def __init__(self, provider_obj): + + tvcache.TVCache.__init__(self, provider_obj) + + # only poll every 15 minutes max + self.minTime = 15 + + def _getRSSData(self): + return {'entries': self.provider._doSearch({'RSS': ['']})} + +provider = TORRENTZProvider() diff --git a/sickbeard/tv.py b/sickbeard/tv.py index ee7229b95b3b9965613789e41af6250223cad603..ccf7deb04ac77e4c78a8685163f011861ba24ba1 100644 --- a/sickbeard/tv.py +++ b/sickbeard/tv.py @@ -2112,35 +2112,6 @@ class TVEpisode(object): name = helpers.remove_non_release_groups(helpers.remove_extension(name)) return name - def release_codec(name): - if hasattr(self, 'location') and self.location: - codecList = ['xvid', 'x264', 'x265', 'h264', 'x 264', 'x 265', 'h 264', 'x.264', 'x.265', 'h.264', 'divx'] - found_codec = None - - for codec in codecList: - if codec in name.lower(): - found_codec = codec - - if found_codec: - if codecList[0] in found_codec: - found_codec = 'XviD' - elif codecList[1] or codecList[4] or codecList[7] in found_codec: - found_codec = codecList[1] - elif codecList[2] or codecList[5] or codecList[8] in found_codec: - found_codec = codecList[2] - elif codecList[3] or codecList[6] or codecList[9] in found_codec: - found_codec = codecList[3] - elif codecList[10] in found_codec: - found_codec = 'DivX' - - logger.log(u"Found following codec for " + name + ": " + found_codec, logger.DEBUG) - return " " + found_codec - else: - logger.log(u"Couldn't find any codec for " + name + ". Codec information won't be added.", logger.DEBUG) - return "" - else: - return "" - def release_group(show, name): if name: name = helpers.remove_non_release_groups(helpers.remove_extension(name)) @@ -2166,7 +2137,9 @@ class TVEpisode(object): show_name = self.show.name # try to get the release encoder to comply with scene naming standards - encoder = release_codec(self.release_name) + encoder = Quality.sceneQualityFromName(self.release_name, epQual) + if encoder: + logger.log(u"Found codec for '" + show_name + ": " + ep_name + "'.", logger.DEBUG) #try to get the release group rel_grp = {}; diff --git a/sickbeard/webserve.py b/sickbeard/webserve.py index 88b9098439bbc32838b69bf9829b1ef4c6d1c5b6..df61991a0d1774402dad8460490969377a52942c 100644 --- a/sickbeard/webserve.py +++ b/sickbeard/webserve.py @@ -2995,11 +2995,13 @@ class Manage(Home, WebRoot): showIDs = toEdit.split("|") showList = [] + showNames = [] for curID in showIDs: curID = int(curID) showObj = helpers.findCertainShow(sickbeard.showList, curID) if showObj: showList.append(showObj) + showNames.append(showObj.name) archive_firstmatch_all_same = True last_archive_firstmatch = None @@ -3115,7 +3117,7 @@ class Manage(Home, WebRoot): air_by_date_value = last_air_by_date if air_by_date_all_same else None root_dir_list = root_dir_list - return t.render(showList=toEdit, archive_firstmatch_value=archive_firstmatch_value, default_ep_status_value=default_ep_status_value, + return t.render(showList=toEdit, showNames=showNames, archive_firstmatch_value=archive_firstmatch_value, default_ep_status_value=default_ep_status_value, paused_value=paused_value, anime_value=anime_value, flatten_folders_value=flatten_folders_value, quality_value=quality_value, subtitles_value=subtitles_value, scene_value=scene_value, sports_value=sports_value, air_by_date_value=air_by_date_value, root_dir_list=root_dir_list, title='Mass Edit', header='Mass Edit', topmenu='manage')