Merge pull request #582 from bikemike222/add_cookies_rss

Added cookie support to custom torrent provider
This commit is contained in:
Nils 2014-06-09 00:20:37 +02:00
commit 166dffeb5a
7 changed files with 66 additions and 34 deletions

View file

@ -34,7 +34,7 @@ var show_nzb_providers = #if $sickbeard.USE_NZBS then "true" else "false"#;
<!-- <!--
\$(document).ready(function(){ \$(document).ready(function(){
#for $curTorrentRssProvider in $sickbeard.torrentRssProviderList: #for $curTorrentRssProvider in $sickbeard.torrentRssProviderList:
\$(this).addTorrentRssProvider('$curTorrentRssProvider.getID()', '$curTorrentRssProvider.name', '$curTorrentRssProvider.url'); \$(this).addTorrentRssProvider('$curTorrentRssProvider.getID()', '$curTorrentRssProvider.name', '$curTorrentRssProvider.url', '$curTorrentRssProvider.cookies');
#end for #end for
}); });
//--> //-->
@ -591,6 +591,16 @@ var show_nzb_providers = #if $sickbeard.USE_NZBS then "true" else "false"#;
<input class="component-desc" type="text" id="torrentrss_url" size="40" /> <input class="component-desc" type="text" id="torrentrss_url" size="40" />
</label> </label>
</div> </div>
<div class="field-pair">
<label class="nocheck clearfix">
<span class="component-title">Cookies:</span>
<input class="component-desc" type="text" id="torrentrss_cookies" size="40" />
</label>
<label class="nocheck clearfix">
<span class="component-title">&nbsp;</span>
<span class="component-desc">eg. uid=xx;pass=yy</span>
</label>
</div>
<div id="torrentrss_add_div"> <div id="torrentrss_add_div">
<input type="button" class="btn torrentrss_save" id="torrentrss_add" value="Add" /> <input type="button" class="btn torrentrss_save" id="torrentrss_add" value="Add" />

View file

