diff --git a/data/images/providers/sotorrent.png b/data/images/providers/sotorrent.png new file mode 100644 index 0000000000000000000000000000000000000000..09b6ce575caa6fb748a13947018f2a62bdb5d33e Binary files /dev/null and b/data/images/providers/sotorrent.png differ diff --git a/data/interfaces/default/config_providers.tmpl b/data/interfaces/default/config_providers.tmpl index 86445278473089974c447b66a8b11b7c9d9a08e5..f7503a6ef8aa2cf55b891b40239c4d8d14de2d6b 100644 --- a/data/interfaces/default/config_providers.tmpl +++ b/data/interfaces/default/config_providers.tmpl @@ -99,7 +99,7 @@ var show_nzb_providers = #if $sickbeard.USE_NZBS then "true" else "false"#; <span class="component-title jumbo">Configure Provider:</span> <span class="component-desc"> #set $provider_config_list = [] - #for $cur_provider in ("omgwtfnzbs", "tvtorrents", "torrentleech", "btn", "binnewz", "t411", "ftdb", "addict", "fnt", "libertalia", "piratebay", "ethor", "thinkgeek", "xthor"): + #for $cur_provider in ("omgwtfnzbs", "tvtorrents", "torrentleech", "btn", "binnewz", "t411", "ftdb", "addict", "fnt", "libertalia", "sotorrent", "piratebay", "ethor", "thinkgeek", "xthor"): #set $cur_provider_obj = $sickbeard.providers.getProviderClass($cur_provider) #if $cur_provider_obj.providerType == $GenericProvider.NZB and not $sickbeard.USE_NZBS: #continue @@ -300,6 +300,21 @@ Nothing to set up for this provider </div> </div><!-- /libertaliaDiv //--> + <div class="providerDiv" id="sotorrentDiv"> + <div class="field-pair"> + <label class="clearfix"> + <span class="component-title">So-torrent User name:</span> + <input class="component-desc" type="text" name="sotorrent_username" value="$sickbeard.SOTORRENT_USERNAME" size="40" /> + </label> + </div> + <div class="field-pair"> + <label class="clearfix"> + <span class="component-title">So-torrent Password:</span> + <input class="component-desc" type="text" name="sotorrent_password" value="$sickbeard.SOTORRENT_PASSWORD" size="40" /> + </label> + </div> + </div><!-- /sotorrentDiv //--> + <div class="providerDiv" id="xthorDiv"> <div class="field-pair"> <label class="clearfix"> diff --git a/sickbeard/__init__.py b/sickbeard/__init__.py index 1fc8340e59c614e02f4cf716b36201c8e62efb88..ee9112dc2718e5eabf07f8bae0db71c9bbe89e01 100644 --- a/sickbeard/__init__.py +++ b/sickbeard/__init__.py @@ -30,7 +30,7 @@ from threading import Lock # apparently py2exe won't build these unless they're imported somewhere from sickbeard import providers, metadata -from providers import ezrss, tvtorrents, torrentleech, btn, nzbsrus, newznab, womble, nzbx, omgwtfnzbs, binnewz, t411, ftdb, libertalia, tpi, fnt, addict, cpasbien, piratebay, gks, kat, ethor, xthor, thinkgeek +from providers import ezrss, tvtorrents, torrentleech, btn, nzbsrus, newznab, womble, nzbx, omgwtfnzbs, binnewz, t411, ftdb, libertalia, sotorrent, tpi, fnt, addict, cpasbien, piratebay, gks, kat, ethor, xthor, thinkgeek from sickbeard.config import CheckSection, check_setting_int, check_setting_str, ConfigMigrator from sickbeard import searchCurrent, searchBacklog, showUpdater, versionChecker, properFinder, frenchFinder, autoPostProcesser, subtitles, traktWatchListChecker, SentFTPChecker @@ -236,6 +236,10 @@ LIBERTALIA = False LIBERTALIA_USERNAME = None LIBERTALIA_PASSWORD = None +SOTORRENT = False +SOTORRENT_USERNAME = None +SOTORRENT_PASSWORD = None + XTHOR = False XTHOR_USERNAME = None XTHOR_PASSWORD = None @@ -494,6 +498,7 @@ def initialize(consoleLogging=True): ADDICT, ADDICT_USERNAME, ADDICT_PASSWORD, \ FNT, FNT_USERNAME, FNT_PASSWORD, \ LIBERTALIA, LIBERTALIA_USERNAME, LIBERTALIA_PASSWORD, \ + SOTORRENT, SOTORRENT_USERNAME, SOTORRENT_PASSWORD, \ XTHOR, XTHOR_USERNAME, XTHOR_PASSWORD, \ THINKGEEK, THINKGEEK_USERNAME, THINKGEEK_PASSWORD, \ THEPIRATEBAY, THEPIRATEBAY_PROXY, THEPIRATEBAY_PROXY_URL, THEPIRATEBAY_TRUSTED, \ @@ -806,6 +811,11 @@ def initialize(consoleLogging=True): LIBERTALIA_USERNAME = check_setting_str(CFG, 'LIBERTALIA', 'username', '') LIBERTALIA_PASSWORD = check_setting_str(CFG, 'LIBERTALIA', 'password', '') + CheckSection(CFG, 'SOTORRENT') + SOTORRENT = bool(check_setting_int(CFG, 'SOTORRENT', 'sotorrent', 0)) + SOTORRENT_USERNAME = check_setting_str(CFG, 'SOTORRENT', 'username', '') + SOTORRENT_PASSWORD = check_setting_str(CFG, 'SOTORRENT', 'password', '') + CheckSection(CFG, 'XTHOR') XTHOR = bool(check_setting_int(CFG, 'XTHOR', 'xthor', 0)) XTHOR_USERNAME = check_setting_str(CFG, 'XTHOR', 'username', '') @@ -1572,6 +1582,11 @@ def save_config(): new_config['LIBERTALIA']['username'] = LIBERTALIA_USERNAME new_config['LIBERTALIA']['password'] = LIBERTALIA_PASSWORD + new_config['SOTORRENT'] = {} + new_config['SOTORRENT']['sotorrent'] = int(SOTORRENT) + new_config['SOTORRENT']['username'] = SOTORRENT_USERNAME + new_config['SOTORRENT']['password'] = SOTORRENT_PASSWORD + new_config['XTHOR'] = {} new_config['XTHOR']['xthor'] = int(XTHOR) new_config['XTHOR']['username'] = XTHOR_USERNAME diff --git a/sickbeard/providers/__init__.py b/sickbeard/providers/__init__.py index b769ebd06dca967972eb032357708accb876ea76..55de106f39193cb6332cd6244ffc077ea00fd670 100644 --- a/sickbeard/providers/__init__.py +++ b/sickbeard/providers/__init__.py @@ -28,6 +28,7 @@ __all__ = ['ezrss', 'addict', 'fnt', 'libertalia', + 'sotorrent', 'cpasbien', 'piratebay', 'kat', diff --git a/sickbeard/providers/sotorrent.py b/sickbeard/providers/sotorrent.py new file mode 100644 index 0000000000000000000000000000000000000000..aff9028c51d668ea29638d89f9f80de47290dbe1 --- /dev/null +++ b/sickbeard/providers/sotorrent.py @@ -0,0 +1,175 @@ +# -*- coding: latin-1 -*- +# Author: Staros +# URL: http://code.google.com/p/sickbeard/ +# +# This file is part of Sick Beard. +# +# Sick Beard 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. +# +# Sick Beard 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 Sick Beard. If not, see <http://www.gnu.org/licenses/>. + +from bs4 import BeautifulSoup +from sickbeard import classes, show_name_helpers, logger +from sickbeard.common import Quality + +import generic +import cookielib +import sickbeard +import urllib +import urllib2 +import random + +class SOTORRENTProvider(generic.TorrentProvider): + + def __init__(self): + generic.TorrentProvider.__init__(self, "Sotorrent") + self.supportsBacklog = True + + self.cj = cookielib.CookieJar() + self.opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(self.cj)) + self.url = "https://so-torrent.com" + + self.login_done = False + + self.params = "q=&c73=1&c75=1" # English (HD and SD) + + def imageName(self): + return 'sotorrent.png' + + def isEnabled(self): + return sickbeard.SOTORRENT + + def getSearchParams(self, searchString, audio_lang, subcat, french=None): + """ + @q string / exact for sphinx tool / c[NUMCAT] + """ + if audio_lang == "en" and french==None: + self.params = urllib.urlencode({ + 'q': searchString, + })+"&c73=1&c75=1" + elif audio_lang == "fr" or french: + self.params = urllib.urlencode({ + 'q': searchString, + })+"&c74=1&c72=1" + else: + self.params = urllib.urlencode({ + 'q': searchString, + })+"&c74=1&c72=1&c73=1&c75=1" + + return self.params + + def _get_season_search_strings(self, show, season): + """ + """ + return [] + + def _get_episode_search_strings(self, ep_obj, french=None): + """ + """ + results = [] + possible_show = show_name_helpers.allPossibleShowNames(ep_obj.show) + list_show = set(possible_show) + for show in list_show: + results.append(self.getSearchParams("%s S%02dE%02d" % (show, ep_obj.scene_season, ep_obj.scene_episode), ep_obj.show.audio_lang, french)) + return results + + + def _get_title_and_url(self, item): + return (item.title, item.url) + + def getQuality(self, item): + return item.getQuality() + + def _doLogin(self, username, password): + + listeUserAgents = [ 'Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_5_5; fr-fr) AppleWebKit/525.18 (KHTML, like Gecko) Version/3.1.2 Safari/525.20.1', + 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/14.0.835.186 Safari/535.1', + 'Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US) AppleWebKit/525.13 (KHTML, like Gecko) Chrome/0.2.149.27 Safari/525.13', + 'Mozilla/5.0 (X11; U; Linux x86_64; en-us) AppleWebKit/528.5+ (KHTML, like Gecko, Safari/528.5+) midori', + 'Mozilla/5.0 (Windows NT 6.0) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/13.0.782.107 Safari/535.1', + 'Mozilla/5.0 (Macintosh; U; PPC Mac OS X; en-us) AppleWebKit/312.1 (KHTML, like Gecko) Safari/312', + 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.12 Safari/535.11', + 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.8 (KHTML, like Gecko) Chrome/17.0.940.0 Safari/535.8' ] + + self.opener.addheaders = [('User-agent', random.choice(listeUserAgents))] + data = urllib.urlencode({'username': username,'password': password, 'submit': ' Se Connecter '}) + r = self.opener.open(self.url + '/connect.php',data) + + for index, cookie in enumerate(self.cj): + if (cookie.name == "pwSoTorrent"): self.login_done = True + + if not self.login_done: + logger.log(u"Unable to login to so-torrent. Please check username and password.", logger.WARNING) + + if self.login_done: + logger.log(u"Login to so-torrent successful", logger.MESSAGE) + + def _doSearch(self, searchString, show=None, season=None, french=None): + if not self.login_done: + self._doLogin(sickbeard.SOTORRENT_USERNAME, sickbeard.SOTORRENT_PASSWORD) + + results = [] + + search_url = "{0}/sphinx.php?{1}".format(self.url, searchString.replace('!','')) + req = self.opener.open(search_url) + page = BeautifulSoup(req) + + torrent_table = page.find("table", {"id" : "torrent_list"}) + if torrent_table: + logger.log(u"So-torrent found shows ! " , logger.DEBUG) + torrent_rows = torrent_table.findAll("tr", {"id" : "infos_sphinx"}) + + for row in torrent_rows: + release = row.strong.string + id_search = row.find("img", {"alt" : "+"}) + id_torrent = id_search['id'].replace('expandoGif', '') + download_url = "https://so-torrent.com/get.php?id={0}".format(id_search['id'].replace('expandoGif', '')) + id_quality = Quality.nameQuality(release) + + if show and french==None: + results.append(SOTORRENTSearchResult(self.opener, release, download_url, id_quality, str(show.audio_lang))) + elif show and french: + results.append(SOTORRENTSearchResult(self.opener, release, download_url, id_quality, 'fr')) + else: + results.append(SOTORRENTSearchResult(self.opener, release, download_url, id_quality)) + + else: + logger.log(u"No table founded.", logger.DEBUG) + self.login_done = False + return results + + def getResult(self, episodes): + """ + Returns a result of the correct type for this provider + """ + result = classes.TorrentDataSearchResult(episodes) + result.provider = self + + return result + +class SOTORRENTSearchResult: + def __init__(self, opener, title, url, quality, audio_langs=None): + self.opener = opener + self.title = title + self.url = url + self.quality = quality + self.audio_langs=audio_langs + + def getNZB(self): + return self.opener.open( self.url , 'wb').read() + + def getQuality(self): + return self.quality + +provider = SOTORRENTProvider() + + diff --git a/sickbeard/webserve.py b/sickbeard/webserve.py index c11bf938b14614a77ff0293e6be3bc0d034596a4..54e57667397b43540cb98d53b7f765f27e445d67 100644 --- a/sickbeard/webserve.py +++ b/sickbeard/webserve.py @@ -1361,7 +1361,7 @@ class ConfigProviders: tvtorrents_digest=None, tvtorrents_hash=None, torrentleech_key=None, btn_api_key=None, - newzbin_username=None, newzbin_password=None,t411_username=None,t411_password=None,ftdb_username=None,ftdb_password=None,addict_username=None,addict_password=None,fnt_username=None,fnt_password=None,libertalia_username=None,libertalia_password=None,xthor_username=None,xthor_password=None,thinkgeek_username=None,thinkgeek_password=None, + newzbin_username=None, newzbin_password=None,t411_username=None,t411_password=None,ftdb_username=None,ftdb_password=None,addict_username=None,addict_password=None,fnt_username=None,fnt_password=None,libertalia_username=None,libertalia_password=None,sotorrent_username=None,sotorrent_password=None,xthor_username=None,xthor_password=None,thinkgeek_username=None,thinkgeek_password=None, ethor_key=None, provider_order=None): @@ -1444,6 +1444,8 @@ class ConfigProviders: sickbeard.FNT = curEnabled elif curProvider == 'libertalia': sickbeard.LIBERTALIA = curEnabled + elif curProvider == 'sotorrent': + sickbeard.SOTORRENT = curEnabled elif curProvider == 'xthor': sickbeard.XTHOR = curEnabled elif curProvider == 'thinkgeek': @@ -1484,6 +1486,9 @@ class ConfigProviders: sickbeard.LIBERTALIA_USERNAME = libertalia_username sickbeard.LIBERTALIA_PASSWORD = libertalia_password + + sickbeard.SOTORRENT_USERNAME = sotorrent_username + sickbeard.SOTORRENT_PASSWORD = sotorrent_password sickbeard.XTHOR_USERNAME = xthor_username sickbeard.XTHOR_PASSWORD = xthor_password