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',
'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 = {}):
pass
def isDisabled(self):
return not self.isEnabled()
def isEnabled(self):
return self.conf('enabled', True)
def test(self):
success = self.notify(message = self.test_message)

11
couchpotato/core/plugins/base.py

@ -7,7 +7,10 @@ import os.path
class Plugin():
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):
@ -25,3 +28,9 @@ class Plugin():
dir = os.path.join(plugin_dir, 'static')
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():
pass
return Renamer()
#config = [{
# 'name': 'Renamer',
# 'tab': 'renaming',
# 'options': {
# 'enabled': {
# 'default': False,
# 'type': 'bool',
# 'description': 'Enable renaming',
# },
# 'from': {
# 'default': '',
# 'type': 'directory',
# 'label': 'From',
# 'description': 'Folder where the movies are downloaded to.',
# },
# 'to': {
# 'default': '',
# 'type': 'directory',
# 'label': 'To',
# 'description': 'Folder where the movies will be moved to.',
# },
# 'run_every': {
# 'default': 1,
# 'type': 'int',
# 'unit': 'min(s)',
# 'description': 'Search for new movies inside the folder every X minutes.',
# }
# }
#}]
config = []
config = [{
'name': 'renamer',
'groups': [
{
'tab': 'renamer',
'name': 'tmdb',
'label': 'TheMovieDB',
'advanced': True,
'description': 'Move and rename your downloaded movies to your movie directory.',
'options': [
{
'name': 'enabled',
'default': False,
'type': 'enabler',
},
{
'name': 'from',
'type': 'directory',
'description': 'Folder where the movies are downloaded to.',
},
{
'name': 'to',
'type': 'directory',
'description': 'Folder where the movies will be moved to.',
},
{
'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
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
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.logger import CPLog
from couchpotato.core.providers.base import Provider
from couchpotato.core.providers.base import MovieProvider
from imdb import IMDb
log = CPLog(__name__)
class IMDB(Provider):
type = 'movie'
class IMDB(MovieProvider):
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.helpers.encoding import simplifyString, toUnicode
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
log = CPLog(__name__)
class TheMovieDb(Provider):
class TheMovieDb(MovieProvider):
"""Api for theMovieDb"""
type = 'movie'
apiUrl = 'http://api.themoviedb.org/2.1'
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){
return this.pages[name]
}
});
window.App = new CouchPotato();

13
couchpotato/static/scripts/page.js

@ -8,18 +8,17 @@ var PageBase = new Class({
has_tab: true,
initialize: function(parent, options) {
initialize: function(options) {
var self = this;
self.setOptions(options)
self.setParent(parent)
// Create main page container
self.el = new Element('div.page.'+self.name);
// Create tab for page
if(self.has_tab){
var nav = self.getParent().getBlock('navigation');
var nav = App.getBlock('navigation');
self.tab = nav.addTab({
'href': '/'+self.name,
'title': self.title,
@ -49,14 +48,6 @@ var PageBase = new Class({
getName: function(){
return this.name
},
setParent: function(parent){
this.app = parent
},
getParent: function(){
return this.app
},
show: function(){
this.el.addClass('active');

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

@ -6,18 +6,10 @@ Page.Settings = new Class({
title: 'Change settings.',
tabs: {
'general': {
'label': 'General'
},
'providers': {
'label': 'Providers'
},
'downloaders': {
'label': 'Downloaders'
},
'notifications': {
'label': 'Notifications'
}
'general': {},
'providers': {},
'downloaders': {},
'notifications': {}
},
open: function(action, params){
@ -150,16 +142,17 @@ Page.Settings = new Class({
if(self.tabs[tab_name] && 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(
new Element('a', {
'href': '/'+self.name+'/'+tab_name+'/',
'text': (tab.label || tab.name).capitalize()
'text': label
})
).inject(self.tabs_container);
if(!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], {
@ -179,7 +172,7 @@ Page.Settings = new Class({
'class': group.advanced ? 'inlineLabels advanced' : 'inlineLabels'
}).adopt(
new Element('h2', {
'text': group.label || group.name.capitalize()
'text': (group.label || group.name).capitalize()
}).adopt(
new Element('span.hint', {
'text': group.description
@ -236,7 +229,7 @@ var OptionBase = new Class({
createLabel: function(){
var self = this;
return new Element('label', {
'text': self.options.label || self.options.name.capitalize()
'text': (self.options.label || self.options.name).capitalize()
})
},

Loading…
Cancel
Save