NZB Provider cleanup

This commit is contained in:
Ruud committed 2012-12-23 02:48:36 +01:00
1 parent 439cda8b63
commit 0d2dcff7f0
10 files changed
+255 -431

No files matched your search

+2 -2
View File
@@ -105,14 +105,14 @@ def fireEvent(name, *args, **kwargs):
# Merge # Merge
if options['merge'] and len(results) > 0: if options['merge'] and len(results) > 0:
# Dict # Dict
if type(results[0]) == dict: if isinstance(results[0], dict):
merged = {} merged = {}
for result in results: for result in results:
merged = mergeDicts(merged, result) merged = mergeDicts(merged, result)
results = merged results = merged
# Lists # Lists
elif type(results[0]) == list: elif isinstance(results[0], list):
merged = [] merged = []
for result in results: for result in results:
merged += result merged += result
+1 -1
View File
@@ -363,7 +363,7 @@ class Searcher(Plugin):
return True return True
# Check if nzb contains imdb link # Check if nzb contains imdb link
if self.checkIMDB([nzb['description']], movie['library']['identifier']): if self.checkIMDB([nzb.get('description', '')], movie['library']['identifier']):
return True return True
for raw_title in movie['library']['titles']: for raw_title in movie['library']['titles']:
+92 -25
View File
@@ -1,15 +1,16 @@
from couchpotato.core.event import addEvent from couchpotato.core.event import addEvent, fireEvent
from couchpotato.core.helpers.encoding import simplifyString from couchpotato.core.helpers.variable import tryFloat, mergeDicts, md5
from couchpotato.core.helpers.variable import tryFloat, getTitle
from couchpotato.core.logger import CPLog from couchpotato.core.logger import CPLog
from couchpotato.core.plugins.base import Plugin from couchpotato.core.plugins.base import Plugin
from couchpotato.environment import Env from couchpotato.environment import Env
from urlparse import urlparse from urlparse import urlparse
import cookielib import cookielib
import json
import re import re
import time import time
import traceback import traceback
import urllib2 import urllib2
import xml.etree.ElementTree as XMLTree
log = CPLog(__name__) log = CPLog(__name__)
@@ -59,8 +60,6 @@ class YarrProvider(Provider):
addEvent('%s.search' % self.type, self.search) addEvent('%s.search' % self.type, self.search)
addEvent('yarr.search', self.search) addEvent('yarr.search', self.search)
addEvent('nzb.feed', self.feed)
def login(self): def login(self):
try: try:
@@ -97,9 +96,6 @@ class YarrProvider(Provider):
return 'try_next' return 'try_next'
def feed(self):
return []
def search(self, movie, quality): def search(self, movie, quality):
return [] return []
@@ -149,22 +145,93 @@ class YarrProvider(Provider):
return [self.cat_backup_id] return [self.cat_backup_id]
def found(self, new): def getJsonData(self, url, **kwargs):
if not new.get('provider_extra'):
new['provider_extra'] = '' data = self.getCache(md5(url), url, **kwargs)
if data:
try:
return json.loads(data)
except:
log.error('Failed to parsing %s: %s', (self.getName(), traceback.format_exc()))
return []
def getRSSData(self, url, **kwargs):
data = self.getCache(md5(url), url, **kwargs)
if data:
try:
data = XMLTree.fromstring(data)
return self.getElements(data, 'channel/item')
except:
log.error('Failed to parsing %s: %s', (self.getName(), traceback.format_exc()))
return []
def getHTMLData(self, url, **kwargs):
return self.getCache(md5(url), url, **kwargs)
class ResultList(list):
result_ids = None
provider = None
movie = None
quality = None
def __init__(self, provider, movie, quality, **kwargs):
self.result_ids = []
self.provider = provider
self.movie = movie
self.quality = quality
self.kwargs = kwargs
super(ResultList, self).__init__()
def extend(self, results):
for r in results:
self.append(r)
def append(self, result):
new_result = self.fillResult(result)
is_correct_movie = fireEvent('searcher.correct_movie',
nzb = new_result, movie = self.movie, quality = self.quality,
imdb_results = self.kwargs.get('imdb_results', False), single = True)
if is_correct_movie and new_result['id'] not in self.result_ids:
new_result['score'] += fireEvent('score.calculate', new_result, self.movie, single = True)
self.found(new_result)
self.result_ids.append(result['id'])
super(ResultList, self).append(new_result)
def fillResult(self, result):
defaults = {
'id': 0,
'type': self.provider.type,
'provider': self.provider.getName(),
'download': self.provider.download,
'url': '',
'name': '',
'age': 0,
'size': 0,
'description': '',
'score': 0
}
return mergeDicts(defaults, result)
def found(self, new_result):
if not new_result.get('provider_extra'):
new_result['provider_extra'] = ''
else: else:
new['provider_extra'] = ', %s' % new['provider_extra'] new_result['provider_extra'] = ', %s' % new_result['provider_extra']
log.info('Found: score(%(score)s) on %(provider)s%(provider_extra)s: %(name)s', new) log.info('Found: score(%(score)s) on %(provider)s%(provider_extra)s: %(name)s', new_result)
def removeDuplicateResults(self, results):
result_ids = []
new_results = []
for result in results:
if result['id'] not in result_ids:
new_results.append(result)
result_ids.append(result['id'])
return new_results
+13 -26
View File
@@ -1,8 +1,8 @@
from bs4 import BeautifulSoup from bs4 import BeautifulSoup
from couchpotato.core.event import fireEvent
from couchpotato.core.helpers.encoding import toUnicode, tryUrlencode from couchpotato.core.helpers.encoding import toUnicode, tryUrlencode
from couchpotato.core.helpers.variable import tryInt, possibleTitles, getTitle from couchpotato.core.helpers.variable import tryInt, possibleTitles, getTitle
from couchpotato.core.logger import CPLog from couchpotato.core.logger import CPLog
from couchpotato.core.providers.base import ResultList
from couchpotato.core.providers.nzb.base import NZBProvider from couchpotato.core.providers.nzb.base import NZBProvider
from couchpotato.environment import Env from couchpotato.environment import Env
from dateutil.parser import parse from dateutil.parser import parse
@@ -35,18 +35,17 @@ class FTDWorld(NZBProvider):
if self.isDisabled(): if self.isDisabled():
return [] return []
results = [] results = ResultList(self, movie, quality)
for title in possibleTitles(getTitle(movie['library'])): for title in possibleTitles(getTitle(movie['library'])):
results.extend(self._search(title, movie, quality)) results.extend(self._search(title, movie, quality))
return self.removeDuplicateResults(results) return results
def _search(self, title, movie, quality): def _search(self, title, movie, quality):
results = []
q = '"%s" %s' % (title, movie['library']['year']) q = '"%s" %s' % (title, movie['library']['year'])
params = { params = tryUrlencode({
'ctitle': q, 'ctitle': q,
'customQuery': 'usr', 'customQuery': 'usr',
'cage': Env.setting('retention', 'nzb'), 'cage': Env.setting('retention', 'nzb'),
@@ -54,10 +53,9 @@ class FTDWorld(NZBProvider):
'csizemax': quality.get('size_max'), 'csizemax': quality.get('size_max'),
'ccategory': 14, 'ccategory': 14,
'ctype': ','.join([str(x) for x in self.getCatId(quality['identifier'])]), 'ctype': ','.join([str(x) for x in self.getCatId(quality['identifier'])]),
} })
cache_key = 'ftdworld.%s.%s' % (movie['library']['identifier'], q) data = self.getHTMLData(self.urls['search'] % params, opener = self.login_opener)
data = self.getCache(cache_key, self.urls['search'] % tryUrlencode(params), opener = self.login_opener)
if data: if data:
try: try:
@@ -66,8 +64,9 @@ class FTDWorld(NZBProvider):
main_table = html.find('table', attrs = {'id':'ftdresult'}) main_table = html.find('table', attrs = {'id':'ftdresult'})
if not main_table: if not main_table:
return results return []
results = ResultList(self, movie, quality)
items = main_table.find_all('tr', attrs = {'class': re.compile('tcontent')}) items = main_table.find_all('tr', attrs = {'class': re.compile('tcontent')})
for item in items: for item in items:
@@ -77,32 +76,20 @@ class FTDWorld(NZBProvider):
up = item.find('img', attrs = {'src': re.compile('up.png')}) up = item.find('img', attrs = {'src': re.compile('up.png')})
down = item.find('img', attrs = {'src': re.compile('down.png')}) down = item.find('img', attrs = {'src': re.compile('down.png')})
new = { results.append({
'id': nzb_id, 'id': nzb_id,
'type': 'nzb',
'provider': self.getName(),
'name': toUnicode(item.find('a', attrs = {'href': re.compile('./spotinfo')}).text.strip()), 'name': toUnicode(item.find('a', attrs = {'href': re.compile('./spotinfo')}).text.strip()),
'age': self.calculateAge(int(time.mktime(parse(tds[2].text).timetuple()))), 'age': self.calculateAge(int(time.mktime(parse(tds[2].text).timetuple()))),
'size': 0,
'url': self.urls['download'] % nzb_id, 'url': self.urls['download'] % nzb_id,
'download': self.loginDownload, 'download': self.loginDownload,
'detail_url': self.urls['detail'] % nzb_id, 'detail_url': self.urls['detail'] % nzb_id,
'description': '',
'score': (tryInt(up.attrs['title'].split(' ')[0]) * 3) - (tryInt(down.attrs['title'].split(' ')[0]) * 3) if up else 0, 'score': (tryInt(up.attrs['title'].split(' ')[0]) * 3) - (tryInt(down.attrs['title'].split(' ')[0]) * 3) if up else 0,
} })
is_correct_movie = fireEvent('searcher.correct_movie',
nzb = new, movie = movie, quality = quality,
imdb_results = False, single = True)
if is_correct_movie:
new['score'] += fireEvent('score.calculate', new, movie, single = True)
results.append(new)
self.found(new)
return results return results
except SyntaxError:
log.error('Failed to parse XML response from NZBClub') except:
log.error('Failed to parse HTML response from FTDWorld')
return results return results
+27 -97
View File
@@ -1,8 +1,8 @@
from couchpotato.core.event import fireEvent
from couchpotato.core.helpers.encoding import tryUrlencode from couchpotato.core.helpers.encoding import tryUrlencode
from couchpotato.core.helpers.rss import RSS from couchpotato.core.helpers.rss import RSS
from couchpotato.core.helpers.variable import cleanHost, splitString from couchpotato.core.helpers.variable import cleanHost, splitString
from couchpotato.core.logger import CPLog from couchpotato.core.logger import CPLog
from couchpotato.core.providers.base import ResultList
from couchpotato.core.providers.nzb.base import NZBProvider from couchpotato.core.providers.nzb.base import NZBProvider
from couchpotato.environment import Env from couchpotato.environment import Env
from dateutil.parser import parse from dateutil.parser import parse
@@ -10,7 +10,6 @@ from urllib2 import HTTPError
from urlparse import urlparse from urlparse import urlparse
import time import time
import traceback import traceback
import xml.etree.ElementTree as XMLTree
log = CPLog(__name__) log = CPLog(__name__)
@@ -29,38 +28,6 @@ class Newznab(NZBProvider, RSS):
http_time_between_calls = 1 # Seconds http_time_between_calls = 1 # Seconds
def feed(self):
hosts = self.getHosts()
results = []
for host in hosts:
result = self.singleFeed(host)
if result:
results.extend(result)
return results
def singleFeed(self, host):
results = []
if self.isDisabled(host):
return results
arguments = tryUrlencode({
't': self.cat_backup_id,
'r': host['api_key'],
'i': 58,
})
url = '%s?%s' % (cleanHost(host['host']) + 'rss', arguments)
cache_key = 'newznab.%s.feed.%s' % (host['host'], arguments)
results = self.createItems(url, cache_key, host, for_feed = True)
return results
def search(self, movie, quality): def search(self, movie, quality):
hosts = self.getHosts() hosts = self.getHosts()
@@ -76,9 +43,10 @@ class Newznab(NZBProvider, RSS):
def singleSearch(self, host, movie, quality): def singleSearch(self, host, movie, quality):
results = []
if self.isDisabled(host): if self.isDisabled(host):
return results return []
results = ResultList(self, movie, quality, imdb_result = True)
cat_id = self.getCatId(quality['identifier']) cat_id = self.getCatId(quality['identifier'])
arguments = tryUrlencode({ arguments = tryUrlencode({
@@ -89,73 +57,35 @@ class Newznab(NZBProvider, RSS):
}) })
url = '%s&%s' % (self.getUrl(host['host'], self.urls['search']), arguments) url = '%s&%s' % (self.getUrl(host['host'], self.urls['search']), arguments)
cache_key = 'newznab.%s.%s.%s' % (host['host'], movie['library']['identifier'], cat_id) nzbs = self.getRSSData(url, cache_timeout = 1800, headers = {'User-Agent': Env.getIdentifier()})
results = self.createItems(url, cache_key, host, movie = movie, quality = quality) for nzb in nzbs:
return results date = None
for item in nzb:
if item.attrib.get('name') == 'usenetdate':
date = item.attrib.get('value')
break
def createItems(self, url, cache_key, host, movie = None, quality = None, for_feed = False): if not date:
results = [] date = self.getTextElement(nzb, 'pubDate')
data = self.getCache(cache_key, url, cache_timeout = 1800, headers = {'User-Agent': Env.getIdentifier()}) nzb_id = self.getTextElement(nzb, 'guid').split('/')[-1:].pop()
if data: name = self.getTextElement(nzb, 'title')
try:
try:
data = XMLTree.fromstring(data)
nzbs = self.getElements(data, 'channel/item')
except Exception, e:
log.debug('%s, %s', (self.getName(), e))
return results
results = [] if not name:
for nzb in nzbs: continue
date = None results.append({
for item in nzb: 'id': nzb_id,
if item.attrib.get('name') == 'usenetdate': 'provider_extra': host['host'],
date = item.attrib.get('value') 'name': self.getTextElement(nzb, 'title'),
break 'age': self.calculateAge(int(time.mktime(parse(date).timetuple()))),
'size': int(self.getElement(nzb, 'enclosure').attrib['length']) / 1024 / 1024,
if not date: 'url': (self.getUrl(host['host'], self.urls['download']) % nzb_id) + self.getApiExt(host),
date = self.getTextElement(nzb, 'pubDate') 'detail_url': '%sdetails/%s' % (cleanHost(host['host']), nzb_id),
'content': self.getTextElement(nzb, 'description'),
nzb_id = self.getTextElement(nzb, 'guid').split('/')[-1:].pop() })
name = self.getTextElement(nzb, 'title')
if not name:
continue
new = {
'id': nzb_id,
'provider': self.getName(),
'provider_extra': host['host'],
'type': 'nzb',
'name': self.getTextElement(nzb, 'title'),
'age': self.calculateAge(int(time.mktime(parse(date).timetuple()))),
'size': int(self.getElement(nzb, 'enclosure').attrib['length']) / 1024 / 1024,
'url': (self.getUrl(host['host'], self.urls['download']) % nzb_id) + self.getApiExt(host),
'download': self.download,
'detail_url': '%sdetails/%s' % (cleanHost(host['host']), nzb_id),
'content': self.getTextElement(nzb, 'description'),
}
if not for_feed:
is_correct_movie = fireEvent('searcher.correct_movie',
nzb = new, movie = movie, quality = quality,
imdb_results = True, single = True)
if is_correct_movie:
new['score'] = fireEvent('score.calculate', new, movie, single = True)
results.append(new)
self.found(new)
else:
results.append(new)
return results
except SyntaxError:
log.error('Failed to parse XML response from Newznab: %s', host)
return results
def getHosts(self): def getHosts(self):
+29 -55
View File
@@ -1,13 +1,12 @@
from bs4 import BeautifulSoup from bs4 import BeautifulSoup
from couchpotato.core.event import fireEvent
from couchpotato.core.helpers.encoding import toUnicode, tryUrlencode from couchpotato.core.helpers.encoding import toUnicode, tryUrlencode
from couchpotato.core.helpers.rss import RSS from couchpotato.core.helpers.rss import RSS
from couchpotato.core.helpers.variable import tryInt, getTitle, possibleTitles from couchpotato.core.helpers.variable import tryInt, getTitle, possibleTitles
from couchpotato.core.logger import CPLog from couchpotato.core.logger import CPLog
from couchpotato.core.providers.base import ResultList
from couchpotato.core.providers.nzb.base import NZBProvider from couchpotato.core.providers.nzb.base import NZBProvider
from dateutil.parser import parse from dateutil.parser import parse
import time import time
import xml.etree.ElementTree as XMLTree
log = CPLog(__name__) log = CPLog(__name__)
@@ -25,81 +24,56 @@ class NZBClub(NZBProvider, RSS):
if self.isDisabled(): if self.isDisabled():
return [] return []
results = [] results = ResultList(self, movie, quality)
for title in possibleTitles(getTitle(movie['library'])): for title in possibleTitles(getTitle(movie['library'])):
results.extend(self._search(title, movie, quality)) results.extend(self._search(title, movie, quality))
return self.removeDuplicateResults(results) return results
def _search(self, title, movie, quality): def _search(self, title, movie, quality):
results = [] results = []
q = '"%s %s" %s' % (title, movie['library']['year'], quality.get('identifier')) q = '"%s %s" %s' % (title, movie['library']['year'], quality.get('identifier'))
params = { params = tryUrlencode({
'q': q, 'q': q,
'ig': '1', 'ig': '1',
'rpp': 200, 'rpp': 200,
'st': 1, 'st': 1,
'sp': 1, 'sp': 1,
'ns': 1, 'ns': 1,
} })
cache_key = 'nzbclub.%s.%s.%s' % (movie['library']['identifier'], quality.get('identifier'), q) nzbs = self.getRSSData(self.urls['search'] % params)
data = self.getCache(cache_key, self.urls['search'] % tryUrlencode(params))
if data:
try:
try:
data = XMLTree.fromstring(data)
nzbs = self.getElements(data, 'channel/item')
except Exception, e:
log.debug('%s, %s', (self.getName(), e))
return results
for nzb in nzbs: for nzb in nzbs:
nzbclub_id = tryInt(self.getTextElement(nzb, "link").split('/nzb_view/')[1].split('/')[0]) nzbclub_id = tryInt(self.getTextElement(nzb, "link").split('/nzb_view/')[1].split('/')[0])
enclosure = self.getElement(nzb, "enclosure").attrib enclosure = self.getElement(nzb, "enclosure").attrib
size = enclosure['length'] size = enclosure['length']
date = self.getTextElement(nzb, "pubDate") date = self.getTextElement(nzb, "pubDate")
def extra_check(item): def extra_check(item):
full_description = self.getCache('nzbclub.%s' % nzbclub_id, item['detail_url'], cache_timeout = 25920000) full_description = self.getCache('nzbclub.%s' % nzbclub_id, item['detail_url'], cache_timeout = 25920000)
for ignored in ['ARCHIVE inside ARCHIVE', 'Incomplete', 'repair impossible']: for ignored in ['ARCHIVE inside ARCHIVE', 'Incomplete', 'repair impossible']:
if ignored in full_description: if ignored in full_description:
log.info('Wrong: Seems to be passworded or corrupted files: %s', new['name']) log.info('Wrong: Seems to be passworded or corrupted files: %s', item['name'])
return False return False
return True return True
new = { results.append({
'id': nzbclub_id, 'id': nzbclub_id,
'type': 'nzb', 'name': toUnicode(self.getTextElement(nzb, "title")),
'provider': self.getName(), 'age': self.calculateAge(int(time.mktime(parse(date).timetuple()))),
'name': toUnicode(self.getTextElement(nzb, "title")), 'size': tryInt(size) / 1024 / 1024,
'age': self.calculateAge(int(time.mktime(parse(date).timetuple()))), 'url': enclosure['url'].replace(' ', '_'),
'size': tryInt(size) / 1024 / 1024, 'detail_url': self.getTextElement(nzb, "link"),
'url': enclosure['url'].replace(' ', '_'), 'get_more_info': self.getMoreInfo,
'download': self.download, 'extra_check': extra_check
'detail_url': self.getTextElement(nzb, "link"), })
'description': '',
'get_more_info': self.getMoreInfo,
'extra_check': extra_check
}
is_correct_movie = fireEvent('searcher.correct_movie',
nzb = new, movie = movie, quality = quality,
imdb_results = False, single = True)
if is_correct_movie:
new['score'] = fireEvent('score.calculate', new, movie, single = True)
results.append(new)
self.found(new)
return results
except SyntaxError:
log.error('Failed to parse XML response from NZBClub')
return results return results
+32 -64
View File
@@ -1,16 +1,14 @@
from bs4 import BeautifulSoup from bs4 import BeautifulSoup
from couchpotato.core.event import fireEvent
from couchpotato.core.helpers.encoding import toUnicode, tryUrlencode from couchpotato.core.helpers.encoding import toUnicode, tryUrlencode
from couchpotato.core.helpers.rss import RSS from couchpotato.core.helpers.rss import RSS
from couchpotato.core.helpers.variable import tryInt, getTitle, possibleTitles from couchpotato.core.helpers.variable import tryInt, getTitle, possibleTitles
from couchpotato.core.logger import CPLog from couchpotato.core.logger import CPLog
from couchpotato.core.providers.base import ResultList
from couchpotato.core.providers.nzb.base import NZBProvider from couchpotato.core.providers.nzb.base import NZBProvider
from couchpotato.environment import Env from couchpotato.environment import Env
from dateutil.parser import parse from dateutil.parser import parse
import re import re
import time import time
import traceback
import xml.etree.ElementTree as XMLTree
log = CPLog(__name__) log = CPLog(__name__)
@@ -19,7 +17,7 @@ class NzbIndex(NZBProvider, RSS):
urls = { urls = {
'download': 'https://www.nzbindex.com/download/', 'download': 'https://www.nzbindex.com/download/',
'api': 'https://www.nzbindex.com/rss/', 'search': 'https://www.nzbindex.com/rss/?%s',
} }
http_time_between_calls = 1 # Seconds http_time_between_calls = 1 # Seconds
@@ -29,13 +27,14 @@ class NzbIndex(NZBProvider, RSS):
if self.isDisabled(): if self.isDisabled():
return [] return []
results = [] results = ResultList(self, movie, quality)
for title in possibleTitles(getTitle(movie['library'])): for title in possibleTitles(getTitle(movie['library'])):
results.extend(self._search(title, movie, quality)) results.extend(self._search(title, movie, quality))
return self.removeDuplicateResults(results) return results
def _search(self, title, movie, quality): def _search(self, title, movie, quality):
results = [] results = []
q = '"%s" %s %s' % (title, movie['library']['year'], quality.get('identifier')) q = '"%s" %s %s' % (title, movie['library']['year'], quality.get('identifier'))
@@ -50,66 +49,37 @@ class NzbIndex(NZBProvider, RSS):
'more': 1, 'more': 1,
'complete': 1, 'complete': 1,
}) })
url = "%s?%s" % (self.urls['api'], arguments)
cache_key = 'nzbindex.%s.%s' % (movie['library']['identifier'], q) nzbs = self.getRSSData(self.urls['search'] % arguments)
data = self.getCache(cache_key, url)
for nzb in nzbs:
enclosure = self.getElement(nzb, 'enclosure').attrib
nzbindex_id = int(self.getTextElement(nzb, "link").split('/')[4])
if data:
try: try:
try: description = self.getTextElement(nzb, "description")
data = XMLTree.fromstring(data)
nzbs = self.getElements(data, 'channel/item')
except Exception, e:
log.debug('%s, %s', (self.getName(), e))
return results
for nzb in nzbs:
enclosure = self.getElement(nzb, 'enclosure').attrib
nzbindex_id = int(self.getTextElement(nzb, "link").split('/')[4])
try:
description = self.getTextElement(nzb, "description")
except:
description = ''
def extra_check(new):
if '#c20000' in new['description'].lower():
log.info('Wrong: Seems to be passworded: %s', new['name'])
return False
return True
new = {
'id': nzbindex_id,
'type': 'nzb',
'provider': self.getName(),
'download': self.download,
'name': self.getTextElement(nzb, "title"),
'age': self.calculateAge(int(time.mktime(parse(self.getTextElement(nzb, "pubDate")).timetuple()))),
'size': tryInt(enclosure['length']) / 1024 / 1024,
'url': enclosure['url'],
'detail_url': enclosure['url'].replace('/download/', '/release/'),
'description': description,
'get_more_info': self.getMoreInfo,
'extra_check': extra_check,
'check_nzb': True,
}
is_correct_movie = fireEvent('searcher.correct_movie',
nzb = new, movie = movie, quality = quality,
imdb_results = False, single = True)
if is_correct_movie:
new['score'] = fireEvent('score.calculate', new, movie, single = True)
results.append(new)
self.found(new)
return results
except: except:
log.error('Failed to parsing %s: %s', (self.getName(), traceback.format_exc())) description = ''
def extra_check(item):
if '#c20000' in item['description'].lower():
log.info('Wrong: Seems to be passworded: %s', item['name'])
return False
return True
results.append({
'id': nzbindex_id,
'name': self.getTextElement(nzb, "title"),
'age': self.calculateAge(int(time.mktime(parse(self.getTextElement(nzb, "pubDate")).timetuple()))),
'size': tryInt(enclosure['length']) / 1024 / 1024,
'url': enclosure['url'],
'detail_url': enclosure['url'].replace('/download/', '/release/'),
'description': description,
'get_more_info': self.getMoreInfo,
'extra_check': extra_check,
})
return results return results
@@ -123,5 +93,3 @@ class NzbIndex(NZBProvider, RSS):
except: except:
pass pass
def isEnabled(self):
return NZBProvider.isEnabled(self) and self.conf('enabled')
+22 -52
View File
@@ -1,11 +1,10 @@
from couchpotato.core.event import fireEvent
from couchpotato.core.helpers.encoding import tryUrlencode from couchpotato.core.helpers.encoding import tryUrlencode
from couchpotato.core.helpers.rss import RSS from couchpotato.core.helpers.rss import RSS
from couchpotato.core.logger import CPLog from couchpotato.core.logger import CPLog
from couchpotato.core.providers.base import ResultList
from couchpotato.core.providers.nzb.base import NZBProvider from couchpotato.core.providers.nzb.base import NZBProvider
from couchpotato.environment import Env from couchpotato.environment import Env
import time import time
import xml.etree.ElementTree as XMLTree
log = CPLog(__name__) log = CPLog(__name__)
@@ -25,13 +24,12 @@ class Nzbsrus(NZBProvider, RSS):
def search(self, movie, quality): def search(self, movie, quality):
results = []
if self.isDisabled(): if self.isDisabled():
return results return []
results = ResultList(self, movie, quality, imdb_result = True)
cat_id_string = '&'.join(['c%s=1' % x for x in self.getCatId(quality.get('identifier'))]) cat_id_string = '&'.join(['c%s=1' % x for x in self.getCatId(quality.get('identifier'))])
arguments = tryUrlencode({ arguments = tryUrlencode({
'searchtext': 'imdb:' + movie['library']['identifier'][2:], 'searchtext': 'imdb:' + movie['library']['identifier'][2:],
'uid': self.conf('userid'), 'uid': self.conf('userid'),
@@ -42,57 +40,29 @@ class Nzbsrus(NZBProvider, RSS):
# check for english_only # check for english_only
if self.conf('english_only'): if self.conf('english_only'):
arguments += "&lang0=1&lang3=1&lang1=1" arguments += '&lang0=1&lang3=1&lang1=1'
url = "%s&%s&%s" % (self.urls['search'], arguments , cat_id_string) url = '%s&%s&%s' % (self.urls['search'], arguments , cat_id_string)
nzbs = self.getRSSData(url, cache_timeout = 1800, headers = {'User-Agent': Env.getIdentifier()})
cache_key = 'nzbsrus.%s.%s' % (movie['library'].get('identifier'), cat_id_string) for nzb in nzbs:
data = self.getCache(cache_key, url, cache_timeout = 1800, headers = {'User-Agent': Env.getIdentifier()}) title = self.getTextElement(nzb, 'name')
if data: if 'error' in title.lower(): continue
try:
try:
data = XMLTree.fromstring(data)
nzbs = self.getElements(data, 'results/result')
except Exception, e:
log.debug('%s, %s', (self.getName(), e))
return results
for nzb in nzbs: nzb_id = self.getTextElement(nzb, 'id')
size = int(round(int(self.getTextElement(nzb, 'size')) / 1048576))
age = int(round((time.time() - int(self.getTextElement(nzb, 'postdate'))) / 86400))
title = self.getTextElement(nzb, "name") results.append({
if 'error' in title.lower(): continue 'id': nzb_id,
'name': title,
id = self.getTextElement(nzb, "id") 'age': age,
size = int(round(int(self.getTextElement(nzb, "size")) / 1048576)) 'size': size,
age = int(round((time.time() - int(self.getTextElement(nzb, "postdate"))) / 86400)) 'url': self.urls['download'] % id + self.getApiExt() + self.getTextElement(nzb, 'key'),
'detail_url': self.urls['detail'] % nzb_id,
new = { 'description': self.getTextElement(nzb, 'addtext'),
'id': id, })
'type': 'nzb',
'provider': self.getName(),
'name': title,
'age': age,
'size': size,
'url': self.urls['download'] % id + self.getApiExt() + self.getTextElement(nzb, "key"),
'download': self.download,
'detail_url': self.urls['detail'] % id,
'description': self.getTextElement(nzb, "addtext"),
'check_nzb': True,
}
is_correct_movie = fireEvent('searcher.correct_movie',
nzb = new, movie = movie, quality = quality,
imdb_results = True, single = True)
if is_correct_movie:
new['score'] = fireEvent('score.calculate', new, movie, single = True)
results.append(new)
self.found(new)
return results
except SyntaxError:
log.error('Failed to parse XML response from Nzbsrus.com')
return results return results
+18 -64
View File
@@ -1,91 +1,45 @@
from couchpotato.core.event import fireEvent
from couchpotato.core.helpers.encoding import tryUrlencode from couchpotato.core.helpers.encoding import tryUrlencode
from couchpotato.core.helpers.rss import RSS
from couchpotato.core.helpers.variable import tryInt from couchpotato.core.helpers.variable import tryInt
from couchpotato.core.logger import CPLog from couchpotato.core.logger import CPLog
from couchpotato.core.providers.base import ResultList
from couchpotato.core.providers.nzb.base import NZBProvider from couchpotato.core.providers.nzb.base import NZBProvider
import json
import traceback
log = CPLog(__name__) log = CPLog(__name__)
class Nzbx(NZBProvider, RSS): class Nzbx(NZBProvider):
endpoint = 'https://nzbx.co/api/'
urls = { urls = {
'search': 'https://nzbx.co/api/search', 'search': 'https://nzbx.co/api/search?%s',
'details': 'https://nzbx.co/api/details?guid=%s', 'details': 'https://nzbx.co/api/details?guid=%s',
'comments': 'https://nzbx.co/api/get-comments?guid=%s',
'ratings': 'https://nzbx.co/api/get-votes?guid=%s',
'downloads': 'https://nzbx.co/api/get-downloads-count?guid=%s',
'categories': 'https://nzbx.co/api/categories',
'groups': 'https://nzbx.co/api/groups',
} }
http_time_between_calls = 1 # Seconds http_time_between_calls = 1 # Seconds
def search(self, movie, quality): def search(self, movie, quality):
results = []
if self.isDisabled(): if self.isDisabled():
return results return []
results = ResultList(self, movie, quality, imdb_result = True)
# Get nbzs
arguments = tryUrlencode({ arguments = tryUrlencode({
'q': movie['library']['identifier'].replace('tt', ''), 'q': movie['library']['identifier'].replace('tt', ''),
'sf': quality.get('size_min'), 'sf': quality.get('size_min'),
}) })
url = "%s?%s" % (self.urls['search'], arguments) nzbs = self.getJsonData(self.urls['search'] % arguments)
cache_key = 'nzbx.%s.%s' % (movie['library']['identifier'], quality.get('identifier')) for nzb in nzbs:
data = self.getCache(cache_key, url) results.append({
'id': nzb['guid'],
if data: 'url': nzb['nzb'],
try: 'detail_url': self.urls['details'] % nzb['guid'],
try: 'name': nzb['name'],
nzbs = json.loads(data) 'age': self.calculateAge(int(nzb['postdate'])),
except Exception, e: 'size': tryInt(nzb['size']) / 1024 / 1024,
log.debug('%s, %s', (self.getName(), e)) 'score': 5 if nzb['votes']['upvotes'] > nzb['votes']['downvotes'] else 0
return results })
for nzb in nzbs:
nzbx_guid = nzb['guid']
def extra_score(item):
score = 0
if item['votes']['upvotes'] > item['votes']['downvotes']:
score += 5
return score
new = {
'guid': nzbx_guid,
'type': 'nzb',
'provider': self.getName(),
'download': self.download,
'url': nzb['nzb'],
'name': nzb['name'],
'age': self.calculateAge(int(nzb['postdate'])),
'size': tryInt(nzb['size']) / 1024 / 1024,
'description': '',
'extra_score': extra_score,
'votes': nzb['votes'],
'check_nzb': True,
}
is_correct_movie = fireEvent('searcher.correct_movie',
nzb = new, movie = movie, quality = quality,
imdb_results = False, single = True)
if is_correct_movie:
new['score'] = fireEvent('score.calculate', new, movie, single = True)
results.append(new)
self.found(new)
return results
except:
log.error('Failed to parsing %s: %s', (self.getName(), traceback.format_exc()))
return results return results
@@ -4,6 +4,7 @@ from couchpotato.core.helpers.encoding import toUnicode, tryUrlencode
from couchpotato.core.helpers.rss import RSS from couchpotato.core.helpers.rss import RSS
from couchpotato.core.helpers.variable import tryInt, getTitle, possibleTitles from couchpotato.core.helpers.variable import tryInt, getTitle, possibleTitles
from couchpotato.core.logger import CPLog from couchpotato.core.logger import CPLog
from couchpotato.core.providers.base import ResultList
from couchpotato.core.providers.nzb.base import NZBProvider from couchpotato.core.providers.nzb.base import NZBProvider
from dateutil.parser import parse from dateutil.parser import parse
from urlparse import urlparse, parse_qs from urlparse import urlparse, parse_qs
@@ -35,66 +36,39 @@ class OMGWTFNZBs(NZBProvider, RSS):
if self.isDisabled() or quality['identifier'] in pre_releases: if self.isDisabled() or quality['identifier'] in pre_releases:
return [] return []
results = [] results = ResultList(self, movie, quality)
for title in possibleTitles(getTitle(movie['library'])): for title in possibleTitles(getTitle(movie['library'])):
results.extend(self._search(title, movie, quality)) results.extend(self._search(title, movie, quality))
return self.removeDuplicateResults(results) return results
def _search(self, title, movie, quality): def _search(self, title, movie, quality):
results = [] results = []
q = '%s %s' % (title, movie['library']['year']) q = '%s %s' % (title, movie['library']['year'])
params = tryUrlencode({
params = {
'search': q, 'search': q,
'catid': ','.join([str(x) for x in self.getCatId(quality['identifier'])]), 'catid': ','.join([str(x) for x in self.getCatId(quality['identifier'])]),
'user': self.conf('username', default = ''), 'user': self.conf('username', default = ''),
'api': self.conf('api_key', default = ''), 'api': self.conf('api_key', default = ''),
} })
cache_key = 'omgwtfnzbs.%s.%s' % (movie['library']['identifier'], q) nzbs = self.getRSSData(self.urls['search'] % params)
data = self.getCache(cache_key, self.urls['search'] % tryUrlencode(params))
if data:
try:
try:
data = XMLTree.fromstring(data)
nzbs = self.getElements(data, 'channel/item')
except Exception, e:
log.debug('%s, %s', (self.getName(), e))
return results
for nzb in nzbs: for nzb in nzbs:
nzb_id = parse_qs(urlparse(self.getTextElement(nzb, "link")).query).get('id')[0] nzb_id = parse_qs(urlparse(self.getTextElement(nzb, 'link')).query).get('id')[0]
enclosure = self.getElement(nzb, "enclosure").attrib enclosure = self.getElement(nzb, 'enclosure').attrib
size = enclosure['length'] size = enclosure['length']
date = self.getTextElement(nzb, "pubDate")
new = { results.append({
'id': nzb_id, 'id': nzb_id,
'type': 'nzb', 'name': toUnicode(self.getTextElement(nzb, 'title')),
'provider': self.getName(), 'age': self.calculateAge(int(time.mktime(parse(self.getTextElement(nzb, 'pubDate')).timetuple()))),
'name': toUnicode(self.getTextElement(nzb, "title")), 'size': tryInt(size) / 1024 / 1024,
'age': self.calculateAge(int(time.mktime(parse(date).timetuple()))), 'url': enclosure['url'],
'size': tryInt(size) / 1024 / 1024, 'detail_url': self.getTextElement(nzb, 'link'),
'url': enclosure['url'], 'description': self.getTextElement(nzb, 'description')
'download': self.download, })
'detail_url': self.getTextElement(nzb, "link"),
'description': self.getTextElement(nzb, 'description')
}
is_correct_movie = fireEvent('searcher.correct_movie',
nzb = new, movie = movie, quality = quality,
imdb_results = False, single = True)
if is_correct_movie:
new['score'] = fireEvent('score.calculate', new, movie, single = True)
results.append(new)
self.found(new)
return results
except SyntaxError:
log.error('Failed to parse XML response from omgwtfnzbs')
return results return results