NZB/Torrent provider base

This commit is contained in:
Ruud
2011-04-12 10:43:37 +02:00
parent 3833b6ead1
commit 05f6d57ea3
21 changed files with 395 additions and 73 deletions
@@ -26,6 +26,12 @@ config = [{
'label': 'Api Key', 'label': 'Api Key',
'description': 'Used for all calls to Sabnzbd.', 'description': 'Used for all calls to Sabnzbd.',
}, },
{
'advanced': True,
'name': 'pp_directory',
'type': 'directory',
'description': 'Your Post-Processing Script directory, set in Sabnzbd > Config > Directories.',
},
], ],
} }
], ],
-6
View File
@@ -14,12 +14,6 @@ class Notification(Plugin):
def notify(self, message = '', data = {}): def notify(self, message = '', data = {}):
pass pass
def isDisabled(self):
return not self.isEnabled()
def isEnabled(self):
return self.conf('enabled', True)
def test(self): def test(self):
success = self.notify(message = self.test_message) success = self.notify(message = self.test_message)
+10 -1
View File
@@ -7,7 +7,10 @@ import os.path
class Plugin(): class Plugin():
def conf(self, attr): def conf(self, attr):
return Env.setting(attr, self.__class__.__name__.lower()) return Env.setting(attr, self.getName().lower())
def getName(self):
return self.__class__.__name__
def registerStatic(self, file_path): def registerStatic(self, file_path):
@@ -25,3 +28,9 @@ class Plugin():
dir = os.path.join(plugin_dir, 'static') dir = os.path.join(plugin_dir, 'static')
return send_from_directory(dir, file) return send_from_directory(dir, file)
def isDisabled(self):
return not self.isEnabled()
def isEnabled(self):
return self.conf('enabled', True)
+41 -32
View File
@@ -1,33 +1,42 @@
def start(): from couchpotato.core.plugins.renamer.main import Renamer
pass
#config = [{ def start():
# 'name': 'Renamer', return Renamer()
# 'tab': 'renaming',
# 'options': { config = [{
# 'enabled': { 'name': 'renamer',
# 'default': False, 'groups': [
# 'type': 'bool', {
# 'description': 'Enable renaming', 'tab': 'renamer',
# }, 'name': 'tmdb',
# 'from': { 'label': 'TheMovieDB',
# 'default': '', 'advanced': True,
# 'type': 'directory', 'description': 'Move and rename your downloaded movies to your movie directory.',
# 'label': 'From', 'options': [
# 'description': 'Folder where the movies are downloaded to.', {
# }, 'name': 'enabled',
# 'to': { 'default': False,
# 'default': '', 'type': 'enabler',
# 'type': 'directory', },
# 'label': 'To', {
# 'description': 'Folder where the movies will be moved to.', 'name': 'from',
# }, 'type': 'directory',
# 'run_every': { 'description': 'Folder where the movies are downloaded to.',
# 'default': 1, },
# 'type': 'int', {
# 'unit': 'min(s)', 'name': 'to',
# 'description': 'Search for new movies inside the folder every X minutes.', 'type': 'directory',
# } 'description': 'Folder where the movies will be moved to.',
# } },
#}] {
config = [] 'name': 'run_every',
'label': 'Run every',
'default': 1,
'type': 'int',
'unit': 'min(s)',
'description': 'Search for new movies inside the folder every X minutes.',
}
],
},
],
}]
+10
View File
@@ -0,0 +1,10 @@
from couchpotato.core.logger import CPLog
from couchpotato.core.plugins.base import Plugin
log = CPLog(__name__)
class Renamer(Plugin):
def __init__(self):
pass
+22
View File
@@ -8,3 +8,25 @@ class Provider(Plugin):
type = None # movie, nzb, torrent, subtitle, trailer type = None # movie, nzb, torrent, subtitle, trailer
timeout = 10 # Default timeout for url requests timeout = 10 # Default timeout for url requests
class MovieProvider(Provider):
type = 'movie'
class NZBProvider(Provider):
type = 'nzb'
time_between_searches = 10 # Seconds
class TorrentProvider(Provider):
type = 'torrent'
class SubtitleProvider(Provider):
type = 'subtitle'
class TrailerProvider(Provider):
type = 'trailer'
+2 -4
View File
@@ -1,14 +1,12 @@
from couchpotato.core.event import addEvent from couchpotato.core.event import addEvent
from couchpotato.core.logger import CPLog from couchpotato.core.logger import CPLog
from couchpotato.core.providers.base import Provider from couchpotato.core.providers.base import MovieProvider
from imdb import IMDb from imdb import IMDb
log = CPLog(__name__) log = CPLog(__name__)
class IMDB(Provider): class IMDB(MovieProvider):
type = 'movie'
def __init__(self): def __init__(self):
@@ -0,0 +1,29 @@
from .main import Newzbin
def start():
return Newzbin()
config = [{
'name': 'newzbin',
'groups': [
{
'tab': 'providers',
'name': 'newzbin',
'options': [
{
'name': 'enabled',
'type': 'enabler',
},
{
'name': 'username',
'default': '',
},
{
'name': 'password',
'default': '',
'type': 'password',
},
],
},
],
}]
@@ -0,0 +1,8 @@
from couchpotato.core.logger import CPLog
from couchpotato.core.providers.base import NZBProvider
log = CPLog(__name__)
class Newzbin(NZBProvider):
pass
@@ -0,0 +1,30 @@
from .main import Newznab
def start():
return Newznab()
config = [{
'name': 'newznab',
'groups': [
{
'tab': 'providers',
'name': 'newznab',
'options': [
{
'name': 'enabled',
'type': 'enabler',
},
{
'name': 'host',
'default': 'http://nzb.su',
},
{
'name': 'api_key',
'default': '',
'label': 'Api Key',
'description': 'Can be found after login on the "API" page, bottom left. The string after "&apikey=".',
},
],
},
],
}]
@@ -0,0 +1,8 @@
from couchpotato.core.logger import CPLog
from couchpotato.core.providers.base import NZBProvider
log = CPLog(__name__)
class Newznab(NZBProvider):
pass
@@ -0,0 +1,29 @@
from .main import NZBMatrix
def start():
return NZBMatrix()
config = [{
'name': 'nzbmatrix',
'groups': [
{
'tab': 'providers',
'name': 'nzbmatrix',
'label': 'NZBMatrix',
'options': [
{
'name': 'enabled',
'type': 'enabler',
},
{
'name': 'username',
},
{
'name': 'api_key',
'default': '9b939aee0aaafc12a65bf448e4af9543',
'label': 'Api Key',
},
],
},
],
}]
@@ -0,0 +1,116 @@
from couchpotato.core.logger import CPLog
from couchpotato.core.providers.base import NZBProvider
log = CPLog(__name__)
class NZBMatrix(NZBProvider):
urls = {
'download': 'https://api.nzbmatrix.com/v1.1/download.php?id=%s%s',
'detail': 'https://nzbmatrix.com/nzb-details.php?id=%s&hit=1',
'search': 'http://rss.nzbmatrix.com/rss.php',
}
cat_ids = [
([42], ['720p', '1080p']),
([2], ['cam', 'ts', 'dvdrip', 'tc', 'r5', 'scr']),
([54], ['brrip']),
([1], ['dvdr']),
]
cat_backup_id = 2
def __init__(self, config):
log.info('Using NZBMatrix provider')
self.config = config
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'))
def isEnabled(self):
return self.conf('enabled') and self.conf('username') and self.conf('apikey')
@@ -0,0 +1,30 @@
from .main import Nzbs
def start():
return Nzbs()
config = [{
'name': 'nzbs',
'groups': [
{
'tab': 'providers',
'name': 'nzbs',
'options': [
{
'name': 'enabled',
'type': 'enabler',
},
{
'name': 'id',
'label': 'Id',
'description': 'Can be found <a href="http://nzbs.org/index.php?action=rss" target="_blank">here</a>, the number after "&amp;i="',
},
{
'name': 'api_key',
'label': 'Api Key',
'description': 'Can be found <a href="http://nzbs.org/index.php?action=rss" target="_blank">here</a>, the string after "&amp;h="'
},
],
},
],
}]
+8
View File
@@ -0,0 +1,8 @@
from couchpotato.core.logger import CPLog
from couchpotato.core.providers.base import NZBProvider
log = CPLog(__name__)
class Nzbs(NZBProvider):
pass
@@ -2,16 +2,15 @@ from __future__ import with_statement
from couchpotato.core.event import addEvent from couchpotato.core.event import addEvent
from couchpotato.core.helpers.encoding import simplifyString, toUnicode from couchpotato.core.helpers.encoding import simplifyString, toUnicode
from couchpotato.core.logger import CPLog from couchpotato.core.logger import CPLog
from couchpotato.core.providers.base import Provider from couchpotato.core.providers.base import MovieProvider
from libs.themoviedb import tmdb from libs.themoviedb import tmdb
log = CPLog(__name__) log = CPLog(__name__)
class TheMovieDb(Provider): class TheMovieDb(MovieProvider):
"""Api for theMovieDb""" """Api for theMovieDb"""
type = 'movie'
apiUrl = 'http://api.themoviedb.org/2.1' apiUrl = 'http://api.themoviedb.org/2.1'
imageUrl = 'http://hwcdn.themoviedb.org' imageUrl = 'http://hwcdn.themoviedb.org'
@@ -0,0 +1,24 @@
from .main import ThePirateBay
def start():
return ThePirateBay()
config = [{
'name': 'themoviedb',
'groups': [
{
'tab': 'providers',
'name': 'tmdb',
'label': 'TheMovieDB',
'advanced': True,
'description': 'Used for all calls to TheMovieDB.',
'options': [
{
'name': 'api_key',
'default': '9b939aee0aaafc12a65bf448e4af9543',
'label': 'Api Key',
},
],
},
],
}]
@@ -0,0 +1,8 @@
from couchpotato.core.logger import CPLog
from couchpotato.core.providers.base import TorrentProvider
log = CPLog(__name__)
class ThePirateBay(TorrentProvider):
pass
@@ -92,6 +92,7 @@ var CouchPotato = new Class({
getPage: function(name){ getPage: function(name){
return this.pages[name] return this.pages[name]
} }
}); });
window.App = new CouchPotato(); window.App = new CouchPotato();
+2 -11
View File
@@ -8,18 +8,17 @@ var PageBase = new Class({
has_tab: true, has_tab: true,
initialize: function(parent, options) { initialize: function(options) {
var self = this; var self = this;
self.setOptions(options) self.setOptions(options)
self.setParent(parent)
// Create main page container // Create main page container
self.el = new Element('div.page.'+self.name); self.el = new Element('div.page.'+self.name);
// Create tab for page // Create tab for page
if(self.has_tab){ if(self.has_tab){
var nav = self.getParent().getBlock('navigation'); var nav = App.getBlock('navigation');
self.tab = nav.addTab({ self.tab = nav.addTab({
'href': '/'+self.name, 'href': '/'+self.name,
'title': self.title, 'title': self.title,
@@ -49,14 +48,6 @@ var PageBase = new Class({
getName: function(){ getName: function(){
return this.name return this.name
}, },
setParent: function(parent){
this.app = parent
},
getParent: function(){
return this.app
},
show: function(){ show: function(){
this.el.addClass('active'); this.el.addClass('active');
+9 -16
View File
@@ -6,18 +6,10 @@ Page.Settings = new Class({
title: 'Change settings.', title: 'Change settings.',
tabs: { tabs: {
'general': { 'general': {},
'label': 'General' 'providers': {},
}, 'downloaders': {},
'providers': { 'notifications': {}
'label': 'Providers'
},
'downloaders': {
'label': 'Downloaders'
},
'notifications': {
'label': 'Notifications'
}
}, },
open: function(action, params){ open: function(action, params){
@@ -150,16 +142,17 @@ Page.Settings = new Class({
if(self.tabs[tab_name] && self.tabs[tab_name].tab) if(self.tabs[tab_name] && self.tabs[tab_name].tab)
return self.tabs[tab_name].tab return self.tabs[tab_name].tab
var label = (tab.label || tab.name).capitalize()
var tab_el = new Element('li').adopt( var tab_el = new Element('li').adopt(
new Element('a', { new Element('a', {
'href': '/'+self.name+'/'+tab_name+'/', 'href': '/'+self.name+'/'+tab_name+'/',
'text': (tab.label || tab.name).capitalize() 'text': label
}) })
).inject(self.tabs_container); ).inject(self.tabs_container);
if(!self.tabs[tab_name]) if(!self.tabs[tab_name])
self.tabs[tab_name] = { self.tabs[tab_name] = {
'label': tab.label || tab.name 'label': label
} }
self.tabs[tab_name] = Object.merge(self.tabs[tab_name], { self.tabs[tab_name] = Object.merge(self.tabs[tab_name], {
@@ -179,7 +172,7 @@ Page.Settings = new Class({
'class': group.advanced ? 'inlineLabels advanced' : 'inlineLabels' 'class': group.advanced ? 'inlineLabels advanced' : 'inlineLabels'
}).adopt( }).adopt(
new Element('h2', { new Element('h2', {
'text': group.label || group.name.capitalize() 'text': (group.label || group.name).capitalize()
}).adopt( }).adopt(
new Element('span.hint', { new Element('span.hint', {
'text': group.description 'text': group.description
@@ -236,7 +229,7 @@ var OptionBase = new Class({
createLabel: function(){ createLabel: function(){
var self = this; var self = this;
return new Element('label', { return new Element('label', {
'text': self.options.label || self.options.name.capitalize() 'text': (self.options.label || self.options.name).capitalize()
}) })
}, },