@ -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; torrentRssProviders[id] = newData;
$('#editATorrentRssProvider').addOption(id, name); $('#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][1] = url;
torrentRssProviders[id][2] = cookies;
$(this).populateTorrentRssSection(); $(this).populateTorrentRssSection();
$(this).makeTorrentRssProviderString(); $(this).makeTorrentRssProviderString();
} }
@ -153,7 +154,7 @@ $(document).ready(function(){
var selectedProvider = $('#editATorrentRssProvider :selected').val(); var selectedProvider = $('#editATorrentRssProvider :selected').val();
if (selectedProvider == 'addTorrentRss') { if (selectedProvider == 'addTorrentRss') {
var data = ['','','','']; var data = ['','',''];
$('#torrentrss_add_div').show(); $('#torrentrss_add_div').show();
$('#torrentrss_update_div').hide(); $('#torrentrss_update_div').hide();
} else { } else {
@ -164,19 +165,16 @@ $(document).ready(function(){
$('#torrentrss_name').val(data[0]); $('#torrentrss_name').val(data[0]);
$('#torrentrss_url').val(data[1]); $('#torrentrss_url').val(data[1]);
$('#torrentrss_uname').val(data[2]); $('#torrentrss_cookies').val(data[2]);
$('#torrentrss_passw').val(data[3]);
if (selectedProvider == 'addTorrentRss') { if (selectedProvider == 'addTorrentRss') {
$('#torrentrss_name').removeAttr("disabled"); $('#torrentrss_name').removeAttr("disabled");
$('#torrentrss_url').removeAttr("disabled"); $('#torrentrss_url').removeAttr("disabled");
$('#torrentrss_uname').removeAttr("disabled"); $('#torrentrss_cookies').removeAttr("disabled");
$('#torrentrss_passw').removeAttr("disabled");
} else { } else {
$('#torrentrss_name').attr("disabled", "disabled"); $('#torrentrss_name').attr("disabled", "disabled");
$('#torrentrss_url').removeAttr("disabled"); $('#torrentrss_url').removeAttr("disabled");
$('#torrentrss_uname').removeAttr("disabled"); $('#torrentrss_cookies').removeAttr("disabled");
$('#torrentrss_passw').removeAttr("disabled")
$('#torrentrss_delete').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(); var selectedProvider = $('#editATorrentRssProvider :selected').val();
@ -324,8 +322,9 @@ $(document).ready(function(){
return; return;
var url = $('#torrentrss_url').val(); 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 name = $('#torrentrss_name').val();
var url = $('#torrentrss_url').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 // send to the form with ajax, get a return value
$.getJSON(sbRoot + '/config/providers/canAddTorrentRssProvider', params, $.getJSON(sbRoot + '/config/providers/canAddTorrentRssProvider', params,
@ -400,7 +400,7 @@ $(document).ready(function(){
return; return;
} }
$(this).addTorrentRssProvider(data.success, name, url); $(this).addTorrentRssProvider(data.success, name, url, cookies);
}); });
}); });

View file

@ -98,7 +98,7 @@ class Cache:
del self.storage[url] del self.storage[url]
return 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. """Return the feed at url.
url - The URL of the feed. url - The URL of the feed.
@ -175,7 +175,7 @@ class Cache:
agent=self.user_agent, agent=self.user_agent,
modified=modified, modified=modified,
etag=etag, etag=etag,
) request_headers=request_headers)
status = parsed_result.get('status', None) status = parsed_result.get('status', None)
logger.debug('HTTP status=%s' % status) logger.debug('HTTP status=%s' % status)

View file

@ -139,22 +139,26 @@ def makeTorrentRssProvider(configString):
if not configString: if not configString:
return None return None
cookies = None
search_mode = 'eponly' search_mode = 'eponly'
search_fallback = 0 search_fallback = 0
backlog_only = 0 backlog_only = 0
try: 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: except ValueError:
try: try:
name, url, enabled = configString.split('|') name, url, enabled, search_mode, search_fallback, backlog_only = configString.split('|')
except ValueError: except ValueError:
logger.log(u"Skipping RSS Torrent provider string: '" + configString + "', incorrect format", logger.ERROR) try:
return None 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'] 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' newProvider.enabled = enabled == '1'
return newProvider return newProvider

View file

@ -35,7 +35,7 @@ from lib.requests import exceptions
from lib.bencode import bdecode from lib.bencode import bdecode
class TorrentRssProvider(generic.TorrentProvider): 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) generic.TorrentProvider.__init__(self, name)
self.cache = TorrentRssCache(self) self.cache = TorrentRssCache(self)
self.url = re.sub('\/$', '', url) self.url = re.sub('\/$', '', url)
@ -47,8 +47,13 @@ class TorrentRssProvider(generic.TorrentProvider):
self.search_fallback = search_fallback self.search_fallback = search_fallback
self.backlog_only = backlog_only self.backlog_only = backlog_only
if cookies:
self.cookies = cookies
else:
self.cookies = None
def configStr(self): 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): def imageName(self):
if ek.ek(os.path.isfile, ek.ek(os.path.join, sickbeard.PROG_DIR, 'data', 'images', 'providers', self.getID() + '.png')): 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): def validateRSS(self):
try: 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() data = self.cache._getRSSData()
if not data: if not data:
@ -121,6 +130,10 @@ class TorrentRssProvider(generic.TorrentProvider):
if not self.session: if not self.session:
self.session = requests.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: try:
parsed = list(urlparse.urlparse(url)) parsed = list(urlparse.urlparse(url))
parsed[2] = re.sub("/{2,}", "/", parsed[2]) # replace two or more / with one parsed[2] = re.sub("/{2,}", "/", parsed[2]) # replace two or more / with one
@ -158,9 +171,12 @@ class TorrentRssCache(tvcache.TVCache):
self.minTime = 15 self.minTime = 15
def _getRSSData(self): def _getRSSData(self):
url = self.provider.url
logger.log(u"TorrentRssCache cache update URL: " + self.provider.url, logger.DEBUG) 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): def _parseItem(self, item):

View file

@ -134,7 +134,7 @@ class TVCache():
return [] return []
def getRSSFeed(self, url, post_data=None): def getRSSFeed(self, url, post_data=None, request_headers=None):
# create provider storaqe cache # create provider storaqe cache
storage = Shove('sqlite:///' + ek.ek(os.path.join, sickbeard.CACHE_DIR, self.provider.name) + '.db') storage = Shove('sqlite:///' + ek.ek(os.path.join, sickbeard.CACHE_DIR, self.provider.name) + '.db')
fc = cache.Cache(storage) fc = cache.Cache(storage)
@ -145,7 +145,7 @@ class TVCache():
if post_data: if post_data:
url += urllib.urlencode(post_data) url += urllib.urlencode(post_data)
f = fc.fetch(url) f = fc.fetch(url, request_headers=request_headers)
if not f: if not f:
logger.log(u"Error loading " + self.providerID + " URL: " + url, logger.ERROR) logger.log(u"Error loading " + self.providerID + " URL: " + url, logger.ERROR)

View file

@ -1457,7 +1457,7 @@ class ConfigProviders:
return '1' return '1'
@cherrypy.expose @cherrypy.expose
def canAddTorrentRssProvider(self, name, url): def canAddTorrentRssProvider(self, name, url, cookies):
if not name: if not name:
return json.dumps({'error': 'Invalid name specified'}) return json.dumps({'error': 'Invalid name specified'})
@ -1465,7 +1465,7 @@ class ConfigProviders:
providerDict = dict( providerDict = dict(
zip([x.getID() for x in sickbeard.torrentRssProviderList], sickbeard.torrentRssProviderList)) 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: if tempProvider.getID() in providerDict:
return json.dumps({'error': 'Exists as ' + providerDict[tempProvider.getID()].name}) return json.dumps({'error': 'Exists as ' + providerDict[tempProvider.getID()].name})
@ -1477,7 +1477,7 @@ class ConfigProviders:
return json.dumps({'error': errMsg}) return json.dumps({'error': errMsg})
@cherrypy.expose @cherrypy.expose
def saveTorrentRssProvider(self, name, url): def saveTorrentRssProvider(self, name, url, cookies):
if not name or not url: if not name or not url:
return '0' return '0'
@ -1487,11 +1487,12 @@ class ConfigProviders:
if name in providerDict: if name in providerDict:
providerDict[name].name = name providerDict[name].name = name
providerDict[name].url = config.clean_url(url) providerDict[name].url = config.clean_url(url)
providerDict[name].cookies = cookies
return providerDict[name].getID() + '|' + providerDict[name].configStr() return providerDict[name].getID() + '|' + providerDict[name].configStr()
else: else:
newProvider = rsstorrent.TorrentRssProvider(name, url) newProvider = rsstorrent.TorrentRssProvider(name, url, cookies)
sickbeard.torrentRssProviderList.append(newProvider) sickbeard.torrentRssProviderList.append(newProvider)
return newProvider.getID() + '|' + newProvider.configStr() return newProvider.getID() + '|' + newProvider.configStr()
@ -1569,10 +1570,10 @@ class ConfigProviders:
if not curTorrentRssProviderStr: if not curTorrentRssProviderStr:
continue continue
curName, curURL = curTorrentRssProviderStr.split('|') curName, curURL, curCookies = curTorrentRssProviderStr.split('|')
curURL = config.clean_url(curURL) curURL = config.clean_url(curURL)
newProvider = rsstorrent.TorrentRssProvider(curName, curURL) newProvider = rsstorrent.TorrentRssProvider(curName, curURL, curCookies)
curID = newProvider.getID() curID = newProvider.getID()
@ -1580,6 +1581,7 @@ class ConfigProviders:
if curID in torrentRssProviderDict: if curID in torrentRssProviderDict:
torrentRssProviderDict[curID].name = curName torrentRssProviderDict[curID].name = curName
torrentRssProviderDict[curID].url = curURL torrentRssProviderDict[curID].url = curURL
torrentRssProviderDict[curID].cookies = curCookies
else: else:
sickbeard.torrentRssProviderList.append(newProvider) sickbeard.torrentRssProviderList.append(newProvider)