Browse Source

NZB/Torrent provider base

pull/1/merge
Ruud 14 years ago
parent
commit
05f6d57ea3
  1. 6
      couchpotato/core/downloaders/sabnzbd/__init__.py
  2. 6
      couchpotato/core/notifications/base.py
  3. 11
      couchpotato/core/plugins/base.py
  4. 71
      couchpotato/core/plugins/renamer/__init__.py
  5. 10
      couchpotato/core/plugins/renamer/main.py
  6. 22
      couchpotato/core/providers/base.py
  7. 6
      couchpotato/core/providers/imdb/main.py
  8. 29
      couchpotato/core/providers/newzbin/__init__.py
  9. 8
      couchpotato/core/providers/newzbin/main.py
  10. 30
      couchpotato/core/providers/newznab/__init__.py
  11. 8
      couchpotato/core/providers/newznab/main.py
  12. 29
      couchpotato/core/providers/nzbmatrix/__init__.py
  13. 116
      couchpotato/core/providers/nzbmatrix/main.py
  14. 30
      couchpotato/core/providers/nzbs/__init__.py
  15. 8
      couchpotato/core/providers/nzbs/main.py
  16. 5
      couchpotato/core/providers/themoviedb/main.py
  17. 24
      couchpotato/core/providers/thepiratebay/__init__.py
  18. 8
      couchpotato/core/providers/thepiratebay/main.py
  19. 1
      couchpotato/static/scripts/couchpotato.js
  20. 13
      couchpotato/static/scripts/page.js
  21. 25
      couchpotato/static/scripts/page/settings.js

6
couchpotato/core/downloaders/sabnzbd/__init__.py

@ -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
couchpotato/core/notifications/base.py

@ -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)

11
couchpotato/core/plugins/base.py

@ -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)

71
couchpotato/core/plugins/renamer/__init__.py

@ -1,33 +1,42 @@
from couchpotato.core.plugins.renamer.main import Renamer
def start(): def start():
pass return Renamer()
#config = [{ config = [{
# 'name': 'Renamer', 'name': 'renamer',
# 'tab': 'renaming', 'groups': [
# 'options': { {
# 'enabled': { 'tab': 'renamer',
# 'default': False, 'name': 'tmdb',
# 'type': 'bool', 'label': 'TheMovieDB',
# 'description': 'Enable renaming', 'advanced': True,
# }, 'description': 'Move and rename your downloaded movies to your movie directory.',
# 'from': { 'options': [
# 'default': '', {
# 'type': 'directory', 'name': 'enabled',
# 'label': 'From', 'default': False,
# 'description': 'Folder where the movies are downloaded to.', 'type': 'enabler',
# }, },
# 'to': { {
# 'default': '', 'name': 'from',
# 'type': 'directory', 'type': 'directory',
# 'label': 'To', 'description': 'Folder where the movies are downloaded to.',
# 'description': 'Folder where the movies will be moved to.', },
# }, {
# 'run_every': { 'name': 'to',
# 'default': 1, 'type': 'directory',
# 'type': 'int', 'description': 'Folder where the movies will be moved to.',
# 'unit': 'min(s)', },
# 'description': 'Search for new movies inside the folder every X minutes.', {
# } 'name': 'run_every',
# } 'label': 'Run every',
#}] 'default': 1,
config = [] 'type': 'int',
'unit': 'min(s)',
'description': 'Search for new movies inside the folder every X minutes.',
}
],
},
],
}]

10
couchpotato/core/plugins/renamer/main.py

@ -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
couchpotato/core/providers/base.py

@ -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'

6
couchpotato/core/providers/imdb/main.py

@ -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):

29
couchpotato/core/providers/newzbin/__init__.py

@ -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',
},
],
},
],
}]

8
couchpotato/core/providers/newzbin/main.py

@ -0,0 +1,8 @@
from couchpotato.core.logger import CPLog
from couchpotato.core.providers.base import NZBProvider
log = CPLog(__name__)
class Newzbin(NZBProvider):
pass

30
couchpotato/core/providers/newznab/__init__.py

@ -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=".',
},
],
},
],
}]

8
couchpotato/core/providers/newznab/main.py

@ -0,0 +1,8 @@
from couchpotato.core.logger import CPLog
from couchpotato.core.providers.base import NZBProvider
log = CPLog(__name__)
class Newznab(NZBProvider):
pass

29
couchpotato/core/providers/nzbmatrix/__init__.py

@ -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',
},
],
},
],
}]

116
couchpotato/core/providers/nzbmatrix/main.py

@ -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')

30
couchpotato/core/providers/nzbs/__init__.py

@ -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
couchpotato/core/providers/nzbs/main.py

@ -0,0 +1,8 @@
from couchpotato.core.logger import CPLog
from couchpotato.core.providers.base import NZBProvider
log = CPLog(__name__)
class Nzbs(NZBProvider):
pass

5
couchpotato/core/providers/themoviedb/main.py

@ -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'

24
couchpotato/core/providers/thepiratebay/__init__.py

@ -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',
},
],
},
],
}]

8
couchpotato/core/providers/thepiratebay/main.py

@ -0,0 +1,8 @@
from couchpotato.core.logger import CPLog
from couchpotato.core.providers.base import TorrentProvider
log = CPLog(__name__)
class ThePirateBay(TorrentProvider):
pass

1
couchpotato/static/scripts/couchpotato.js

@ -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();

13
couchpotato/static/scripts/page.js

@ -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');

25
couchpotato/static/scripts/page/settings.js

@ -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()
}) })
}, },

Loading…
Cancel
Save