From 89c944ec94dc8de5e6b9b2a23ffff14ff8833336 Mon Sep 17 00:00:00 2001 From: Bike Mike Date: Sun, 25 May 2014 09:28:13 +0200 Subject: [PATCH] Added cookie support to custom torrent provider --- .../interfaces/default/config_providers.tmpl | 12 +++++++- gui/slick/js/configProviders.js | 28 +++++++++---------- lib/feedcache/cache.py | 4 +-- sickbeard/providers/__init__.py | 14 ++++++---- sickbeard/providers/rsstorrent.py | 24 +++++++++++++--- sickbeard/tvcache.py | 4 +-- sickbeard/webserve.py | 14 ++++++---- 7 files changed, 66 insertions(+), 34 deletions(-) diff --git a/gui/slick/interfaces/default/config_providers.tmpl b/gui/slick/interfaces/default/config_providers.tmpl index a8f82cf0..56d8537f 100644 --- a/gui/slick/interfaces/default/config_providers.tmpl +++ b/gui/slick/interfaces/default/config_providers.tmpl @@ -34,7 +34,7 @@ var show_nzb_providers = #if $sickbeard.USE_NZBS then "true" else "false"#; @@ -590,6 +590,16 @@ var show_nzb_providers = #if $sickbeard.USE_NZBS then "true" else "false"#; +
+ + +
diff --git a/gui/slick/js/configProviders.js b/gui/slick/js/configProviders.js index b5f04da1..52eb6a39 100644 --- a/gui/slick/js/configProviders.js +++ b/gui/slick/js/configProviders.js @@ -44,9 +44,9 @@ $(document).ready(function(){ } - $.fn.addTorrentRssProvider = function (id, name, url) { + $.fn.addTorrentRssProvider = function (id, name, url, cookies) { - var newData = [name, url]; + var newData = [name, url, cookies]; torrentRssProviders[id] = newData; $('#editATorrentRssProvider').addOption(id, name); @@ -84,8 +84,9 @@ $(document).ready(function(){ } - $.fn.updateTorrentRssProvider = function (id, url) { + $.fn.updateTorrentRssProvider = function (id, url, cookies) { torrentRssProviders[id][1] = url; + torrentRssProviders[id][2] = cookies; $(this).populateTorrentRssSection(); $(this).makeTorrentRssProviderString(); } @@ -153,7 +154,7 @@ $(document).ready(function(){ var selectedProvider = $('#editATorrentRssProvider :selected').val(); if (selectedProvider == 'addTorrentRss') { - var data = ['','','','']; + var data = ['','','']; $('#torrentrss_add_div').show(); $('#torrentrss_update_div').hide(); } else { @@ -164,19 +165,16 @@ $(document).ready(function(){ $('#torrentrss_name').val(data[0]); $('#torrentrss_url').val(data[1]); - $('#torrentrss_uname').val(data[2]); - $('#torrentrss_passw').val(data[3]); + $('#torrentrss_cookies').val(data[2]); if (selectedProvider == 'addTorrentRss') { $('#torrentrss_name').removeAttr("disabled"); $('#torrentrss_url').removeAttr("disabled"); - $('#torrentrss_uname').removeAttr("disabled"); - $('#torrentrss_passw').removeAttr("disabled"); + $('#torrentrss_cookies').removeAttr("disabled"); } else { $('#torrentrss_name').attr("disabled", "disabled"); $('#torrentrss_url').removeAttr("disabled"); - $('#torrentrss_uname').removeAttr("disabled"); - $('#torrentrss_passw').removeAttr("disabled") + $('#torrentrss_cookies').removeAttr("disabled"); $('#torrentrss_delete').removeAttr("disabled"); } @@ -316,7 +314,7 @@ $(document).ready(function(){ }); - $('#torrentrss_url,#torrentrss_uname,#torrentrss_key').change(function(){ + $('#torrentrss_url,#torrentrss_cookies').change(function(){ var selectedProvider = $('#editATorrentRssProvider :selected').val(); @@ -324,8 +322,9 @@ $(document).ready(function(){ return; var url = $('#torrentrss_url').val(); + var cookies = $('#torrentrss_cookies').val(); - $(this).updateTorrentRssProvider(selectedProvider, url); + $(this).updateTorrentRssProvider(selectedProvider, url, cookies); }); @@ -390,7 +389,8 @@ $(document).ready(function(){ var name = $('#torrentrss_name').val(); var url = $('#torrentrss_url').val(); - var params = { name: name, url: url} + var cookies = $('#torrentrss_cookies').val(); + var params = { name: name, url: url, cookies: cookies} // send to the form with ajax, get a return value $.getJSON(sbRoot + '/config/providers/canAddTorrentRssProvider', params, @@ -400,7 +400,7 @@ $(document).ready(function(){ return; } - $(this).addTorrentRssProvider(data.success, name, url); + $(this).addTorrentRssProvider(data.success, name, url, cookies); }); }); diff --git a/lib/feedcache/cache.py b/lib/feedcache/cache.py index fbaef63a..6ec0a39a 100644 --- a/lib/feedcache/cache.py +++ b/lib/feedcache/cache.py @@ -98,7 +98,7 @@ class Cache: del self.storage[url] return - def fetch(self, url, force_update=False, offline=False): + def fetch(self, url, force_update=False, offline=False, request_headers=None): """Return the feed at url. url - The URL of the feed. @@ -175,7 +175,7 @@ class Cache: agent=self.user_agent, modified=modified, etag=etag, - ) + request_headers=request_headers) status = parsed_result.get('status', None) logger.debug('HTTP status=%s' % status) diff --git a/sickbeard/providers/__init__.py b/sickbeard/providers/__init__.py index b8579492..d2c7fc4a 100644 --- a/sickbeard/providers/__init__.py +++ b/sickbeard/providers/__init__.py @@ -138,22 +138,26 @@ def makeTorrentRssProvider(configString): if not configString: return None + cookies = None search_mode = 'eponly' search_fallback = 0 backlog_only = 0 try: - name, url, enabled, search_mode, search_fallback, backlog_only = configString.split('|') + name, url, cookies, enabled, search_mode, search_fallback, backlog_only = configString.split('|') except ValueError: try: - name, url, enabled = configString.split('|') + name, url, enabled, search_mode, search_fallback, backlog_only = configString.split('|') except ValueError: - logger.log(u"Skipping RSS Torrent provider string: '" + configString + "', incorrect format", logger.ERROR) - return None + try: + name, url, enabled = configString.split('|') + except ValueError: + logger.log(u"Skipping RSS Torrent provider string: '" + configString + "', incorrect format", logger.ERROR) + return None torrentRss = sys.modules['sickbeard.providers.rsstorrent'] - newProvider = torrentRss.TorrentRssProvider(name, url, search_mode, search_fallback, backlog_only) + newProvider = torrentRss.TorrentRssProvider(name, url, cookies, search_mode, search_fallback, backlog_only) newProvider.enabled = enabled == '1' return newProvider diff --git a/sickbeard/providers/rsstorrent.py b/sickbeard/providers/rsstorrent.py index 8b6695a5..7b9f9a47 100644 --- a/sickbeard/providers/rsstorrent.py +++ b/sickbeard/providers/rsstorrent.py @@ -35,7 +35,7 @@ from lib.requests import exceptions from lib.bencode import bdecode class TorrentRssProvider(generic.TorrentProvider): - def __init__(self, name, url, search_mode='eponly', search_fallback=False, backlog_only=False): + def __init__(self, name, url, cookies, search_mode='eponly', search_fallback=False, backlog_only=False): generic.TorrentProvider.__init__(self, name) self.cache = TorrentRssCache(self) self.url = re.sub('\/$', '', url) @@ -47,8 +47,13 @@ class TorrentRssProvider(generic.TorrentProvider): self.search_fallback = search_fallback self.backlog_only = backlog_only + if cookies: + self.cookies = cookies + else: + self.cookies = None + def configStr(self): - return self.name + '|' + self.url + '|' + str(int(self.enabled)) + '|' + self.search_mode + '|' + str(int(self.search_fallback)) + '|' + str(int(self.backlog_only)) + return self.name + '|' + self.url + '|' + self.cookies + '|' + str(int(self.enabled)) + '|' + self.search_mode + '|' + str(int(self.search_fallback)) + '|' + str(int(self.backlog_only)) def imageName(self): if ek.ek(os.path.isfile, ek.ek(os.path.join, sickbeard.PROG_DIR, 'data', 'images', 'providers', self.getID() + '.png')): @@ -84,6 +89,10 @@ class TorrentRssProvider(generic.TorrentProvider): def validateRSS(self): try: + if self.cookies: + cookie_validator=re.compile("^(\w+=\w+)(;\w+=\w+)*$") + if not cookie_validator.match(self.cookies): + return (False, 'Cookie is not correctly formatted: ' + self.cookies) data = self.cache._getRSSData() if not data: @@ -121,6 +130,10 @@ class TorrentRssProvider(generic.TorrentProvider): if not self.session: self.session = requests.Session() + if self.cookies: + requests.utils.add_dict_to_cookiejar(self.session.cookies, + dict(x.rsplit('=', 1) for x in (self.cookies.split(';')))) + try: parsed = list(urlparse.urlparse(url)) parsed[2] = re.sub("/{2,}", "/", parsed[2]) # replace two or more / with one @@ -158,9 +171,12 @@ class TorrentRssCache(tvcache.TVCache): self.minTime = 15 def _getRSSData(self): - url = self.provider.url logger.log(u"TorrentRssCache cache update URL: " + self.provider.url, logger.DEBUG) - return self.getRSSFeed(url) + if self.provider.cookies: + request_headers = { 'Cookie': self.provider.cookies } + else: + request_headers = None + return self.getRSSFeed(self.provider.url, request_headers=request_headers) def _parseItem(self, item): diff --git a/sickbeard/tvcache.py b/sickbeard/tvcache.py index b983893b..d3634e1b 100644 --- a/sickbeard/tvcache.py +++ b/sickbeard/tvcache.py @@ -136,7 +136,7 @@ class TVCache(): return [] - def getRSSFeed(self, url, post_data=None): + def getRSSFeed(self, url, post_data=None, request_headers=None): # create provider storaqe cache storage = Shove('sqlite:///' + ek.ek(os.path.join, sickbeard.CACHE_DIR, self.provider.name) + '.db') fc = cache.Cache(storage) @@ -147,7 +147,7 @@ class TVCache(): if post_data: url = url + 'api?' + urllib.urlencode(post_data) - f = fc.fetch(url) + f = fc.fetch(url, request_headers=request_headers) if not f: logger.log(u"Error loading " + self.providerID + " URL: " + url, logger.ERROR) diff --git a/sickbeard/webserve.py b/sickbeard/webserve.py index 5af09213..e24d3462 100644 --- a/sickbeard/webserve.py +++ b/sickbeard/webserve.py @@ -1399,7 +1399,7 @@ class ConfigProviders: return '1' @cherrypy.expose - def canAddTorrentRssProvider(self, name, url): + def canAddTorrentRssProvider(self, name, url, cookies): if not name: return json.dumps({'error': 'Invalid name specified'}) @@ -1407,7 +1407,7 @@ class ConfigProviders: providerDict = dict( zip([x.getID() for x in sickbeard.torrentRssProviderList], sickbeard.torrentRssProviderList)) - tempProvider = rsstorrent.TorrentRssProvider(name, url) + tempProvider = rsstorrent.TorrentRssProvider(name, url, cookies) if tempProvider.getID() in providerDict: return json.dumps({'error': 'Exists as ' + providerDict[tempProvider.getID()].name}) @@ -1419,7 +1419,7 @@ class ConfigProviders: return json.dumps({'error': errMsg}) @cherrypy.expose - def saveTorrentRssProvider(self, name, url): + def saveTorrentRssProvider(self, name, url, cookies): if not name or not url: return '0' @@ -1429,11 +1429,12 @@ class ConfigProviders: if name in providerDict: providerDict[name].name = name providerDict[name].url = config.clean_url(url) + providerDict[name].cookies = cookies return providerDict[name].getID() + '|' + providerDict[name].configStr() else: - newProvider = rsstorrent.TorrentRssProvider(name, url) + newProvider = rsstorrent.TorrentRssProvider(name, url, cookies) sickbeard.torrentRssProviderList.append(newProvider) return newProvider.getID() + '|' + newProvider.configStr() @@ -1511,10 +1512,10 @@ class ConfigProviders: if not curTorrentRssProviderStr: continue - curName, curURL = curTorrentRssProviderStr.split('|') + curName, curURL, curCookies = curTorrentRssProviderStr.split('|') curURL = config.clean_url(curURL) - newProvider = rsstorrent.TorrentRssProvider(curName, curURL) + newProvider = rsstorrent.TorrentRssProvider(curName, curURL, curCookies) curID = newProvider.getID() @@ -1522,6 +1523,7 @@ class ConfigProviders: if curID in torrentRssProviderDict: torrentRssProviderDict[curID].name = curName torrentRssProviderDict[curID].url = curURL + torrentRssProviderDict[curID].cookies = curCookies else: sickbeard.torrentRssProviderList.append(newProvider)