Settings
Movie List Directory selection
This commit is contained in:
1 parent
272e0b8527
commit
8682be33fb
27 files changed
+1770
-233
No files matched your search
@@ -6,6 +6,7 @@ from flask.helpers import url_for
|
|||||||
from flask.module import Module
|
from flask.module import Module
|
||||||
from flask.templating import render_template
|
from flask.templating import render_template
|
||||||
from werkzeug.utils import redirect
|
from werkzeug.utils import redirect
|
||||||
|
import os
|
||||||
|
|
||||||
app = Flask(__name__)
|
app = Flask(__name__)
|
||||||
log = CPLog(__name__)
|
log = CPLog(__name__)
|
||||||
@@ -15,7 +16,7 @@ web = Module(__name__, 'web')
|
|||||||
@web.route('/')
|
@web.route('/')
|
||||||
@requires_auth
|
@requires_auth
|
||||||
def index():
|
def index():
|
||||||
return render_template('index.html')
|
return render_template('index.html', sep = os.sep)
|
||||||
|
|
||||||
@app.errorhandler(404)
|
@app.errorhandler(404)
|
||||||
def page_not_found(error):
|
def page_not_found(error):
|
||||||
|
|||||||
@@ -1,8 +1,66 @@
|
|||||||
|
from couchpotato.api.file_browser import FileBrowser
|
||||||
|
from couchpotato.core.settings import settings
|
||||||
|
from couchpotato.core.settings.loader import settings_loader
|
||||||
from flask import Module
|
from flask import Module
|
||||||
from flask.helpers import jsonify
|
from flask.helpers import jsonify
|
||||||
|
import flask
|
||||||
|
|
||||||
api = Module(__name__)
|
api = Module(__name__)
|
||||||
|
|
||||||
@api.route('/')
|
@api.route('')
|
||||||
def index():
|
def index():
|
||||||
return jsonify({'test': 'bla'})
|
return jsonify({'test': 'bla'})
|
||||||
|
|
||||||
|
|
||||||
|
@api.route('settings/')
|
||||||
|
def settings_view():
|
||||||
|
return jsonify({
|
||||||
|
'sections': settings_loader.sections,
|
||||||
|
'values': settings.getValues()
|
||||||
|
})
|
||||||
|
|
||||||
|
@api.route('setting.save/')
|
||||||
|
def setting_save_view():
|
||||||
|
a = flask.request.args
|
||||||
|
|
||||||
|
section = a.get('section')
|
||||||
|
option = a.get('name')
|
||||||
|
value = a.get('value')
|
||||||
|
|
||||||
|
settings.set(section, option, value)
|
||||||
|
settings.save()
|
||||||
|
|
||||||
|
return jsonify({
|
||||||
|
'success': True,
|
||||||
|
});
|
||||||
|
|
||||||
|
@api.route('movie/')
|
||||||
|
def movie():
|
||||||
|
return jsonify({
|
||||||
|
'success': True,
|
||||||
|
'movies': [
|
||||||
|
{
|
||||||
|
'name': 'Movie 1',
|
||||||
|
'description': 'Description 1',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'name': 'Movie 2',
|
||||||
|
'description': 'Description 2',
|
||||||
|
}
|
||||||
|
]
|
||||||
|
})
|
||||||
|
|
||||||
|
@api.route('directory.list/')
|
||||||
|
def director_list():
|
||||||
|
a = flask.request.args
|
||||||
|
|
||||||
|
try:
|
||||||
|
fb = FileBrowser(a.get('path', '/'))
|
||||||
|
dirs = fb.getDirectories()
|
||||||
|
except:
|
||||||
|
dirs = []
|
||||||
|
|
||||||
|
return jsonify({
|
||||||
|
'empty': len(dirs) == 0,
|
||||||
|
'dirs': dirs,
|
||||||
|
})
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
import os
|
||||||
|
import string
|
||||||
|
|
||||||
|
if os.name == 'nt':
|
||||||
|
import win32file
|
||||||
|
|
||||||
|
class FileBrowser():
|
||||||
|
|
||||||
|
def __init__(self, path = '/'):
|
||||||
|
self.path = path
|
||||||
|
|
||||||
|
def getDirectories(self):
|
||||||
|
|
||||||
|
# Return driveletters or root if path is empty
|
||||||
|
if self.path == '/' or not self.path:
|
||||||
|
if os.name == 'nt':
|
||||||
|
return self.getDriveLetters()
|
||||||
|
self.path = '/'
|
||||||
|
|
||||||
|
dirs = []
|
||||||
|
for f in os.listdir(self.path):
|
||||||
|
path = os.path.join(self.path, f)
|
||||||
|
if(os.path.isdir(path)):
|
||||||
|
dirs.append(path)
|
||||||
|
|
||||||
|
return dirs
|
||||||
|
|
||||||
|
def getFiles(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def getDriveLetters(self):
|
||||||
|
|
||||||
|
driveletters = []
|
||||||
|
for drive in string.ascii_uppercase:
|
||||||
|
if win32file.GetDriveType(drive + ":") == win32file.DRIVE_FIXED:
|
||||||
|
driveletters.append(drive + ":")
|
||||||
|
|
||||||
|
return driveletters
|
||||||
+5
-5
@@ -77,10 +77,10 @@ def cmd_couchpotato(base_path, args):
|
|||||||
|
|
||||||
|
|
||||||
# Load configs
|
# Load configs
|
||||||
from couchpotato.core.settings.loader import SettingsLoader
|
from couchpotato.core.settings.loader import settings_loader
|
||||||
sl = SettingsLoader(root = base_path)
|
settings_loader.load(root = base_path)
|
||||||
sl.addConfig('couchpotato', 'core')
|
settings_loader.addConfig('couchpotato', 'core')
|
||||||
sl.run()
|
settings_loader.run()
|
||||||
|
|
||||||
|
|
||||||
# Create app
|
# Create app
|
||||||
@@ -103,7 +103,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/%s/' % (url_base, 'api', api_key))
|
app.register_module(api, url_prefix = '%s/%s/%s/' % (url_base, 'api', api_key if not debug else 'apikey'))
|
||||||
|
|
||||||
# Go go go!
|
# Go go go!
|
||||||
app.run(use_reloader = reloader)
|
app.run(use_reloader = reloader)
|
||||||
@@ -1,12 +1,59 @@
|
|||||||
from uuid import uuid4
|
from uuid import uuid4
|
||||||
|
|
||||||
config = ('global', {
|
config = [{
|
||||||
'debug': False,
|
'name': 'global',
|
||||||
'host': '0.0.0.0',
|
'tab': 'general',
|
||||||
'port': 5000,
|
'options': {
|
||||||
'username': '',
|
'debug': {
|
||||||
'password': '',
|
'advanced': True,
|
||||||
'launch_browser': True,
|
'default': False,
|
||||||
'url_base': '',
|
'type': 'bool',
|
||||||
'api_key': uuid4().hex,
|
'label': 'Debug',
|
||||||
})
|
'description': 'Enable debugging.',
|
||||||
|
},
|
||||||
|
'host': {
|
||||||
|
'advanced': True,
|
||||||
|
'default': '0.0.0.0',
|
||||||
|
'type': 'string',
|
||||||
|
'label': 'Host',
|
||||||
|
'description': 'Host that I should listen to 0.0.0.0 listens to everything.',
|
||||||
|
},
|
||||||
|
'port': {
|
||||||
|
'default': 5000,
|
||||||
|
'type': 'int',
|
||||||
|
'label': 'Port',
|
||||||
|
'description': 'The port I should listen to.',
|
||||||
|
},
|
||||||
|
'username': {
|
||||||
|
'default': '',
|
||||||
|
'type': 'string',
|
||||||
|
'label': 'Username',
|
||||||
|
},
|
||||||
|
'password': {
|
||||||
|
'default': '',
|
||||||
|
'password': True,
|
||||||
|
'type': 'string',
|
||||||
|
'label': 'Password',
|
||||||
|
},
|
||||||
|
'launch_browser': {
|
||||||
|
'default': True,
|
||||||
|
'type': 'bool',
|
||||||
|
'label': 'Launch Browser',
|
||||||
|
'description': 'Launch the browser when I start.',
|
||||||
|
},
|
||||||
|
'url_base': {
|
||||||
|
'advanced': True,
|
||||||
|
'default': '',
|
||||||
|
'type': 'string',
|
||||||
|
'label': 'Url Base',
|
||||||
|
'description': 'When using mod_proxy use this to prepend the url with this.',
|
||||||
|
},
|
||||||
|
'api_key': {
|
||||||
|
'default': uuid4().hex,
|
||||||
|
'type': 'string',
|
||||||
|
'readonly': True,
|
||||||
|
'label': 'Api Key',
|
||||||
|
'description': 'This is top-secret! Don\'t share this!',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}]
|
||||||
@@ -1,4 +1,30 @@
|
|||||||
config = ('Renamer', {
|
config = [{
|
||||||
'enabled': False,
|
'name': 'Renamer',
|
||||||
'cleanup': False
|
'tab': 'renaming',
|
||||||
})
|
'options': {
|
||||||
|
'enabled': {
|
||||||
|
'default': False,
|
||||||
|
'type': 'bool',
|
||||||
|
'description': 'Enable renaming',
|
||||||
|
},
|
||||||
|
'from': {
|
||||||
|
'default': '',
|
||||||
|
'type': 'directory',
|
||||||
|
'label': 'From',
|
||||||
|
'description': 'Folder where the movies are downloaded to.',
|
||||||
|
},
|
||||||
|
'to': {
|
||||||
|
'default': '',
|
||||||
|
'type': 'directory',
|
||||||
|
'label': 'To',
|
||||||
|
'description': 'Folder where the movies will be moved to.',
|
||||||
|
},
|
||||||
|
'run_every': {
|
||||||
|
'default': 1,
|
||||||
|
'type': 'int',
|
||||||
|
'unit': 'min(s)',
|
||||||
|
'description': 'Search for new movies inside the folder every X minutes.',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}]
|
||||||
|
|
||||||
@@ -1,3 +1,12 @@
|
|||||||
config = ('TheMovieDB', {
|
config = [{
|
||||||
'key': '9b939aee0aaafc12a65bf448e4af9543'
|
'name': 'TheMovieDB',
|
||||||
})
|
'tab': 'providers',
|
||||||
|
'options': {
|
||||||
|
'api_key': {
|
||||||
|
'advanced': True,
|
||||||
|
'default': '9b939aee0aaafc12a65bf448e4af9543',
|
||||||
|
'type': 'string',
|
||||||
|
'description': 'Api key to use for calls to TheMovieDB.',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}]
|
||||||
@@ -27,7 +27,7 @@ class Settings():
|
|||||||
return self.p
|
return self.p
|
||||||
|
|
||||||
def sections(self):
|
def sections(self):
|
||||||
return self.s
|
return self.p.sections()
|
||||||
|
|
||||||
def connectSignals(self):
|
def connectSignals(self):
|
||||||
signal('settings.register').connect(self.registerDefaults)
|
signal('settings.register').connect(self.registerDefaults)
|
||||||
@@ -46,24 +46,34 @@ class Settings():
|
|||||||
self.save(self)
|
self.save(self)
|
||||||
|
|
||||||
def set(self, section, option, value):
|
def set(self, section, option, value):
|
||||||
return self.p.set(section, option, value)
|
return self.p.set(section, option, self.cleanValue(value))
|
||||||
|
|
||||||
def get(self, option = '', section = 'global', default = ''):
|
def get(self, option = '', section = 'global', default = ''):
|
||||||
|
|
||||||
try:
|
try:
|
||||||
value = self.p.get(section, option)
|
value = self.p.get(section, option)
|
||||||
|
return self.cleanValue(value)
|
||||||
if(self.is_int(value)):
|
|
||||||
return int(value)
|
|
||||||
|
|
||||||
if str(value).lower() in self.bool:
|
|
||||||
return self.bool.get(str(value).lower())
|
|
||||||
|
|
||||||
return value if type(value) != str else value.strip()
|
|
||||||
except:
|
except:
|
||||||
return default
|
return default
|
||||||
|
|
||||||
def save(self, caller):
|
def cleanValue(self, value):
|
||||||
|
if(self.is_int(value)):
|
||||||
|
return int(value)
|
||||||
|
|
||||||
|
if str(value).lower() in self.bool:
|
||||||
|
return self.bool.get(str(value).lower())
|
||||||
|
|
||||||
|
return value.strip()
|
||||||
|
|
||||||
|
def getValues(self):
|
||||||
|
values = {}
|
||||||
|
for section in self.sections():
|
||||||
|
values[section] = {}
|
||||||
|
for option in self.p.items(section):
|
||||||
|
(option_name, option_value) = option
|
||||||
|
values[section][option_name] = option_value
|
||||||
|
return values
|
||||||
|
|
||||||
|
def save(self, caller = ''):
|
||||||
with open(self.file, 'wb') as configfile:
|
with open(self.file, 'wb') as configfile:
|
||||||
self.p.write(configfile)
|
self.p.write(configfile)
|
||||||
|
|
||||||
|
|||||||
@@ -8,12 +8,14 @@ log = CPLog(__name__)
|
|||||||
class SettingsLoader:
|
class SettingsLoader:
|
||||||
|
|
||||||
configs = {}
|
configs = {}
|
||||||
|
sections = {}
|
||||||
|
|
||||||
def __init__(self, root = ''):
|
def __init__(self):
|
||||||
|
|
||||||
self.settings_register = signal('settings.register')
|
self.settings_register = signal('settings.register')
|
||||||
self.settings_save = signal('settings.save')
|
self.settings_save = signal('settings.save')
|
||||||
|
|
||||||
|
def load(self, root = ''):
|
||||||
|
|
||||||
self.paths = {
|
self.paths = {
|
||||||
'plugins' : ('couchpotato.core.plugins', os.path.join(root, 'couchpotato', 'core', 'plugins')),
|
'plugins' : ('couchpotato.core.plugins', os.path.join(root, 'couchpotato', 'core', 'plugins')),
|
||||||
'providers' : ('couchpotato.core.providers', os.path.join(root, 'couchpotato', 'core', 'providers')),
|
'providers' : ('couchpotato.core.providers', os.path.join(root, 'couchpotato', 'core', 'providers')),
|
||||||
@@ -42,8 +44,13 @@ class SettingsLoader:
|
|||||||
module_name = '%s.%s' % (module, name)
|
module_name = '%s.%s' % (module, name)
|
||||||
try:
|
try:
|
||||||
m = getattr(self.loadModule(module_name), name)
|
m = getattr(self.loadModule(module_name), name)
|
||||||
(section, options) = m.config
|
|
||||||
self.settings_register.send(section, options = options, save = save)
|
for section in m.config:
|
||||||
|
self.addSection(section['name'], section)
|
||||||
|
options = {}
|
||||||
|
for key, option in section['options'].iteritems():
|
||||||
|
options[key] = option['default']
|
||||||
|
self.settings_register.send(section['name'], options = options, save = save)
|
||||||
|
|
||||||
return True
|
return True
|
||||||
except Exception, e:
|
except Exception, e:
|
||||||
@@ -62,3 +69,11 @@ class SettingsLoader:
|
|||||||
return m
|
return m
|
||||||
except:
|
except:
|
||||||
raise
|
raise
|
||||||
|
|
||||||
|
def addSection(self, section_name, options):
|
||||||
|
self.sections[section_name] = options
|
||||||
|
|
||||||
|
def getSections(self):
|
||||||
|
return self.sections
|
||||||
|
|
||||||
|
settings_loader = SettingsLoader()
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
var BlockBase = new Class({
|
||||||
|
|
||||||
|
Implements: [Options, Events],
|
||||||
|
|
||||||
|
options: {},
|
||||||
|
|
||||||
|
initialize: function(parent, options){
|
||||||
|
var self = this;
|
||||||
|
self.setOptions(options);
|
||||||
|
|
||||||
|
self.parent = parent;
|
||||||
|
|
||||||
|
self.create();
|
||||||
|
},
|
||||||
|
|
||||||
|
create: function(){
|
||||||
|
this.el = new Element('div.block');
|
||||||
|
},
|
||||||
|
|
||||||
|
toElement: function(){
|
||||||
|
return this.el
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
var Block = {}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
Block.Footer = new Class({
|
||||||
|
|
||||||
|
Extends: BlockBase,
|
||||||
|
|
||||||
|
create: function(){
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
self.el = new Element('div.footer');
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
Block.Navigation = new Class({
|
||||||
|
|
||||||
|
Extends: BlockBase,
|
||||||
|
|
||||||
|
create: function(){
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
self.el = new Element('ul.navigation');
|
||||||
|
},
|
||||||
|
|
||||||
|
addTab: function(tab){
|
||||||
|
var self = this
|
||||||
|
|
||||||
|
return new Element('li').adopt(
|
||||||
|
new Element('a', tab)
|
||||||
|
).inject(self.el)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
Block.Search = new Class({
|
||||||
|
|
||||||
|
Extends: BlockBase,
|
||||||
|
|
||||||
|
create: function(){
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
self.el = new Element('div.search_form');
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
@@ -3,20 +3,13 @@ var CouchPotato = new Class({
|
|||||||
Implements: [Options],
|
Implements: [Options],
|
||||||
|
|
||||||
defaults: {
|
defaults: {
|
||||||
page: 'movie',
|
page: 'wanted',
|
||||||
action: 'index',
|
action: 'index',
|
||||||
params: {}
|
params: {}
|
||||||
},
|
},
|
||||||
|
|
||||||
pages: [],
|
pages: [],
|
||||||
|
block: [],
|
||||||
tabs: [
|
|
||||||
{'href': '/movie/', 'title':'Gimmy gimmy gimmy!', 'label':'Wanted'},
|
|
||||||
{'href': '/manage/', 'title':'Do stuff to your existing movies!', 'label':'Manage'},
|
|
||||||
{'href': '/feed/', 'title':'Which wanted movies are released soon?', 'label':'Soon'},
|
|
||||||
{'href': '/log/', 'title':'Show recent logs.', 'class':'logLink', 'label':'Logs'},
|
|
||||||
{'href': '/config/', 'title':'Change settings.', 'id':'showConfig'}
|
|
||||||
],
|
|
||||||
|
|
||||||
initialize: function(options) {
|
initialize: function(options) {
|
||||||
var self = this;
|
var self = this;
|
||||||
@@ -25,38 +18,24 @@ var CouchPotato = new Class({
|
|||||||
self.c = $(document.body)
|
self.c = $(document.body)
|
||||||
|
|
||||||
self.route = new Route(self.defaults);
|
self.route = new Route(self.defaults);
|
||||||
self.api = new Api(self.options.api_url)
|
self.api = new Api(self.options.api)
|
||||||
|
|
||||||
History.addEvent('change', self.createPage.bind(self));
|
self.createLayout();
|
||||||
|
self.createPages();
|
||||||
|
|
||||||
|
History.addEvent('change', self.openPage.bind(self));
|
||||||
History.handleInitialState();
|
History.handleInitialState();
|
||||||
|
|
||||||
self.createLayout()
|
self.c.addEvent('click:relay(a)', self.pushState.bind(self));
|
||||||
self.createNavigation()
|
|
||||||
|
|
||||||
self.c.addEvent('click:relay(a)', self.openPage.bind(self))
|
|
||||||
},
|
},
|
||||||
|
|
||||||
openPage: function(e){
|
pushState: function(e){
|
||||||
var self = this;
|
var self = this;
|
||||||
(e).stop()
|
(e).stop();
|
||||||
|
|
||||||
var url = e.target.get('href')
|
|
||||||
History.push(url)
|
|
||||||
},
|
|
||||||
|
|
||||||
createNavigation: function(){
|
|
||||||
var self = this
|
|
||||||
|
|
||||||
self.tabs.each(function(tab){
|
|
||||||
new Element('li').adopt(
|
|
||||||
new Element('a', {
|
|
||||||
'href': tab.href,
|
|
||||||
'title': tab.title,
|
|
||||||
'text': tab.label
|
|
||||||
})
|
|
||||||
).inject(self.navigation)
|
|
||||||
})
|
|
||||||
|
|
||||||
|
var url = e.target.get('href');
|
||||||
|
if(History.getPath() != url)
|
||||||
|
History.push(url);
|
||||||
},
|
},
|
||||||
|
|
||||||
createLayout: function(){
|
createLayout: function(){
|
||||||
@@ -64,15 +43,27 @@ var CouchPotato = new Class({
|
|||||||
|
|
||||||
self.c.adopt(
|
self.c.adopt(
|
||||||
self.header = new Element('div.header').adopt(
|
self.header = new Element('div.header').adopt(
|
||||||
self.navigation = new Element('ul.navigation'),
|
self.block.navigation = new Block.Navigation(self, {}),
|
||||||
self.add_form = new Element('div.add_form')
|
self.block.search = new Block.Search(self, {})
|
||||||
),
|
),
|
||||||
self.content = new Element('div.content'),
|
self.content = new Element('div.content'),
|
||||||
self.footer = new Element('div.footer')
|
self.block.footer = new Block.Footer(self, {})
|
||||||
)
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
createPage: function(url) {
|
createPages: function(){
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
Object.each(Page, function(page_class, class_name){
|
||||||
|
pg = new Page[class_name](self, {});
|
||||||
|
self.pages[class_name] = pg;
|
||||||
|
|
||||||
|
$(pg).inject(self.content);
|
||||||
|
});
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
openPage: function(url) {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
self.route.parse(url);
|
self.route.parse(url);
|
||||||
@@ -80,14 +71,19 @@ var CouchPotato = new Class({
|
|||||||
var action = self.route.getAction();
|
var action = self.route.getAction();
|
||||||
var params = self.route.getParams();
|
var params = self.route.getParams();
|
||||||
|
|
||||||
var pg = self.pages[page_name]
|
var page = self.pages[page_name];
|
||||||
if(!pg){
|
page.open(action, params);
|
||||||
pg = new Page[page_name]();
|
page.show();
|
||||||
pg.setParent(self)
|
|
||||||
self.pages[page_name] = pg;
|
|
||||||
}
|
|
||||||
pg.open(action, params)
|
|
||||||
|
|
||||||
|
if(self.current_page)
|
||||||
|
self.current_page.hide()
|
||||||
|
|
||||||
|
self.current_page = page;
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
getBlock: function(block_name){
|
||||||
|
return this.block[block_name]
|
||||||
},
|
},
|
||||||
|
|
||||||
getApi: function(){
|
getApi: function(){
|
||||||
@@ -95,77 +91,41 @@ var CouchPotato = new Class({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
var PageBase = new Class({
|
|
||||||
|
|
||||||
Implements: [Options],
|
|
||||||
|
|
||||||
initialize: function(options) {
|
|
||||||
|
|
||||||
},
|
|
||||||
|
|
||||||
open: function(action, params){
|
|
||||||
var self = this;
|
|
||||||
p('Opening: ' +self.getName() + ', ' + action + ', ' + Object.toQueryString(params));
|
|
||||||
|
|
||||||
try {
|
|
||||||
self[action+'Action'](params)
|
|
||||||
}
|
|
||||||
catch (e){
|
|
||||||
self.errorAction(e)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
errorAction: function(e){
|
|
||||||
p('Error, action not found', e);
|
|
||||||
},
|
|
||||||
|
|
||||||
getName: function(){
|
|
||||||
return this.name
|
|
||||||
},
|
|
||||||
|
|
||||||
setParent: function(parent){
|
|
||||||
this.parent = parent
|
|
||||||
},
|
|
||||||
|
|
||||||
getParent: function(){
|
|
||||||
return this.parent
|
|
||||||
},
|
|
||||||
|
|
||||||
api: function(){
|
|
||||||
return this.parent.getApi()
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
var Api = new Class({
|
var Api = new Class({
|
||||||
|
|
||||||
url: '',
|
url: '',
|
||||||
|
|
||||||
initialize: function(url){
|
initialize: function(options){
|
||||||
var self = this
|
var self = this
|
||||||
|
|
||||||
self.url = url
|
self.options = options;
|
||||||
self.req = new Request.JSON({
|
self.req = new Request.JSON({
|
||||||
'method': 'get'
|
'method': 'get'
|
||||||
})
|
})
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
request: function(type, params, data){
|
request: function(type, options){
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
self.req.setOptions({
|
new Request.JSON(Object.merge({
|
||||||
'url': self.createUrl(type, params),
|
'method': 'get',
|
||||||
'data': data
|
'url': self.createUrl(type),
|
||||||
})
|
}, options)).send()
|
||||||
self.req.send()
|
|
||||||
},
|
},
|
||||||
|
|
||||||
createUrl: function(action, params){
|
createUrl: function(action){
|
||||||
return this.url + (action || 'default') + '/?' + Object.toQueryString(params)
|
return this.options.url + (action || 'default') + '/'
|
||||||
|
},
|
||||||
|
|
||||||
|
getOption: function(name){
|
||||||
|
return this.options[name]
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
var Route = new Class({
|
var Route = new Class({
|
||||||
|
|
||||||
defaults: {},
|
defaults: {},
|
||||||
|
|||||||
@@ -3,10 +3,10 @@
|
|||||||
MooTools: the javascript framework
|
MooTools: the javascript framework
|
||||||
|
|
||||||
web build:
|
web build:
|
||||||
- http://mootools.net/core/755c9fd7bb9342a1fa57db060c2cd141
|
- http://mootools.net/core/efcfcd2923b4129a00a22580c45b1d75
|
||||||
|
|
||||||
packager build:
|
packager build:
|
||||||
- packager build Core/Class Core/Class.Extras Core/Element Core/Request.JSON Core/DOMReady
|
- packager build Core/Class Core/Class.Extras Core/Element Core/Element.Style Core/Request.JSON Core/DOMReady
|
||||||
|
|
||||||
/*
|
/*
|
||||||
---
|
---
|
||||||
@@ -3120,6 +3120,187 @@ Element.Properties.html = (function(){
|
|||||||
})();
|
})();
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
---
|
||||||
|
|
||||||
|
name: Element.Style
|
||||||
|
|
||||||
|
description: Contains methods for interacting with the styles of Elements in a fashionable way.
|
||||||
|
|
||||||
|
license: MIT-style license.
|
||||||
|
|
||||||
|
requires: Element
|
||||||
|
|
||||||
|
provides: Element.Style
|
||||||
|
|
||||||
|
...
|
||||||
|
*/
|
||||||
|
|
||||||
|
(function(){
|
||||||
|
|
||||||
|
var html = document.html;
|
||||||
|
|
||||||
|
Element.Properties.styles = {set: function(styles){
|
||||||
|
this.setStyles(styles);
|
||||||
|
}};
|
||||||
|
|
||||||
|
var hasOpacity = (html.style.opacity != null);
|
||||||
|
var reAlpha = /alpha\(opacity=([\d.]+)\)/i;
|
||||||
|
|
||||||
|
var setOpacity = function(element, opacity){
|
||||||
|
if (!element.currentStyle || !element.currentStyle.hasLayout) element.style.zoom = 1;
|
||||||
|
if (hasOpacity){
|
||||||
|
element.style.opacity = opacity;
|
||||||
|
} else {
|
||||||
|
opacity = (opacity == 1) ? '' : 'alpha(opacity=' + opacity * 100 + ')';
|
||||||
|
var filter = element.style.filter || element.getComputedStyle('filter') || '';
|
||||||
|
element.style.filter = filter.test(reAlpha) ? filter.replace(reAlpha, opacity) : filter + opacity;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Element.Properties.opacity = {
|
||||||
|
|
||||||
|
set: function(opacity){
|
||||||
|
var visibility = this.style.visibility;
|
||||||
|
if (opacity == 0 && visibility != 'hidden') this.style.visibility = 'hidden';
|
||||||
|
else if (opacity != 0 && visibility != 'visible') this.style.visibility = 'visible';
|
||||||
|
|
||||||
|
setOpacity(this, opacity);
|
||||||
|
},
|
||||||
|
|
||||||
|
get: (hasOpacity) ? function(){
|
||||||
|
var opacity = this.style.opacity || this.getComputedStyle('opacity');
|
||||||
|
return (opacity == '') ? 1 : opacity;
|
||||||
|
} : function(){
|
||||||
|
var opacity, filter = (this.style.filter || this.getComputedStyle('filter'));
|
||||||
|
if (filter) opacity = filter.match(reAlpha);
|
||||||
|
return (opacity == null || filter == null) ? 1 : (opacity[1] / 100);
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
var floatName = (html.style.cssFloat == null) ? 'styleFloat' : 'cssFloat';
|
||||||
|
|
||||||
|
Element.implement({
|
||||||
|
|
||||||
|
getComputedStyle: function(property){
|
||||||
|
if (this.currentStyle) return this.currentStyle[property.camelCase()];
|
||||||
|
var defaultView = Element.getDocument(this).defaultView,
|
||||||
|
computed = defaultView ? defaultView.getComputedStyle(this, null) : null;
|
||||||
|
return (computed) ? computed.getPropertyValue((property == floatName) ? 'float' : property.hyphenate()) : null;
|
||||||
|
},
|
||||||
|
|
||||||
|
setOpacity: function(value){
|
||||||
|
setOpacity(this, value);
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
|
||||||
|
getOpacity: function(){
|
||||||
|
return this.get('opacity');
|
||||||
|
},
|
||||||
|
|
||||||
|
setStyle: function(property, value){
|
||||||
|
switch (property){
|
||||||
|
case 'opacity': return this.set('opacity', parseFloat(value));
|
||||||
|
case 'float': property = floatName;
|
||||||
|
}
|
||||||
|
property = property.camelCase();
|
||||||
|
if (typeOf(value) != 'string'){
|
||||||
|
var map = (Element.Styles[property] || '@').split(' ');
|
||||||
|
value = Array.from(value).map(function(val, i){
|
||||||
|
if (!map[i]) return '';
|
||||||
|
return (typeOf(val) == 'number') ? map[i].replace('@', Math.round(val)) : val;
|
||||||
|
}).join(' ');
|
||||||
|
} else if (value == String(Number(value))){
|
||||||
|
value = Math.round(value);
|
||||||
|
}
|
||||||
|
this.style[property] = value;
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
|
||||||
|
getStyle: function(property){
|
||||||
|
switch (property){
|
||||||
|
case 'opacity': return this.get('opacity');
|
||||||
|
case 'float': property = floatName;
|
||||||
|
}
|
||||||
|
property = property.camelCase();
|
||||||
|
var result = this.style[property];
|
||||||
|
if (!result || property == 'zIndex'){
|
||||||
|
result = [];
|
||||||
|
for (var style in Element.ShortStyles){
|
||||||
|
if (property != style) continue;
|
||||||
|
for (var s in Element.ShortStyles[style]) result.push(this.getStyle(s));
|
||||||
|
return result.join(' ');
|
||||||
|
}
|
||||||
|
result = this.getComputedStyle(property);
|
||||||
|
}
|
||||||
|
if (result){
|
||||||
|
result = String(result);
|
||||||
|
var color = result.match(/rgba?\([\d\s,]+\)/);
|
||||||
|
if (color) result = result.replace(color[0], color[0].rgbToHex());
|
||||||
|
}
|
||||||
|
if (Browser.opera || (Browser.ie && isNaN(parseFloat(result)))){
|
||||||
|
if (property.test(/^(height|width)$/)){
|
||||||
|
var values = (property == 'width') ? ['left', 'right'] : ['top', 'bottom'], size = 0;
|
||||||
|
values.each(function(value){
|
||||||
|
size += this.getStyle('border-' + value + '-width').toInt() + this.getStyle('padding-' + value).toInt();
|
||||||
|
}, this);
|
||||||
|
return this['offset' + property.capitalize()] - size + 'px';
|
||||||
|
}
|
||||||
|
if (Browser.opera && String(result).indexOf('px') != -1) return result;
|
||||||
|
if (property.test(/(border(.+)Width|margin|padding)/)) return '0px';
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
},
|
||||||
|
|
||||||
|
setStyles: function(styles){
|
||||||
|
for (var style in styles) this.setStyle(style, styles[style]);
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
|
||||||
|
getStyles: function(){
|
||||||
|
var result = {};
|
||||||
|
Array.flatten(arguments).each(function(key){
|
||||||
|
result[key] = this.getStyle(key);
|
||||||
|
}, this);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
Element.Styles = {
|
||||||
|
left: '@px', top: '@px', bottom: '@px', right: '@px',
|
||||||
|
width: '@px', height: '@px', maxWidth: '@px', maxHeight: '@px', minWidth: '@px', minHeight: '@px',
|
||||||
|
backgroundColor: 'rgb(@, @, @)', backgroundPosition: '@px @px', color: 'rgb(@, @, @)',
|
||||||
|
fontSize: '@px', letterSpacing: '@px', lineHeight: '@px', clip: 'rect(@px @px @px @px)',
|
||||||
|
margin: '@px @px @px @px', padding: '@px @px @px @px', border: '@px @ rgb(@, @, @) @px @ rgb(@, @, @) @px @ rgb(@, @, @)',
|
||||||
|
borderWidth: '@px @px @px @px', borderStyle: '@ @ @ @', borderColor: 'rgb(@, @, @) rgb(@, @, @) rgb(@, @, @) rgb(@, @, @)',
|
||||||
|
zIndex: '@', 'zoom': '@', fontWeight: '@', textIndent: '@px', opacity: '@'
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Element.ShortStyles = {margin: {}, padding: {}, border: {}, borderWidth: {}, borderStyle: {}, borderColor: {}};
|
||||||
|
|
||||||
|
['Top', 'Right', 'Bottom', 'Left'].each(function(direction){
|
||||||
|
var Short = Element.ShortStyles;
|
||||||
|
var All = Element.Styles;
|
||||||
|
['margin', 'padding'].each(function(style){
|
||||||
|
var sd = style + direction;
|
||||||
|
Short[style][sd] = All[sd] = '@px';
|
||||||
|
});
|
||||||
|
var bd = 'border' + direction;
|
||||||
|
Short.border[bd] = All[bd] = '@px @ rgb(@, @, @)';
|
||||||
|
var bdw = bd + 'Width', bds = bd + 'Style', bdc = bd + 'Color';
|
||||||
|
Short[bd] = {};
|
||||||
|
Short.borderWidth[bdw] = Short[bd][bdw] = All[bdw] = '@px';
|
||||||
|
Short.borderStyle[bds] = Short[bd][bds] = All[bds] = '@';
|
||||||
|
Short.borderColor[bdc] = Short[bd][bdc] = All[bdc] = 'rgb(@, @, @)';
|
||||||
|
});
|
||||||
|
|
||||||
|
})();
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,141 @@
|
|||||||
// MooTools: the javascript framework.
|
// MooTools: the javascript framework.
|
||||||
// Load this file's selection again by visiting: http://mootools.net/more/82d3c4f6ee721f808321f6bf6818d8fb
|
// Load this file's selection again by visiting: http://mootools.net/more/4da9e3082bf0d4194b76d7e5b3874113
|
||||||
// Or build this file again with packager using: packager build More/Element.Delegation More/Element.Shortcuts
|
// Or build this file again with packager using: packager build More/Element.Forms More/Element.Delegation More/Element.Shortcuts
|
||||||
|
/*
|
||||||
|
---
|
||||||
|
|
||||||
|
script: String.Extras.js
|
||||||
|
|
||||||
|
name: String.Extras
|
||||||
|
|
||||||
|
description: Extends the String native object to include methods useful in managing various kinds of strings (query strings, urls, html, etc).
|
||||||
|
|
||||||
|
license: MIT-style license
|
||||||
|
|
||||||
|
authors:
|
||||||
|
- Aaron Newton
|
||||||
|
- Guillermo Rauch
|
||||||
|
- Christopher Pitt
|
||||||
|
|
||||||
|
requires:
|
||||||
|
- Core/String
|
||||||
|
- Core/Array
|
||||||
|
|
||||||
|
provides: [String.Extras]
|
||||||
|
|
||||||
|
...
|
||||||
|
*/
|
||||||
|
|
||||||
|
(function(){
|
||||||
|
|
||||||
|
var special = {
|
||||||
|
'a': /[àáâãäåăą]/g,
|
||||||
|
'A': /[ÀÁÂÃÄÅĂĄ]/g,
|
||||||
|
'c': /[ćčç]/g,
|
||||||
|
'C': /[ĆČÇ]/g,
|
||||||
|
'd': /[ďđ]/g,
|
||||||
|
'D': /[ĎÐ]/g,
|
||||||
|
'e': /[èéêëěę]/g,
|
||||||
|
'E': /[ÈÉÊËĚĘ]/g,
|
||||||
|
'g': /[ğ]/g,
|
||||||
|
'G': /[Ğ]/g,
|
||||||
|
'i': /[ìíîï]/g,
|
||||||
|
'I': /[ÌÍÎÏ]/g,
|
||||||
|
'l': /[ĺľł]/g,
|
||||||
|
'L': /[ĹĽŁ]/g,
|
||||||
|
'n': /[ñňń]/g,
|
||||||
|
'N': /[ÑŇŃ]/g,
|
||||||
|
'o': /[òóôõöøő]/g,
|
||||||
|
'O': /[ÒÓÔÕÖØ]/g,
|
||||||
|
'r': /[řŕ]/g,
|
||||||
|
'R': /[ŘŔ]/g,
|
||||||
|
's': /[ššş]/g,
|
||||||
|
'S': /[ŠŞŚ]/g,
|
||||||
|
't': /[ťţ]/g,
|
||||||
|
'T': /[ŤŢ]/g,
|
||||||
|
'ue': /[ü]/g,
|
||||||
|
'UE': /[Ü]/g,
|
||||||
|
'u': /[ùúûůµ]/g,
|
||||||
|
'U': /[ÙÚÛŮ]/g,
|
||||||
|
'y': /[ÿý]/g,
|
||||||
|
'Y': /[ŸÝ]/g,
|
||||||
|
'z': /[žźż]/g,
|
||||||
|
'Z': /[ŽŹŻ]/g,
|
||||||
|
'th': /[þ]/g,
|
||||||
|
'TH': /[Þ]/g,
|
||||||
|
'dh': /[ð]/g,
|
||||||
|
'DH': /[Ð]/g,
|
||||||
|
'ss': /[ß]/g,
|
||||||
|
'oe': /[œ]/g,
|
||||||
|
'OE': /[Œ]/g,
|
||||||
|
'ae': /[æ]/g,
|
||||||
|
'AE': /[Æ]/g
|
||||||
|
},
|
||||||
|
|
||||||
|
tidy = {
|
||||||
|
' ': /[\xa0\u2002\u2003\u2009]/g,
|
||||||
|
'*': /[\xb7]/g,
|
||||||
|
'\'': /[\u2018\u2019]/g,
|
||||||
|
'"': /[\u201c\u201d]/g,
|
||||||
|
'...': /[\u2026]/g,
|
||||||
|
'-': /[\u2013]/g,
|
||||||
|
// '--': /[\u2014]/g,
|
||||||
|
'»': /[\uFFFD]/g
|
||||||
|
};
|
||||||
|
|
||||||
|
var walk = function(string, replacements){
|
||||||
|
var result = string;
|
||||||
|
for (key in replacements) result = result.replace(replacements[key], key);
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
|
||||||
|
var getRegexForTag = function(tag, contents){
|
||||||
|
tag = tag || '';
|
||||||
|
var regstr = contents ? "<" + tag + "(?!\\w)[^>]*>([\\s\\S]*?)<\/" + tag + "(?!\\w)>" : "<\/?" + tag + "([^>]+)?>";
|
||||||
|
reg = new RegExp(regstr, "gi");
|
||||||
|
return reg;
|
||||||
|
};
|
||||||
|
|
||||||
|
String.implement({
|
||||||
|
|
||||||
|
standardize: function(){
|
||||||
|
return walk(this, special);
|
||||||
|
},
|
||||||
|
|
||||||
|
repeat: function(times){
|
||||||
|
return new Array(times + 1).join(this);
|
||||||
|
},
|
||||||
|
|
||||||
|
pad: function(length, str, direction){
|
||||||
|
if (this.length >= length) return this;
|
||||||
|
|
||||||
|
var pad = (str == null ? ' ' : '' + str)
|
||||||
|
.repeat(length - this.length)
|
||||||
|
.substr(0, length - this.length);
|
||||||
|
|
||||||
|
if (!direction || direction == 'right') return this + pad;
|
||||||
|
if (direction == 'left') return pad + this;
|
||||||
|
|
||||||
|
return pad.substr(0, (pad.length / 2).floor()) + this + pad.substr(0, (pad.length / 2).ceil());
|
||||||
|
},
|
||||||
|
|
||||||
|
getTags: function(tag, contents){
|
||||||
|
return this.match(getRegexForTag(tag, contents)) || [];
|
||||||
|
},
|
||||||
|
|
||||||
|
stripTags: function(tag, contents){
|
||||||
|
return this.replace(getRegexForTag(tag, contents), '');
|
||||||
|
},
|
||||||
|
|
||||||
|
tidy: function(){
|
||||||
|
return walk(this, tidy);
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
})();
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -35,6 +170,148 @@ MooTools.More = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
---
|
||||||
|
|
||||||
|
script: Element.Forms.js
|
||||||
|
|
||||||
|
name: Element.Forms
|
||||||
|
|
||||||
|
description: Extends the Element native object to include methods useful in managing inputs.
|
||||||
|
|
||||||
|
license: MIT-style license
|
||||||
|
|
||||||
|
authors:
|
||||||
|
- Aaron Newton
|
||||||
|
|
||||||
|
requires:
|
||||||
|
- Core/Element
|
||||||
|
- /String.Extras
|
||||||
|
- /MooTools.More
|
||||||
|
|
||||||
|
provides: [Element.Forms]
|
||||||
|
|
||||||
|
...
|
||||||
|
*/
|
||||||
|
|
||||||
|
Element.implement({
|
||||||
|
|
||||||
|
tidy: function(){
|
||||||
|
this.set('value', this.get('value').tidy());
|
||||||
|
},
|
||||||
|
|
||||||
|
getTextInRange: function(start, end){
|
||||||
|
return this.get('value').substring(start, end);
|
||||||
|
},
|
||||||
|
|
||||||
|
getSelectedText: function(){
|
||||||
|
if (this.setSelectionRange) return this.getTextInRange(this.getSelectionStart(), this.getSelectionEnd());
|
||||||
|
return document.selection.createRange().text;
|
||||||
|
},
|
||||||
|
|
||||||
|
getSelectedRange: function(){
|
||||||
|
if (this.selectionStart != null){
|
||||||
|
return {
|
||||||
|
start: this.selectionStart,
|
||||||
|
end: this.selectionEnd
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
var pos = {
|
||||||
|
start: 0,
|
||||||
|
end: 0
|
||||||
|
};
|
||||||
|
var range = this.getDocument().selection.createRange();
|
||||||
|
if (!range || range.parentElement() != this) return pos;
|
||||||
|
var duplicate = range.duplicate();
|
||||||
|
|
||||||
|
if (this.type == 'text'){
|
||||||
|
pos.start = 0 - duplicate.moveStart('character', -100000);
|
||||||
|
pos.end = pos.start + range.text.length;
|
||||||
|
} else {
|
||||||
|
var value = this.get('value');
|
||||||
|
var offset = value.length;
|
||||||
|
duplicate.moveToElementText(this);
|
||||||
|
duplicate.setEndPoint('StartToEnd', range);
|
||||||
|
if (duplicate.text.length) offset -= value.match(/[\n\r]*$/)[0].length;
|
||||||
|
pos.end = offset - duplicate.text.length;
|
||||||
|
duplicate.setEndPoint('StartToStart', range);
|
||||||
|
pos.start = offset - duplicate.text.length;
|
||||||
|
}
|
||||||
|
return pos;
|
||||||
|
},
|
||||||
|
|
||||||
|
getSelectionStart: function(){
|
||||||
|
return this.getSelectedRange().start;
|
||||||
|
},
|
||||||
|
|
||||||
|
getSelectionEnd: function(){
|
||||||
|
return this.getSelectedRange().end;
|
||||||
|
},
|
||||||
|
|
||||||
|
setCaretPosition: function(pos){
|
||||||
|
if (pos == 'end') pos = this.get('value').length;
|
||||||
|
this.selectRange(pos, pos);
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
|
||||||
|
getCaretPosition: function(){
|
||||||
|
return this.getSelectedRange().start;
|
||||||
|
},
|
||||||
|
|
||||||
|
selectRange: function(start, end){
|
||||||
|
if (this.setSelectionRange){
|
||||||
|
this.focus();
|
||||||
|
this.setSelectionRange(start, end);
|
||||||
|
} else {
|
||||||
|
var value = this.get('value');
|
||||||
|
var diff = value.substr(start, end - start).replace(/\r/g, '').length;
|
||||||
|
start = value.substr(0, start).replace(/\r/g, '').length;
|
||||||
|
var range = this.createTextRange();
|
||||||
|
range.collapse(true);
|
||||||
|
range.moveEnd('character', start + diff);
|
||||||
|
range.moveStart('character', start);
|
||||||
|
range.select();
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
|
||||||
|
insertAtCursor: function(value, select){
|
||||||
|
var pos = this.getSelectedRange();
|
||||||
|
var text = this.get('value');
|
||||||
|
this.set('value', text.substring(0, pos.start) + value + text.substring(pos.end, text.length));
|
||||||
|
if (select !== false) this.selectRange(pos.start, pos.start + value.length);
|
||||||
|
else this.setCaretPosition(pos.start + value.length);
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
|
||||||
|
insertAroundCursor: function(options, select){
|
||||||
|
options = Object.append({
|
||||||
|
before: '',
|
||||||
|
defaultMiddle: '',
|
||||||
|
after: ''
|
||||||
|
}, options);
|
||||||
|
|
||||||
|
var value = this.getSelectedText() || options.defaultMiddle;
|
||||||
|
var pos = this.getSelectedRange();
|
||||||
|
var text = this.get('value');
|
||||||
|
|
||||||
|
if (pos.start == pos.end){
|
||||||
|
this.set('value', text.substring(0, pos.start) + options.before + value + options.after + text.substring(pos.end, text.length));
|
||||||
|
this.selectRange(pos.start + options.before.length, pos.end + options.before.length + value.length);
|
||||||
|
} else {
|
||||||
|
var current = text.substring(pos.start, pos.end);
|
||||||
|
this.set('value', text.substring(0, pos.start) + options.before + current + options.after + text.substring(pos.end, text.length));
|
||||||
|
var selStart = pos.start + options.before.length;
|
||||||
|
if (select !== false) this.selectRange(selStart, selStart + current.length);
|
||||||
|
else this.setCaretPosition(selStart + text.length);
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,78 @@
|
|||||||
|
var PageBase = new Class({
|
||||||
|
|
||||||
|
Implements: [Options, Events],
|
||||||
|
|
||||||
|
options: {
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
has_tab: true,
|
||||||
|
|
||||||
|
initialize: function(parent, options) {
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
self.setOptions(options)
|
||||||
|
self.setParent(parent)
|
||||||
|
|
||||||
|
// Create main page container
|
||||||
|
self.el = new Element('div.page.'+self.name);
|
||||||
|
|
||||||
|
// Create tab for page
|
||||||
|
if(self.has_tab){
|
||||||
|
var nav = self.getParent().getBlock('navigation');
|
||||||
|
self.tab = nav.addTab({
|
||||||
|
'href': '/'+self.name,
|
||||||
|
'title': self.title,
|
||||||
|
'text': self.name.capitalize()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
open: function(action, params){
|
||||||
|
var self = this;
|
||||||
|
//p('Opening: ' +self.getName() + ', ' + action + ', ' + Object.toQueryString(params));
|
||||||
|
|
||||||
|
try {
|
||||||
|
self[action+'Action'](params);
|
||||||
|
self.fireEvent('opened');
|
||||||
|
}
|
||||||
|
catch (e){
|
||||||
|
self.errorAction(e);
|
||||||
|
self.fireEvent('error');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
errorAction: function(e){
|
||||||
|
p('Error, action not found', e);
|
||||||
|
},
|
||||||
|
|
||||||
|
getName: function(){
|
||||||
|
return this.name
|
||||||
|
},
|
||||||
|
|
||||||
|
setParent: function(parent){
|
||||||
|
this.app = parent
|
||||||
|
},
|
||||||
|
|
||||||
|
getParent: function(){
|
||||||
|
return this.app
|
||||||
|
},
|
||||||
|
|
||||||
|
api: function(){
|
||||||
|
return this.getParent().getApi()
|
||||||
|
},
|
||||||
|
|
||||||
|
show: function(){
|
||||||
|
this.el.addClass('active');
|
||||||
|
},
|
||||||
|
|
||||||
|
hide: function(){
|
||||||
|
this.el.removeClass('active');
|
||||||
|
},
|
||||||
|
|
||||||
|
toElement: function(){
|
||||||
|
return this.el
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var Page = {}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
Page.Log = new Class({
|
||||||
|
|
||||||
|
Extends: PageBase,
|
||||||
|
|
||||||
|
name: 'log',
|
||||||
|
title: 'Show recent logs.'
|
||||||
|
|
||||||
|
})
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
Page.Manage = new Class({
|
||||||
|
|
||||||
|
Extends: PageBase,
|
||||||
|
|
||||||
|
name: 'manage',
|
||||||
|
title: 'Do stuff to your existing movies!'
|
||||||
|
|
||||||
|
})
|
||||||
@@ -0,0 +1,426 @@
|
|||||||
|
Page.Settings = new Class({
|
||||||
|
|
||||||
|
Extends: PageBase,
|
||||||
|
|
||||||
|
name: 'settings',
|
||||||
|
title: 'Change settings.',
|
||||||
|
|
||||||
|
groups: {},
|
||||||
|
|
||||||
|
open: function(action, params){
|
||||||
|
var self = this
|
||||||
|
//p('open config', action, params)
|
||||||
|
|
||||||
|
if(!self.data)
|
||||||
|
self.getData(self.create.bind(self))
|
||||||
|
else
|
||||||
|
self.openTab(action);
|
||||||
|
},
|
||||||
|
|
||||||
|
openTab: function(action){
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
if(self.current)
|
||||||
|
self.toggleTab(self.current, true);
|
||||||
|
|
||||||
|
self.toggleTab(action)
|
||||||
|
self.current = action;
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
toggleTab: function(tab, hide){
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
var a = hide ? 'removeClass' : 'addClass';
|
||||||
|
var c = 'active';
|
||||||
|
|
||||||
|
var g = self.groups[tab] || self.groups.general
|
||||||
|
g.tab[a](c);
|
||||||
|
g.group[a](c);
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
getData: function(onComplete){
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
if(onComplete)
|
||||||
|
self.api().request('settings', {
|
||||||
|
'useSpinner': true,
|
||||||
|
'spinnerOptions': {
|
||||||
|
'target': self.el
|
||||||
|
},
|
||||||
|
'onComplete': function(json){
|
||||||
|
self.data = json;
|
||||||
|
onComplete(json);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
return self.data;
|
||||||
|
},
|
||||||
|
|
||||||
|
getValue: function(section, name){
|
||||||
|
var self = this;
|
||||||
|
try {
|
||||||
|
return self.data.values[section][name] || '';
|
||||||
|
}
|
||||||
|
catch(e){
|
||||||
|
return ''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
create: function(json){
|
||||||
|
var self = this
|
||||||
|
|
||||||
|
self.el.adopt(
|
||||||
|
self.tabs = new Element('ul.tabs'),
|
||||||
|
self.containers = new Element('form.uniForm.containers')
|
||||||
|
);
|
||||||
|
|
||||||
|
Object.each(json.sections, function(section, section_name){
|
||||||
|
|
||||||
|
// Create tab
|
||||||
|
var tab = new Element('li').adopt(
|
||||||
|
new Element('a', {
|
||||||
|
'href': '/'+self.name+'/'+section.tab+'/',
|
||||||
|
'text': section.tab.capitalize()
|
||||||
|
})
|
||||||
|
).inject(self.tabs);
|
||||||
|
var group = new Element('div.group').inject(self.containers);
|
||||||
|
|
||||||
|
self.groups[section.tab] = {
|
||||||
|
'tab': tab,
|
||||||
|
'group': group
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add section
|
||||||
|
var fieldset = new Element('fieldset.inlineLabels').inject(group)
|
||||||
|
Object.each(section.options, function(option, option_name){
|
||||||
|
var class_name = (option.type || 'input').capitalize();
|
||||||
|
var input = new Option[class_name](self, section_name, option_name, option);
|
||||||
|
input.inject(fieldset);
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
self.openTab();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
var OptionBase = new Class({
|
||||||
|
|
||||||
|
Implements: [Options, Events],
|
||||||
|
|
||||||
|
klass: 'textInput',
|
||||||
|
focused_class : 'focused',
|
||||||
|
save_on_change: true,
|
||||||
|
|
||||||
|
initialize: function(parent, section, name, options){
|
||||||
|
var self = this
|
||||||
|
self.setOptions(options)
|
||||||
|
|
||||||
|
self.page = parent;
|
||||||
|
self.section = section;
|
||||||
|
self.name = name;
|
||||||
|
|
||||||
|
self.createBase();
|
||||||
|
self.create();
|
||||||
|
self.createHint();
|
||||||
|
self.setAdvanced();
|
||||||
|
|
||||||
|
// Add focus events
|
||||||
|
self.input.addEvents({
|
||||||
|
'change': self.changed.bind(self),
|
||||||
|
'keyup': self.changed.bind(self),
|
||||||
|
'focus': function() {
|
||||||
|
self.el.addClass(self.focused_class);
|
||||||
|
},
|
||||||
|
'blur' : function() {
|
||||||
|
self.el.removeClass(self.focused_class);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create the element
|
||||||
|
*/
|
||||||
|
createBase: function(){
|
||||||
|
var self = this
|
||||||
|
self.el = new Element('div.ctrlHolder')
|
||||||
|
},
|
||||||
|
|
||||||
|
create: function(){},
|
||||||
|
|
||||||
|
setAdvanced: function(){
|
||||||
|
this.el.addClass(this.options.advanced ? 'advanced': '')
|
||||||
|
},
|
||||||
|
|
||||||
|
createHint: function(){
|
||||||
|
var self = this;
|
||||||
|
if(self.options.description)
|
||||||
|
new Element('p.formHint', {
|
||||||
|
'text': self.options.description
|
||||||
|
}).inject(self.el);
|
||||||
|
},
|
||||||
|
|
||||||
|
// Element has changed, do something
|
||||||
|
changed: function(){
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
if(self.getValue() != self.previous_value){
|
||||||
|
if(self.save_on_change){
|
||||||
|
if(self.changed_timer) clearTimeout(self.changed_timer);
|
||||||
|
self.changed_timer = self.save.delay(300, self);
|
||||||
|
}
|
||||||
|
self.fireEvent('change')
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
save: function(){
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
self.api().request('setting.save', {
|
||||||
|
'data': {
|
||||||
|
'section': self.section,
|
||||||
|
'name': self.name,
|
||||||
|
'value': self.getValue()
|
||||||
|
},
|
||||||
|
'useSpinner': true,
|
||||||
|
'spinnerOptions': {
|
||||||
|
'target': self.el
|
||||||
|
},
|
||||||
|
'onComplete': self.saveCompleted.bind(self)
|
||||||
|
});
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
saveCompleted: function(json){
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
var sc = json.success ? 'save_success' : 'save_failed';
|
||||||
|
|
||||||
|
self.previous_value = self.getValue();
|
||||||
|
self.el.addClass(sc);
|
||||||
|
|
||||||
|
(function(){
|
||||||
|
self.el.removeClass(sc);
|
||||||
|
}).delay(3000, self);
|
||||||
|
},
|
||||||
|
|
||||||
|
setName: function(name){
|
||||||
|
this.name = name;
|
||||||
|
},
|
||||||
|
|
||||||
|
postName: function(){
|
||||||
|
var self = this;
|
||||||
|
return self.section +'['+self.name+']';
|
||||||
|
},
|
||||||
|
|
||||||
|
getValue: function(){
|
||||||
|
var self = this;
|
||||||
|
return self.input.get('value');
|
||||||
|
},
|
||||||
|
|
||||||
|
getSettingValue: function(){
|
||||||
|
var self = this;
|
||||||
|
return self.page.getValue(self.section, self.name);
|
||||||
|
},
|
||||||
|
|
||||||
|
api: function(){
|
||||||
|
return this.page.api();
|
||||||
|
},
|
||||||
|
|
||||||
|
inject: function(el, position){
|
||||||
|
this.el.inject(el, position);
|
||||||
|
return this.el;
|
||||||
|
},
|
||||||
|
|
||||||
|
toElement: function(){
|
||||||
|
return this.el;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
var Option = {}
|
||||||
|
Option.String = new Class({
|
||||||
|
Extends: OptionBase,
|
||||||
|
|
||||||
|
type: 'input',
|
||||||
|
|
||||||
|
create: function(){
|
||||||
|
var self = this
|
||||||
|
|
||||||
|
self.el.adopt(
|
||||||
|
new Element('label', {
|
||||||
|
'text': self.options.label
|
||||||
|
}),
|
||||||
|
self.input = new Element('input', {
|
||||||
|
'name': self.postName(),
|
||||||
|
'value': self.getSettingValue()
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Option.Dropdown = new Class({
|
||||||
|
Extends: OptionBase,
|
||||||
|
|
||||||
|
create: function(){
|
||||||
|
var self = this
|
||||||
|
|
||||||
|
new Element('label', {
|
||||||
|
'text': self.options.label
|
||||||
|
}).adopt(
|
||||||
|
self.input = new Element('select', {
|
||||||
|
'name': self.postName()
|
||||||
|
})
|
||||||
|
).inject(self.el)
|
||||||
|
|
||||||
|
Object.each(self.options.values, function(label, value){
|
||||||
|
new Element('option', {
|
||||||
|
'text': label,
|
||||||
|
'value': value
|
||||||
|
}).inject(self.input)
|
||||||
|
})
|
||||||
|
|
||||||
|
self.input.set('value', self.getSettingValue());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Option.Checkbox = new Class({
|
||||||
|
Extends: OptionBase,
|
||||||
|
|
||||||
|
type: 'checkbox',
|
||||||
|
|
||||||
|
create: function(){
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
new Element('label', {
|
||||||
|
'text': self.options.label
|
||||||
|
}).adopt(
|
||||||
|
self.input = new Element('input', {
|
||||||
|
'type': 'checkbox',
|
||||||
|
'value': self.getSettingValue(),
|
||||||
|
'checked': self.getSettingValue() !== undefined
|
||||||
|
})
|
||||||
|
).inject(self.el);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Option.Bool = new Class({
|
||||||
|
Extends: Option.Checkbox
|
||||||
|
});
|
||||||
|
|
||||||
|
Option.Int = new Class({
|
||||||
|
Extends: Option.String
|
||||||
|
});
|
||||||
|
|
||||||
|
Option.Directory = new Class({
|
||||||
|
|
||||||
|
Extends: OptionBase,
|
||||||
|
|
||||||
|
type: 'span',
|
||||||
|
browser: '',
|
||||||
|
save_on_change: false,
|
||||||
|
|
||||||
|
create: function(){
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
|
||||||
|
self.el.adopt(
|
||||||
|
new Element('label', {
|
||||||
|
'text': self.options.label
|
||||||
|
}),
|
||||||
|
self.input = new Element('span', {
|
||||||
|
'text': self.getSettingValue(),
|
||||||
|
'events': {
|
||||||
|
'click': self.showBrowser.bind(self),
|
||||||
|
'outerClick': self.hideBrowser.bind(self)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
self.cached = {};
|
||||||
|
},
|
||||||
|
|
||||||
|
showBrowser: function(){
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
if(!self.browser)
|
||||||
|
self.browser = new Element('div.directory_list').adopt(
|
||||||
|
self.dir_list = new Element('ul')
|
||||||
|
).inject(self.input, 'after')
|
||||||
|
|
||||||
|
self.getDirs()
|
||||||
|
self.browser.show()
|
||||||
|
},
|
||||||
|
|
||||||
|
hideBrowser: function(){
|
||||||
|
this.browser.hide()
|
||||||
|
},
|
||||||
|
|
||||||
|
fillBrowser: function(json){
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
var c = self.getCurrentDir();
|
||||||
|
var v = self.input.get('value');
|
||||||
|
var add = true
|
||||||
|
|
||||||
|
if(!json){
|
||||||
|
json = self.cached[c];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
self.cached[c] = json;
|
||||||
|
}
|
||||||
|
|
||||||
|
self.dir_list.empty();
|
||||||
|
json.dirs.each(function(dir){
|
||||||
|
if(dir.indexOf(v) != -1){
|
||||||
|
new Element('li', {
|
||||||
|
'text': dir
|
||||||
|
}).inject(self.dir_list)
|
||||||
|
|
||||||
|
if(add){
|
||||||
|
self.input.insertAtCursor(dir.substring(v.length), true);
|
||||||
|
add = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
getDirs: function(){
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
var c = self.getCurrentDir();
|
||||||
|
|
||||||
|
if(self.cached[c]){
|
||||||
|
self.fillBrowser()
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
self.api().request('directory.list', {
|
||||||
|
'data': {
|
||||||
|
'path': c
|
||||||
|
},
|
||||||
|
'onComplete': self.fillBrowser.bind(self)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
getCurrentDir: function(){
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
var v = self.input.get('value');
|
||||||
|
var sep = self.api().getOption('path_sep');
|
||||||
|
var dirs = v.split(sep);
|
||||||
|
dirs.pop();
|
||||||
|
|
||||||
|
return dirs.join(sep)
|
||||||
|
},
|
||||||
|
|
||||||
|
getValue: function(){
|
||||||
|
var self = this;
|
||||||
|
return self.input.get('text');
|
||||||
|
}
|
||||||
|
});
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
Page.Soon = new Class({
|
||||||
|
|
||||||
|
Extends: PageBase,
|
||||||
|
|
||||||
|
name: 'soon',
|
||||||
|
title: 'Which wanted movies are released soon?'
|
||||||
|
|
||||||
|
})
|
||||||
@@ -0,0 +1,73 @@
|
|||||||
|
Page.Wanted = new Class({
|
||||||
|
|
||||||
|
Extends: PageBase,
|
||||||
|
|
||||||
|
name: 'wanted',
|
||||||
|
title: 'Gimmy gimmy gimmy!',
|
||||||
|
|
||||||
|
movies: [],
|
||||||
|
|
||||||
|
indexAction: function(param){
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
self.get()
|
||||||
|
},
|
||||||
|
|
||||||
|
list: function(){
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
if(!self.movie_container)
|
||||||
|
self.movie_container = new Element('div.movies').inject(self.el);
|
||||||
|
|
||||||
|
self.movie_container.empty();
|
||||||
|
Object.each(self.movies, function(info){
|
||||||
|
var m = new Movie(self, {}, info);
|
||||||
|
$(m).inject(self.movie_container);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
get: function(status, onComplete){
|
||||||
|
var self = this
|
||||||
|
|
||||||
|
if(self.movies.length == 0)
|
||||||
|
self.api().request('movie', {
|
||||||
|
'data': {},
|
||||||
|
'onComplete': function(json){
|
||||||
|
self.store(json.movies);
|
||||||
|
self.list();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
else
|
||||||
|
self.list()
|
||||||
|
},
|
||||||
|
|
||||||
|
store: function(movies){
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
self.movies = movies;
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
var Movie = new Class({
|
||||||
|
|
||||||
|
Extends: BlockBase,
|
||||||
|
|
||||||
|
initialize: function(self, options, data){
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
self.data = data;
|
||||||
|
|
||||||
|
self.parent(self, options);
|
||||||
|
},
|
||||||
|
|
||||||
|
create: function(){
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
self.el = new Element('div.movie', {
|
||||||
|
'text': self.data.name
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
@@ -1,72 +0,0 @@
|
|||||||
var Page = {}
|
|
||||||
|
|
||||||
Page.Movie = new Class({
|
|
||||||
|
|
||||||
Extends: PageBase,
|
|
||||||
|
|
||||||
name: 'movie',
|
|
||||||
|
|
||||||
initialize: function(options){
|
|
||||||
|
|
||||||
},
|
|
||||||
|
|
||||||
indexAction: function(param){
|
|
||||||
var self = this
|
|
||||||
self.getMovies()
|
|
||||||
},
|
|
||||||
|
|
||||||
getMovies: function(){
|
|
||||||
var self = this
|
|
||||||
|
|
||||||
this.api().request('movie', {'status': 'wanted'})
|
|
||||||
}
|
|
||||||
|
|
||||||
})
|
|
||||||
|
|
||||||
Page.Manage = new Class({
|
|
||||||
|
|
||||||
Extends: PageBase,
|
|
||||||
|
|
||||||
name: 'manage',
|
|
||||||
|
|
||||||
initialize: function(options){
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
})
|
|
||||||
|
|
||||||
Page.Soon = new Class({
|
|
||||||
|
|
||||||
Extends: PageBase,
|
|
||||||
|
|
||||||
name: 'soon',
|
|
||||||
|
|
||||||
initialize: function(options){
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
})
|
|
||||||
|
|
||||||
Page.Config = new Class({
|
|
||||||
|
|
||||||
Extends: PageBase,
|
|
||||||
|
|
||||||
name: 'config',
|
|
||||||
|
|
||||||
initialize: function(options){
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
})
|
|
||||||
|
|
||||||
Page.Log = new Class({
|
|
||||||
|
|
||||||
Extends: PageBase,
|
|
||||||
|
|
||||||
name: 'log',
|
|
||||||
|
|
||||||
initialize: function(options){
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
})
|
|
||||||
@@ -96,7 +96,7 @@ form {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*** Navigation ***/
|
/*** Navigation ***/
|
||||||
#header {
|
.header {
|
||||||
background: #f7f7f7;
|
background: #f7f7f7;
|
||||||
padding:10px;
|
padding:10px;
|
||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
@@ -106,22 +106,16 @@ form {
|
|||||||
-webkit-box-shadow: 0 0 30px rgba(0,0,0,0.1);
|
-webkit-box-shadow: 0 0 30px rgba(0,0,0,0.1);
|
||||||
position: fixed;
|
position: fixed;
|
||||||
width: 99%;
|
width: 99%;
|
||||||
|
z-index: 9999;
|
||||||
}
|
}
|
||||||
|
|
||||||
#header .navigation {
|
.header .navigation {
|
||||||
width: 960px;
|
width: 960px;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
overflow:hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
#header .navigation ul {
|
.header .navigation li {
|
||||||
float: left;
|
|
||||||
padding: 0;
|
|
||||||
margin: 0 0 0 6px;
|
|
||||||
width: 450px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#header .navigation ul li {
|
|
||||||
color: #8b8b8b;
|
color: #8b8b8b;
|
||||||
display: block;
|
display: block;
|
||||||
font-size:20px;
|
font-size:20px;
|
||||||
@@ -131,31 +125,31 @@ form {
|
|||||||
float: left;
|
float: left;
|
||||||
}
|
}
|
||||||
|
|
||||||
#header .navigation ul li a {
|
.header .navigation li a {
|
||||||
display: block;
|
display: block;
|
||||||
padding: 15px;
|
padding: 15px;
|
||||||
}
|
}
|
||||||
#header .navigation ul li:first-child a { padding-left: 10px; }
|
.header .navigation li:first-child a { padding-left: 10px; }
|
||||||
#header .navigation ul li a.logLink { font-size: 13px; padding: 23px 20px 15px; }
|
.header .navigation li a.logLink { font-size: 13px; padding: 23px 20px 15px; }
|
||||||
#header .navigation ul li a#showConfig {
|
.header .navigation li a#showConfig {
|
||||||
background: url('../../media/images/gear.png') no-repeat center;
|
background: url('../../media/images/gear.png') no-repeat center;
|
||||||
height: 35px;
|
height: 35px;
|
||||||
width: 10px;
|
width: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#header .navigation ul li span {
|
.header .navigation li span {
|
||||||
display: block;
|
display: block;
|
||||||
margin-top: 5px;
|
margin-top: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#header .navigation ul li.disabled {
|
.header .navigation li.disabled {
|
||||||
color: #e5e5e5;
|
color: #e5e5e5;
|
||||||
}
|
}
|
||||||
|
|
||||||
#header .navigation ul li a:link, #header .navigation ul li a:visited {
|
.header .navigation li a:link, .header .navigation li a:visited {
|
||||||
color: #2c2c2c;
|
color: #2c2c2c;
|
||||||
}
|
}
|
||||||
|
|
||||||
#header .navigation ul li a:hover, #header .navigation ul li a:active {
|
.header .navigation li a:hover, .header .navigation li a:active {
|
||||||
color: #8b8b8b;
|
color: #8b8b8b;
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,154 @@
|
|||||||
|
/* ------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Copyright (c) 2010, Dragan Babic
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person
|
||||||
|
obtaining a copy of this software and associated documentation
|
||||||
|
files (the "Software"), to deal in the Software without
|
||||||
|
restriction, including without limitation the rights to use,
|
||||||
|
copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the
|
||||||
|
Software is furnished to do so, subject to the following
|
||||||
|
conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be
|
||||||
|
included in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||||
|
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||||
|
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||||
|
OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------ */
|
||||||
|
/* ############################# GENERALS ################################### */
|
||||||
|
/* ------------------------------------------------------------------------------ */
|
||||||
|
|
||||||
|
.uniForm{ margin: 0; padding: 0; position: relative; z-index: 1; } /* reset stuff */
|
||||||
|
|
||||||
|
/* Some generals and more resets */
|
||||||
|
.uniForm fieldset{ border: none; margin: 0; padding: 0; }
|
||||||
|
.uniForm fieldset legend{ margin: 0; padding: 0; }
|
||||||
|
|
||||||
|
/* This are the main units that contain form elements */
|
||||||
|
.uniForm .ctrlHolder,
|
||||||
|
.uniForm .buttonHolder{ margin: 0; padding: 0; clear: both; }
|
||||||
|
|
||||||
|
/* Clear all floats */
|
||||||
|
.uniForm:after,
|
||||||
|
.uniForm .buttonHolder:after,
|
||||||
|
.uniForm .ctrlHolder:after,
|
||||||
|
.uniForm .ctrlHolder .multiField:after,
|
||||||
|
.uniForm .inlineLabel:after{ content: "."; display: block; height: 0; line-height: 0; font-size: 0; clear: both; min-height: 0; visibility: hidden; }
|
||||||
|
|
||||||
|
.uniForm label,
|
||||||
|
.uniForm button{ cursor: pointer; }
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------------ */
|
||||||
|
/* ########################## DEFAULT LAYOUT ################################ */
|
||||||
|
/* ------------------------------------------------------------------------------ */
|
||||||
|
/* Styles for form controls where labels are above the input elements */
|
||||||
|
/* ------------------------------------------------------------------------------ */
|
||||||
|
|
||||||
|
.uniForm label,
|
||||||
|
.uniForm .label{ display: block; float: none; margin: 0 0 .5em 0; padding: 0; line-height: 100%; width: auto; }
|
||||||
|
|
||||||
|
/* Float the input elements */
|
||||||
|
.uniForm .textInput,
|
||||||
|
.uniForm .fileUpload,
|
||||||
|
.uniForm .selectInput,
|
||||||
|
.uniForm select,
|
||||||
|
.uniForm textarea{ float: left; width: 53%; margin: 0; }
|
||||||
|
|
||||||
|
/* Postition the hints */
|
||||||
|
.uniForm .formHint{ float: right; width: 43%; margin: 0; clear: none; }
|
||||||
|
|
||||||
|
/* Position the elements inside combo boxes (multiple inputs/selects/checkboxes/radio buttons per unit) */
|
||||||
|
.uniForm ul{ float: left; width: 53%; margin: 0; padding: 0; }
|
||||||
|
.uniForm ul li{ margin: 0 0 .5em 0; list-style: none; }
|
||||||
|
.uniForm ul li label{ margin: 0; float: none; display: block; overflow: visible; }
|
||||||
|
/* Alternate layout */
|
||||||
|
.uniForm ul.alternate li{ float: left; width: 30%; margin-right: 3%; }
|
||||||
|
.uniForm ul.alternate li label{ float: none; display: block; width: 98%; }
|
||||||
|
.uniForm ul .textInput,
|
||||||
|
.uniForm ul .selectInput,
|
||||||
|
.uniForm ul select,
|
||||||
|
.uniForm ul.alternate .textInput,
|
||||||
|
.uniForm ul.alternate .selectInput,
|
||||||
|
.uniForm ul.alternate select{ width: 98%; margin-top: .5em; display: block; float: none; }
|
||||||
|
|
||||||
|
/* Required fields asterisk styling */
|
||||||
|
.uniForm label em,
|
||||||
|
.uniForm .label em{ float: left; width: 1em; margin: 0 0 0 -1em; }
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------------ */
|
||||||
|
/* ######################### ALTERNATE LAYOUT ############################### */
|
||||||
|
/* ------------------------------------------------------------------------------ */
|
||||||
|
/* Styles for form controls where labels are in line with the input elements */
|
||||||
|
/* Set the class of the parent (preferably to a fieldset) to .inlineLabels */
|
||||||
|
/* ------------------------------------------------------------------------------ */
|
||||||
|
|
||||||
|
.uniForm .inlineLabels label,
|
||||||
|
.uniForm .inlineLabels .label{ float: left; margin: .3em 2% 0 0; padding: 0; line-height: 1; position: relative; width: 32%; }
|
||||||
|
|
||||||
|
/* Float the input elements */
|
||||||
|
.uniForm .inlineLabels .textInput,
|
||||||
|
.uniForm .inlineLabels .fileUpload,
|
||||||
|
.uniForm .inlineLabels .selectInput,
|
||||||
|
.uniForm .inlineLabels select,
|
||||||
|
.uniForm .inlineLabels textarea{ float: left; width: 64%; }
|
||||||
|
|
||||||
|
/* Postition the hints */
|
||||||
|
.uniForm .inlineLabels .formHint{ clear: both; float: none; width: auto; margin-left: 34%; position: static; }
|
||||||
|
|
||||||
|
/* Position the elements inside combo boxes (multiple inputs/selects/checkboxes/radio buttons per unit) */
|
||||||
|
.uniForm .inlineLabels ul{ float: left; width: 66%; }
|
||||||
|
.uniForm .inlineLabels ul li{ margin: .5em 0; }
|
||||||
|
.uniForm .inlineLabels ul li label{ float: none; display: block; width: 100%; }
|
||||||
|
/* Alternate layout */
|
||||||
|
.uniForm .inlineLabels ul.alternate li{ margin-right: 3%; margin-top: .25em; }
|
||||||
|
.uniForm .inlineLabels ul li label .textInput,
|
||||||
|
.uniForm .inlineLabels ul li label textarea,
|
||||||
|
.uniForm .inlineLabels ul li label select{ float: none; display: block; width: 98%; }
|
||||||
|
|
||||||
|
/* Required fields asterisk styling */
|
||||||
|
.uniForm .inlineLabels label em,
|
||||||
|
.uniForm .inlineLabels .label em{ display: block; float: none; margin: 0; position: absolute; right: 0; }
|
||||||
|
|
||||||
|
/* ----------------------------------------------------------------------------- */
|
||||||
|
/* ########################### Additional Stuff ################################ */
|
||||||
|
/* ----------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/* Generals */
|
||||||
|
.uniForm legend{ color: inherit; }
|
||||||
|
|
||||||
|
.uniForm .secondaryAction{ float: left; }
|
||||||
|
|
||||||
|
/* .inlineLabel is used for inputs within labels - checkboxes and radio buttons */
|
||||||
|
.uniForm .inlineLabel input,
|
||||||
|
.uniForm .inlineLabels .inlineLabel input,
|
||||||
|
.uniForm .blockLabels .inlineLabel input,
|
||||||
|
/* class .inlineLabel is depreciated */
|
||||||
|
.uniForm label input{ float: none; display: inline; margin: 0; padding: 0; border: none; }
|
||||||
|
|
||||||
|
.uniForm .buttonHolder .inlineLabel,
|
||||||
|
.uniForm .buttonHolder label{ float: left; margin: .5em 0 0 0; width: auto; max-width: 60%; text-align: left; }
|
||||||
|
|
||||||
|
/* When you don't want to use a label */
|
||||||
|
.uniForm .inlineLabels .noLabel ul{ margin-left: 34%; /* Match to width of label + gap to field */ }
|
||||||
|
|
||||||
|
/* Classes for control of the widths of the fields */
|
||||||
|
.uniForm .small { width: 30% !important; }
|
||||||
|
.uniForm .medium{ width: 45% !important; }
|
||||||
|
.uniForm .large { } /* Large is default and should match the value you set for .textInput, textarea or select */
|
||||||
|
.uniForm .auto { width: auto !important; }
|
||||||
|
.uniForm .small,
|
||||||
|
.uniForm .medium,
|
||||||
|
.uniForm .auto{ margin-right: 4px; }
|
||||||
|
|
||||||
|
/* Columns */
|
||||||
|
.uniForm .col{ float: left; }
|
||||||
|
.uniForm .col{ width: 50%; }
|
||||||
@@ -0,0 +1,153 @@
|
|||||||
|
/* ------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
UNI-FORM DEFAULT by DRAGAN BABIC (v2) | Wed, 31 Mar 10
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Copyright (c) 2010, Dragan Babic
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person
|
||||||
|
obtaining a copy of this software and associated documentation
|
||||||
|
files (the "Software"), to deal in the Software without
|
||||||
|
restriction, including without limitation the rights to use,
|
||||||
|
copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the
|
||||||
|
Software is furnished to do so, subject to the following
|
||||||
|
conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be
|
||||||
|
included in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||||
|
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||||
|
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||||
|
OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------ */
|
||||||
|
|
||||||
|
.uniForm{}
|
||||||
|
|
||||||
|
.uniForm legend{ font-weight: bold; font-size: 100%; margin: 0; padding: 1.5em 0; }
|
||||||
|
|
||||||
|
.uniForm .ctrlHolder{ padding: 1em; border-bottom: 1px solid #efefef; }
|
||||||
|
.uniForm .ctrlHolder.focused{ background: #fffcdf; }
|
||||||
|
|
||||||
|
.uniForm .inlineLabels .noLabel{}
|
||||||
|
|
||||||
|
.uniForm .buttonHolder{ background: #efefef; text-align: right; margin: 1.5em 0 0 0; padding: 1.5em;
|
||||||
|
/* CSS3 */
|
||||||
|
border-radius: 4px;
|
||||||
|
-webkit-border-radius: 4px;
|
||||||
|
-moz-border-radius: 4px;
|
||||||
|
-o-border-radius: 4px;
|
||||||
|
-khtml-border-radius: 4px;
|
||||||
|
}
|
||||||
|
.uniForm .buttonHolder .primaryAction{ padding: 10px 22px; line-height: 1; background: #254a86; border: 1px solid #163362; font-size: 12px; font-weight: bold; color: #fff;
|
||||||
|
/* CSS3 */
|
||||||
|
border-radius: 4px;
|
||||||
|
-webkit-border-radius: 4px;
|
||||||
|
-moz-border-radius: 4px;
|
||||||
|
-o-border-radius: 4px;
|
||||||
|
-khtml-border-radius: 4px;
|
||||||
|
box-shadow: 1px 1px 0 #fff;
|
||||||
|
-webkit-box-shadow: 1px 1px 0 #fff;
|
||||||
|
-moz-box-shadow: 1px 1px 0 #fff;
|
||||||
|
text-shadow: -1px -1px 0 rgba(0,0,0,.25);
|
||||||
|
}
|
||||||
|
.uniForm .buttonHolder .primaryAction:active{ position: relative; top: 1px; }
|
||||||
|
.uniForm .secondaryAction { text-align: left; }
|
||||||
|
.uniForm button.secondaryAction { background: transparent; border: none; color: #777; margin: 1.25em 0 0 0; padding: 0; }
|
||||||
|
|
||||||
|
.uniForm .inlineLabels label em,
|
||||||
|
.uniForm .inlineLabels .label em{ font-style: normal; font-weight: bold; }
|
||||||
|
.uniForm label small{ font-size: .75em; color: #777; }
|
||||||
|
|
||||||
|
.uniForm .textInput,
|
||||||
|
.uniForm textarea { padding: 4px 2px; border: 1px solid #aaa; background: #fff; }
|
||||||
|
.uniForm textarea { height: 12em; }
|
||||||
|
.uniForm select {}
|
||||||
|
.uniForm .fileUpload {}
|
||||||
|
|
||||||
|
.uniForm ul{}
|
||||||
|
.uniForm li{}
|
||||||
|
.uniForm ul li label{ font-size: .85em; }
|
||||||
|
|
||||||
|
.uniForm .small {}
|
||||||
|
.uniForm .medium{}
|
||||||
|
.uniForm .large {} /* Large is default and should match the value you set for .textInput, textarea or select */
|
||||||
|
.uniForm .auto {}
|
||||||
|
.uniForm .small,
|
||||||
|
.uniForm .medium,
|
||||||
|
.uniForm .auto{}
|
||||||
|
|
||||||
|
/* Get rid of the 'glow' effect in WebKit, optional */
|
||||||
|
.uniForm .ctrlHolder .textInput:focus,
|
||||||
|
.uniForm .ctrlHolder textarea:focus{ outline: none; }
|
||||||
|
|
||||||
|
.uniForm .formHint { font-size: .85em; color: #777; }
|
||||||
|
.uniForm .inlineLabels .formHint { padding-top: .5em; }
|
||||||
|
.uniForm .ctrlHolder.focused .formHint{ color: #333; }
|
||||||
|
|
||||||
|
/* ----------------------------------------------------------------------------- */
|
||||||
|
/* ############################### Messages #################################### */
|
||||||
|
/* ----------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/* Error message at the top of the form */
|
||||||
|
.uniForm #errorMsg{ background: #ffdfdf; border: 1px solid #f3afb5; margin: 0 0 1.5em 0; padding: 0 1.5em;
|
||||||
|
/* CSS3 */
|
||||||
|
border-radius: 4px;
|
||||||
|
-webkit-border-radius: 4px;
|
||||||
|
-moz-border-radius: 4px;
|
||||||
|
-o-border-radius: 4px;
|
||||||
|
-khtml-border-radius: 4px;
|
||||||
|
}
|
||||||
|
.uniForm #errorMsg h3{} /* Feel free to use a heading level suitable to your page structure */
|
||||||
|
.uniForm #errorMsg ol{ margin: 0 0 1.5em 0; padding: 0; }
|
||||||
|
.uniForm #errorMsg ol li{ margin: 0 0 3px 1.5em; padding: 7px; background: #f6bec1; position: relative; font-size: .85em;
|
||||||
|
/* CSS3 */
|
||||||
|
border-radius: 4px;
|
||||||
|
-webkit-border-radius: 4px;
|
||||||
|
-moz-border-radius: 4px;
|
||||||
|
-o-border-radius: 4px;
|
||||||
|
-khtml-border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniForm .ctrlHolder.error,
|
||||||
|
.uniForm .ctrlHolder.focused.error{ background: #ffdfdf; border: 1px solid #f3afb5;
|
||||||
|
/* CSS3 */
|
||||||
|
border-radius: 4px;
|
||||||
|
-webkit-border-radius: 4px;
|
||||||
|
-moz-border-radius: 4px;
|
||||||
|
-o-border-radius: 4px;
|
||||||
|
-khtml-border-radius: 4px;
|
||||||
|
}
|
||||||
|
.uniForm .ctrlHolder.error input.error,
|
||||||
|
.uniForm .ctrlHolder.error select.error,
|
||||||
|
.uniForm .ctrlHolder.error textarea.error{ color: #af4c4c; margin: 0 0 6px 0; padding: 4px; }
|
||||||
|
|
||||||
|
/* Success messages at the top of the form */
|
||||||
|
.uniForm #okMsg{ background: #c8ffbf; border: 1px solid #a2ef95; margin: 0 0 1.5em 0; padding: 0 1.5em; text-align: center;
|
||||||
|
/* CSS3 */
|
||||||
|
border-radius: 4px;
|
||||||
|
-webkit-border-radius: 4px;
|
||||||
|
-moz-border-radius: 4px;
|
||||||
|
-o-border-radius: 4px;
|
||||||
|
-khtml-border-radius: 4px;
|
||||||
|
}
|
||||||
|
.uniForm #OKMsg p{ margin: 0; }
|
||||||
|
|
||||||
|
/* ----------------------------------------------------------------------------- */
|
||||||
|
/* ############################### Columns ##################################### */
|
||||||
|
/* ----------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
.uniForm .col{}
|
||||||
|
.uniForm .col.first{}
|
||||||
|
.uniForm .col.last{}
|
||||||
|
.uniForm .col{ margin-bottom: 1.5em; }
|
||||||
|
/* Use .first and .last classes to control the layout/spacing of your columns */
|
||||||
|
.uniForm .col.first{ width: 49%; float: left; clear: none; }
|
||||||
|
.uniForm .col.last { width: 49%; float: right; clear: none; margin-right: 0; }
|
||||||
@@ -2,18 +2,35 @@
|
|||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<link rel="stylesheet" href="{{ url_for('.static', filename='style/main.css') }}">
|
<link rel="stylesheet" href="{{ url_for('.static', filename='style/main.css') }}">
|
||||||
|
<link rel="stylesheet" href="{{ url_for('.static', filename='style/uniform.generic.css') }}">
|
||||||
|
<link rel="stylesheet" href="{{ url_for('.static', filename='style/uniform.css') }}">
|
||||||
<script type="text/javascript" src="{{ url_for('.static', filename='scripts/mootools.js') }}"></script>
|
<script type="text/javascript" src="{{ url_for('.static', filename='scripts/mootools.js') }}"></script>
|
||||||
<script type="text/javascript" src="{{ url_for('.static', filename='scripts/mootools_more.js') }}"></script>
|
<script type="text/javascript" src="{{ url_for('.static', filename='scripts/mootools_more.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/history.js') }}"></script>
|
<script type="text/javascript" src="{{ url_for('.static', filename='scripts/history.js') }}"></script>
|
||||||
<script type="text/javascript" src="{{ url_for('.static', filename='scripts/pages.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/footer.js') }}"></script>
|
||||||
|
<script type="text/javascript" src="{{ url_for('.static', filename='scripts/block/search.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/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/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" />
|
||||||
|
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
window.addEvent('domready', function() {
|
window.addEvent('domready', function() {
|
||||||
var cp = new CouchPotato({
|
var cp = new CouchPotato({
|
||||||
'base_url': '{{ request.path }}',
|
'base_url': '{{ request.path }}',
|
||||||
'api_url': '{{ url_for('api.index') }}'
|
'api': {
|
||||||
|
'url': '{{ url_for('api.index') }}',
|
||||||
|
'path_sep': '{{ sep }}'
|
||||||
|
}
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
Reference in new issue
Block a user