Enabler option
This commit is contained in:
+1
-1
@@ -133,7 +133,7 @@ def cmd_couchpotato(base_path, args):
|
|||||||
|
|
||||||
# Register modules
|
# Register modules
|
||||||
app.register_module(web, url_prefix = '%s/' % url_base)
|
app.register_module(web, url_prefix = '%s/' % url_base)
|
||||||
app.register_module(api, url_prefix = '%s/%s/' % (url_base, api_key if not debug else 'api'))
|
app.register_module(api, url_prefix = '%s/%s/' % (url_base, api_key))
|
||||||
|
|
||||||
# Go go go!
|
# Go go go!
|
||||||
app.run(use_reloader = reloader)
|
app.run(use_reloader = reloader)
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ config = [{
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
'name': 'launch_browser',
|
'name': 'launch_browser',
|
||||||
'default': True,
|
'default': 1,
|
||||||
'type': 'bool',
|
'type': 'bool',
|
||||||
'label': 'Launch Browser',
|
'label': 'Launch Browser',
|
||||||
'description': 'Launch the browser when I start.',
|
'description': 'Launch the browser when I start.',
|
||||||
@@ -51,13 +51,13 @@ config = [{
|
|||||||
{
|
{
|
||||||
'name': 'api_key',
|
'name': 'api_key',
|
||||||
'default': uuid4().hex,
|
'default': uuid4().hex,
|
||||||
'readonly': True,
|
'readonly': 1,
|
||||||
'label': 'Api Key',
|
'label': 'Api Key',
|
||||||
'description': "This is top-secret! Don't share this!",
|
'description': "This is top-secret! Don't share this!",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'name': 'debug',
|
'name': 'debug',
|
||||||
'default': False,
|
'default': 0,
|
||||||
'type': 'bool',
|
'type': 'bool',
|
||||||
'label': 'Debug',
|
'label': 'Debug',
|
||||||
'description': 'Enable debugging.',
|
'description': 'Enable debugging.',
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
from couchpotato.core.event import addEvent
|
from couchpotato.core.event import addEvent
|
||||||
from couchpotato.core.plugins.base import Plugin
|
from couchpotato.core.plugins.base import Plugin
|
||||||
from couchpotato.environment import Env
|
|
||||||
|
|
||||||
class Downloader(Plugin):
|
class Downloader(Plugin):
|
||||||
|
|
||||||
@@ -10,9 +10,6 @@ class Downloader(Plugin):
|
|||||||
def download(self, data = {}):
|
def download(self, data = {}):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def conf(self, attr):
|
|
||||||
return Env.setting(attr, self.__class__.__name__.lower())
|
|
||||||
|
|
||||||
def isDisabled(self):
|
def isDisabled(self):
|
||||||
return not self.isEnabled()
|
return not self.isEnabled()
|
||||||
|
|
||||||
|
|||||||
@@ -10,20 +10,16 @@ config = [{
|
|||||||
'tab': 'downloaders',
|
'tab': 'downloaders',
|
||||||
'name': 'blackhole',
|
'name': 'blackhole',
|
||||||
'label': 'Black hole',
|
'label': 'Black hole',
|
||||||
'description': 'Fill in your Sabnzbd settings.',
|
'description': 'Download NZBs to a specific folder.',
|
||||||
'options': [
|
'options': [
|
||||||
{
|
{
|
||||||
'name': 'enabled',
|
'name': 'enabled',
|
||||||
'default': False,
|
'default': 0,
|
||||||
'type': 'bool',
|
'type': 'enabler',
|
||||||
'label': 'Enabled',
|
|
||||||
'description': 'Send snatched NZBs to Sabnzbd',
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'name': 'directory',
|
'name': 'directory',
|
||||||
'default': '',
|
|
||||||
'type': 'directory',
|
'type': 'directory',
|
||||||
'label': 'Directory',
|
|
||||||
'description': 'Directory where the .nzb (or .torrent) file is saved to.',
|
'description': 'Directory where the .nzb (or .torrent) file is saved to.',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -10,26 +10,19 @@ config = [{
|
|||||||
'tab': 'downloaders',
|
'tab': 'downloaders',
|
||||||
'name': 'sabnzbd',
|
'name': 'sabnzbd',
|
||||||
'label': 'Sabnzbd',
|
'label': 'Sabnzbd',
|
||||||
'description': 'Fill in your Sabnzbd settings.',
|
'description': 'Send NZBs to your Sabnzbd installation.',
|
||||||
'options': [
|
'options': [
|
||||||
{
|
{
|
||||||
'name': 'enabled',
|
'name': 'enabled',
|
||||||
'default': False,
|
'default': 0,
|
||||||
'type': 'bool',
|
'type': 'enabler',
|
||||||
'label': 'Enabled',
|
|
||||||
'description': 'Send snatched NZBs to Sabnzbd',
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'name': 'host',
|
'name': 'host',
|
||||||
'default': 'localhost:8080',
|
'default': 'localhost:8080',
|
||||||
'type': 'string',
|
|
||||||
'label': 'Host',
|
|
||||||
'description': 'Test',
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'name': 'api_key',
|
'name': 'api_key',
|
||||||
'default': '',
|
|
||||||
'type': 'string',
|
|
||||||
'label': 'Api Key',
|
'label': 'Api Key',
|
||||||
'description': 'Used for all calls to Sabnzbd.',
|
'description': 'Used for all calls to Sabnzbd.',
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
from couchpotato.core.event import addEvent
|
from couchpotato.core.event import addEvent
|
||||||
from couchpotato.core.helpers.request import jsonified
|
from couchpotato.core.helpers.request import jsonified
|
||||||
from couchpotato.core.plugins.base import Plugin
|
from couchpotato.core.plugins.base import Plugin
|
||||||
from couchpotato.environment import Env
|
|
||||||
|
|
||||||
class Notification(Plugin):
|
class Notification(Plugin):
|
||||||
|
|
||||||
@@ -14,9 +14,6 @@ class Notification(Plugin):
|
|||||||
def notify(self, message = '', data = {}):
|
def notify(self, message = '', data = {}):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def conf(self, attr):
|
|
||||||
return Env.setting(attr, self.__class__.__name__.lower())
|
|
||||||
|
|
||||||
def isDisabled(self):
|
def isDisabled(self):
|
||||||
return not self.isEnabled()
|
return not self.isEnabled()
|
||||||
|
|
||||||
|
|||||||
@@ -12,20 +12,16 @@ config = [{
|
|||||||
'options': [
|
'options': [
|
||||||
{
|
{
|
||||||
'name': 'enabled',
|
'name': 'enabled',
|
||||||
'default': False,
|
'default': 0,
|
||||||
'type': 'enabler',
|
'type': 'enabler',
|
||||||
'description': '',
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'name': 'host',
|
'name': 'host',
|
||||||
'default': 'localhost',
|
'default': 'localhost',
|
||||||
'description': '',
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'name': 'password',
|
'name': 'password',
|
||||||
'default': '',
|
|
||||||
'type': 'password',
|
'type': 'password',
|
||||||
'description': '',
|
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,23 +13,18 @@ config = [{
|
|||||||
'options': [
|
'options': [
|
||||||
{
|
{
|
||||||
'name': 'enabled',
|
'name': 'enabled',
|
||||||
'default': False,
|
'default': 0,
|
||||||
'type': 'enabler',
|
'type': 'enabler',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'name': 'host',
|
'name': 'host',
|
||||||
'default': 'localhost',
|
'default': 'localhost',
|
||||||
'description': '',
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'name': 'database',
|
'name': 'database',
|
||||||
'default': '',
|
|
||||||
'description': '',
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'name': 'mount',
|
'name': 'mount',
|
||||||
'default': '',
|
|
||||||
'description': '',
|
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,17 +13,14 @@ config = [{
|
|||||||
'options': [
|
'options': [
|
||||||
{
|
{
|
||||||
'name': 'enabled',
|
'name': 'enabled',
|
||||||
'default': False,
|
'default': 0,
|
||||||
'type': 'enabler',
|
'type': 'enabler',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'name': 'username',
|
'name': 'username',
|
||||||
'default': '',
|
|
||||||
'type': 'string',
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'name': 'password',
|
'name': 'password',
|
||||||
'default': '',
|
|
||||||
'type': 'password',
|
'type': 'password',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -12,20 +12,16 @@ config = [{
|
|||||||
'options': [
|
'options': [
|
||||||
{
|
{
|
||||||
'name': 'enabled',
|
'name': 'enabled',
|
||||||
'default': False,
|
'default': 0,
|
||||||
'type': 'enabler',
|
'type': 'enabler',
|
||||||
'description': '',
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'name': 'host',
|
'name': 'host',
|
||||||
'default': 'localhost',
|
'default': 'localhost',
|
||||||
'description': '',
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'name': 'password',
|
'name': 'password',
|
||||||
'default': '',
|
|
||||||
'type': 'password',
|
'type': 'password',
|
||||||
'description': '',
|
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,21 +12,17 @@ config = [{
|
|||||||
'options': [
|
'options': [
|
||||||
{
|
{
|
||||||
'name': 'enabled',
|
'name': 'enabled',
|
||||||
'default': False,
|
'default': 0,
|
||||||
'type': 'enabler',
|
'type': 'enabler',
|
||||||
'description': '',
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'name': 'api_key',
|
'name': 'api_key',
|
||||||
'default': '',
|
|
||||||
'label': 'Api key',
|
'label': 'Api key',
|
||||||
'description': '',
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'name': 'priority',
|
'name': 'priority',
|
||||||
'default': '0',
|
'default': '0',
|
||||||
'type': 'dropdown',
|
'type': 'dropdown',
|
||||||
'description': '',
|
|
||||||
'values': [('Very Low', -2), ('Moderate', -1), ('Normal', 0), ('High', 1), ('Emergency', 2)]
|
'values': [('Very Low', -2), ('Moderate', -1), ('Normal', 0), ('High', 1), ('Emergency', 2)]
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -12,25 +12,21 @@ config = [{
|
|||||||
'options': [
|
'options': [
|
||||||
{
|
{
|
||||||
'name': 'enabled',
|
'name': 'enabled',
|
||||||
'default': False,
|
'default': 0,
|
||||||
'type': 'enabler',
|
'type': 'enabler',
|
||||||
'description': '',
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'name': 'host',
|
'name': 'host',
|
||||||
'default': 'localhost:8080',
|
'default': 'localhost:8080',
|
||||||
'description': '',
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'name': 'username',
|
'name': 'username',
|
||||||
'default': 'xbmc',
|
'default': 'xbmc',
|
||||||
'description': '',
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'name': 'password',
|
'name': 'password',
|
||||||
'default': 'xbmc',
|
'default': 'xbmc',
|
||||||
'type': 'password',
|
'type': 'password',
|
||||||
'description': '',
|
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
|
from couchpotato.environment import Env
|
||||||
|
|
||||||
|
|
||||||
class Plugin():
|
class Plugin():
|
||||||
|
|
||||||
def __init__(self):
|
def conf(self, attr):
|
||||||
pass
|
return Env.setting(attr, self.__class__.__name__.lower())
|
||||||
|
|||||||
@@ -8,24 +8,22 @@ if os.name == 'nt':
|
|||||||
|
|
||||||
class FileBrowser():
|
class FileBrowser():
|
||||||
|
|
||||||
def __init__(self, path = '/'):
|
def __init__(self):
|
||||||
self.path = path
|
|
||||||
|
|
||||||
addApiView('directory.list', self.view)
|
addApiView('directory.list', self.view)
|
||||||
|
|
||||||
def getDirectories(self):
|
def getDirectories(self, path = '/', show_hidden = True):
|
||||||
|
|
||||||
# Return driveletters or root if path is empty
|
# Return driveletters or root if path is empty
|
||||||
if self.path == '/' or not self.path:
|
if path == '/' or not path:
|
||||||
if os.name == 'nt':
|
if os.name == 'nt':
|
||||||
return self.getDriveLetters()
|
return self.getDriveLetters()
|
||||||
self.path = '/'
|
path = '/'
|
||||||
|
|
||||||
dirs = []
|
dirs = []
|
||||||
for f in os.listdir(self.path):
|
for f in os.listdir(path):
|
||||||
path = os.path.join(self.path, f)
|
p = os.path.join(path, f)
|
||||||
if(os.path.isdir(path)):
|
if(os.path.isdir(p)):
|
||||||
dirs.append(path)
|
dirs.append(p + '/')
|
||||||
|
|
||||||
return dirs
|
return dirs
|
||||||
|
|
||||||
@@ -44,8 +42,7 @@ class FileBrowser():
|
|||||||
def view(self):
|
def view(self):
|
||||||
|
|
||||||
try:
|
try:
|
||||||
fb = FileBrowser(getParam('path', '/'))
|
dirs = self.getDirectories(path = getParam('path', '/'), show_hidden = getParam('show_hidden', True))
|
||||||
dirs = fb.getDirectories()
|
|
||||||
except:
|
except:
|
||||||
dirs = []
|
dirs = []
|
||||||
|
|
||||||
|
|||||||
@@ -3,11 +3,8 @@ from couchpotato.core.plugins.base import Plugin
|
|||||||
|
|
||||||
log = CPLog(__name__)
|
log = CPLog(__name__)
|
||||||
|
|
||||||
|
|
||||||
class Provider(Plugin):
|
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
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ from imdb import IMDb
|
|||||||
|
|
||||||
log = CPLog(__name__)
|
log = CPLog(__name__)
|
||||||
|
|
||||||
|
|
||||||
class IMDB(Provider):
|
class IMDB(Provider):
|
||||||
|
|
||||||
type = 'movie'
|
type = 'movie'
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
from couchpotato.core.providers.tmdb.main import TMDBWrapper
|
from .main import TheMovieDb
|
||||||
|
|
||||||
def start():
|
def start():
|
||||||
return TMDBWrapper()
|
return TheMovieDb()
|
||||||
|
|
||||||
config = [{
|
config = [{
|
||||||
'name': 'themoviedb',
|
'name': 'themoviedb',
|
||||||
@@ -11,13 +11,12 @@ config = [{
|
|||||||
'name': 'tmdb',
|
'name': 'tmdb',
|
||||||
'label': 'TheMovieDB',
|
'label': 'TheMovieDB',
|
||||||
'advanced': True,
|
'advanced': True,
|
||||||
|
'description': 'Used for all calls to TheMovieDB.',
|
||||||
'options': [
|
'options': [
|
||||||
{
|
{
|
||||||
'name': 'api_key',
|
'name': 'api_key',
|
||||||
'default': '9b939aee0aaafc12a65bf448e4af9543',
|
'default': '9b939aee0aaafc12a65bf448e4af9543',
|
||||||
'type': 'string',
|
|
||||||
'label': 'Api Key',
|
'label': 'Api Key',
|
||||||
'description': 'Used for all calls to TheMovieDB.',
|
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -3,13 +3,12 @@ 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 Provider
|
||||||
from couchpotato.environment import Env
|
|
||||||
from libs.themoviedb import tmdb
|
from libs.themoviedb import tmdb
|
||||||
import copy
|
|
||||||
|
|
||||||
log = CPLog(__name__)
|
log = CPLog(__name__)
|
||||||
|
|
||||||
class TMDBWrapper(Provider):
|
|
||||||
|
class TheMovieDb(Provider):
|
||||||
"""Api for theMovieDb"""
|
"""Api for theMovieDb"""
|
||||||
|
|
||||||
type = 'movie'
|
type = 'movie'
|
||||||
@@ -23,9 +22,6 @@ class TMDBWrapper(Provider):
|
|||||||
# Use base wrapper
|
# Use base wrapper
|
||||||
tmdb.Config.api_key = self.conf('api_key')
|
tmdb.Config.api_key = self.conf('api_key')
|
||||||
|
|
||||||
def conf(self, attr):
|
|
||||||
return Env.setting(attr, 'themoviedb')
|
|
||||||
|
|
||||||
def search(self, q, limit = 12):
|
def search(self, q, limit = 12):
|
||||||
''' Find movie by name '''
|
''' Find movie by name '''
|
||||||
|
|
||||||
|
|||||||
@@ -108,13 +108,13 @@ class Settings():
|
|||||||
|
|
||||||
def saveView(self):
|
def saveView(self):
|
||||||
|
|
||||||
a = getParams()
|
params = getParams()
|
||||||
|
|
||||||
section = a.get('section')
|
section = params.get('section')
|
||||||
option = a.get('name')
|
option = params.get('name')
|
||||||
value = a.get('value')
|
value = params.get('value')
|
||||||
|
|
||||||
self.set(option, section, value)
|
self.set(section, option, value)
|
||||||
self.save()
|
self.save()
|
||||||
|
|
||||||
return jsonified({
|
return jsonified({
|
||||||
|
|||||||
@@ -33,12 +33,6 @@ Block.Search = new Class({
|
|||||||
|
|
||||||
self.spinner = new Spinner(self.result_container);
|
self.spinner = new Spinner(self.result_container);
|
||||||
|
|
||||||
self.OuterClickStack = new EventStack.OuterClick();
|
|
||||||
History.addEvent('change', self.hideResults.bind(self, true));
|
|
||||||
|
|
||||||
//debug
|
|
||||||
//self.input.set('value', 'kick ass')
|
|
||||||
//self.autocomplete()
|
|
||||||
},
|
},
|
||||||
|
|
||||||
clear: function(e){
|
clear: function(e){
|
||||||
@@ -59,8 +53,14 @@ Block.Search = new Class({
|
|||||||
|
|
||||||
self.result_container.fade(bool ? 0 : 1)
|
self.result_container.fade(bool ? 0 : 1)
|
||||||
|
|
||||||
if(!bool && self.OuterClickStack.stack.length == 0)
|
if(bool){
|
||||||
self.OuterClickStack.push(self.hideResults.bind(self, true), self.el);
|
History.removeEvent('change', self.hideResults.bind(self, !bool));
|
||||||
|
self.el.removeEvent('outerClick', self.hideResults.bind(self, !bool));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
History.addEvent('change', self.hideResults.bind(self, !bool));
|
||||||
|
self.el.addEvent('outerClick', self.hideResults.bind(self, !bool));
|
||||||
|
}
|
||||||
|
|
||||||
self.hidden = bool;
|
self.hidden = bool;
|
||||||
},
|
},
|
||||||
@@ -161,8 +161,6 @@ Block.Search.Item = new Class({
|
|||||||
self.alternative_titles = [];
|
self.alternative_titles = [];
|
||||||
|
|
||||||
self.create();
|
self.create();
|
||||||
|
|
||||||
self.OuterClickStack = new EventStack.OuterClick();
|
|
||||||
},
|
},
|
||||||
|
|
||||||
create: function(){
|
create: function(){
|
||||||
@@ -239,7 +237,7 @@ Block.Search.Item = new Class({
|
|||||||
|
|
||||||
self.data_container.tween('margin-left', 0, self.width);
|
self.data_container.tween('margin-left', 0, self.width);
|
||||||
|
|
||||||
self.OuterClickStack.push(self.closeOptions.bind(self), self.el);
|
self.el.addEvents('outerClick', self.closeOptions.bind(self))
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -321,6 +319,7 @@ Block.Search.Item = new Class({
|
|||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
self.data_container.tween('margin-left', self.width, 0);
|
self.data_container.tween('margin-left', self.width, 0);
|
||||||
|
self.el.removeEvents('outerClick', self.closeOptions.bind(self))
|
||||||
},
|
},
|
||||||
|
|
||||||
toElement: function(){
|
toElement: function(){
|
||||||
|
|||||||
@@ -186,6 +186,45 @@ var p = function(){
|
|||||||
console.log(arguments)
|
console.log(arguments)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
(function(){
|
||||||
|
var events;
|
||||||
|
|
||||||
|
var check = function(e) {
|
||||||
|
var target = $(e.target);
|
||||||
|
var parents = target.getParents();
|
||||||
|
events.each(function(item) {
|
||||||
|
var element = item.element;
|
||||||
|
if (element != target && !parents.contains(element))
|
||||||
|
item.fn.call(element, e);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
Element.Events.outerClick = {
|
||||||
|
onAdd : function(fn) {
|
||||||
|
if (!events) {
|
||||||
|
document.addEvent('click', check);
|
||||||
|
events = [];
|
||||||
|
}
|
||||||
|
events.push( {
|
||||||
|
element : this,
|
||||||
|
fn : fn
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
onRemove : function(fn) {
|
||||||
|
events = events.filter(function(item) {
|
||||||
|
return item.element != this || item.fn != fn;
|
||||||
|
}, this);
|
||||||
|
if (!events.length) {
|
||||||
|
document.removeEvent('click', check);
|
||||||
|
events = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
})();
|
||||||
|
|
||||||
|
|
||||||
function randomString(length, extra) {
|
function randomString(length, extra) {
|
||||||
var chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz" + (extra ? '-._!@#$%^&*()+=' : '');
|
var chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz" + (extra ? '-._!@#$%^&*()+=' : '');
|
||||||
var stringLength = length || 8;
|
var stringLength = length || 8;
|
||||||
|
|||||||
@@ -1,71 +0,0 @@
|
|||||||
/*
|
|
||||||
---
|
|
||||||
|
|
||||||
name: EventStack
|
|
||||||
|
|
||||||
description: Helps you Escape.
|
|
||||||
|
|
||||||
authors: Christoph Pojer (@cpojer)
|
|
||||||
|
|
||||||
license: MIT-style license.
|
|
||||||
|
|
||||||
requires: [Core/Class.Extras, Core/Element.Event, Class-Extras/Class.Binds]
|
|
||||||
|
|
||||||
provides: EventStack
|
|
||||||
|
|
||||||
...
|
|
||||||
*/
|
|
||||||
|
|
||||||
(function(){
|
|
||||||
|
|
||||||
this.EventStack = new Class({
|
|
||||||
|
|
||||||
Implements: [Options, Class.Binds],
|
|
||||||
|
|
||||||
options: {
|
|
||||||
event: 'keyup',
|
|
||||||
condition: function(event){
|
|
||||||
return (event.key == 'esc');
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
initialize: function(options){
|
|
||||||
this.setOptions(options);
|
|
||||||
this.stack = [];
|
|
||||||
this.data = [];
|
|
||||||
|
|
||||||
document.addEvent(this.options.event, this.bound('condition'));
|
|
||||||
},
|
|
||||||
|
|
||||||
condition: function(event){
|
|
||||||
if (this.options.condition.call(this, event, this.data.getLast()))
|
|
||||||
this.pop(event);
|
|
||||||
},
|
|
||||||
|
|
||||||
erase: function(fn){
|
|
||||||
this.data.erase(this.data[this.stack.indexOf(fn)]);
|
|
||||||
this.stack.erase(fn);
|
|
||||||
|
|
||||||
return this;
|
|
||||||
},
|
|
||||||
|
|
||||||
push: function(fn, data){
|
|
||||||
this.erase(fn);
|
|
||||||
this.data.push(data || null);
|
|
||||||
this.stack.push(fn);
|
|
||||||
|
|
||||||
return this;
|
|
||||||
},
|
|
||||||
|
|
||||||
pop: function(event){
|
|
||||||
var fn = this.stack.pop(),
|
|
||||||
data = this.data.pop();
|
|
||||||
|
|
||||||
if (fn) fn.call(this, event, data);
|
|
||||||
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
}).call(this);
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
/*
|
|
||||||
---
|
|
||||||
|
|
||||||
name: EventStack.OuterClick
|
|
||||||
|
|
||||||
description: Helps you escape from clicks outside of a certain area.
|
|
||||||
|
|
||||||
authors: Christoph Pojer (@cpojer)
|
|
||||||
|
|
||||||
license: MIT-style license.
|
|
||||||
|
|
||||||
requires: [EventStack]
|
|
||||||
|
|
||||||
provides: EventStack.OuterClick
|
|
||||||
|
|
||||||
...
|
|
||||||
*/
|
|
||||||
|
|
||||||
EventStack.OuterClick = new Class({
|
|
||||||
|
|
||||||
Extends: EventStack,
|
|
||||||
|
|
||||||
options: {
|
|
||||||
event: 'click',
|
|
||||||
condition: function(event, element){
|
|
||||||
return element && !element.contains(event.target);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
@@ -77,7 +77,7 @@ Page.Settings = new Class({
|
|||||||
getValue: function(section, name){
|
getValue: function(section, name){
|
||||||
var self = this;
|
var self = this;
|
||||||
try {
|
try {
|
||||||
return self.data.values[section][name] || '';
|
return self.data.values[section][name];
|
||||||
}
|
}
|
||||||
catch(e){
|
catch(e){
|
||||||
return ''
|
return ''
|
||||||
@@ -131,6 +131,7 @@ Page.Settings = new Class({
|
|||||||
var class_name = (option.type || 'string').capitalize();
|
var class_name = (option.type || 'string').capitalize();
|
||||||
var input = new Option[class_name](self, section_name, option.name, option);
|
var input = new Option[class_name](self, section_name, option.name, option);
|
||||||
input.inject(group_el);
|
input.inject(group_el);
|
||||||
|
input.fireEvent('injected')
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
@@ -218,6 +219,8 @@ var OptionBase = new Class({
|
|||||||
'keyup': self.changed.bind(self)
|
'keyup': self.changed.bind(self)
|
||||||
});
|
});
|
||||||
|
|
||||||
|
self.addEvent('injected', self.afterInject.bind(self))
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -249,6 +252,8 @@ var OptionBase = new Class({
|
|||||||
}).inject(self.el);
|
}).inject(self.el);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
afterInject: function(){},
|
||||||
|
|
||||||
// Element has changed, do something
|
// Element has changed, do something
|
||||||
changed: function(){
|
changed: function(){
|
||||||
var self = this;
|
var self = this;
|
||||||
@@ -266,7 +271,7 @@ var OptionBase = new Class({
|
|||||||
save: function(){
|
save: function(){
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
Api.request('setting.save', {
|
Api.request('settings.save', {
|
||||||
'data': {
|
'data': {
|
||||||
'section': self.section,
|
'section': self.section,
|
||||||
'name': self.name,
|
'name': self.name,
|
||||||
@@ -327,7 +332,7 @@ var Option = {}
|
|||||||
Option.String = new Class({
|
Option.String = new Class({
|
||||||
Extends: OptionBase,
|
Extends: OptionBase,
|
||||||
|
|
||||||
type: 'input',
|
type: 'string',
|
||||||
|
|
||||||
create: function(){
|
create: function(){
|
||||||
var self = this
|
var self = this
|
||||||
@@ -375,23 +380,35 @@ Option.Checkbox = new Class({
|
|||||||
create: function(){
|
create: function(){
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
var randomId = 'option-'+Math.floor(Math.random()*1000000)
|
var randomId = 'r-'+randomString()
|
||||||
|
|
||||||
self.el.adopt(
|
self.el.adopt(
|
||||||
self.createLabel().set('for', randomId),
|
self.createLabel().set('for', randomId),
|
||||||
self.input = new Element('input', {
|
self.input = new Element('input', {
|
||||||
'type': 'checkbox',
|
'type': 'checkbox',
|
||||||
'value': self.getSettingValue(),
|
'checked': self.getSettingValue(),
|
||||||
'checked': self.getSettingValue() !== undefined,
|
|
||||||
'id': randomId
|
'id': randomId
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
getValue: function(){
|
||||||
|
var self = this;
|
||||||
|
return +self.input.checked;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Option.Password = new Class({
|
Option.Password = new Class({
|
||||||
Extends: Option.String,
|
Extends: Option.String,
|
||||||
type: 'password'
|
type: 'password',
|
||||||
|
|
||||||
|
create: function(){
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
self.parent()
|
||||||
|
self.input.set('type', 'password')
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Option.Bool = new Class({
|
Option.Bool = new Class({
|
||||||
@@ -399,7 +416,37 @@ Option.Bool = new Class({
|
|||||||
});
|
});
|
||||||
|
|
||||||
Option.Enabler = new Class({
|
Option.Enabler = new Class({
|
||||||
Extends: Option.Bool
|
Extends: Option.Bool,
|
||||||
|
|
||||||
|
create: function(){
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
self.el.adopt(
|
||||||
|
self.input = new Element('input', {
|
||||||
|
'type': 'checkbox',
|
||||||
|
'checked': self.getSettingValue(),
|
||||||
|
'id': 'r-'+randomString(),
|
||||||
|
'events': {
|
||||||
|
'change': self.checkState.bind(self)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
)
|
||||||
|
},
|
||||||
|
|
||||||
|
checkState: function(){
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
self.parentFieldset[ self.getValue() ? 'addClass' : 'removeClass']('enabled');
|
||||||
|
},
|
||||||
|
|
||||||
|
afterInject: function(){
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
self.parentFieldset = self.el.getParent('fieldset')
|
||||||
|
self.el.inject(self.parentFieldset, 'top')
|
||||||
|
self.checkState()
|
||||||
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
Option.Int = new Class({
|
Option.Int = new Class({
|
||||||
@@ -413,18 +460,17 @@ Option.Directory = new Class({
|
|||||||
type: 'span',
|
type: 'span',
|
||||||
browser: '',
|
browser: '',
|
||||||
save_on_change: false,
|
save_on_change: false,
|
||||||
|
show_hidden: false,
|
||||||
|
|
||||||
create: function(){
|
create: function(){
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
|
|
||||||
self.el.adopt(
|
self.el.adopt(
|
||||||
self.createLabel(),
|
self.createLabel(),
|
||||||
self.input = new Element('span', {
|
self.input = new Element('span', {
|
||||||
'text': self.getSettingValue(),
|
'text': self.getSettingValue(),
|
||||||
'events': {
|
'events': {
|
||||||
'click': self.showBrowser.bind(self),
|
'click': self.showBrowser.bind(self)
|
||||||
'outerClick': self.hideBrowser.bind(self)
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
@@ -432,47 +478,99 @@ Option.Directory = new Class({
|
|||||||
self.cached = {};
|
self.cached = {};
|
||||||
},
|
},
|
||||||
|
|
||||||
|
selectDirectory: function(e, el){
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
self.input.set('text', el.get('data-value'));
|
||||||
|
|
||||||
|
self.getDirs()
|
||||||
|
self.fireEvent('change')
|
||||||
|
},
|
||||||
|
|
||||||
|
previousDirectory: function(e){
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
self.selectDirectory(null, self.back_button)
|
||||||
|
},
|
||||||
|
|
||||||
showBrowser: function(){
|
showBrowser: function(){
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
if(!self.browser)
|
if(!self.browser)
|
||||||
self.browser = new Element('div.directory_list').adopt(
|
self.browser = new Element('div.directory_list').adopt(
|
||||||
self.dir_list = new Element('ul')
|
self.back_button = new Element('a.button.back', {
|
||||||
|
'text': '',
|
||||||
|
'events': {
|
||||||
|
'click': self.previousDirectory.bind(self)
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
self.dir_list = new Element('ul', {
|
||||||
|
'events': {
|
||||||
|
'click:relay(li)': self.selectDirectory.bind(self)
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
new Element('div.actions').adopt(
|
||||||
|
new Element('a.button.cancel', {
|
||||||
|
'text': 'Cancel',
|
||||||
|
'events': {
|
||||||
|
'click': self.hideBrowser.bind(self)
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
new Element('span', {
|
||||||
|
'text': 'or'
|
||||||
|
}),
|
||||||
|
self.save_button = new Element('a.button.save', {
|
||||||
|
'text': 'Save',
|
||||||
|
'events': {
|
||||||
|
'click': self.hideBrowser.bind(self, true)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
)
|
||||||
).inject(self.input, 'after')
|
).inject(self.input, 'after')
|
||||||
|
|
||||||
self.getDirs()
|
self.getDirs()
|
||||||
self.browser.show()
|
self.browser.show()
|
||||||
|
self.el.addEvent('outerClick', self.hideBrowser.bind(self))
|
||||||
},
|
},
|
||||||
|
|
||||||
hideBrowser: function(){
|
hideBrowser: function(save){
|
||||||
this.browser.hide()
|
var self = this;
|
||||||
|
|
||||||
|
if(save) self.save()
|
||||||
|
|
||||||
|
self.browser.hide()
|
||||||
|
self.el.removeEvent('outerClick', self.hideBrowser.bind(self))
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
fillBrowser: function(json){
|
fillBrowser: function(json){
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
var c = self.getCurrentDir();
|
var c = self.getParentDir();
|
||||||
var v = self.input.get('value');
|
var v = self.input.get('text');
|
||||||
var add = true
|
var previous_dir = self.getParentDir(c.substring(0, c.length-1));
|
||||||
|
|
||||||
if(!json){
|
if(previous_dir){
|
||||||
json = self.cached[c];
|
self.back_button.set('data-value', previous_dir)
|
||||||
|
self.back_button.set('text', self.getCurrentDirname(previous_dir))
|
||||||
|
self.back_button.show()
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
self.cached[c] = json;
|
self.back_button.hide()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(!json)
|
||||||
|
json = self.cached[c];
|
||||||
|
else
|
||||||
|
self.cached[c] = json;
|
||||||
|
|
||||||
self.dir_list.empty();
|
self.dir_list.empty();
|
||||||
json.dirs.each(function(dir){
|
json.dirs.each(function(dir){
|
||||||
if(dir.indexOf(v) != -1){
|
if(dir.indexOf(v) != -1){
|
||||||
new Element('li', {
|
new Element('li', {
|
||||||
'text': dir
|
'data-value': dir,
|
||||||
|
'text': self.getCurrentDirname(dir)
|
||||||
}).inject(self.dir_list)
|
}).inject(self.dir_list)
|
||||||
|
|
||||||
if(add){
|
|
||||||
self.input.insertAtCursor(dir.substring(v.length), true);
|
|
||||||
add = false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
@@ -480,7 +578,7 @@ Option.Directory = new Class({
|
|||||||
getDirs: function(){
|
getDirs: function(){
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
var c = self.getCurrentDir();
|
var c = self.getParentDir();
|
||||||
|
|
||||||
if(self.cached[c]){
|
if(self.cached[c]){
|
||||||
self.fillBrowser()
|
self.fillBrowser()
|
||||||
@@ -488,22 +586,31 @@ Option.Directory = new Class({
|
|||||||
else {
|
else {
|
||||||
Api.request('directory.list', {
|
Api.request('directory.list', {
|
||||||
'data': {
|
'data': {
|
||||||
'path': c
|
'path': c,
|
||||||
|
'show_hidden': +self.show_hidden
|
||||||
},
|
},
|
||||||
'onComplete': self.fillBrowser.bind(self)
|
'onComplete': self.fillBrowser.bind(self)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
getCurrentDir: function(){
|
getParentDir: function(dir){
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
var v = self.input.get('value');
|
var v = dir || self.input.get('text');
|
||||||
var sep = Api.getOption('path_sep');
|
var sep = Api.getOption('path_sep');
|
||||||
var dirs = v.split(sep);
|
var dirs = v.split(sep);
|
||||||
dirs.pop();
|
dirs.pop();
|
||||||
|
|
||||||
return dirs.join(sep)
|
return dirs.join(sep) + sep
|
||||||
|
},
|
||||||
|
|
||||||
|
getCurrentDirname: function(dir){
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
var dir_split = dir.split(Api.getOption('path_sep'));
|
||||||
|
|
||||||
|
return dir_split[dir_split.length-2] || '/'
|
||||||
},
|
},
|
||||||
|
|
||||||
getValue: function(){
|
getValue: function(){
|
||||||
|
|||||||
@@ -297,19 +297,19 @@ Movie.Action.Delete = new Class({
|
|||||||
});
|
});
|
||||||
|
|
||||||
$(self.mask).adopt(
|
$(self.mask).adopt(
|
||||||
new Element('a.button.delete', {
|
new Element('a.button.cancel', {
|
||||||
'text': 'Delete movie',
|
'text': 'Cancel',
|
||||||
'events': {
|
'events': {
|
||||||
'click': self.del.bind(self)
|
'click': self.mask.hide.bind(self.mask)
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
new Element('span', {
|
new Element('span', {
|
||||||
'text': 'or'
|
'text': 'or'
|
||||||
}),
|
}),
|
||||||
new Element('a.button.cancel', {
|
new Element('a.button.delete', {
|
||||||
'text': 'Cancel',
|
'text': 'Delete movie',
|
||||||
'events': {
|
'events': {
|
||||||
'click': self.mask.hide.bind(self.mask)
|
'click': self.del.bind(self)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -15,8 +15,6 @@
|
|||||||
<script type="text/javascript" src="{{ url_for('.static', filename='scripts/library/uniform.js') }}"></script>
|
<script type="text/javascript" src="{{ url_for('.static', filename='scripts/library/uniform.js') }}"></script>
|
||||||
<script type="text/javascript" src="{{ url_for('.static', filename='scripts/couchpotato.js') }}"></script>
|
<script type="text/javascript" src="{{ url_for('.static', filename='scripts/couchpotato.js') }}"></script>
|
||||||
<script type="text/javascript" src="{{ url_for('.static', filename='scripts/library/history.js') }}"></script>
|
<script type="text/javascript" src="{{ url_for('.static', filename='scripts/library/history.js') }}"></script>
|
||||||
<script type="text/javascript" src="{{ url_for('.static', filename='scripts/library/eventstack.js') }}"></script>
|
|
||||||
<script type="text/javascript" src="{{ url_for('.static', filename='scripts/library/eventstack_outerclick.js') }}"></script>
|
|
||||||
|
|
||||||
<script type="text/javascript" src="{{ url_for('.static', filename='scripts/block.js') }}"></script>
|
<script type="text/javascript" src="{{ url_for('.static', filename='scripts/block.js') }}"></script>
|
||||||
<script type="text/javascript" src="{{ url_for('.static', filename='scripts/block/navigation.js') }}"></script>
|
<script type="text/javascript" src="{{ url_for('.static', filename='scripts/block/navigation.js') }}"></script>
|
||||||
|
|||||||
Reference in New Issue
Block a user