Providers, wizard base, core notifier base

This commit is contained in:
Ruud committed 2011-04-15 12:21:13 +02:00
1 parent 16f2d5e5f5
commit 49bf6caa52
25 files changed
+1149 -181

No files matched your search

+4
View File
@@ -20,6 +20,10 @@ class NZBProvider(Provider):
time_between_searches = 10 # Seconds
def isEnabled(self):
return True # nzb_downloaded is enabled check
class TorrentProvider(Provider):
type = 'torrent'
+131 -1
View File
@@ -1,8 +1,138 @@
from couchpotato.core.event import addEvent
from couchpotato.core.logger import CPLog
from couchpotato.core.providers.base import NZBProvider
from dateutil.parser import parse
from urllib import urlencode
from urllib2 import URLError
import time
log = CPLog(__name__)
class Newzbin(NZBProvider):
pass
searchUrl = 'https://www.newzbin.com/search/'
formatIds = {
2: ['scr'],
1: ['cam'],
4: ['tc'],
8: ['ts'],
1024: ['r5'],
}
cat_ids = [
([2097152], ['1080p']),
([524288], ['720p']),
([262144], ['brrip']),
([2], ['dvdr']),
]
cat_backup_id = -1
def __init__(self):
addEvent('provider.nzb.search', self.search)
def search(self, movie, quality):
self.cleanCache();
results = []
if not self.enabled() or not self.isAvailable(self.searchUrl):
return results
formatId = self.getFormatId(type)
catId = self.getCatId(type)
arguments = urlencode({
'searchaction': 'Search',
'u_url_posts_only': '0',
'u_show_passworded': '0',
'q_url': 'imdb.com/title/' + movie.imdb,
'sort': 'ps_totalsize',
'order': 'asc',
'u_post_results_amt': '100',
'feed': 'rss',
'category': '6',
'ps_rb_video_format': str(catId),
'ps_rb_source': str(formatId),
})
url = "%s?%s" % (self.searchUrl, arguments)
cacheId = str('%s %s %s' % (movie.imdb, str(formatId), str(catId)))
singleCat = True
try:
cached = False
if(self.cache.get(cacheId)):
data = True
cached = True
log.info('Getting RSS from cache: %s.' % cacheId)
else:
log.info('Searching: %s' % url)
data = self.urlopen(url, username = self.conf('username'), password = self.conf('password'))
self.cache[cacheId] = {
'time': time.time()
}
except (IOError, URLError):
log.error('Failed to open %s.' % url)
return results
if data:
try:
try:
if cached:
xml = self.cache[cacheId]['xml']
else:
xml = self.getItems(data)
self.cache[cacheId]['xml'] = xml
except:
log.debug('No valid xml or to many requests.. You never know with %s.' % self.name)
return results
for item in xml:
title = self.gettextelement(item, "title")
if 'error' in title.lower(): continue
REPORT_NS = 'http://www.newzbin.com/DTD/2007/feeds/report/';
# Add attributes to name
for attr in item.find('{%s}attributes' % REPORT_NS):
title += ' ' + attr.text
id = int(self.gettextelement(item, '{%s}id' % REPORT_NS))
size = str(int(self.gettextelement(item, '{%s}size' % REPORT_NS)) / 1024 / 1024) + ' mb'
date = str(self.gettextelement(item, '{%s}postdate' % REPORT_NS))
new = self.feedItem()
new.id = id
new.type = 'nzb'
new.name = title
new.date = int(time.mktime(parse(date).timetuple()))
new.size = self.parseSize(size)
new.url = str(self.gettextelement(item, '{%s}nzb' % REPORT_NS))
new.detailUrl = str(self.gettextelement(item, 'link'))
new.content = self.gettextelement(item, "description")
new.score = self.calcScore(new, movie)
new.addbyid = True
new.checkNZB = False
if new.date > time.time() - (int(self.config.get('NZB', 'retention')) * 24 * 60 * 60) and self.isCorrectMovie(new, movie, type, imdbResults = True, singleCategory = singleCat):
results.append(new)
log.info('Found: %s' % new.name)
return results
except SyntaxError:
log.error('Failed to parse XML response from newzbin.com')
return results
def getFormatId(self, format):
for id, quality in self.formatIds.iteritems():
for q in quality:
if q == format:
return id
return self.catBackupId
def isEnabled(self):
return NZBProvider.isEnabled(self) and self.conf('enabled') and self.conf('username') and self.conf('password')
@@ -17,6 +17,7 @@ config = [{
{
'name': 'host',
'default': 'http://nzb.su',
'description': 'The hostname of your newznab provider, like http://nzb.su'
},
{
'name': 'api_key',
+119 -1
View File
@@ -1,8 +1,126 @@
from couchpotato.core.event import addEvent
from couchpotato.core.helpers.variable import cleanHost
from couchpotato.core.logger import CPLog
from couchpotato.core.providers.base import NZBProvider
from dateutil.parser import parse
from urllib import urlencode
from urllib2 import URLError
import time
log = CPLog(__name__)
class Newznab(NZBProvider):
pass
urls = {
'download': 'get&id=%s%s',
'detail': 'details&id=%s',
}
cat_ids = [
([2000], ['brrip']),
([2010], ['dvdr']),
([2030], ['cam', 'ts', 'dvdrip', 'tc', 'r5', 'scr']),
([2040], ['720p', '1080p']),
]
cat_backup_id = 2000
time_between_searches = 1 # Seconds
def __init__(self):
addEvent('provider.nzb.search', self.search)
def getUrl(self, type):
return cleanHost(self.conf('host')) + 'api?t=' + type
def search(self, movie, quality):
self.cleanCache();
results = []
if not self.enabled() or not self.isAvailable(self.getUrl(self.searchUrl)):
return results
catId = self.getCatId(type)
arguments = urlencode({
'imdbid': movie.imdb.replace('tt', ''),
'cat': catId,
'apikey': self.conf('apikey'),
't': self.searchUrl,
'extended': 1
})
url = "%s&%s" % (self.getUrl(self.searchUrl), arguments)
cacheId = str(movie.imdb) + '-' + str(catId)
singleCat = (len(self.catIds.get(catId)) == 1 and catId != self.catBackupId)
try:
cached = False
if(self.cache.get(cacheId)):
data = True
cached = True
log.info('Getting RSS from cache: %s.' % cacheId)
else:
log.info('Searching: %s' % url)
data = self.urlopen(url)
self.cache[cacheId] = {
'time': time.time()
}
except (IOError, URLError):
log.error('Failed to open %s.' % url)
return results
if data:
try:
try:
if cached:
xml = self.cache[cacheId]['xml']
else:
xml = self.getItems(data)
self.cache[cacheId]['xml'] = xml
except:
log.debug('No valid xml or to many requests.' % self.name)
return results
results = []
for nzb in xml:
for item in nzb:
if item.attrib.get('name') == 'size':
size = item.attrib.get('value')
elif item.attrib.get('name') == 'usenetdate':
date = item.attrib.get('value')
new = self.feedItem()
new.id = self.gettextelement(nzb, "guid").split('/')[-1:].pop()
new.type = 'nzb'
new.name = self.gettextelement(nzb, "title")
new.date = int(time.mktime(parse(date).timetuple()))
new.size = int(size) / 1024 / 1024
new.url = self.downloadLink(new.id)
new.detailUrl = self.detailLink(new.id)
new.content = self.gettextelement(nzb, "description")
new.score = self.calcScore(new, movie)
if new.date > time.time() - (int(self.config.get('NZB', 'retention')) * 24 * 60 * 60) and self.isCorrectMovie(new, movie, type, imdbResults = True, singleCategory = singleCat):
results.append(new)
log.info('Found: %s' % new.name)
return results
except SyntaxError:
log.error('Failed to parse XML response from Newznab')
return False
return results
def isEnabled(self):
return NZBProvider.isEnabled(self) and self.conf('enabled') and self.conf('host') and self.conf('apikey')
def getApiExt(self):
return '&apikey=%s' % self.conf('apikey')
def downloadLink(self, id):
return self.getUrl(self.downloadUrl) % (id, self.getApiExt())
def detailLink(self, id):
return self.getUrl(self.detailUrl) % id
@@ -20,7 +20,7 @@ config = [{
},
{
'name': 'api_key',
'default': '9b939aee0aaafc12a65bf448e4af9543',
'default': '',
'label': 'Api Key',
},
],
@@ -1,5 +1,10 @@
from couchpotato.core.event import addEvent
from couchpotato.core.logger import CPLog
from couchpotato.core.providers.base import NZBProvider
from dateutil.parser import parse
from urllib import urlencode
from urllib2 import URLError
import time
log = CPLog(__name__)
@@ -20,12 +25,10 @@ class NZBMatrix(NZBProvider):
]
cat_backup_id = 2
def __init__(self, config):
log.info('Using NZBMatrix provider')
def __init__(self):
addEvent('provider.nzb.search', self.search)
self.config = config
def find(self, movie, quality, type, retry = False):
def search(self, movie, quality):
self.cleanCache();
@@ -113,4 +116,4 @@ class NZBMatrix(NZBProvider):
return '&username=%s&apikey=%s' % (self.conf('username'), self.conf('apikey'))
def isEnabled(self):
return self.conf('enabled') and self.conf('username') and self.conf('apikey')
return NZBProvider.isEnabled(self) and self.conf('enabled') and self.conf('username') and self.conf('apikey')
@@ -1,124 +0,0 @@
from app.config.cplog import CPLog
from app.lib.provider.yarr.base import nzbBase
from dateutil.parser import parse
from urllib import urlencode
from urllib2 import URLError
import time
log = CPLog(__name__)
class nzbMatrix(nzbBase):
"""Api for NZBMatrix"""
name = 'NZBMatrix'
downloadUrl = 'https://api.nzbmatrix.com/v1.1/download.php?id=%s%s'
detailUrl = 'https://nzbmatrix.com/nzb-details.php?id=%s&hit=1'
searchUrl = 'http://rss.nzbmatrix.com/rss.php'
catIds = {
42: ['720p', '1080p'],
2: ['cam', 'ts', 'dvdrip', 'tc', 'r5', 'scr'],
54: ['brrip'],
1: ['dvdr']
}
catBackupId = 2
timeBetween = 10 # Seconds
def __init__(self, config):
log.info('Using NZBMatrix provider')
self.config = config
def conf(self, option):
return self.config.get('NZBMatrix', option)
def enabled(self):
return self.conf('enabled') and self.config.get('NZB', 'enabled') and self.conf('username') and self.conf('apikey')
def find(self, movie, quality, type, retry = False):
self.cleanCache();
results = []
if not self.enabled() or not self.isAvailable(self.searchUrl):
return results
catId = self.getCatId(type)
arguments = urlencode({
'term': movie.imdb,
'subcat': catId,
'username': self.conf('username'),
'apikey': self.conf('apikey'),
'searchin': 'weblink',
'english': 1 if self.conf('english') else 0,
})
url = "%s?%s" % (self.searchUrl, arguments)
cacheId = str(movie.imdb) + '-' + str(catId)
singleCat = (len(self.catIds.get(catId)) == 1 and catId != self.catBackupId)
try:
cached = False
if(self.cache.get(cacheId)):
data = True
cached = True
log.info('Getting RSS from cache: %s.' % cacheId)
else:
log.info('Searching: %s' % url)
data = self.urlopen(url)
self.cache[cacheId] = {
'time': time.time()
}
except (IOError, URLError):
log.error('Failed to open %s.' % url)
return results
if data:
try:
try:
if cached:
xml = self.cache[cacheId]['xml']
else:
xml = self.getItems(data)
self.cache[cacheId]['xml'] = xml
except:
log.debug('No valid xml or to many requests.. You never know with %s.' % self.name)
return results
for nzb in xml:
title = self.gettextelement(nzb, "title")
if 'error' in title.lower(): continue
id = int(self.gettextelement(nzb, "link").split('&')[0].partition('id=')[2])
size = self.gettextelement(nzb, "description").split('<br /><b>')[2].split('> ')[1]
date = str(self.gettextelement(nzb, "description").split('<br /><b>')[3].partition('Added:</b> ')[2])
new = self.feedItem()
new.id = id
new.type = 'nzb'
new.name = title
new.date = int(time.mktime(parse(date).timetuple()))
new.size = self.parseSize(size)
new.url = self.downloadLink(id)
new.detailUrl = self.detailLink(id)
new.content = self.gettextelement(nzb, "description")
new.score = self.calcScore(new, movie)
new.checkNZB = True
if new.date > time.time() - (int(self.config.get('NZB', 'retention')) * 24 * 60 * 60):
if self.isCorrectMovie(new, movie, type, imdbResults = True, singleCategory = singleCat):
results.append(new)
log.info('Found: %s' % new.name)
else:
log.info('Found outside retention: %s' % new.name)
return results
except SyntaxError:
log.error('Failed to parse XML response from NZBMatrix.com')
return results
def getApiExt(self):
return '&username=%s&apikey=%s' % (self.conf('username'), self.conf('apikey'))
+115 -1
View File
@@ -1,8 +1,122 @@
from couchpotato.core.event import addEvent
from couchpotato.core.logger import CPLog
from couchpotato.core.providers.base import NZBProvider
from dateutil.parser import parse
from urllib import urlencode
from urllib2 import URLError
import time
log = CPLog(__name__)
class Nzbs(NZBProvider):
pass
urls = {
'download': 'http://nzbs.org/index.php?action=getnzb&nzbid=%s%s',
'nfo': 'http://nzbs.org/index.php?action=view&nzbid=%s&nfo=1',
'detail': 'http://nzbs.org/index.php?action=view&nzbid=%s',
'api': 'http://nzbs.org/rss.php',
}
cat_ids = [
([4], ['720p', '1080p']),
([2], ['cam', 'ts', 'dvdrip', 'tc', 'brrip', 'r5', 'scr']),
([9], ['dvdr']),
]
cat_backup_id = 't2'
time_between_searches = 3 # Seconds
def __init__(self):
addEvent('provider.nzb.search', self.search)
def search(self, movie, quality):
self.cleanCache();
results = []
if not self.enabled() or not self.isAvailable(self.apiUrl + '?test' + self.getApiExt()):
return results
catId = self.getCatId(type)
arguments = urlencode({
'action':'search',
'q': self.toSearchString(movie.name),
'catid': catId,
'i': self.conf('id'),
'h': self.conf('key'),
'age': self.config.get('NZB', 'retention')
})
url = "%s?%s" % (self.apiUrl, arguments)
cacheId = str(movie.imdb) + '-' + str(catId)
singleCat = (len(self.catIds.get(catId)) == 1 and catId != self.catBackupId)
try:
cached = False
if(self.cache.get(cacheId)):
data = True
cached = True
log.info('Getting RSS from cache: %s.' % cacheId)
else:
log.info('Searching: %s' % url)
data = self.urlopen(url)
self.cache[cacheId] = {
'time': time.time()
}
except (IOError, URLError):
log.error('Failed to open %s.' % url)
return results
if data:
log.debug('Parsing NZBs.org RSS.')
try:
try:
if cached:
xml = self.cache[cacheId]['xml']
else:
xml = self.getItems(data)
self.cache[cacheId]['xml'] = xml
except:
retry = False
if retry == False:
log.error('No valid xml, to many requests? Try again in 15sec.')
time.sleep(15)
return self.find(movie, quality, type, retry = True)
else:
log.error('Failed again.. disable %s for 15min.' % self.name)
self.available = False
return results
for nzb in xml:
id = int(self.gettextelement(nzb, "link").partition('nzbid=')[2])
size = self.gettextelement(nzb, "description").split('</a><br />')[1].split('">')[1]
new = self.feedItem()
new.id = id
new.type = 'nzb'
new.name = self.gettextelement(nzb, "title")
new.date = int(time.mktime(parse(self.gettextelement(nzb, "pubDate")).timetuple()))
new.size = self.parseSize(size)
new.url = self.downloadLink(id)
new.detailUrl = self.detailLink(id)
new.content = self.gettextelement(nzb, "description")
new.score = self.calcScore(new, movie)
if self.isCorrectMovie(new, movie, type, singleCategory = singleCat):
results.append(new)
log.info('Found: %s' % new.name)
return results
except SyntaxError:
log.error('Failed to parse XML response from NZBs.org')
return False
return results
def isEnabled(self):
return NZBProvider.isEnabled(self) and self.conf('enabled') and self.conf('id') and self.conf('key')
def getApiExt(self):
return '&i=%s&h=%s' % (self.conf('id'), self.conf('key'))
@@ -5,4 +5,144 @@ log = CPLog(__name__)
class ThePirateBay(TorrentProvider):
pass
urls = {
'download': 'http://torrents.thepiratebay.org/%s/%s.torrent',
'nfo': 'http://thepiratebay.org/torrent/%s',
'detail': 'http://thepiratebay.org/torrent/%s',
'search': 'http://thepiratebay.org/search/%s/0/7/%d',
}
cat_ids = [
([207], ['720p', '1080p']),
([200], ['cam', 'ts', 'dvdrip', 'tc', 'r5', 'scr', 'brrip']),
([202], ['dvdr'])
]
cat_backup_id = 200
ignore_string = {
'720p': ' -brrip -bdrip',
'1080p': ' -brrip -bdrip'
}
def __init__(self):
pass
def find(self, movie, quality, type):
results = []
if not self.enabled() or not self.isAvailable(self.apiUrl):
return results
url = self.apiUrl % (quote_plus(self.toSearchString(movie.name + ' ' + quality) + self.makeIgnoreString(type)), self.getCatId(type))
log.info('Searching: %s' % url)
try:
data = urllib2.urlopen(url, timeout = self.timeout).read()
except (IOError, URLError):
log.error('Failed to open %s.' % url)
return results
try:
tables = SoupStrainer('table')
html = BeautifulSoup(data, parseOnlyThese = tables)
resultTable = html.find('table', attrs = {'id':'searchResult'})
for result in resultTable.findAll('tr'):
details = result.find('a', attrs = {'class':'detLink'})
if details:
href = re.search('/(?P<id>\d+)/', details['href'])
id = href.group('id')
name = self.toSaveString(details.contents[0])
desc = result.find('font', attrs = {'class':'detDesc'}).contents[0].split(',')
date = ''
size = 0
for item in desc:
# Weird date stuff
if 'uploaded' in item.lower():
date = item.replace('Uploaded', '')
date = date.replace('Today', '')
# Do something with yesterday
yesterdayMinus = 0
if 'Y-day' in date:
date = date.replace('Y-day', '')
yesterdayMinus = 86400
datestring = date.replace('&nbsp;', ' ').strip()
date = int(time.mktime(parse(datestring).timetuple())) - yesterdayMinus
# size
elif 'size' in item.lower():
size = item.replace('Size', '')
seedleech = []
for td in result.findAll('td'):
try:
seedleech.append(int(td.contents[0]))
except ValueError:
pass
seeders = 0
leechers = 0
if len(seedleech) == 2 and seedleech[0] > 0 and seedleech[1] > 0:
seeders = seedleech[0]
leechers = seedleech[1]
# to item
new = self.feedItem()
new.id = id
new.type = 'torrent'
new.name = name
new.date = date
new.size = self.parseSize(size)
new.seeders = seeders
new.leechers = leechers
new.url = self.downloadLink(id, name)
new.score = self.calcScore(new, movie) + self.uploader(result) + (seeders / 10)
if seeders > 0 and (new.date + (int(self.conf('wait')) * 60 * 60) < time.time()) and Qualities.types.get(type).get('minSize') <= new.size:
new.detailUrl = self.detailLink(id)
new.content = self.getInfo(new.detailUrl)
if self.isCorrectMovie(new, movie, type):
results.append(new)
log.info('Found: %s' % new.name)
return results
except AttributeError:
log.debug('No search results found.')
return []
def makeIgnoreString(self, type):
ignore = self.ignoreString.get(type)
return ignore if ignore else ''
def uploader(self, html):
score = 0
if html.find('img', attr = {'alt':'VIP'}):
score += 3
if html.find('img', attr = {'alt':'Trusted'}):
score += 1
return score
def getInfo(self, url):
log.debug('Getting info: %s' % url)
try:
data = urllib2.urlopen(url, timeout = self.timeout).read()
pass
except IOError:
log.error('Failed to open %s.' % url)
return ''
div = SoupStrainer('div')
html = BeautifulSoup(data, parseOnlyThese = div)
html = html.find('div', attrs = {'class':'nfo'})
return str(html).decode("utf-8", "replace")
def downloadLink(self, id, name):
return self.downloadUrl % (id, quote_plus(name))
def isEnabled(self):
return self.conf('enabled') and TorrentProvider.isEnabled(self)