Merge branch 'master' of https://github.com/CouchPotato/CouchPotato
This commit is contained in:
commit
a1a814c153
33 files changed
+708
-365
No files matched your search
+2
-1
@@ -48,6 +48,7 @@ def cmd_couchpotato(base_path, args):
|
|||||||
Env.get('settings').setFile(os.path.join(options.data_dir, 'settings.conf'))
|
Env.get('settings').setFile(os.path.join(options.data_dir, 'settings.conf'))
|
||||||
Env.set('app_dir', base_path)
|
Env.set('app_dir', base_path)
|
||||||
Env.set('data_dir', options.data_dir)
|
Env.set('data_dir', options.data_dir)
|
||||||
|
Env.set('log_path', os.path.join(log_dir, 'CouchPotato.log'))
|
||||||
Env.set('db_path', 'sqlite:///' + os.path.join(options.data_dir, 'couchpotato.db'))
|
Env.set('db_path', 'sqlite:///' + os.path.join(options.data_dir, 'couchpotato.db'))
|
||||||
Env.set('cache_dir', os.path.join(options.data_dir, 'cache'))
|
Env.set('cache_dir', os.path.join(options.data_dir, 'cache'))
|
||||||
Env.set('cache', FileSystemCache(os.path.join(Env.get('cache_dir'), 'python')))
|
Env.set('cache', FileSystemCache(os.path.join(Env.get('cache_dir'), 'python')))
|
||||||
@@ -73,7 +74,7 @@ def cmd_couchpotato(base_path, args):
|
|||||||
logger.addHandler(hdlr)
|
logger.addHandler(hdlr)
|
||||||
|
|
||||||
# To file
|
# To file
|
||||||
hdlr2 = handlers.RotatingFileHandler(os.path.join(log_dir, 'CouchPotato.log'), 'a', 5000000, 4)
|
hdlr2 = handlers.RotatingFileHandler(Env.get('log_path'), 'a', 500000, 10)
|
||||||
hdlr2.setFormatter(formatter)
|
hdlr2.setFormatter(formatter)
|
||||||
logger.addHandler(hdlr2)
|
logger.addHandler(hdlr2)
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ class Blackhole(Downloader):
|
|||||||
|
|
||||||
type = ['nzb', 'torrent']
|
type = ['nzb', 'torrent']
|
||||||
|
|
||||||
def download(self, data = {}):
|
def download(self, data = {}, movie = {}):
|
||||||
|
|
||||||
if self.isDisabled() or not self.isCorrectType(data.get('type')):
|
if self.isDisabled() or not self.isCorrectType(data.get('type')):
|
||||||
return
|
return
|
||||||
@@ -23,7 +23,8 @@ class Blackhole(Downloader):
|
|||||||
if not directory or not os.path.isdir(directory):
|
if not directory or not os.path.isdir(directory):
|
||||||
log.error('No directory set for blackhole %s download.' % data.get('type'))
|
log.error('No directory set for blackhole %s download.' % data.get('type'))
|
||||||
else:
|
else:
|
||||||
fullPath = os.path.join(directory, toSafeString(data.get('name')) + '.' + data.get('type'))
|
cp_tag = '.cp(' + movie['library'].get('identifier') + ')' if movie['library'].get('identifier') else ''
|
||||||
|
fullPath = os.path.join(directory, '%s%s.%s' % (toSafeString(data.get('name')), cp_tag , data.get('type')))
|
||||||
|
|
||||||
try:
|
try:
|
||||||
if not os.path.isfile(fullPath):
|
if not os.path.isfile(fullPath):
|
||||||
|
|||||||
@@ -26,6 +26,11 @@ config = [{
|
|||||||
'label': 'Api Key',
|
'label': 'Api Key',
|
||||||
'description': 'Used for all calls to Sabnzbd.',
|
'description': 'Used for all calls to Sabnzbd.',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
'name': 'category',
|
||||||
|
'label': 'Category',
|
||||||
|
'description': 'The category CP places the nzb in. Like <strong>movies</strong> or <strong>couchpotato</strong>',
|
||||||
|
},
|
||||||
{
|
{
|
||||||
'advanced': True,
|
'advanced': True,
|
||||||
'name': 'pp_directory',
|
'name': 'pp_directory',
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ class Sabnzbd(Downloader):
|
|||||||
|
|
||||||
type = ['nzb']
|
type = ['nzb']
|
||||||
|
|
||||||
def download(self, data = {}):
|
def download(self, data = {}, movie = {}):
|
||||||
|
|
||||||
if self.isDisabled() or not self.isCorrectType(data.get('type')):
|
if self.isDisabled() or not self.isCorrectType(data.get('type')):
|
||||||
return
|
return
|
||||||
@@ -34,11 +34,14 @@ class Sabnzbd(Downloader):
|
|||||||
else:
|
else:
|
||||||
pp = False
|
pp = False
|
||||||
|
|
||||||
|
|
||||||
|
cp_tag = '.cp(' + movie['library'].get('identifier') + ')' if movie['library'].get('identifier') else ''
|
||||||
params = {
|
params = {
|
||||||
'apikey': self.conf('api_key'),
|
'apikey': self.conf('api_key'),
|
||||||
'cat': self.conf('category'),
|
'cat': self.conf('category'),
|
||||||
'mode': 'addurl',
|
'mode': 'addurl',
|
||||||
'name': data.get('url')
|
'name': data.get('url'),
|
||||||
|
'nzbname': '%s%s' % (data.get('name'), cp_tag),
|
||||||
}
|
}
|
||||||
|
|
||||||
# sabNzbd complains about "invalid archive file" for newzbin urls
|
# sabNzbd complains about "invalid archive file" for newzbin urls
|
||||||
@@ -53,9 +56,9 @@ class Sabnzbd(Downloader):
|
|||||||
log.info("URL: " + url)
|
log.info("URL: " + url)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
r = urllib2.urlopen(url, timeout = 30)
|
r = urllib2.urlopen(url)
|
||||||
except:
|
except Exception, e:
|
||||||
log.error("Unable to connect to SAB.")
|
log.error("Unable to connect to SAB: %s" % e)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
result = r.read().strip()
|
result = r.read().strip()
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ def fireEvent(name, *args, **kwargs):
|
|||||||
|
|
||||||
if single and not merge:
|
if single and not merge:
|
||||||
results = None
|
results = None
|
||||||
if result[0][0] == True and result[0][1]:
|
if result[0][0] is True and result[0][1] is not None:
|
||||||
results = result[0][1]
|
results = result[0][1]
|
||||||
elif result[0][1]:
|
elif result[0][1]:
|
||||||
errorHandler(result[0][1])
|
errorHandler(result[0][1])
|
||||||
|
|||||||
@@ -13,9 +13,9 @@ class CoreNotifier(Plugin):
|
|||||||
messages = []
|
messages = []
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
|
||||||
addEvent('notify', self.notify)
|
addEvent('notify', self.notify)
|
||||||
addEvent('notify.core_notifier', self.notify)
|
addEvent('notify.core', self.frontend)
|
||||||
addEvent('core_notifier.frontend', self.frontend)
|
|
||||||
|
|
||||||
addApiView('core_notifier.listener', self.listener)
|
addApiView('core_notifier.listener', self.listener)
|
||||||
|
|
||||||
@@ -29,7 +29,6 @@ class CoreNotifier(Plugin):
|
|||||||
})
|
})
|
||||||
|
|
||||||
def frontend(self, type = 'notification', data = {}):
|
def frontend(self, type = 'notification', data = {}):
|
||||||
|
|
||||||
self.messages.append({
|
self.messages.append({
|
||||||
'time': time.time(),
|
'time': time.time(),
|
||||||
'type': type,
|
'type': type,
|
||||||
@@ -38,12 +37,15 @@ class CoreNotifier(Plugin):
|
|||||||
|
|
||||||
def listener(self):
|
def listener(self):
|
||||||
|
|
||||||
|
messages = []
|
||||||
for message in self.messages:
|
for message in self.messages:
|
||||||
|
print message['time'], (time.time() - 5)
|
||||||
#delete message older then 15s
|
#delete message older then 15s
|
||||||
if message['time'] < (time.time() - 15):
|
if message['time'] > (time.time() - 15):
|
||||||
del message
|
messages.append(message)
|
||||||
|
|
||||||
|
self.messages = []
|
||||||
return jsonified({
|
return jsonified({
|
||||||
'success': True,
|
'success': True,
|
||||||
'result': self.messages,
|
'result': messages,
|
||||||
})
|
})
|
||||||
@@ -7,7 +7,7 @@ var NotificationBase = new Class({
|
|||||||
var self = this;
|
var self = this;
|
||||||
self.setOptions(options);
|
self.setOptions(options);
|
||||||
|
|
||||||
//App.addEvent('load', self.request.bind(self));
|
App.addEvent('load', self.request.bind(self));
|
||||||
|
|
||||||
self.addEvent('notification', self.notify.bind(self))
|
self.addEvent('notification', self.notify.bind(self))
|
||||||
|
|
||||||
@@ -33,7 +33,7 @@ var NotificationBase = new Class({
|
|||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
Array.each(json.result, function(result){
|
Array.each(json.result, function(result){
|
||||||
self.fireEvent(result.type, result.data)
|
App.fireEvent(result.type, result.data)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -96,9 +96,10 @@ class LibraryPlugin(Plugin):
|
|||||||
library.files.append(file)
|
library.files.append(file)
|
||||||
db.commit()
|
db.commit()
|
||||||
except:
|
except:
|
||||||
pass
|
log.debug('Failed to attach to library: %s' % traceback.format_exc())
|
||||||
#log.debug('Failed to attach to library: %s' % traceback.format_exc())
|
|
||||||
|
|
||||||
fireEvent('library.update.after')
|
library_dict = library.to_dict({'titles': {}, 'files':{}})
|
||||||
|
|
||||||
return library.to_dict({'titles': {}, 'files':{}})
|
fireEvent('notify.core', type = 'library.update', data = library_dict)
|
||||||
|
|
||||||
|
return library_dict
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
from .main import Logging
|
||||||
|
|
||||||
|
def start():
|
||||||
|
return Logging()
|
||||||
|
|
||||||
|
config = []
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
from couchpotato.api import addApiView
|
||||||
|
from couchpotato.core.helpers.request import jsonified, getParam
|
||||||
|
from couchpotato.core.plugins.base import Plugin
|
||||||
|
from couchpotato.environment import Env
|
||||||
|
|
||||||
|
|
||||||
|
class Logging(Plugin):
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
addApiView('logging.get', self.get)
|
||||||
|
|
||||||
|
def get(self):
|
||||||
|
|
||||||
|
nr = int(getParam('nr', 0))
|
||||||
|
path = '%s%s' % (Env.get('log_path'), '.%s' % nr if nr > 0 else '')
|
||||||
|
|
||||||
|
# Reverse
|
||||||
|
f = open(path, 'r')
|
||||||
|
lines = []
|
||||||
|
for line in f.readlines():
|
||||||
|
lines.insert(0, line)
|
||||||
|
|
||||||
|
log = ''
|
||||||
|
for line in lines:
|
||||||
|
log += line
|
||||||
|
|
||||||
|
return jsonified({
|
||||||
|
'success': True,
|
||||||
|
'log': log,
|
||||||
|
})
|
||||||
@@ -38,7 +38,7 @@ class MoviePlugin(Plugin):
|
|||||||
movies = []
|
movies = []
|
||||||
for movie in results:
|
for movie in results:
|
||||||
temp = movie.to_dict(deep = {
|
temp = movie.to_dict(deep = {
|
||||||
'releases': {'status': {}, 'quality': {}, 'files':{}},
|
'releases': {'status': {}, 'quality': {}, 'files':{}, 'info': {}},
|
||||||
'library': {'titles': {}, 'files':{}},
|
'library': {'titles': {}, 'files':{}},
|
||||||
'files': {}
|
'files': {}
|
||||||
})
|
})
|
||||||
@@ -68,7 +68,7 @@ class MoviePlugin(Plugin):
|
|||||||
fireEventAsync('library.update', identifier = movie.library.identifier, default_title = default_title, force = True)
|
fireEventAsync('library.update', identifier = movie.library.identifier, default_title = default_title, force = True)
|
||||||
fireEventAsync('searcher.single', movie.to_dict(deep = {
|
fireEventAsync('searcher.single', movie.to_dict(deep = {
|
||||||
'profile': {'types': {'quality': {}}},
|
'profile': {'types': {'quality': {}}},
|
||||||
'releases': {'status': {}, 'quality': {}},
|
'releases': {'status': {}, 'quality': {}, 'files': {}, 'info': {}},
|
||||||
'library': {'titles': {}, 'files':{}},
|
'library': {'titles': {}, 'files':{}},
|
||||||
'files': {}
|
'files': {}
|
||||||
}))
|
}))
|
||||||
@@ -119,7 +119,7 @@ class MoviePlugin(Plugin):
|
|||||||
db.commit()
|
db.commit()
|
||||||
|
|
||||||
movie_dict = m.to_dict(deep = {
|
movie_dict = m.to_dict(deep = {
|
||||||
'releases': {'status': {}, 'quality': {}},
|
'releases': {'status': {}, 'quality': {}, 'files': {}, 'info': {}},
|
||||||
'library': {'titles': {}}
|
'library': {'titles': {}}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -3,10 +3,11 @@ var MovieList = new Class({
|
|||||||
Implements: [Options],
|
Implements: [Options],
|
||||||
|
|
||||||
options: {
|
options: {
|
||||||
navigation: true
|
navigation: false
|
||||||
},
|
},
|
||||||
|
|
||||||
movies: [],
|
movies: [],
|
||||||
|
letters: {},
|
||||||
|
|
||||||
initialize: function(options){
|
initialize: function(options){
|
||||||
var self = this;
|
var self = this;
|
||||||
@@ -19,6 +20,8 @@ var MovieList = new Class({
|
|||||||
create: function(){
|
create: function(){
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
|
self.el.empty();
|
||||||
|
|
||||||
// Create the alphabet nav
|
// Create the alphabet nav
|
||||||
if(self.options.navigation)
|
if(self.options.navigation)
|
||||||
self.createNavigation();
|
self.createNavigation();
|
||||||
@@ -29,14 +32,19 @@ var MovieList = new Class({
|
|||||||
}, info);
|
}, info);
|
||||||
$(m).inject(self.el);
|
$(m).inject(self.el);
|
||||||
m.fireEvent('injected');
|
m.fireEvent('injected');
|
||||||
|
|
||||||
|
if(self.options.navigation){
|
||||||
|
var first_char = m.getTitle().substr(0, 1);
|
||||||
|
self.activateLetter(first_char);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
self.el.addEvents({
|
self.el.addEvents({
|
||||||
'mouseenter:relay(.movie)': function(e, el){
|
'mouseenter:relay(.movie)': function(e, el){
|
||||||
el.addClass('hover')
|
el.addClass('hover');
|
||||||
},
|
},
|
||||||
'mouseleave:relay(.movie)': function(e, el){
|
'mouseleave:relay(.movie)': function(e, el){
|
||||||
el.removeClass('hover')
|
el.removeClass('hover');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
@@ -44,7 +52,6 @@ var MovieList = new Class({
|
|||||||
createNavigation: function(){
|
createNavigation: function(){
|
||||||
var self = this;
|
var self = this;
|
||||||
var chars = '#ABCDEFGHIJKLMNOPQRSTUVWXYZ';
|
var chars = '#ABCDEFGHIJKLMNOPQRSTUVWXYZ';
|
||||||
var selected = 'Z';
|
|
||||||
|
|
||||||
self.navigation = new Element('div.alph_nav').adopt(
|
self.navigation = new Element('div.alph_nav').adopt(
|
||||||
self.alpha = new Element('ul.inlay'),
|
self.alpha = new Element('ul.inlay'),
|
||||||
@@ -54,32 +61,39 @@ var MovieList = new Class({
|
|||||||
new Element('li.thumbnails'),
|
new Element('li.thumbnails'),
|
||||||
new Element('li.text')
|
new Element('li.text')
|
||||||
)
|
)
|
||||||
).inject(this.el, 'top')
|
).inject(this.el, 'top');
|
||||||
|
|
||||||
chars.split('').each(function(c){
|
chars.split('').each(function(c){
|
||||||
new Element('li', {
|
self.letters[c] = new Element('li', {
|
||||||
'text': c,
|
'text': c,
|
||||||
'class': c == selected ? 'selected' : ''
|
'class': 'letter_'+c
|
||||||
}).inject(self.alpha)
|
}).inject(self.alpha);
|
||||||
})
|
});
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
|
activateLetter: function(letter){
|
||||||
|
this.letters[letter].addClass('active');
|
||||||
|
},
|
||||||
|
|
||||||
getMovies: function(status, onComplete){
|
update: function(){
|
||||||
var self = this
|
var self = this;
|
||||||
|
|
||||||
if(self.movies.length == 0)
|
self.getMovies();
|
||||||
Api.request('movie.list', {
|
},
|
||||||
'data': {
|
|
||||||
'status': self.options.status
|
getMovies: function(){
|
||||||
},
|
var self = this;
|
||||||
'onComplete': function(json){
|
|
||||||
self.store(json.movies);
|
Api.request('movie.list', {
|
||||||
self.create();
|
'data': {
|
||||||
}
|
'status': self.options.status
|
||||||
})
|
},
|
||||||
else
|
'onComplete': function(json){
|
||||||
self.list()
|
self.store(json.movies);
|
||||||
|
self.create();
|
||||||
|
}
|
||||||
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
store: function(movies){
|
store: function(movies){
|
||||||
|
|||||||
@@ -159,7 +159,11 @@
|
|||||||
text-align: center;
|
text-align: center;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
margin: 0 -1px 0 0;
|
margin: 0 -1px 0 0;
|
||||||
|
color: #666;
|
||||||
}
|
}
|
||||||
|
.movies .alph_nav li.active {
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
.movies .alph_nav li:hover, .movies .alph_nav li.onlay {
|
.movies .alph_nav li:hover, .movies .alph_nav li.onlay {
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
|
|||||||
@@ -127,7 +127,8 @@ var MovieAction = new Class({
|
|||||||
self.movie = movie;
|
self.movie = movie;
|
||||||
|
|
||||||
self.create();
|
self.create();
|
||||||
self.el.addClass(self.class_name)
|
if(self.el)
|
||||||
|
self.el.addClass(self.class_name)
|
||||||
},
|
},
|
||||||
|
|
||||||
create: function(){},
|
create: function(){},
|
||||||
@@ -141,7 +142,7 @@ var MovieAction = new Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
toElement: function(){
|
toElement: function(){
|
||||||
return this.el
|
return this.el || null
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
@@ -173,4 +174,46 @@ var IMDBAction = new Class({
|
|||||||
window.open('http://www.imdb.com/title/'+self.id+'/');
|
window.open('http://www.imdb.com/title/'+self.id+'/');
|
||||||
}
|
}
|
||||||
|
|
||||||
})
|
});
|
||||||
|
|
||||||
|
var ReleaseAction = new Class({
|
||||||
|
|
||||||
|
Extends: MovieAction,
|
||||||
|
id: null,
|
||||||
|
|
||||||
|
create: function(){
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
self.id = self.movie.get('identifier');
|
||||||
|
|
||||||
|
self.el = new Element('a.releases', {
|
||||||
|
'title': 'Show the releases that are available for ' + self.movie.getTitle(),
|
||||||
|
'events': {
|
||||||
|
'click': self.show.bind(self)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
show: function(e){
|
||||||
|
var self = this;
|
||||||
|
(e).stop();
|
||||||
|
|
||||||
|
if(!self.options_container){
|
||||||
|
self.options_container = new Element('div.options').adopt(
|
||||||
|
$(self.movie.thumbnail).clone(),
|
||||||
|
self.release_container = new Element('div.releases')
|
||||||
|
).inject(self.movie, 'top');
|
||||||
|
|
||||||
|
Array.each(self.movie.data.releases, function(release){
|
||||||
|
p(release);
|
||||||
|
new Element('div', {
|
||||||
|
'text': release.title
|
||||||
|
}).inject(self.release_container)
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
self.movie.slide('in');
|
||||||
|
},
|
||||||
|
|
||||||
|
});
|
||||||
@@ -13,7 +13,7 @@ log = CPLog(__name__)
|
|||||||
class QualityPlugin(Plugin):
|
class QualityPlugin(Plugin):
|
||||||
|
|
||||||
qualities = [
|
qualities = [
|
||||||
{'identifier': 'bd50', 'size': (15000, 60000), 'label': 'BR-Disk', 'width': 1920, 'alternative': ['1080p', 'bd25'], 'allow': [], 'ext':[], 'tags': ['x264', 'h264', 'blu ray']},
|
{'identifier': 'bd50', 'size': (15000, 60000), 'label': 'BR-Disk', 'width': 1920, 'alternative': ['bd25'], 'allow': ['1080p'], 'ext':[], 'tags': ['x264', 'h264', 'bluray']},
|
||||||
{'identifier': '1080p', 'size': (5000, 20000), 'label': '1080P', 'width': 1920, 'alternative': [], 'allow': [], 'ext':['mkv', 'm2ts'], 'tags': ['x264', 'h264', 'bluray']},
|
{'identifier': '1080p', 'size': (5000, 20000), 'label': '1080P', 'width': 1920, 'alternative': [], 'allow': [], 'ext':['mkv', 'm2ts'], 'tags': ['x264', 'h264', 'bluray']},
|
||||||
{'identifier': '720p', 'size': (3500, 10000), 'label': '720P', 'width': 1280, 'alternative': [], 'allow': [], 'ext':['mkv', 'm2ts'], 'tags': ['x264', 'h264', 'bluray']},
|
{'identifier': '720p', 'size': (3500, 10000), 'label': '720P', 'width': 1280, 'alternative': [], 'allow': [], 'ext':['mkv', 'm2ts'], 'tags': ['x264', 'h264', 'bluray']},
|
||||||
{'identifier': 'brrip', 'size': (700, 7000), 'label': 'BR-Rip', 'alternative': ['bdrip'], 'allow': ['720p'], 'ext':['avi']},
|
{'identifier': 'brrip', 'size': (700, 7000), 'label': 'BR-Rip', 'alternative': ['bdrip'], 'allow': ['720p'], 'ext':['avi']},
|
||||||
|
|||||||
@@ -0,0 +1,6 @@
|
|||||||
|
from .main import Release
|
||||||
|
|
||||||
|
def start():
|
||||||
|
return Release()
|
||||||
|
|
||||||
|
config = []
|
||||||
@@ -0,0 +1,75 @@
|
|||||||
|
from couchpotato import get_session
|
||||||
|
from couchpotato.core.event import fireEvent, addEvent
|
||||||
|
from couchpotato.core.logger import CPLog
|
||||||
|
from couchpotato.core.plugins.base import Plugin
|
||||||
|
from couchpotato.core.settings.model import File, Release, Movie
|
||||||
|
from sqlalchemy.sql.expression import and_, or_
|
||||||
|
|
||||||
|
log = CPLog(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
class Release(Plugin):
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
addEvent('release.add', self.add)
|
||||||
|
|
||||||
|
def add(self, group):
|
||||||
|
db = get_session()
|
||||||
|
|
||||||
|
identifier = '%s.%s.%s' % (group['library']['identifier'], group['meta_data'].get('audio', 'unknown'), group['meta_data']['quality']['identifier'])
|
||||||
|
|
||||||
|
# Add movie
|
||||||
|
done_status = fireEvent('status.get', 'done', single = True)
|
||||||
|
movie = db.query(Movie).filter_by(library_id = group['library'].get('id')).first()
|
||||||
|
if not movie:
|
||||||
|
movie = Movie(
|
||||||
|
library_id = group['library'].get('id'),
|
||||||
|
profile_id = 0,
|
||||||
|
status_id = done_status.get('id')
|
||||||
|
)
|
||||||
|
db.add(movie)
|
||||||
|
db.commit()
|
||||||
|
|
||||||
|
# Add release
|
||||||
|
snatched_status = fireEvent('status.get', 'snatched', single = True)
|
||||||
|
release = db.query(Release).filter(
|
||||||
|
or_(
|
||||||
|
Release.identifier == identifier,
|
||||||
|
and_(Release.identifier.startswith(group['library']['identifier'], Release.status_id == snatched_status.get('id')))
|
||||||
|
)
|
||||||
|
).first()
|
||||||
|
if not release:
|
||||||
|
release = Release(
|
||||||
|
identifier = identifier,
|
||||||
|
movie = movie,
|
||||||
|
quality_id = group['meta_data']['quality'].get('id'),
|
||||||
|
status_id = done_status.get('id')
|
||||||
|
)
|
||||||
|
db.add(release)
|
||||||
|
db.commit()
|
||||||
|
|
||||||
|
# Add each file type
|
||||||
|
for type in group['files']:
|
||||||
|
for file in group['files'][type]:
|
||||||
|
added_file = self.saveFile(file, type = type, include_media_info = type is 'movie')
|
||||||
|
try:
|
||||||
|
added_file = db.query(File).filter_by(id = added_file.get('id')).one()
|
||||||
|
release.files.append(added_file)
|
||||||
|
db.commit()
|
||||||
|
except Exception, e:
|
||||||
|
log.debug('Failed to attach "%s" to release: %s' % (file, e))
|
||||||
|
|
||||||
|
db.remove()
|
||||||
|
|
||||||
|
|
||||||
|
def saveFile(self, file, type = 'unknown', include_media_info = False):
|
||||||
|
|
||||||
|
properties = {}
|
||||||
|
|
||||||
|
# Get media info for files
|
||||||
|
if include_media_info:
|
||||||
|
properties = {}
|
||||||
|
|
||||||
|
# Check database and update/insert if necessary
|
||||||
|
return fireEvent('file.add', path = file, part = self.getPartNumber(file), type = self.file_types[type], properties = properties, single = True)
|
||||||
|
|
||||||
@@ -18,13 +18,14 @@ class Renamer(Plugin):
|
|||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
|
||||||
addEvent('renamer.scan', self.scan)
|
addEvent('renamer.scan', self.scan)
|
||||||
#addEvent('app.load', self.scan)
|
addEvent('app.load', self.scan)
|
||||||
|
|
||||||
#fireEvent('schedule.interval', 'renamer.scan', self.scan, minutes = self.conf('run_every'))
|
fireEvent('schedule.interval', 'renamer.scan', self.scan, minutes = self.conf('run_every'))
|
||||||
|
|
||||||
def scan(self):
|
def scan(self):
|
||||||
|
|
||||||
groups = fireEvent('scanner.scan', folder = self.conf('from'), single = True)
|
groups = fireEvent('scanner.scan', folder = self.conf('from'), single = True)
|
||||||
|
if groups is None: return
|
||||||
|
|
||||||
destination = self.conf('to')
|
destination = self.conf('to')
|
||||||
folder_name = self.conf('folder_name')
|
folder_name = self.conf('folder_name')
|
||||||
@@ -151,42 +152,52 @@ class Renamer(Plugin):
|
|||||||
# Before renaming, remove the lower quality files
|
# Before renaming, remove the lower quality files
|
||||||
db = get_session()
|
db = get_session()
|
||||||
library = db.query(Library).filter_by(identifier = group['library']['identifier']).first()
|
library = db.query(Library).filter_by(identifier = group['library']['identifier']).first()
|
||||||
|
done_status = fireEvent('status.get', 'done', single = True)
|
||||||
for movie in library.movies:
|
for movie in library.movies:
|
||||||
for release in movie.releases:
|
for release in movie.releases:
|
||||||
if release.quality.order < group['meta_data']['quality']['order']:
|
if release.quality.order < group['meta_data']['quality']['order']:
|
||||||
log.info('Removing older release for %s, with quality %s' % (movie.library.titles[0].title, release.quality.label))
|
log.info('Removing older release for %s, with quality %s' % (movie.library.titles[0].title, release.quality.label))
|
||||||
elif release.quality.order is group['meta_data']['quality']['order']:
|
elif release.status_id is done_status.get('id'):
|
||||||
log.info('Same quality release already exists for %s, with quality %s. Assuming repack.' % (movie.library.titles[0].title, release.quality.label))
|
if release.quality.order is group['meta_data']['quality']['order']:
|
||||||
else:
|
log.info('Same quality release already exists for %s, with quality %s. Assuming repack.' % (movie.library.titles[0].title, release.quality.label))
|
||||||
log.info('Better quality release already exists for %s, with quality %s' % (movie.library.titles[0].title, release.quality.label))
|
else:
|
||||||
|
log.info('Better quality release already exists for %s, with quality %s' % (movie.library.titles[0].title, release.quality.label))
|
||||||
|
|
||||||
# Add _EXISTS_ to the parent dir
|
# Add _EXISTS_ to the parent dir
|
||||||
if group['dirname']:
|
if group['dirname']:
|
||||||
for rename_me in rename_files: # Don't rename anything in this group
|
for rename_me in rename_files: # Don't rename anything in this group
|
||||||
rename_files[rename_me] = None
|
rename_files[rename_me] = None
|
||||||
rename_files[group['parentdir']] = group['parentdir'].replace(group['dirname'], '_EXISTS_%s' % group['dirname'])
|
rename_files[group['parentdir']] = group['parentdir'].replace(group['dirname'], '_EXISTS_%s' % group['dirname'])
|
||||||
else: # Add it to filename
|
else: # Add it to filename
|
||||||
for rename_me in rename_files:
|
for rename_me in rename_files:
|
||||||
filename = os.path.basename(rename_me)
|
filename = os.path.basename(rename_me)
|
||||||
rename_files[rename_me] = rename_me.replace(filename, '_EXISTS_%s' % filename)
|
rename_files[rename_me] = rename_me.replace(filename, '_EXISTS_%s' % filename)
|
||||||
|
|
||||||
break
|
break
|
||||||
|
|
||||||
for file in release.files:
|
for file in release.files:
|
||||||
log.info('Removing "%s"' % file.path)
|
log.info('Removing "%s"' % file.path)
|
||||||
|
|
||||||
# Rename
|
# Rename
|
||||||
for rename_me in rename_files:
|
for src in rename_files:
|
||||||
if rename_files[rename_me]:
|
if rename_files[src]:
|
||||||
log.info('Renaming "%s" to "%s"' % (rename_me, rename_files[rename_me]))
|
|
||||||
|
|
||||||
path = os.path.dirname(rename_files[rename_me])
|
dst = rename_files[src]
|
||||||
|
|
||||||
|
log.info('Renaming "%s" to "%s"' % (src, dst))
|
||||||
|
|
||||||
|
path = os.path.dirname(dst)
|
||||||
try:
|
try:
|
||||||
if not os.path.isdir(path): os.makedirs(path)
|
if not os.path.isdir(path): os.makedirs(path)
|
||||||
except:
|
except:
|
||||||
log.error('Failed creating dir %s: %s' % (path, traceback.format_exc()))
|
log.error('Failed creating dir %s: %s' % (path, traceback.format_exc()))
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
try:
|
||||||
|
shutil.move(src, dst)
|
||||||
|
except:
|
||||||
|
log.error('Failed moving the file "%s" : %s' % (os.path.basename(src), traceback.format_exc()))
|
||||||
|
|
||||||
#print rename_me, rename_files[rename_me]
|
#print rename_me, rename_files[rename_me]
|
||||||
|
|
||||||
# Search for trailers
|
# Search for trailers
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ from couchpotato.core.plugins.base import Plugin
|
|||||||
from couchpotato.core.settings.model import File, Release, Movie
|
from couchpotato.core.settings.model import File, Release, Movie
|
||||||
from couchpotato.environment import Env
|
from couchpotato.environment import Env
|
||||||
from flask.helpers import json
|
from flask.helpers import json
|
||||||
from themoviedb.tmdb import opensubtitleHashFile
|
from sqlalchemy.sql.expression import and_, or_
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
import subprocess
|
import subprocess
|
||||||
@@ -70,6 +70,7 @@ class Scanner(Plugin):
|
|||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
|
||||||
#addEvent('app.load', self.scanLibrary)
|
#addEvent('app.load', self.scanLibrary)
|
||||||
|
addEvent('scanner.create_file_identifier', self.createStringIdentifier)
|
||||||
|
|
||||||
addEvent('scanner.scan', self.scan)
|
addEvent('scanner.scan', self.scan)
|
||||||
|
|
||||||
@@ -95,7 +96,7 @@ class Scanner(Plugin):
|
|||||||
#library = db.query(Library).filter_by(id = library.get('id')).one()
|
#library = db.query(Library).filter_by(id = library.get('id')).one()
|
||||||
|
|
||||||
# Add release
|
# Add release
|
||||||
self.addRelease(group)
|
fireEvent('release.add', group = group)
|
||||||
|
|
||||||
# Add identifier for library update
|
# Add identifier for library update
|
||||||
update_after.append(group['library'].get('identifier'))
|
update_after.append(group['library'].get('identifier'))
|
||||||
@@ -133,7 +134,7 @@ class Scanner(Plugin):
|
|||||||
is_dvd_file = self.isDVDFile(file_path)
|
is_dvd_file = self.isDVDFile(file_path)
|
||||||
if os.path.getsize(file_path) > self.minimal_filesize['media'] or is_dvd_file: # Minimal 300MB files or is DVD file
|
if os.path.getsize(file_path) > self.minimal_filesize['media'] or is_dvd_file: # Minimal 300MB files or is DVD file
|
||||||
|
|
||||||
identifier = self.createFileIdentifier(file_path, folder, exclude_filename = is_dvd_file)
|
identifier = self.createStringIdentifier(file_path, folder, exclude_filename = is_dvd_file)
|
||||||
|
|
||||||
if not movie_files.get(identifier):
|
if not movie_files.get(identifier):
|
||||||
movie_files[identifier] = {
|
movie_files[identifier] = {
|
||||||
@@ -221,51 +222,6 @@ class Scanner(Plugin):
|
|||||||
|
|
||||||
return movie_files
|
return movie_files
|
||||||
|
|
||||||
|
|
||||||
def addRelease(self, group):
|
|
||||||
db = get_session()
|
|
||||||
|
|
||||||
identifier = '%s.%s.%s' % (group['library']['identifier'], group['meta_data'].get('audio', 'unknown'), group['meta_data']['quality']['identifier'])
|
|
||||||
|
|
||||||
# Add movie
|
|
||||||
done_status = fireEvent('status.get', 'done', single = True)
|
|
||||||
movie = db.query(Movie).filter_by(library_id = group['library'].get('id')).first()
|
|
||||||
if not movie:
|
|
||||||
movie = Movie(
|
|
||||||
library_id = group['library'].get('id'),
|
|
||||||
profile_id = 0,
|
|
||||||
status_id = done_status.get('id')
|
|
||||||
)
|
|
||||||
db.add(movie)
|
|
||||||
db.commit()
|
|
||||||
|
|
||||||
# Add release
|
|
||||||
release = db.query(Release).filter_by(identifier = identifier).first()
|
|
||||||
if not release:
|
|
||||||
|
|
||||||
release = Release(
|
|
||||||
identifier = identifier,
|
|
||||||
movie = movie,
|
|
||||||
quality_id = group['meta_data']['quality'].get('id'),
|
|
||||||
status_id = done_status.get('id')
|
|
||||||
)
|
|
||||||
db.add(release)
|
|
||||||
db.commit()
|
|
||||||
|
|
||||||
# Add each file type
|
|
||||||
for type in group['files']:
|
|
||||||
|
|
||||||
for file in group['files'][type]:
|
|
||||||
added_file = self.saveFile(file, type = type, include_media_info = type is 'movie')
|
|
||||||
try:
|
|
||||||
added_file = db.query(File).filter_by(id = added_file.get('id')).one()
|
|
||||||
release.files.append(added_file)
|
|
||||||
db.commit()
|
|
||||||
except Exception, e:
|
|
||||||
log.debug('Failed to attach "%s" to release: %s' % (file, e))
|
|
||||||
|
|
||||||
db.remove()
|
|
||||||
|
|
||||||
def getMetaData(self, group):
|
def getMetaData(self, group):
|
||||||
|
|
||||||
data = {}
|
data = {}
|
||||||
@@ -374,17 +330,6 @@ class Scanner(Plugin):
|
|||||||
log.error('No imdb_id found for %s.' % group['identifiers'])
|
log.error('No imdb_id found for %s.' % group['identifiers'])
|
||||||
return {}
|
return {}
|
||||||
|
|
||||||
def saveFile(self, file, type = 'unknown', include_media_info = False):
|
|
||||||
|
|
||||||
properties = {}
|
|
||||||
|
|
||||||
# Get media info for files
|
|
||||||
if include_media_info:
|
|
||||||
properties = {}
|
|
||||||
|
|
||||||
# Check database and update/insert if necessary
|
|
||||||
return fireEvent('file.add', path = file, part = self.getPartNumber(file), type = self.file_types[type], properties = properties, single = True)
|
|
||||||
|
|
||||||
def getCPImdb(self, string):
|
def getCPImdb(self, string):
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@@ -501,9 +446,9 @@ class Scanner(Plugin):
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
def getGroupFiles(self, identifier, folder, file_pile):
|
def getGroupFiles(self, identifier, folder, file_pile):
|
||||||
return set(filter(lambda s:identifier in self.createFileIdentifier(s, folder), file_pile))
|
return set(filter(lambda s:identifier in self.createStringIdentifier(s, folder), file_pile))
|
||||||
|
|
||||||
def createFileIdentifier(self, file_path, folder, exclude_filename = False):
|
def createStringIdentifier(self, file_path, folder = '', exclude_filename = False):
|
||||||
|
|
||||||
identifier = file_path.replace(folder, '') # root folder
|
identifier = file_path.replace(folder, '') # root folder
|
||||||
identifier = os.path.splitext(identifier)[0] # ext
|
identifier = os.path.splitext(identifier)[0] # ext
|
||||||
|
|||||||
@@ -1,14 +1,16 @@
|
|||||||
|
from couchpotato.core.event import fireEvent
|
||||||
from couchpotato.core.helpers.encoding import simplifyString
|
from couchpotato.core.helpers.encoding import simplifyString
|
||||||
from couchpotato.environment import Env
|
from couchpotato.environment import Env
|
||||||
import re
|
import re
|
||||||
|
|
||||||
name_scores = [
|
name_scores = [
|
||||||
'proper:2', 'repack:2',
|
'proper:5', 'repack:5',
|
||||||
'unrated:1',
|
'unrated:1',
|
||||||
'x264:1',
|
'x264:1', 'h264:1',
|
||||||
'DTS:4', 'AC3:2',
|
'DTS:4', 'AC3:2',
|
||||||
'720p:10', '1080p:10', 'bluray:10', 'dvd:1', 'dvdrip:1', 'brrip:1', 'bdrip:1',
|
'720p:10', '1080p:10', 'bluray:10', 'dvd:1', 'dvdrip:1', 'brrip:1', 'bdrip:1', 'bd50:1', 'bd25:1',
|
||||||
'metis:1', 'diamond:1', 'wiki:1', 'CBGB:1',
|
'imbt:1', 'cocain:1', 'vomit:1', 'fico:1', 'arrow:1', 'pukka:1', 'prism:1', 'devise:1', 'esir:1',
|
||||||
|
'metis:1', 'diamond:1', 'wiki:1', 'cbgb:1', 'crossbow:1', 'sinners:1', 'amiable:1', 'refined:1', 'twizted:1', 'felony:1', 'hubris:1', 'machd:1',
|
||||||
'german:-10', 'french:-10', 'spanish:-10', 'swesub:-20', 'danish:-10'
|
'german:-10', 'french:-10', 'spanish:-10', 'swesub:-20', 'danish:-10'
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -40,12 +42,8 @@ def nameScore(name, year):
|
|||||||
|
|
||||||
def nameRatioScore(nzb_name, movie_name):
|
def nameRatioScore(nzb_name, movie_name):
|
||||||
|
|
||||||
nzb_words = re.split('\W+', simplifyString(nzb_name))
|
nzb_words = re.split('\W+', fireEvent('scanner.create_file_identifier', nzb_name, single = True))
|
||||||
movie_words = re.split('\W+', simplifyString(movie_name))
|
movie_words = re.split('\W+', simplifyString(movie_name))
|
||||||
|
|
||||||
# Replace .,-_ with space
|
left_over = set(nzb_words) - set(movie_words)
|
||||||
left_over = len(nzb_words) - len(movie_words)
|
return 10 - len(left_over)
|
||||||
if 2 <= left_over <= 6:
|
|
||||||
return 4
|
|
||||||
else:
|
|
||||||
return 0
|
|
||||||
@@ -1,9 +1,10 @@
|
|||||||
from couchpotato import get_session
|
from couchpotato import get_session
|
||||||
from couchpotato.core.event import addEvent, fireEvent
|
from couchpotato.core.event import addEvent, fireEvent
|
||||||
from couchpotato.core.helpers.encoding import simplifyString
|
from couchpotato.core.helpers.encoding import simplifyString
|
||||||
|
from couchpotato.core.helpers.variable import md5
|
||||||
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.core.settings.model import Movie
|
from couchpotato.core.settings.model import Movie, Release, ReleaseInfo
|
||||||
from couchpotato.environment import Env
|
from couchpotato.environment import Env
|
||||||
import re
|
import re
|
||||||
|
|
||||||
@@ -19,7 +20,7 @@ class Searcher(Plugin):
|
|||||||
|
|
||||||
# Schedule cronjob
|
# Schedule cronjob
|
||||||
fireEvent('schedule.cron', 'searcher.all', self.all, day = self.conf('cron_day'), hour = self.conf('cron_hour'), minute = self.conf('cron_minute'))
|
fireEvent('schedule.cron', 'searcher.all', self.all, day = self.conf('cron_day'), hour = self.conf('cron_hour'), minute = self.conf('cron_minute'))
|
||||||
#addEvent('app.load', self.all)
|
addEvent('app.load', self.all)
|
||||||
|
|
||||||
def all(self):
|
def all(self):
|
||||||
|
|
||||||
@@ -29,48 +30,88 @@ class Searcher(Plugin):
|
|||||||
Movie.status.has(identifier = 'active')
|
Movie.status.has(identifier = 'active')
|
||||||
).all()
|
).all()
|
||||||
|
|
||||||
snatched_status = fireEvent('status.get', 'snatched', single = True)
|
|
||||||
|
|
||||||
for movie in movies:
|
for movie in movies:
|
||||||
success = self.single(movie.to_dict(deep = {
|
self.single(movie.to_dict(deep = {
|
||||||
'profile': {'types': {'quality': {}}},
|
'profile': {'types': {'quality': {}}},
|
||||||
'releases': {'status': {}, 'quality': {}},
|
'releases': {'status': {}, 'quality': {}},
|
||||||
'library': {'titles': {}, 'files':{}},
|
'library': {'titles': {}, 'files':{}},
|
||||||
'files': {}
|
'files': {}
|
||||||
}))
|
}))
|
||||||
|
|
||||||
# Mark as snatched on success
|
|
||||||
if success:
|
|
||||||
movie.status_id = snatched_status.get('id')
|
|
||||||
db.commit()
|
|
||||||
|
|
||||||
|
|
||||||
def single(self, movie):
|
def single(self, movie):
|
||||||
|
|
||||||
|
downloaded_status = fireEvent('status.get', 'downloaded', single = True)
|
||||||
|
available_status = fireEvent('status.get', 'available', single = True)
|
||||||
|
snatched_status = fireEvent('status.get', 'snatched', single = True)
|
||||||
|
|
||||||
successful = False
|
successful = False
|
||||||
for type in movie['profile']['types']:
|
for type in movie['profile']['types']:
|
||||||
|
print type
|
||||||
|
|
||||||
has_better_quality = False
|
has_better_quality = 0
|
||||||
|
default_title = movie['library']['titles'][0]['title']
|
||||||
|
|
||||||
# See if beter quality is available
|
# See if beter quality is available
|
||||||
for release in movie['releases']:
|
for release in movie['releases']:
|
||||||
if release['quality']['order'] <= type['quality']['order']:
|
if release['quality']['order'] <= type['quality']['order'] and release['status_id'] is not available_status.get('id'):
|
||||||
has_better_quality = True
|
has_better_quality += 1
|
||||||
|
|
||||||
# Don't search for quality lower then already available.
|
# Don't search for quality lower then already available.
|
||||||
if not has_better_quality:
|
if has_better_quality is 0:
|
||||||
|
|
||||||
log.info('Search for %s in %s' % (movie['library']['titles'][0]['title'], type['quality']['label']))
|
log.info('Search for %s in %s' % (default_title, type['quality']['label']))
|
||||||
results = fireEvent('provider.yarr.search', movie, type['quality'], merge = True)
|
results = fireEvent('provider.yarr.search', movie, type['quality'], merge = True)
|
||||||
sorted_results = sorted(results, key = lambda k: k['score'], reverse = True)
|
sorted_results = sorted(results, key = lambda k: k['score'], reverse = True)
|
||||||
|
|
||||||
|
# Add them to this movie releases list
|
||||||
for nzb in sorted_results:
|
for nzb in sorted_results:
|
||||||
successful = fireEvent('download', data = nzb, single = True)
|
db = get_session()
|
||||||
|
|
||||||
|
rls = db.query(Release).filter_by(identifier = md5(nzb['url'])).first()
|
||||||
|
if not rls:
|
||||||
|
rls = Release(
|
||||||
|
identifier = md5(nzb['url']),
|
||||||
|
movie_id = movie.get('id'),
|
||||||
|
quality_id = type.get('quality_id'),
|
||||||
|
status_id = available_status.get('id')
|
||||||
|
)
|
||||||
|
db.add(rls)
|
||||||
|
db.commit()
|
||||||
|
|
||||||
|
for info in nzb:
|
||||||
|
rls_info = ReleaseInfo(
|
||||||
|
identifier = info,
|
||||||
|
value = nzb[info]
|
||||||
|
)
|
||||||
|
rls.info.append(rls_info)
|
||||||
|
db.commit()
|
||||||
|
|
||||||
|
|
||||||
|
for nzb in sorted_results:
|
||||||
|
successful = fireEvent('download', data = nzb, movie = movie, single = True)
|
||||||
|
|
||||||
if successful:
|
if successful:
|
||||||
log.info('Downloading of %s successful.' % nzb.get('name'))
|
log.info('Downloading of %s successful.' % nzb.get('name'))
|
||||||
|
|
||||||
|
# Mark release as snatched
|
||||||
|
db = get_session()
|
||||||
|
rls = db.query(Release).filter_by(identifier = md5(nzb['url'])).first()
|
||||||
|
rls.status_id = snatched_status.get('id')
|
||||||
|
db.commit()
|
||||||
|
|
||||||
|
# Mark movie snatched if quality is finish-checked
|
||||||
|
if type['finish']:
|
||||||
|
mvie = db.query(Movie).filter_by(id = movie['id']).first()
|
||||||
|
mvie.status_id = snatched_status.get('id')
|
||||||
|
db.commit()
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
return False
|
||||||
|
else:
|
||||||
|
log.info('Better quality (%s) already available or snatched for %s' % (type['quality']['label'], default_title))
|
||||||
|
break
|
||||||
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -118,7 +118,7 @@ class YarrProvider(Provider):
|
|||||||
if identifier in qualities:
|
if identifier in qualities:
|
||||||
return ids
|
return ids
|
||||||
|
|
||||||
return False
|
return [self.cat_backup_id]
|
||||||
|
|
||||||
def found(self, new):
|
def found(self, new):
|
||||||
log.info('Found: score(%(score)s): %(name)s' % new)
|
log.info('Found: score(%(score)s): %(name)s' % new)
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ class Newznab(NZBProvider, RSS):
|
|||||||
})
|
})
|
||||||
url = "%s&%s" % (self.getUrl(self.urls['search']), arguments)
|
url = "%s&%s" % (self.getUrl(self.urls['search']), arguments)
|
||||||
|
|
||||||
cache_key = '%s-%s' % (movie['library']['identifier'], cat_id[0])
|
cache_key = 'newznab.%s.%s' % (movie['library']['identifier'], cat_id[0])
|
||||||
single_cat = (len(cat_id) == 1 and cat_id[0] != self.cat_backup_id)
|
single_cat = (len(cat_id) == 1 and cat_id[0] != self.cat_backup_id)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
|||||||
@@ -0,0 +1,21 @@
|
|||||||
|
from .main import NzbIndex
|
||||||
|
|
||||||
|
def start():
|
||||||
|
return NzbIndex()
|
||||||
|
|
||||||
|
config = [{
|
||||||
|
'name': 'nzbindex',
|
||||||
|
'groups': [
|
||||||
|
{
|
||||||
|
'tab': 'providers',
|
||||||
|
'name': 'nzbindex',
|
||||||
|
'description': 'Free provider, but less accurate.',
|
||||||
|
'options': [
|
||||||
|
{
|
||||||
|
'name': 'enabled',
|
||||||
|
'type': 'enabler',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}]
|
||||||
@@ -0,0 +1,97 @@
|
|||||||
|
from couchpotato.core.event import addEvent, fireEvent
|
||||||
|
from couchpotato.core.helpers.encoding import simplifyString
|
||||||
|
from couchpotato.core.helpers.rss import RSS
|
||||||
|
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
|
||||||
|
import xml.etree.ElementTree as XMLTree
|
||||||
|
|
||||||
|
log = CPLog(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
class NzbIndex(NZBProvider, RSS):
|
||||||
|
|
||||||
|
urls = {
|
||||||
|
'download': 'http://www.nzbindex.nl/download/%s/%s',
|
||||||
|
'api': 'http://www.nzbindex.nl/rss/', #http://www.nzbindex.nl/rss/?q=due+date+720p&age=1000&sort=agedesc&minsize=3500&maxsize=10000
|
||||||
|
}
|
||||||
|
|
||||||
|
time_between_searches = 1 # Seconds
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
addEvent('provider.nzb.search', self.search)
|
||||||
|
addEvent('provider.yarr.search', self.search)
|
||||||
|
|
||||||
|
def search(self, movie, quality):
|
||||||
|
|
||||||
|
results = []
|
||||||
|
if self.isDisabled() or not self.isAvailable(self.urls['api']):
|
||||||
|
return results
|
||||||
|
|
||||||
|
arguments = urlencode({
|
||||||
|
'q': '%s %s' % (simplifyString(movie['library']['titles'][0]['title']), quality.get('identifier')),
|
||||||
|
'sort': 'agedesc',
|
||||||
|
'minsize': quality.get('size_min'),
|
||||||
|
'maxsize': quality.get('size_max'),
|
||||||
|
'rating': '1',
|
||||||
|
})
|
||||||
|
url = "%s?%s" % (self.urls['api'], arguments)
|
||||||
|
|
||||||
|
cache_key = 'nzbindex.%s.%s' % (movie['library'].get('identifier'), quality.get('identifier'))
|
||||||
|
|
||||||
|
try:
|
||||||
|
data = self.getCache(cache_key)
|
||||||
|
if not data:
|
||||||
|
data = self.urlopen(url)
|
||||||
|
self.setCache(cache_key, data)
|
||||||
|
except (IOError, URLError):
|
||||||
|
log.error('Failed to open %s.' % url)
|
||||||
|
return results
|
||||||
|
|
||||||
|
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:
|
||||||
|
|
||||||
|
enclosure = self.getElements(nzb, 'enclosure')[0].attrib
|
||||||
|
|
||||||
|
id = int(self.getTextElement(nzb, "link").split('/')[4])
|
||||||
|
new = {
|
||||||
|
'id': id,
|
||||||
|
'type': 'nzb',
|
||||||
|
'name': self.getTextElement(nzb, "title"),
|
||||||
|
'age': self.calculateAge(int(time.mktime(parse(self.getTextElement(nzb, "pubDate")).timetuple()))),
|
||||||
|
'size': enclosure['length'],
|
||||||
|
'url': enclosure['url'],
|
||||||
|
'detail_url': enclosure['url'].replace('/download/', '/release/'),
|
||||||
|
'description': self.getTextElement(nzb, "description"),
|
||||||
|
'check_nzb': True,
|
||||||
|
}
|
||||||
|
new['score'] = fireEvent('score.calculate', new, movie, single = True)
|
||||||
|
|
||||||
|
is_correct_movie = fireEvent('searcher.correct_movie',
|
||||||
|
nzb = new, movie = movie, quality = quality,
|
||||||
|
imdb_results = False, single_category = False, single = True)
|
||||||
|
|
||||||
|
if is_correct_movie:
|
||||||
|
results.append(new)
|
||||||
|
self.found(new)
|
||||||
|
|
||||||
|
return results
|
||||||
|
except SyntaxError:
|
||||||
|
log.error('Failed to parse XML response from NZBMatrix.com')
|
||||||
|
|
||||||
|
return results
|
||||||
|
|
||||||
|
|
||||||
|
def isEnabled(self):
|
||||||
|
return NZBProvider.isEnabled(self) and self.conf('enabled')
|
||||||
@@ -53,7 +53,7 @@ class NZBMatrix(NZBProvider, RSS):
|
|||||||
url = "%s?%s" % (self.urls['search'], arguments)
|
url = "%s?%s" % (self.urls['search'], arguments)
|
||||||
log.info('Searching: %s' % url)
|
log.info('Searching: %s' % url)
|
||||||
|
|
||||||
cache_key = '%s-%s' % (movie['library'].get('identifier'), cat_ids)
|
cache_key = 'nzbmatrix.%s.%s' % (movie['library'].get('identifier'), cat_ids)
|
||||||
single_cat = True
|
single_cat = True
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ class Nzbs(NZBProvider, RSS):
|
|||||||
})
|
})
|
||||||
url = "%s?%s" % (self.urls['api'], arguments)
|
url = "%s?%s" % (self.urls['api'], arguments)
|
||||||
|
|
||||||
cache_key = '%s-%s' % (movie['library'].get('identifier'), str(cat_id))
|
cache_key = 'nzbs.%s.%s' % (movie['library'].get('identifier'), str(cat_id))
|
||||||
|
|
||||||
try:
|
try:
|
||||||
data = self.getCache(cache_key)
|
data = self.getCache(cache_key)
|
||||||
@@ -72,8 +72,9 @@ class Nzbs(NZBProvider, RSS):
|
|||||||
|
|
||||||
for nzb in nzbs:
|
for nzb in nzbs:
|
||||||
|
|
||||||
|
id = int(self.getTextElement(nzb, "link").partition('nzbid=')[2])
|
||||||
new = {
|
new = {
|
||||||
'id': int(self.getTextElement(nzb, "link").partition('nzbid=')[2]),
|
'id': id,
|
||||||
'type': 'nzb',
|
'type': 'nzb',
|
||||||
'name': self.getTextElement(nzb, "title"),
|
'name': self.getTextElement(nzb, "title"),
|
||||||
'age': self.calculateAge(int(time.mktime(parse(self.getTextElement(nzb, "pubDate")).timetuple()))),
|
'age': self.calculateAge(int(time.mktime(parse(self.getTextElement(nzb, "pubDate")).timetuple()))),
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ class Env:
|
|||||||
_data_dir = ""
|
_data_dir = ""
|
||||||
_cache_dir = ""
|
_cache_dir = ""
|
||||||
_db_path = ""
|
_db_path = ""
|
||||||
|
_log_path = ""
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def doDebug():
|
def doDebug():
|
||||||
|
|||||||
File renamed without changes.
File renamed without changes.
@@ -3,6 +3,25 @@ Page.Log = new Class({
|
|||||||
Extends: PageBase,
|
Extends: PageBase,
|
||||||
|
|
||||||
name: 'log',
|
name: 'log',
|
||||||
title: 'Show recent logs.'
|
title: 'Show recent logs.',
|
||||||
|
|
||||||
|
indexAction: function(){
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
if(self.log) self.log.destroy();
|
||||||
|
self.log = new Element('div.log', {
|
||||||
|
'text': 'loading...'
|
||||||
|
}).inject(self.el)
|
||||||
|
|
||||||
|
Api.request('logging.get', {
|
||||||
|
'data': {
|
||||||
|
'nr': 0
|
||||||
|
},
|
||||||
|
'onComplete': function(json){
|
||||||
|
self.log.set('html', '<pre>'+json.log+'</pre>')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
})
|
})
|
||||||
@@ -8,222 +8,240 @@ Page.Wanted = new Class({
|
|||||||
indexAction: function(param){
|
indexAction: function(param){
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
self.list = new MovieList({
|
if(!self.list){
|
||||||
'status': 'active',
|
|
||||||
'actions': Wanted.Action
|
// Wanted movies
|
||||||
});
|
self.wanted = new MovieList({
|
||||||
$(self.list).inject(self.el);
|
'status': 'active',
|
||||||
|
'actions': WantedActions
|
||||||
|
});
|
||||||
|
$(self.wanted).inject(self.el);
|
||||||
|
App.addEvent('library.update', self.wanted.update.bind(self.wanted));
|
||||||
|
|
||||||
|
// Snatched movies
|
||||||
|
self.snatched = new MovieList({
|
||||||
|
'status': 'snatched',
|
||||||
|
'actions': SnatchedActions
|
||||||
|
});
|
||||||
|
$(self.snatched).inject(self.el);
|
||||||
|
App.addEvent('library.update', self.snatched.update.bind(self.snatched));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
var Wanted = {
|
var WantedActions = {
|
||||||
'Action': {
|
'IMBD': IMDBAction
|
||||||
'IMBD': IMDBAction
|
//,'releases': ReleaseAction
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Wanted.Action.Edit = new Class({
|
,'Edit': new Class({
|
||||||
|
|
||||||
Extends: MovieAction,
|
Extends: MovieAction,
|
||||||
|
|
||||||
create: function(){
|
create: function(){
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
self.el = new Element('a.edit', {
|
self.el = new Element('a.edit', {
|
||||||
'title': 'Refresh the movie info and do a forced search',
|
'title': 'Refresh the movie info and do a forced search',
|
||||||
'events': {
|
'events': {
|
||||||
'click': self.editMovie.bind(self)
|
'click': self.editMovie.bind(self)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
editMovie: function(e){
|
||||||
|
var self = this;
|
||||||
|
(e).stop();
|
||||||
|
|
||||||
|
if(!self.options_container){
|
||||||
|
self.options_container = new Element('div.options').adopt(
|
||||||
|
$(self.movie.thumbnail).clone(),
|
||||||
|
new Element('div.form', {
|
||||||
|
'styles': {
|
||||||
|
'line-height': self.movie.getHeight()
|
||||||
|
}
|
||||||
|
}).adopt(
|
||||||
|
self.title_select = new Element('select', {
|
||||||
|
'name': 'title'
|
||||||
|
}),
|
||||||
|
self.profile_select = new Element('select', {
|
||||||
|
'name': 'profile'
|
||||||
|
}),
|
||||||
|
new Element('a.button.edit', {
|
||||||
|
'text': 'Save',
|
||||||
|
'events': {
|
||||||
|
'click': self.save.bind(self)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
)
|
||||||
|
).inject(self.movie, 'top');
|
||||||
|
|
||||||
|
Array.each(self.movie.data.library.titles, function(alt){
|
||||||
|
new Element('option', {
|
||||||
|
'text': alt.title
|
||||||
|
}).inject(self.title_select);
|
||||||
|
});
|
||||||
|
|
||||||
|
Object.each(Quality.profiles, function(profile){
|
||||||
|
new Element('option', {
|
||||||
|
'value': profile.id ? profile.id : profile.data.id,
|
||||||
|
'text': profile.label ? profile.label : profile.data.label
|
||||||
|
}).inject(self.profile_select);
|
||||||
|
self.profile_select.set('value', self.movie.profile.get('id'));
|
||||||
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
});
|
self.movie.slide('in');
|
||||||
|
},
|
||||||
|
|
||||||
|
save: function(e){
|
||||||
|
(e).stop();
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
Api.request('movie.edit', {
|
||||||
|
'data': {
|
||||||
|
'id': self.movie.get('id'),
|
||||||
|
'default_title': self.title_select.get('value'),
|
||||||
|
'profile_id': self.profile_select.get('value')
|
||||||
|
},
|
||||||
|
'useSpinner': true,
|
||||||
|
'spinnerTarget': $(self.movie),
|
||||||
|
'onComplete': function(){
|
||||||
|
self.movie.quality.set('text', self.profile_select.getSelected()[0].get('text'));
|
||||||
|
self.movie.title.set('text', self.title_select.getSelected()[0].get('text'));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
self.movie.slide('out');
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
},
|
,'Refresh': new Class({
|
||||||
|
|
||||||
editMovie: function(e){
|
Extends: MovieAction,
|
||||||
var self = this;
|
|
||||||
(e).stop();
|
create: function(){
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
self.el = new Element('a.refresh', {
|
||||||
|
'title': 'Refresh the movie info and do a forced search',
|
||||||
|
'events': {
|
||||||
|
'click': self.doSearch.bind(self)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
doSearch: function(e){
|
||||||
|
var self = this;
|
||||||
|
(e).stop();
|
||||||
|
|
||||||
|
Api.request('movie.refresh', {
|
||||||
|
'data': {
|
||||||
|
'id': self.movie.get('id')
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
if(!self.options_container){
|
,'Delete': new Class({
|
||||||
self.options_container = new Element('div.options').adopt(
|
|
||||||
$(self.movie.thumbnail).clone(),
|
Extends: MovieAction,
|
||||||
new Element('div.form', {
|
|
||||||
|
Implements: [Chain],
|
||||||
|
|
||||||
|
create: function(){
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
self.el = new Element('a.delete', {
|
||||||
|
'title': 'Remove the movie from your wanted list',
|
||||||
|
'events': {
|
||||||
|
'click': self.showConfirm.bind(self)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
showConfirm: function(e){
|
||||||
|
var self = this;
|
||||||
|
(e).stop();
|
||||||
|
|
||||||
|
if(!self.delete_container){
|
||||||
|
self.delete_container = new Element('div.delete_container', {
|
||||||
'styles': {
|
'styles': {
|
||||||
'line-height': self.movie.getHeight()
|
'line-height': self.movie.getHeight()
|
||||||
}
|
}
|
||||||
}).adopt(
|
}).adopt(
|
||||||
self.title_select = new Element('select', {
|
new Element('a.cancel', {
|
||||||
'name': 'title'
|
'text': 'Cancel',
|
||||||
}),
|
|
||||||
self.profile_select = new Element('select', {
|
|
||||||
'name': 'profile'
|
|
||||||
}),
|
|
||||||
new Element('a.button.edit', {
|
|
||||||
'text': 'Save',
|
|
||||||
'events': {
|
'events': {
|
||||||
'click': self.save.bind(self)
|
'click': self.hideConfirm.bind(self)
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
new Element('span.or', {
|
||||||
|
'text': 'or'
|
||||||
|
}),
|
||||||
|
new Element('a.button.delete', {
|
||||||
|
'text': 'Delete ' + self.movie.title.get('text'),
|
||||||
|
'events': {
|
||||||
|
'click': self.del.bind(self)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
)
|
).inject(self.movie, 'top');
|
||||||
).inject(self.movie, 'top');
|
|
||||||
|
|
||||||
Array.each(self.movie.data.library.titles, function(alt){
|
|
||||||
new Element('option', {
|
|
||||||
'text': alt.title
|
|
||||||
}).inject(self.title_select)
|
|
||||||
});
|
|
||||||
|
|
||||||
Object.each(Quality.profiles, function(profile){
|
|
||||||
new Element('option', {
|
|
||||||
'value': profile.id ? profile.id : profile.data.id,
|
|
||||||
'text': profile.label ? profile.label : profile.data.label
|
|
||||||
}).inject(self.profile_select);
|
|
||||||
self.profile_select.set('value', self.movie.profile.get('id'));
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
self.movie.slide('in');
|
|
||||||
},
|
|
||||||
|
|
||||||
save: function(e){
|
|
||||||
(e).stop();
|
|
||||||
var self = this;
|
|
||||||
|
|
||||||
Api.request('movie.edit', {
|
|
||||||
'data': {
|
|
||||||
'id': self.movie.get('id'),
|
|
||||||
'default_title': self.title_select.get('value'),
|
|
||||||
'profile_id': self.profile_select.get('value')
|
|
||||||
},
|
|
||||||
'useSpinner': true,
|
|
||||||
'spinnerTarget': $(self.movie),
|
|
||||||
'onComplete': function(){
|
|
||||||
self.movie.quality.set('text', self.profile_select.getSelected()[0].get('text'))
|
|
||||||
self.movie.title.set('text', self.title_select.getSelected()[0].get('text'))
|
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
self.movie.slide('in');
|
||||||
self.movie.slide('out');
|
|
||||||
}
|
},
|
||||||
|
|
||||||
})
|
hideConfirm: function(e){
|
||||||
|
var self = this;
|
||||||
Wanted.Action.Refresh = new Class({
|
(e).stop();
|
||||||
|
|
||||||
Extends: MovieAction,
|
self.movie.slide('out');
|
||||||
|
},
|
||||||
create: function(){
|
|
||||||
var self = this;
|
del: function(e){
|
||||||
|
(e).stop();
|
||||||
self.el = new Element('a.refresh', {
|
var self = this;
|
||||||
'title': 'Refresh the movie info and do a forced search',
|
|
||||||
'events': {
|
var movie = $(self.movie);
|
||||||
'click': self.doSearch.bind(self)
|
|
||||||
}
|
self.chain(
|
||||||
});
|
function(){
|
||||||
|
$(movie).mask().addClass('loading');
|
||||||
},
|
self.callChain();
|
||||||
|
},
|
||||||
doSearch: function(e){
|
function(){
|
||||||
var self = this;
|
Api.request('movie.delete', {
|
||||||
(e).stop();
|
'data': {
|
||||||
|
'id': self.movie.get('id')
|
||||||
Api.request('movie.refresh', {
|
},
|
||||||
'data': {
|
'onComplete': function(){
|
||||||
'id': self.movie.get('id')
|
movie.set('tween', {
|
||||||
}
|
'onComplete': function(){
|
||||||
})
|
movie.destroy();
|
||||||
}
|
}
|
||||||
|
});
|
||||||
})
|
movie.tween('height', 0);
|
||||||
|
}
|
||||||
Wanted.Action.Delete = new Class({
|
});
|
||||||
|
|
||||||
Extends: MovieAction,
|
|
||||||
|
|
||||||
Implements: [Chain],
|
|
||||||
|
|
||||||
create: function(){
|
|
||||||
var self = this;
|
|
||||||
|
|
||||||
self.el = new Element('a.delete', {
|
|
||||||
'title': 'Remove the movie from your wanted list',
|
|
||||||
'events': {
|
|
||||||
'click': self.showConfirm.bind(self)
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
},
|
|
||||||
|
|
||||||
showConfirm: function(e){
|
|
||||||
var self = this;
|
|
||||||
(e).stop();
|
|
||||||
|
|
||||||
if(!self.delete_container){
|
|
||||||
self.delete_container = new Element('div.delete_container', {
|
|
||||||
'styles': {
|
|
||||||
'line-height': self.movie.getHeight()
|
|
||||||
}
|
}
|
||||||
}).adopt(
|
);
|
||||||
new Element('a.cancel', {
|
|
||||||
'text': 'Cancel',
|
self.callChain();
|
||||||
'events': {
|
|
||||||
'click': self.hideConfirm.bind(self)
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
new Element('span.or', {
|
|
||||||
'text': 'or'
|
|
||||||
}),
|
|
||||||
new Element('a.button.delete', {
|
|
||||||
'text': 'Delete ' + self.movie.title.get('text'),
|
|
||||||
'events': {
|
|
||||||
'click': self.del.bind(self)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
).inject(self.movie, 'top')
|
|
||||||
}
|
}
|
||||||
|
|
||||||
self.movie.slide('in');
|
})
|
||||||
|
};
|
||||||
|
|
||||||
},
|
var SnatchedActions = {
|
||||||
|
'IMBD': IMDBAction
|
||||||
hideConfirm: function(e){
|
,'Releases': ReleaseAction
|
||||||
var self = this;
|
,'Delete': WantedActions.Delete
|
||||||
(e).stop();
|
};
|
||||||
|
|
||||||
self.movie.slide('out');
|
|
||||||
},
|
|
||||||
|
|
||||||
del: function(e){
|
|
||||||
(e).stop()
|
|
||||||
var self = this;
|
|
||||||
|
|
||||||
var movie = $(self.movie);
|
|
||||||
|
|
||||||
self.chain(
|
|
||||||
function(){
|
|
||||||
$(movie).mask().addClass('loading')
|
|
||||||
self.callChain();
|
|
||||||
},
|
|
||||||
function(){
|
|
||||||
Api.request('movie.delete', {
|
|
||||||
'data': {
|
|
||||||
'id': self.movie.get('id')
|
|
||||||
},
|
|
||||||
'onComplete': function(){
|
|
||||||
movie.set('tween', {
|
|
||||||
'onComplete': function(){
|
|
||||||
movie.destroy();
|
|
||||||
}
|
|
||||||
})
|
|
||||||
movie.tween('height', 0)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
self.callChain();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
})
|
|
||||||
@@ -31,10 +31,10 @@
|
|||||||
|
|
||||||
<script type="text/javascript" src="{{ url_for('.static', filename='scripts/page.js') }}"></script>
|
<script type="text/javascript" src="{{ url_for('.static', filename='scripts/page.js') }}"></script>
|
||||||
<script type="text/javascript" src="{{ url_for('.static', filename='scripts/page/wanted.js') }}"></script>
|
<script type="text/javascript" src="{{ url_for('.static', filename='scripts/page/wanted.js') }}"></script>
|
||||||
<script type="text/javascript" src="{{ url_for('.static', filename='scripts/page/settings.js') }}"></script>
|
|
||||||
<script type="text/javascript" src="{{ url_for('.static', filename='scripts/page/log.js') }}"></script>
|
<script type="text/javascript" src="{{ url_for('.static', filename='scripts/page/log.js') }}"></script>
|
||||||
<script type="text/javascript" src="{{ url_for('.static', filename='scripts/page/soon.js') }}"></script>
|
<script type="text/javascript" src="{{ url_for('.static', filename='scripts/page/settings.js') }}"></script>
|
||||||
<script type="text/javascript" src="{{ url_for('.static', filename='scripts/page/manage.js') }}"></script>
|
<!--<script type="text/javascript" src="{{ url_for('.static', filename='scripts/page/soon.js') }}"></script>
|
||||||
|
<script type="text/javascript" src="{{ url_for('.static', filename='scripts/page/manage.js') }}"></script>-->
|
||||||
|
|
||||||
<link href="{{ url_for('.static', filename='images/favicon.ico') }}" rel="icon" type="image/x-icon" />
|
<link href="{{ url_for('.static', filename='images/favicon.ico') }}" rel="icon" type="image/x-icon" />
|
||||||
<link rel="apple-touch-icon" href="{{ url_for('.static', filename='images/homescreen.png') }}" />
|
<link rel="apple-touch-icon" href="{{ url_for('.static', filename='images/homescreen.png') }}" />
|
||||||
|
|||||||
Reference in new issue
Block a user