Searcher, settings styling
This commit is contained in:
@@ -2,11 +2,9 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
'''Wrapper for the command line interface.'''
|
'''Wrapper for the command line interface.'''
|
||||||
|
|
||||||
from os.path import dirname, isfile
|
from os.path import dirname
|
||||||
import os
|
import os
|
||||||
import subprocess
|
|
||||||
import sys
|
import sys
|
||||||
import traceback
|
|
||||||
|
|
||||||
# Root path
|
# Root path
|
||||||
base_path = dirname(os.path.abspath(__file__))
|
base_path = dirname(os.path.abspath(__file__))
|
||||||
@@ -17,37 +15,8 @@ sys.path.insert(0, os.path.join(base_path, 'libs'))
|
|||||||
from couchpotato.core.logger import CPLog
|
from couchpotato.core.logger import CPLog
|
||||||
log = CPLog(__name__)
|
log = CPLog(__name__)
|
||||||
|
|
||||||
try:
|
|
||||||
from couchpotato import cli
|
|
||||||
except ImportError, e:
|
|
||||||
log.info('Checking local dependencies...')
|
|
||||||
if isfile(__file__):
|
|
||||||
cwd = dirname(__file__)
|
|
||||||
log.info('Updating libraries...')
|
|
||||||
stdout, stderr = subprocess.Popen(['git', 'submodule', 'init'],
|
|
||||||
stderr = subprocess.PIPE,
|
|
||||||
stdout = subprocess.PIPE).communicate()
|
|
||||||
if stderr:
|
|
||||||
log.info('[WARNING] Git is complaining:')
|
|
||||||
log.info(stderr)
|
|
||||||
stdout, stderr = subprocess.Popen(['git', 'submodule', 'update'],
|
|
||||||
stderr = subprocess.PIPE,
|
|
||||||
stdout = subprocess.PIPE).communicate()
|
|
||||||
if stderr:
|
|
||||||
log.info('[WARNING] Git is complaining:')
|
|
||||||
log.info(stderr)
|
|
||||||
|
|
||||||
log.info('Passing execution to couchpotato...')
|
|
||||||
try:
|
|
||||||
from couchpotato import cli
|
|
||||||
except ImportError:
|
|
||||||
log.error("[ERROR]: Something's seriously wrong.")
|
|
||||||
log.error(traceback.print_exc())
|
|
||||||
sys.exit(1)
|
|
||||||
else:
|
|
||||||
# Running from Titanium
|
|
||||||
raise NotImplementedError("Don't know how to do that.")
|
|
||||||
|
|
||||||
|
from couchpotato import cli
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
try:
|
try:
|
||||||
cli.cmd_couchpotato(base_path, sys.argv[1:])
|
cli.cmd_couchpotato(base_path, sys.argv[1:])
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
from argparse import ArgumentParser
|
from argparse import ArgumentParser
|
||||||
from couchpotato import get_engine, web
|
from couchpotato import web
|
||||||
from couchpotato.api import api
|
from couchpotato.api import api
|
||||||
from couchpotato.core.settings.model import *
|
|
||||||
from libs.daemon import createDaemon
|
from libs.daemon import createDaemon
|
||||||
from logging import handlers
|
from logging import handlers
|
||||||
import logging
|
import logging
|
||||||
@@ -110,9 +109,8 @@ def cmd_couchpotato(base_path, args):
|
|||||||
upgrade(db, repo)
|
upgrade(db, repo)
|
||||||
|
|
||||||
# Configure Database
|
# Configure Database
|
||||||
from elixir import setup_all, create_all
|
from couchpotato.core.settings.model import setup
|
||||||
setup_all()
|
setup()
|
||||||
create_all(get_engine())
|
|
||||||
|
|
||||||
|
|
||||||
# Create app
|
# Create app
|
||||||
|
|||||||
@@ -4,59 +4,81 @@ def start():
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
config = [{
|
config = [{
|
||||||
'name': 'global',
|
'name': 'core',
|
||||||
'tab': 'general',
|
'groups': [
|
||||||
'options': {
|
{
|
||||||
'debug': {
|
'tab': 'general',
|
||||||
|
'name': 'basics',
|
||||||
|
'label': 'Basics',
|
||||||
|
'description': 'Needs restart before changes take effect.',
|
||||||
|
'options': [
|
||||||
|
{
|
||||||
|
'name': 'username',
|
||||||
|
'default': '',
|
||||||
|
'type': 'string',
|
||||||
|
'label': 'Username',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'name': 'password',
|
||||||
|
'default': '',
|
||||||
|
'password': True,
|
||||||
|
'type': 'string',
|
||||||
|
'label': 'Password',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'name': '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 all ips.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'name': 'port',
|
||||||
|
'default': 5000,
|
||||||
|
'type': 'int',
|
||||||
|
'label': 'Port',
|
||||||
|
'description': 'The port I should listen to.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'name': 'launch_browser',
|
||||||
|
'default': True,
|
||||||
|
'type': 'bool',
|
||||||
|
'label': 'Launch Browser',
|
||||||
|
'description': 'Launch the browser when I start.',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'tab': 'general',
|
||||||
|
'name': 'advanced',
|
||||||
|
'label': 'Advanced',
|
||||||
|
'description': "For those who know what the're doing",
|
||||||
'advanced': True,
|
'advanced': True,
|
||||||
'default': False,
|
'options': [
|
||||||
'type': 'bool',
|
{
|
||||||
'label': 'Debug',
|
'name': 'api_key',
|
||||||
'description': 'Enable debugging.',
|
'default': uuid4().hex,
|
||||||
|
'type': 'string',
|
||||||
|
'readonly': True,
|
||||||
|
'label': 'Api Key',
|
||||||
|
'description': "This is top-secret! Don't share this!",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'name': 'debug',
|
||||||
|
'default': False,
|
||||||
|
'type': 'bool',
|
||||||
|
'label': 'Debug',
|
||||||
|
'description': 'Enable debugging.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'name': 'url_base',
|
||||||
|
'default': '',
|
||||||
|
'type': 'string',
|
||||||
|
'label': 'Url Base',
|
||||||
|
'description': 'When using mod_proxy use this to prepend the url with this.',
|
||||||
|
},
|
||||||
|
],
|
||||||
},
|
},
|
||||||
'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!',
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}]
|
}]
|
||||||
|
|||||||
@@ -53,8 +53,9 @@ class Loader:
|
|||||||
for section in module.config:
|
for section in module.config:
|
||||||
fireEventAsync('settings.options', section['name'], section)
|
fireEventAsync('settings.options', section['name'], section)
|
||||||
options = {}
|
options = {}
|
||||||
for key, option in section['options'].iteritems():
|
for group in section['groups']:
|
||||||
options[key] = option['default']
|
for option in group['options']:
|
||||||
|
options[option['name']] = option['default']
|
||||||
fireEventAsync('settings.register', section_name = section['name'], options = options, save = save)
|
fireEventAsync('settings.register', section_name = section['name'], options = options, save = save)
|
||||||
return True
|
return True
|
||||||
except Exception, e:
|
except Exception, e:
|
||||||
|
|||||||
@@ -1,33 +1,33 @@
|
|||||||
def start():
|
def start():
|
||||||
pass
|
pass
|
||||||
|
|
||||||
config = [{
|
#config = [{
|
||||||
'name': 'Renamer',
|
# 'name': 'Renamer',
|
||||||
'tab': 'renaming',
|
# 'tab': 'renaming',
|
||||||
'options': {
|
# 'options': {
|
||||||
'enabled': {
|
# 'enabled': {
|
||||||
'default': False,
|
# 'default': False,
|
||||||
'type': 'bool',
|
# 'type': 'bool',
|
||||||
'description': 'Enable renaming',
|
# 'description': 'Enable renaming',
|
||||||
},
|
# },
|
||||||
'from': {
|
# 'from': {
|
||||||
'default': '',
|
# 'default': '',
|
||||||
'type': 'directory',
|
# 'type': 'directory',
|
||||||
'label': 'From',
|
# 'label': 'From',
|
||||||
'description': 'Folder where the movies are downloaded to.',
|
# 'description': 'Folder where the movies are downloaded to.',
|
||||||
},
|
# },
|
||||||
'to': {
|
# 'to': {
|
||||||
'default': '',
|
# 'default': '',
|
||||||
'type': 'directory',
|
# 'type': 'directory',
|
||||||
'label': 'To',
|
# 'label': 'To',
|
||||||
'description': 'Folder where the movies will be moved to.',
|
# 'description': 'Folder where the movies will be moved to.',
|
||||||
},
|
# },
|
||||||
'run_every': {
|
# 'run_every': {
|
||||||
'default': 1,
|
# 'default': 1,
|
||||||
'type': 'int',
|
# 'type': 'int',
|
||||||
'unit': 'min(s)',
|
# 'unit': 'min(s)',
|
||||||
'description': 'Search for new movies inside the folder every X minutes.',
|
# 'description': 'Search for new movies inside the folder every X minutes.',
|
||||||
}
|
# }
|
||||||
}
|
# }
|
||||||
}]
|
#}]
|
||||||
|
config = []
|
||||||
|
|||||||
@@ -4,14 +4,22 @@ def start():
|
|||||||
return TMDB()
|
return TMDB()
|
||||||
|
|
||||||
config = [{
|
config = [{
|
||||||
'name': 'TheMovieDB',
|
'name': 'themoviedb',
|
||||||
'tab': 'providers',
|
'groups': [
|
||||||
'options': {
|
{
|
||||||
'api_key': {
|
'tab': 'providers',
|
||||||
|
'name': 'tmdb',
|
||||||
|
'label': 'TheMovieDB',
|
||||||
'advanced': True,
|
'advanced': True,
|
||||||
'default': '9b939aee0aaafc12a65bf448e4af9543',
|
'options': [
|
||||||
'type': 'string',
|
{
|
||||||
'description': 'Api key to use for calls to TheMovieDB.',
|
'name': 'api_key',
|
||||||
}
|
'default': '9b939aee0aaafc12a65bf448e4af9543',
|
||||||
}
|
'type': 'string',
|
||||||
|
'label': 'Api Key',
|
||||||
|
'description': 'Used for all calls to TheMovieDB.',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
}]
|
}]
|
||||||
|
|||||||
@@ -5,8 +5,9 @@ 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 couchpotato.environment import Env
|
||||||
from urllib import quote_plus
|
from urllib import quote_plus
|
||||||
import urllib2
|
import copy
|
||||||
import simplejson as json
|
import simplejson as json
|
||||||
|
import urllib2
|
||||||
|
|
||||||
log = CPLog(__name__)
|
log = CPLog(__name__)
|
||||||
|
|
||||||
@@ -21,7 +22,7 @@ class TMDB(Provider):
|
|||||||
addEvent('provider.movie.search', self.search)
|
addEvent('provider.movie.search', self.search)
|
||||||
|
|
||||||
def conf(self, attr):
|
def conf(self, attr):
|
||||||
return Env.setting(attr, 'TheMovieDB')
|
return Env.setting(attr, 'themoviedb')
|
||||||
|
|
||||||
def search(self, q, limit = 12, alternative = True):
|
def search(self, q, limit = 12, alternative = True):
|
||||||
''' Find movie by name '''
|
''' Find movie by name '''
|
||||||
@@ -48,7 +49,7 @@ class TMDB(Provider):
|
|||||||
nr = 0
|
nr = 0
|
||||||
for movie in data:
|
for movie in data:
|
||||||
|
|
||||||
year = movie['released'][:4]
|
year = str(movie['released'])[:4]
|
||||||
|
|
||||||
# Poster url
|
# Poster url
|
||||||
poster = ''
|
poster = ''
|
||||||
@@ -59,7 +60,7 @@ class TMDB(Provider):
|
|||||||
break
|
break
|
||||||
|
|
||||||
# 1900 is the same as None
|
# 1900 is the same as None
|
||||||
if year == '1900':
|
if year == '1900' or year.lower() == 'none':
|
||||||
year = None
|
year = None
|
||||||
|
|
||||||
movie_data = {
|
movie_data = {
|
||||||
@@ -70,14 +71,13 @@ class TMDB(Provider):
|
|||||||
'year': year,
|
'year': year,
|
||||||
'tagline': 'This is the tagline of the movie',
|
'tagline': 'This is the tagline of the movie',
|
||||||
}
|
}
|
||||||
results.append(movie_data)
|
results.append(copy.deepcopy(movie_data))
|
||||||
|
|
||||||
alternativeName = movie['alternative_name']
|
alternativeName = movie['alternative_name']
|
||||||
if alternativeName and alternative:
|
if alternativeName and alternative:
|
||||||
if alternativeName.lower() != movie['name'].lower() and alternativeName.lower() != 'none' and alternativeName != None:
|
if alternativeName.lower() != movie['name'].lower() and alternativeName.lower() != 'none' and alternativeName != None:
|
||||||
movie_data['name'] = toUnicode(alternativeName)
|
movie_data['name'] = toUnicode(alternativeName)
|
||||||
results.append(movie_data)
|
results.append(copy.deepcopy(movie_data))
|
||||||
|
|
||||||
nr += 1
|
nr += 1
|
||||||
if nr == limit:
|
if nr == limit:
|
||||||
break
|
break
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ class Settings():
|
|||||||
def set(self, section, option, value):
|
def set(self, section, option, value):
|
||||||
return self.p.set(section, option, self.cleanValue(value))
|
return self.p.set(section, option, self.cleanValue(value))
|
||||||
|
|
||||||
def get(self, option = '', section = 'global', default = ''):
|
def get(self, option = '', section = 'core', default = ''):
|
||||||
try:
|
try:
|
||||||
value = self.p.get(section, option)
|
value = self.p.get(section, option)
|
||||||
return self.cleanValue(value)
|
return self.cleanValue(value)
|
||||||
|
|||||||
@@ -121,3 +121,12 @@ class RenameHistory(Entity):
|
|||||||
new = Field(String(255))
|
new = Field(String(255))
|
||||||
|
|
||||||
file = ManyToOne('File')
|
file = ManyToOne('File')
|
||||||
|
|
||||||
|
|
||||||
|
def setup():
|
||||||
|
""" Setup the database and create the tables that don't exists yet """
|
||||||
|
from elixir import setup_all, create_all
|
||||||
|
from couchpotato import get_engine
|
||||||
|
|
||||||
|
setup_all()
|
||||||
|
create_all(get_engine())
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ class Env:
|
|||||||
return setattr(Env, '_' + attr, value)
|
return setattr(Env, '_' + attr, value)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def setting(attr, section = 'global', value = None, default = ''):
|
def setting(attr, section = 'core', value = None, default = ''):
|
||||||
|
|
||||||
# Return setting
|
# Return setting
|
||||||
if value == None:
|
if value == None:
|
||||||
|
|||||||
BIN
couchpotato/static/images/close_button.png
Normal file
BIN
couchpotato/static/images/close_button.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.3 KiB |
@@ -17,10 +17,6 @@ var BlockBase = new Class({
|
|||||||
this.el = new Element('div.block');
|
this.el = new Element('div.block');
|
||||||
},
|
},
|
||||||
|
|
||||||
api: function(){
|
|
||||||
return this.getParent().getApi()
|
|
||||||
},
|
|
||||||
|
|
||||||
getParent: function(){
|
getParent: function(){
|
||||||
return this.page
|
return this.page
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -8,17 +8,57 @@ Block.Search = new Class({
|
|||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
self.el = new Element('div.search_form').adopt(
|
self.el = new Element('div.search_form').adopt(
|
||||||
self.input = new Element('input', {
|
new Element('div.input').adopt(
|
||||||
'events': {
|
self.input = new Element('input', {
|
||||||
'keyup': self.keyup.bind(self)
|
'events': {
|
||||||
|
'keyup': self.keyup.bind(self),
|
||||||
|
'focus': self.hideResults.bind(self, false)
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
new Element('a', {
|
||||||
|
'events': {
|
||||||
|
'click': self.clear.bind(self)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
),
|
||||||
|
self.result_container = new Element('div.results_container', {
|
||||||
|
'tween': {
|
||||||
|
'duration': 200
|
||||||
}
|
}
|
||||||
}),
|
}).adopt(
|
||||||
self.results = new Element('div.results')
|
new Element('div.pointer'),
|
||||||
|
self.results = new Element('div.results')
|
||||||
|
).fade('hide')
|
||||||
);
|
);
|
||||||
|
|
||||||
// Debug
|
self.spinner = new Spinner(self.result_container);
|
||||||
self.input.set('value', 'iron man');
|
|
||||||
self.autocomplete(0)
|
self.OuterClickStack = new EventStack.OuterClick();
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
clear: function(e){
|
||||||
|
var self = this;
|
||||||
|
(e).stop();
|
||||||
|
|
||||||
|
self.input.set('value', '');
|
||||||
|
self.input.focus()
|
||||||
|
|
||||||
|
self.movies = []
|
||||||
|
self.results.empty()
|
||||||
|
},
|
||||||
|
|
||||||
|
hideResults: function(bool){
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
if(self.hidden == bool) return;
|
||||||
|
|
||||||
|
self.result_container.fade(bool ? 0 : 1)
|
||||||
|
|
||||||
|
if(!bool && self.OuterClickStack.stack.length == 0)
|
||||||
|
self.OuterClickStack.push(self.hideResults.bind(self, true), self.el);
|
||||||
|
|
||||||
|
self.hidden = bool;
|
||||||
},
|
},
|
||||||
|
|
||||||
keyup: function(e){
|
keyup: function(e){
|
||||||
@@ -36,6 +76,13 @@ Block.Search = new Class({
|
|||||||
autocomplete: function(delay){
|
autocomplete: function(delay){
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
|
if(!self.q()){
|
||||||
|
self.hideResults(true)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
self.spinner.show()
|
||||||
|
|
||||||
if(self.autocomplete_timer) clearTimeout(self.autocomplete_timer)
|
if(self.autocomplete_timer) clearTimeout(self.autocomplete_timer)
|
||||||
self.autocomplete_timer = self.list.delay((delay || 300), self)
|
self.autocomplete_timer = self.list.delay((delay || 300), self)
|
||||||
},
|
},
|
||||||
@@ -48,13 +95,16 @@ Block.Search = new Class({
|
|||||||
var q = self.q();
|
var q = self.q();
|
||||||
var cache = self.cache[q];
|
var cache = self.cache[q];
|
||||||
|
|
||||||
if(!cache)
|
self.hideResults(false)
|
||||||
self.api_request = self.api().request('movie.add.search', {
|
|
||||||
|
if(!cache){
|
||||||
|
self.api_request = Api.request('movie.add.search', {
|
||||||
'data': {
|
'data': {
|
||||||
'q': q
|
'q': q
|
||||||
},
|
},
|
||||||
'onComplete': self.fill.bind(self, q)
|
'onComplete': self.fill.bind(self, q)
|
||||||
})
|
})
|
||||||
|
}
|
||||||
else
|
else
|
||||||
self.fill(q, cache)
|
self.fill(q, cache)
|
||||||
|
|
||||||
@@ -65,20 +115,28 @@ Block.Search = new Class({
|
|||||||
fill: function(q, json){
|
fill: function(q, json){
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
|
self.spinner.hide();
|
||||||
self.cache[q] = json
|
self.cache[q] = json
|
||||||
|
|
||||||
self.movies = []
|
self.movies = []
|
||||||
self.results.empty()
|
self.results.empty()
|
||||||
|
|
||||||
Object.each(json.movies, function(movie){
|
Object.each(json.movies, function(movie){
|
||||||
var m = new Block.Search.Item(movie);
|
|
||||||
$(m).inject(self.results)
|
if(!movie.imdb || (movie.imdb && !self.results.getElement('#'+movie.imdb))){
|
||||||
|
var m = new Block.Search.Item(movie);
|
||||||
|
$(m).inject(self.results)
|
||||||
|
}
|
||||||
|
|
||||||
self.movies.include(m)
|
self.movies.include(m)
|
||||||
});
|
});
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
|
loading: function(bool){
|
||||||
|
this.el[bool ? 'addClass' : 'removeClass']('loading')
|
||||||
|
},
|
||||||
|
|
||||||
q: function(){
|
q: function(){
|
||||||
return this.input.get('value').trim();
|
return this.input.get('value').trim();
|
||||||
}
|
}
|
||||||
@@ -93,31 +151,58 @@ Block.Search.Item = new Class({
|
|||||||
self.info = info;
|
self.info = info;
|
||||||
|
|
||||||
self.create();
|
self.create();
|
||||||
|
|
||||||
|
self.OuterClickStack = new EventStack.OuterClick();
|
||||||
},
|
},
|
||||||
|
|
||||||
create: function(){
|
create: function(){
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
self.el = new Element('div.movie').adopt(
|
var info = self.info
|
||||||
self.name = new Element('h2', {
|
|
||||||
'text': self.info.name
|
self.el = new Element('div.movie', {
|
||||||
}),
|
'id': info.imdb
|
||||||
self.tagline = new Element('span', {
|
}).adopt(
|
||||||
'text': self.info.tagline
|
new Element('div.add').adopt(
|
||||||
}),
|
new Element('span', {
|
||||||
self.year = self.info.year ? new Element('span', {
|
'text': 'test'
|
||||||
'text': self.info.year
|
})
|
||||||
}) : null,
|
),
|
||||||
self.director = self.info.director ? new Element('span', {
|
self.data_container = new Element('div.data', {
|
||||||
'text': 'Director:' + self.info.director
|
'tween': {
|
||||||
}) : null,
|
duration: 400,
|
||||||
self.starring = self.info.actors ? new Element('span', {
|
transition: 'quint:in:out'
|
||||||
'text': 'Starring:'
|
},
|
||||||
}) : null
|
'events': {
|
||||||
|
'click': self.showOptions.bind(self)
|
||||||
|
}
|
||||||
|
}).adopt(
|
||||||
|
self.thumbnail = info.poster ? new Element('img.thumbnail', {
|
||||||
|
'src': info.poster
|
||||||
|
}) : null,
|
||||||
|
new Element('div.info').adopt(
|
||||||
|
self.name = new Element('h2', {
|
||||||
|
'text': info.name
|
||||||
|
}).adopt(
|
||||||
|
self.year = info.year ? new Element('span', {
|
||||||
|
'text': info.year
|
||||||
|
}) : null
|
||||||
|
),
|
||||||
|
self.tagline = new Element('span', {
|
||||||
|
'text': info.tagline
|
||||||
|
}),
|
||||||
|
self.director = self.info.director ? new Element('span', {
|
||||||
|
'text': 'Director:' + info.director
|
||||||
|
}) : null,
|
||||||
|
self.starring = info.actors ? new Element('span', {
|
||||||
|
'text': 'Starring:'
|
||||||
|
}) : null
|
||||||
|
)
|
||||||
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
if(self.info.actors){
|
if(info.actors){
|
||||||
Object.each(self.info.actors, function(actor){
|
Object.each(info.actors, function(actor){
|
||||||
new Element('span', {
|
new Element('span', {
|
||||||
'text': actor.name
|
'text': actor.name
|
||||||
}).inject(self.starring)
|
}).inject(self.starring)
|
||||||
@@ -125,6 +210,24 @@ Block.Search.Item = new Class({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
showOptions: function(){
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
if(!self.width)
|
||||||
|
self.width = self.data_container.getCoordinates().width
|
||||||
|
|
||||||
|
self.data_container.tween('margin-left', 0, self.width);
|
||||||
|
|
||||||
|
self.OuterClickStack.push(self.closeOptions.bind(self), self.el);
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
closeOptions: function(){
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
self.data_container.tween('margin-left', self.width, 0);
|
||||||
|
},
|
||||||
|
|
||||||
toElement: function(){
|
toElement: function(){
|
||||||
return this.el
|
return this.el
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,7 +18,6 @@ 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)
|
|
||||||
|
|
||||||
self.createLayout();
|
self.createLayout();
|
||||||
self.createPages();
|
self.createPages();
|
||||||
@@ -43,8 +42,10 @@ 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.block.navigation = new Block.Navigation(self, {}),
|
new Element('div').adopt(
|
||||||
self.block.search = new Block.Search(self, {})
|
self.block.navigation = new Block.Navigation(self, {}),
|
||||||
|
self.block.search = new Block.Search(self, {})
|
||||||
|
)
|
||||||
),
|
),
|
||||||
self.content = new Element('div.content'),
|
self.content = new Element('div.content'),
|
||||||
self.block.footer = new Block.Footer(self, {})
|
self.block.footer = new Block.Footer(self, {})
|
||||||
@@ -71,36 +72,29 @@ var CouchPotato = new Class({
|
|||||||
var action = self.route.getAction();
|
var action = self.route.getAction();
|
||||||
var params = self.route.getParams();
|
var params = self.route.getParams();
|
||||||
|
|
||||||
|
if(self.current_page)
|
||||||
|
self.current_page.hide()
|
||||||
|
|
||||||
var page = self.pages[page_name];
|
var page = self.pages[page_name];
|
||||||
page.open(action, params);
|
page.open(action, params);
|
||||||
page.show();
|
page.show();
|
||||||
|
|
||||||
if(self.current_page)
|
|
||||||
self.current_page.hide()
|
|
||||||
|
|
||||||
self.current_page = page;
|
self.current_page = page;
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
getBlock: function(block_name){
|
getBlock: function(block_name){
|
||||||
return this.block[block_name]
|
return this.block[block_name]
|
||||||
},
|
|
||||||
|
|
||||||
getApi: function(){
|
|
||||||
return this.api
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
var Api = new Class({
|
var ApiClass = new Class({
|
||||||
|
|
||||||
url: '',
|
setup: function(options){
|
||||||
|
|
||||||
initialize: function(options){
|
|
||||||
var self = this
|
var self = this
|
||||||
|
|
||||||
self.options = options;
|
self.options = options;
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
request: function(type, options){
|
request: function(type, options){
|
||||||
@@ -123,6 +117,7 @@ var Api = new Class({
|
|||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
window.Api = new ApiClass()
|
||||||
|
|
||||||
|
|
||||||
var Route = new Class({
|
var Route = new Class({
|
||||||
@@ -183,4 +178,44 @@ var Route = new Class({
|
|||||||
var p = function(){
|
var p = function(){
|
||||||
if(typeof(console) !== 'undefined' && console != null)
|
if(typeof(console) !== 'undefined' && console != null)
|
||||||
console.log(arguments)
|
console.log(arguments)
|
||||||
}
|
};
|
||||||
|
|
||||||
|
(function(){
|
||||||
|
|
||||||
|
var keyPaths = [];
|
||||||
|
|
||||||
|
var saveKeyPath = function(path) {
|
||||||
|
keyPaths.push({
|
||||||
|
sign: (path[0] === '+' || path[0] === '-')? parseInt(path.shift()+1) : 1,
|
||||||
|
path: path
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
var valueOf = function(object, path) {
|
||||||
|
var ptr = object;
|
||||||
|
path.each(function(key) { ptr = ptr[key] });
|
||||||
|
return ptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
var comparer = function(a, b) {
|
||||||
|
for (var i = 0, l = keyPaths.length; i < l; i++) {
|
||||||
|
aVal = valueOf(a, keyPaths[i].path);
|
||||||
|
bVal = valueOf(b, keyPaths[i].path);
|
||||||
|
if (aVal > bVal) return keyPaths[i].sign;
|
||||||
|
if (aVal < bVal) return -keyPaths[i].sign;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
Array.implement('sortBy', function(){
|
||||||
|
keyPaths.empty();
|
||||||
|
Array.each(arguments, function(argument) {
|
||||||
|
switch (typeOf(argument)) {
|
||||||
|
case "array": saveKeyPath(argument); break;
|
||||||
|
case "string": saveKeyPath(argument.match(/[+-]|[^.]+/g)); break;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return this.sort(comparer);
|
||||||
|
});
|
||||||
|
|
||||||
|
})();
|
||||||
71
couchpotato/static/scripts/eventstack.js
Normal file
71
couchpotato/static/scripts/eventstack.js
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
/*
|
||||||
|
---
|
||||||
|
|
||||||
|
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);
|
||||||
30
couchpotato/static/scripts/eventstack_outerclick.js
Normal file
30
couchpotato/static/scripts/eventstack_outerclick.js
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
/*
|
||||||
|
---
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
140
couchpotato/static/scripts/mootools_tween_css3.js
Normal file
140
couchpotato/static/scripts/mootools_tween_css3.js
Normal file
@@ -0,0 +1,140 @@
|
|||||||
|
/*
|
||||||
|
---
|
||||||
|
name: Fx.Tween.CSS3.Replacement
|
||||||
|
script: Fx.Tween.CSS3.Replacement.js
|
||||||
|
license: MIT-style license.
|
||||||
|
description: Same behavior like Fx.Tween but tries to use native CSS3 transition if possible (Overwrites Fx.Tween).
|
||||||
|
copyright: Copyright (c) 2010, Dipl.-Ing. (FH) André Fiedler <kontakt at visualdrugs dot net>, based on code by eskimoblood (mootools users group)
|
||||||
|
authors: [André Fiedler, eskimoblood]
|
||||||
|
|
||||||
|
requires: [Core/Class.Extras, Core/Element.Event, Core/Element.Style, Core/Fx.Tween]
|
||||||
|
|
||||||
|
provides: [Fx.Tween]
|
||||||
|
...
|
||||||
|
*/
|
||||||
|
|
||||||
|
Element.NativeEvents.transitionend = 2;
|
||||||
|
Element.NativeEvents.webkitTransitionEnd = 2;
|
||||||
|
Element.NativeEvents.oTransitionEnd = 2;
|
||||||
|
|
||||||
|
Element.Events.transitionend = {
|
||||||
|
base: Browser.safari || Browser.chrome ? 'webkitTransitionEnd' : (Browser.opera ? 'oTransitionEnd' : 'transitionend')
|
||||||
|
};
|
||||||
|
|
||||||
|
Event.implement({
|
||||||
|
|
||||||
|
getPropertyName: function(){
|
||||||
|
return this.event.propertyName;
|
||||||
|
},
|
||||||
|
|
||||||
|
getElapsedTime: function(nativeTime){
|
||||||
|
return nativeTime ? this.event.elapsedTime : (this.event.elapsedTime * 1000).toInt();
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
Element.implement({
|
||||||
|
|
||||||
|
supportStyle: function(style){
|
||||||
|
var value = this.style[style];
|
||||||
|
return !!(value || value == '');
|
||||||
|
},
|
||||||
|
|
||||||
|
supportVendorStyle: function(style){
|
||||||
|
var prefixedStyle = null;
|
||||||
|
return this.supportStyle(style) ? style : ['webkit', 'Moz', 'o'].some(function(prefix){
|
||||||
|
prefixedStyle = prefix + style.capitalize();
|
||||||
|
return this.supportStyle(prefixedStyle);
|
||||||
|
}, this) ? prefixedStyle : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
Fx.TweenCSS2 = Fx.Tween;
|
||||||
|
|
||||||
|
Fx.Tween = new Class({
|
||||||
|
|
||||||
|
Extends: Fx.TweenCSS2,
|
||||||
|
|
||||||
|
transitionTimings: {
|
||||||
|
'linear' : '0,0,1,1',
|
||||||
|
'expo:in' : '0.71,0.01,0.83,0',
|
||||||
|
'expo:out' : '0.14,1,0.32,0.99',
|
||||||
|
'expo:in:out' : '0.85,0,0.15,1',
|
||||||
|
'circ:in' : '0.34,0,0.96,0.23',
|
||||||
|
'circ:out' : '0,0.5,0.37,0.98',
|
||||||
|
'circ:in:out' : '0.88,0.1,0.12,0.9',
|
||||||
|
'sine:in' : '0.22,0.04,0.36,0',
|
||||||
|
'sine:out' : '0.04,0,0.5,1',
|
||||||
|
'sine:in:out' : '0.37,0.01,0.63,1',
|
||||||
|
'quad:in' : '0.14,0.01,0.49,0',
|
||||||
|
'quad:out' : '0.01,0,0.43,1',
|
||||||
|
'quad:in:out' : '0.47,0.04,0.53,0.96',
|
||||||
|
'cubic:in' : '0.35,0,0.65,0',
|
||||||
|
'cubic:out' : '0.09,0.25,0.24,1',
|
||||||
|
'cubic:in:out' : '0.66,0,0.34,1',
|
||||||
|
'quart:in' : '0.69,0,0.76,0.17',
|
||||||
|
'quart:out' : '0.26,0.96,0.44,1',
|
||||||
|
'quart:in:out' : '0.76,0,0.24,1',
|
||||||
|
'quint:in' : '0.64,0,0.78,0',
|
||||||
|
'quint:out' : '0.22,1,0.35,1',
|
||||||
|
'quint:in:out' : '0.9,0,0.1,1'
|
||||||
|
},
|
||||||
|
|
||||||
|
initialize: function(element, options){
|
||||||
|
options.transition = options.transition || 'sine:in:out';
|
||||||
|
this.parent(element, options);
|
||||||
|
if (typeof this.options.transition != 'string') alert('Only short notated transitions (like \'sine:in\') are supported by Fx.Tween.CSS3');
|
||||||
|
this.options.transition = this.options.transition.toLowerCase();
|
||||||
|
this.transition = this.element.supportVendorStyle('transition');
|
||||||
|
this.css3Supported = !!this.transition && !!this.transitionTimings[this.options.transition];
|
||||||
|
},
|
||||||
|
|
||||||
|
check: function(){
|
||||||
|
if (!this.boundComplete) return true;
|
||||||
|
return this.parent();
|
||||||
|
},
|
||||||
|
|
||||||
|
start: function(property, from, to){
|
||||||
|
if (this.css3Supported){
|
||||||
|
if (!this.check(property, from, to)) return this;
|
||||||
|
var args = Array.flatten(arguments);
|
||||||
|
this.property = this.options.property || args.shift();
|
||||||
|
var parsed = this.prepare(this.element, this.property, args);
|
||||||
|
this.from = parsed.from;
|
||||||
|
this.to = parsed.to;
|
||||||
|
this.boundComplete = function(event){
|
||||||
|
if (event.getPropertyName() == this.property /* && event.getElapsedTime() == this.options.duration */ ){
|
||||||
|
this.element.removeEvent('transitionend', this.boundComplete);
|
||||||
|
this.boundComplete = null;
|
||||||
|
this.fireEvent('complete', this.subject);
|
||||||
|
}
|
||||||
|
}.bind(this);
|
||||||
|
this.element.addEvent('transitionend', this.boundComplete);
|
||||||
|
var trans = function(){
|
||||||
|
this.element.setStyle(this.transition, this.property + ' ' + this.options.duration + 'ms cubic-bezier(' + this.transitionTimings[this.options.transition] + ')');
|
||||||
|
this.element.setStyle(this.property, this.to[0].value + + this.options.unit);
|
||||||
|
}.bind(this);
|
||||||
|
if (args[1]){
|
||||||
|
this.element.setStyle(this.transition, 'none');
|
||||||
|
this.element.setStyle(this.property, this.from[0].value + + this.options.unit);
|
||||||
|
trans.delay(0.1);
|
||||||
|
} else
|
||||||
|
trans();
|
||||||
|
this.fireEvent('start', this.subject);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
return this.parent(property, from, to);
|
||||||
|
},
|
||||||
|
|
||||||
|
cancel: function(){
|
||||||
|
if (this.css3Supported){
|
||||||
|
this.element.setStyle(this.transition, 'none');
|
||||||
|
this.element.removeEvent('transitionend', this.boundComplete);
|
||||||
|
this.boundComplete = null;
|
||||||
|
}
|
||||||
|
this.parent();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
@@ -57,10 +57,6 @@ var PageBase = new Class({
|
|||||||
getParent: function(){
|
getParent: function(){
|
||||||
return this.app
|
return this.app
|
||||||
},
|
},
|
||||||
|
|
||||||
api: function(){
|
|
||||||
return this.getParent().getApi()
|
|
||||||
},
|
|
||||||
|
|
||||||
show: function(){
|
show: function(){
|
||||||
this.el.addClass('active');
|
this.el.addClass('active');
|
||||||
|
|||||||
@@ -5,11 +5,19 @@ Page.Settings = new Class({
|
|||||||
name: 'settings',
|
name: 'settings',
|
||||||
title: 'Change settings.',
|
title: 'Change settings.',
|
||||||
|
|
||||||
groups: {},
|
tabs: {
|
||||||
|
'general': {
|
||||||
|
'label': 'General'
|
||||||
|
},
|
||||||
|
'providers': {
|
||||||
|
'label': 'Providers'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
open: function(action, params){
|
open: function(action, params){
|
||||||
var self = this
|
var self = this
|
||||||
//p('open config', action, params)
|
self.action = action;
|
||||||
|
self.params = params;
|
||||||
|
|
||||||
if(!self.data)
|
if(!self.data)
|
||||||
self.getData(self.create.bind(self))
|
self.getData(self.create.bind(self))
|
||||||
@@ -19,6 +27,7 @@ Page.Settings = new Class({
|
|||||||
|
|
||||||
openTab: function(action){
|
openTab: function(action){
|
||||||
var self = this;
|
var self = this;
|
||||||
|
action = action || self.action
|
||||||
|
|
||||||
if(self.current)
|
if(self.current)
|
||||||
self.toggleTab(self.current, true);
|
self.toggleTab(self.current, true);
|
||||||
@@ -27,16 +36,16 @@ Page.Settings = new Class({
|
|||||||
self.current = action;
|
self.current = action;
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
toggleTab: function(tab, hide){
|
toggleTab: function(tab_name, hide){
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
var a = hide ? 'removeClass' : 'addClass';
|
var a = hide ? 'removeClass' : 'addClass';
|
||||||
var c = 'active';
|
var c = 'active';
|
||||||
|
|
||||||
var g = self.groups[tab] || self.groups.general;
|
var t = self.tabs[tab_name] || self.tabs[self.action] || self.tabs.general;
|
||||||
g.tab[a](c);
|
t.tab[a](c);
|
||||||
g.group[a](c);
|
t.content[a](c);
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -44,7 +53,7 @@ Page.Settings = new Class({
|
|||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
if(onComplete)
|
if(onComplete)
|
||||||
self.api().request('settings', {
|
Api.request('settings', {
|
||||||
'useSpinner': true,
|
'useSpinner': true,
|
||||||
'spinnerOptions': {
|
'spinnerOptions': {
|
||||||
'target': self.el
|
'target': self.el
|
||||||
@@ -68,38 +77,79 @@ Page.Settings = new Class({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
showAdvanced: function(){
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
var c = self.advanced_toggle.checked ? 'addClass' : 'removeClass';
|
||||||
|
self.el[c]('show_advanced')
|
||||||
|
},
|
||||||
|
|
||||||
create: function(json){
|
create: function(json){
|
||||||
var self = this
|
var self = this
|
||||||
|
|
||||||
self.el.adopt(
|
self.el.adopt(
|
||||||
self.tabs = new Element('ul.tabs'),
|
self.tabs_container = new Element('ul.tabs'),
|
||||||
self.containers = new Element('form.uniForm.containers')
|
self.containers = new Element('form.uniForm.containers').adopt(
|
||||||
|
new Element('label.advanced_toggle').adopt(
|
||||||
|
new Element('span', {
|
||||||
|
'text': 'Show advanced settings'
|
||||||
|
}),
|
||||||
|
self.advanced_toggle = new Element('input[type=checkbox]', {
|
||||||
|
'events': {
|
||||||
|
'change': self.showAdvanced.bind(self)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
)
|
||||||
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Create tabs
|
||||||
|
Object.each(self.tabs, function(tab, tab_name){
|
||||||
|
if(!self.tabs[tab_name].tab){
|
||||||
|
var tab_el = new Element('li').adopt(
|
||||||
|
new Element('a', {
|
||||||
|
'href': '/'+self.name+'/'+tab_name+'/',
|
||||||
|
'text': tab.label.capitalize()
|
||||||
|
})
|
||||||
|
).inject(self.tabs_container);
|
||||||
|
|
||||||
|
self.tabs[tab_name] = Object.merge(self.tabs[tab_name], {
|
||||||
|
'tab': tab_el,
|
||||||
|
'content': new Element('div.tab_content').inject(self.containers),
|
||||||
|
'groups': {}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Add content to tabs
|
||||||
Object.each(json.options, function(section, section_name){
|
Object.each(json.options, function(section, section_name){
|
||||||
|
|
||||||
// Create tab
|
// Add groups to content
|
||||||
var tab = new Element('li').adopt(
|
section.groups.sortBy('order').each(function(group){
|
||||||
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] = {
|
// Create the group
|
||||||
'tab': tab,
|
var group_el = new Element('fieldset', {
|
||||||
'group': group
|
'class': group.advanced ? 'inlineLabels advanced' : 'inlineLabels'
|
||||||
}
|
}).adopt(
|
||||||
|
new Element('h2', {
|
||||||
|
'text': group.label
|
||||||
|
}).adopt(
|
||||||
|
new Element('span.hint', {
|
||||||
|
'text': group.description
|
||||||
|
})
|
||||||
|
)
|
||||||
|
).inject(self.tabs[group.tab].content);
|
||||||
|
|
||||||
|
self.tabs[group.tab].groups[group.name] = group_el
|
||||||
|
|
||||||
|
// Add options to group
|
||||||
|
group.options.sortBy('order').each(function(option){
|
||||||
|
var class_name = (option.type || 'input').capitalize();
|
||||||
|
var input = new Option[class_name](self, section_name, option.name, option);
|
||||||
|
input.inject(group_el);
|
||||||
|
});
|
||||||
|
|
||||||
// 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();
|
self.openTab();
|
||||||
@@ -251,6 +301,7 @@ Option.String = new Class({
|
|||||||
'text': self.options.label
|
'text': self.options.label
|
||||||
}),
|
}),
|
||||||
self.input = new Element('input', {
|
self.input = new Element('input', {
|
||||||
|
'type': 'text',
|
||||||
'name': self.postName(),
|
'name': self.postName(),
|
||||||
'value': self.getSettingValue()
|
'value': self.getSettingValue()
|
||||||
})
|
})
|
||||||
@@ -291,15 +342,19 @@ Option.Checkbox = new Class({
|
|||||||
create: function(){
|
create: function(){
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
|
var randomId = 'option-'+Math.floor(Math.random()*1000000)
|
||||||
|
|
||||||
new Element('label', {
|
new Element('label', {
|
||||||
'text': self.options.label
|
'text': self.options.label,
|
||||||
}).adopt(
|
'for': randomId
|
||||||
self.input = new Element('input', {
|
}).inject(self.el);
|
||||||
'type': 'checkbox',
|
|
||||||
'value': self.getSettingValue(),
|
self.input = new Element('input', {
|
||||||
'checked': self.getSettingValue() !== undefined
|
'type': 'checkbox',
|
||||||
})
|
'value': self.getSettingValue(),
|
||||||
).inject(self.el);
|
'checked': self.getSettingValue() !== undefined,
|
||||||
|
'id': randomId
|
||||||
|
}).inject(self.el);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ Page.Wanted = new Class({
|
|||||||
var self = this
|
var self = this
|
||||||
|
|
||||||
if(self.movies.length == 0)
|
if(self.movies.length == 0)
|
||||||
self.api().request('movie', {
|
Api.request('movie', {
|
||||||
'data': {},
|
'data': {},
|
||||||
'onComplete': function(json){
|
'onComplete': function(json){
|
||||||
self.store(json.movies);
|
self.store(json.movies);
|
||||||
|
|||||||
@@ -1,8 +1,11 @@
|
|||||||
|
/* @override http://localhost:5000/static/style/main.css */
|
||||||
|
|
||||||
html {
|
html {
|
||||||
color: #343434;
|
color: #343434;
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
line-height: 1.5;
|
line-height: 1.5;
|
||||||
font-family: "Helvetica Neue", Helvetica, Arial, Geneva, sans-serif;
|
font-family: Helvetica, Arial, Geneva, sans-serif;
|
||||||
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
@@ -10,6 +13,7 @@ body {
|
|||||||
padding: 0;
|
padding: 0;
|
||||||
background: #fff;
|
background: #fff;
|
||||||
overflow-y: scroll;
|
overflow-y: scroll;
|
||||||
|
height: 100%;
|
||||||
}
|
}
|
||||||
body.noscroll { overflow: hidden; }
|
body.noscroll { overflow: hidden; }
|
||||||
|
|
||||||
@@ -42,11 +46,13 @@ a {
|
|||||||
a:hover { color: #4d66c4; }
|
a:hover { color: #4d66c4; }
|
||||||
|
|
||||||
.page {
|
.page {
|
||||||
|
display: none;
|
||||||
width: 960px;
|
width: 960px;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
line-height: 24px;
|
line-height: 24px;
|
||||||
padding: 0 0 20px;
|
padding: 0 0 20px;
|
||||||
}
|
}
|
||||||
|
.page.active { display: block; }
|
||||||
|
|
||||||
.page .noticeMe {
|
.page .noticeMe {
|
||||||
background-color: lightgoldenrodyellow;
|
background-color: lightgoldenrodyellow;
|
||||||
@@ -59,7 +65,7 @@ a:hover { color: #4d66c4; }
|
|||||||
|
|
||||||
.content {
|
.content {
|
||||||
clear:both;
|
clear:both;
|
||||||
padding: 130px 10px 10px;
|
padding: 80px 10px 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.footer {
|
.footer {
|
||||||
@@ -99,7 +105,6 @@ form {
|
|||||||
.header {
|
.header {
|
||||||
background: #f7f7f7;
|
background: #f7f7f7;
|
||||||
padding:10px;
|
padding:10px;
|
||||||
margin-bottom: 20px;
|
|
||||||
border-bottom: 1px solid #f1f1f1;
|
border-bottom: 1px solid #f1f1f1;
|
||||||
height: 60px;
|
height: 60px;
|
||||||
-moz-box-shadow: 0 0 30px rgba(0,0,0,0.1);
|
-moz-box-shadow: 0 0 30px rgba(0,0,0,0.1);
|
||||||
@@ -109,20 +114,24 @@ form {
|
|||||||
z-index: 9999;
|
z-index: 9999;
|
||||||
}
|
}
|
||||||
|
|
||||||
.header .navigation {
|
.header > div {
|
||||||
width: 960px;
|
width: 960px;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
.header .navigation {
|
||||||
|
display: inline-block;
|
||||||
|
width: 75%;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
.header .navigation li {
|
.header .navigation li {
|
||||||
color: #8b8b8b;
|
color: #8b8b8b;
|
||||||
display: block;
|
display: inline-block;
|
||||||
font-size:20px;
|
font-size:20px;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
float: left;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.header .navigation li a {
|
.header .navigation li a {
|
||||||
@@ -153,3 +162,4 @@ form {
|
|||||||
.header .navigation li a:hover, .header .navigation li a:active {
|
.header .navigation li a:hover, .header .navigation li a:active {
|
||||||
color: #8b8b8b;
|
color: #8b8b8b;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
119
couchpotato/static/style/movie_add.css
Normal file
119
couchpotato/static/style/movie_add.css
Normal file
@@ -0,0 +1,119 @@
|
|||||||
|
/* @override http://localhost:5000/static/style/movie_add.css */
|
||||||
|
|
||||||
|
.search_form {
|
||||||
|
display: inline-block;
|
||||||
|
width: 25%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search_form input {
|
||||||
|
padding-right: 25px;
|
||||||
|
border: 1px solid #aaa;
|
||||||
|
padding: 4px;
|
||||||
|
margin: 0;
|
||||||
|
font-size: 14px;
|
||||||
|
width: 90%;
|
||||||
|
|
||||||
|
border-radius: 3px;
|
||||||
|
-webkit-border-radius: 3px;
|
||||||
|
-moz-border-radius: 3px;
|
||||||
|
}
|
||||||
|
.search_form .input a {
|
||||||
|
width: 12px;
|
||||||
|
height: 20px;
|
||||||
|
display: inline-block;
|
||||||
|
margin: 0 0 -5px -20px;
|
||||||
|
top: 4px;
|
||||||
|
right: 5px;
|
||||||
|
background: url('../images/close_button.png') 0 center no-repeat;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
.search_form .input a:hover { background-position: -12px center; }
|
||||||
|
|
||||||
|
.search_form .results_container {
|
||||||
|
padding: 10px 0;
|
||||||
|
position: absolute;
|
||||||
|
background: #fff;
|
||||||
|
margin: 11px 0 0 -243px;
|
||||||
|
width: 470px;
|
||||||
|
min-height: 140px;
|
||||||
|
|
||||||
|
box-shadow: 0 0 30px rgba(0,0,0,0.2);
|
||||||
|
-moz-box-shadow: 0 0 30px rgba(0,0,0,0.2);
|
||||||
|
-webkit-box-shadow: 0 0 30px rgba(0,0,0,0.2);
|
||||||
|
|
||||||
|
border-radius: 3px;
|
||||||
|
-webkit-border-radius: 3px;
|
||||||
|
-moz-border-radius: 3px;
|
||||||
|
}
|
||||||
|
.search_form .spinner {
|
||||||
|
background: #fff url('../images/spinner.gif') no-repeat center 70px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search_form .pointer {
|
||||||
|
border-right: 10px solid transparent;
|
||||||
|
border-left: 10px solid transparent;
|
||||||
|
border-bottom: 10px solid #fff;
|
||||||
|
display: block;
|
||||||
|
position: absolute;
|
||||||
|
width: 0px;
|
||||||
|
left: 50%;
|
||||||
|
margin: -19px 0 0 110px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search_form .results .movie {
|
||||||
|
overflow: hidden;
|
||||||
|
background: #666;
|
||||||
|
min-height: 140px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search_form .results .movie .add {
|
||||||
|
min-height: 140px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search_form .results .movie .data {
|
||||||
|
padding: 0 15px;
|
||||||
|
width: 440px;
|
||||||
|
position: relative;
|
||||||
|
min-height: 100px;
|
||||||
|
top: 0;
|
||||||
|
margin: -140px 0 0 0;
|
||||||
|
background: #fff;
|
||||||
|
min-height: 140px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search_form .results .movie .thumbnail {
|
||||||
|
width: 17%;
|
||||||
|
display: inline-block;
|
||||||
|
margin: 15px 3% 15px 0;
|
||||||
|
vertical-align: top;
|
||||||
|
|
||||||
|
border-radius: 3px;
|
||||||
|
-moz-border-radius: 3px;
|
||||||
|
-webkit-border-radius: 3px;
|
||||||
|
box-shadow: 0 0 3px rgba(0,0,0,0.35);
|
||||||
|
-moz-box-shadow: 0 0 3px rgba(0,0,0,0.35);
|
||||||
|
-webkit-box-shadow: 0 0 3px rgba(0,0,0,0.35);
|
||||||
|
}
|
||||||
|
|
||||||
|
.search_form .results .movie .info {
|
||||||
|
width: 74%;
|
||||||
|
display: inline-block;
|
||||||
|
vertical-align: top;
|
||||||
|
padding: 15px 0;
|
||||||
|
background: #fff;
|
||||||
|
}
|
||||||
|
.search_form .results .movie .add +.info {
|
||||||
|
margin-left: 20%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search_form .results .movie .info h2 {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search_form .results .movie .info h2 span {
|
||||||
|
padding: 0 5px;
|
||||||
|
content: ")";
|
||||||
|
}
|
||||||
|
|
||||||
|
.search_form .results .movie .info h2 span:before { content: "("; }
|
||||||
|
.search_form .results .movie .info h2 span:after { content: ")"; }
|
||||||
126
couchpotato/static/style/page/settings.css
Normal file
126
couchpotato/static/style/page/settings.css
Normal file
@@ -0,0 +1,126 @@
|
|||||||
|
/* @override http://localhost:5000/static/style/page/settings.css */
|
||||||
|
|
||||||
|
.page.settings {
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page.settings .tabs {
|
||||||
|
float: left;
|
||||||
|
width: 20%;
|
||||||
|
font-size: 25px;
|
||||||
|
text-align: right;
|
||||||
|
list-style: none;
|
||||||
|
padding: 40px 0;
|
||||||
|
margin: 0;
|
||||||
|
min-height: 300px;
|
||||||
|
}
|
||||||
|
.page.settings .tabs a {
|
||||||
|
display: block;
|
||||||
|
padding: 10px 15px;
|
||||||
|
border: 1px solid transparent;
|
||||||
|
position: relative;
|
||||||
|
z-index: 200;
|
||||||
|
margin-right: -1px;
|
||||||
|
}
|
||||||
|
.page.settings .tabs .active a {
|
||||||
|
color: black;
|
||||||
|
background: #fbfbfb;
|
||||||
|
border-color: #f1f1f1;
|
||||||
|
border-right-color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page.settings .containers {
|
||||||
|
width: 75.8%;
|
||||||
|
float: left;
|
||||||
|
padding: 20px 2%;
|
||||||
|
min-height: 300px;
|
||||||
|
background: #fbfbfb;
|
||||||
|
border-left: 1px solid #f1f1f1;s
|
||||||
|
}
|
||||||
|
|
||||||
|
.page.settings .advanced {
|
||||||
|
display: none;
|
||||||
|
color: #ce3b19;
|
||||||
|
}
|
||||||
|
.page.settings.show_advanced .advanced { display: block; }
|
||||||
|
|
||||||
|
.page.settings .tab_content {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.page.settings .tab_content.active { display: block; }
|
||||||
|
|
||||||
|
.page.settings fieldset {
|
||||||
|
padding: 10px 0;
|
||||||
|
}
|
||||||
|
.page.settings fieldset h2 {
|
||||||
|
font-weight: normal;
|
||||||
|
font-size: 25px;
|
||||||
|
padding: 0 9px 10px;
|
||||||
|
margin: 0;
|
||||||
|
border-bottom: 1px solid #f3f3f3;
|
||||||
|
}
|
||||||
|
.page.settings fieldset h2 .hint {
|
||||||
|
color: #888;
|
||||||
|
font-size: 12px;
|
||||||
|
margin-left: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page.settings .ctrlHolder {
|
||||||
|
line-height: 25px;
|
||||||
|
padding: 10px;
|
||||||
|
border-bottom: 1px solid #f3f3f3;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
.page.settings .ctrlHolder:last-child { border: none; }
|
||||||
|
.page.settings .ctrlHolder:hover { background: rgba(211,234,254,0.1); }
|
||||||
|
.page.settings .ctrlHolder.focused:hover { background: rgba(251,246,48,0.29); }
|
||||||
|
|
||||||
|
.page.settings .ctrlHolder .formHint {
|
||||||
|
float: right;
|
||||||
|
width: 47%;
|
||||||
|
margin: -18px 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page.settings .ctrlHolder input[type=checkbox] + .formHint {
|
||||||
|
float: none;
|
||||||
|
width: auto;
|
||||||
|
display: inline-block;
|
||||||
|
margin-left: 1% !important;
|
||||||
|
color: #222;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page.settings .ctrlHolder label {
|
||||||
|
font-weight: bold;
|
||||||
|
width: 20%;
|
||||||
|
margin: 0;
|
||||||
|
padding: 6px 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page.settings input[type=text] {
|
||||||
|
border: 1px solid #aaa;
|
||||||
|
padding: 3px;
|
||||||
|
margin: 0;
|
||||||
|
width: 30%;
|
||||||
|
|
||||||
|
border-radius: 3px;
|
||||||
|
-webkit-border-radius: 3px;
|
||||||
|
-moz-border-radius: 3px;
|
||||||
|
}
|
||||||
|
.page.settings .input.xsmall { width: 5% }
|
||||||
|
.page.settings .input.small { width: 10% }
|
||||||
|
.page.settings .input.medium { width: 15% }
|
||||||
|
.page.settings .input.large { width: 25% }
|
||||||
|
.page.settings .input.xlarge { width: 30% }
|
||||||
|
|
||||||
|
.page.settings .advanced_toggle {
|
||||||
|
clear: both;
|
||||||
|
display: block;
|
||||||
|
text-align: right;
|
||||||
|
height: 20px;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
.page.settings .advanced_toggle span { padding: 0 5px; }
|
||||||
|
.page.settings.show_advanced .advanced_toggle {
|
||||||
|
color: #ce3b19;
|
||||||
|
}
|
||||||
@@ -5,12 +5,17 @@
|
|||||||
<link rel="stylesheet" href="{{ url_for('.static', filename='style/uniform.generic.css') }}">
|
<link rel="stylesheet" href="{{ url_for('.static', filename='style/uniform.generic.css') }}">
|
||||||
<link rel="stylesheet" href="{{ url_for('.static', filename='style/uniform.css') }}">
|
<link rel="stylesheet" href="{{ url_for('.static', filename='style/uniform.css') }}">
|
||||||
|
|
||||||
|
<link rel="stylesheet" href="{{ url_for('.static', filename='style/page/settings.css') }}">
|
||||||
|
<link rel="stylesheet" href="{{ url_for('.static', filename='style/movie_add.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/uniform.js') }}"></script>
|
<script type="text/javascript" src="{{ url_for('.static', filename='scripts/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/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/eventstack.js') }}"></script>
|
||||||
|
<script type="text/javascript" src="{{ url_for('.static', filename='scripts/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>
|
||||||
@@ -29,13 +34,15 @@
|
|||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
window.addEvent('domready', function() {
|
window.addEvent('domready', function() {
|
||||||
new Uniform();
|
new Uniform();
|
||||||
|
|
||||||
|
Api.setup({
|
||||||
|
'url': '{{ url_for('api.index') }}',
|
||||||
|
'path_sep': '{{ sep }}',
|
||||||
|
'is_remote': false
|
||||||
|
})
|
||||||
|
|
||||||
var cp = new CouchPotato({
|
var cp = new CouchPotato({
|
||||||
'base_url': '{{ request.path }}',
|
'base_url': '{{ request.path }}'
|
||||||
'api': {
|
|
||||||
'url': '{{ url_for('api.index') }}',
|
|
||||||
'path_sep': '{{ sep }}',
|
|
||||||
'is_remote': false
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
Reference in New Issue
Block a user