16 changed files with 339 additions and 132 deletions
@ -0,0 +1,2 @@ |
|||||
|
/settings.conf |
||||
|
/logs/*.log |
@ -1,8 +1,54 @@ |
|||||
|
from blinker import signal |
||||
from couchpotato import app |
from couchpotato import app |
||||
import argparse |
from couchpotato.settings import Settings |
||||
|
from logging import handlers |
||||
|
from optparse import OptionParser |
||||
|
import logging |
||||
|
import os.path |
||||
|
import sys |
||||
|
|
||||
def cmd_couchpotato(): |
|
||||
"""Commandline entry point.""" |
def cmd_couchpotato(base_path): |
||||
# Make sure views are imported and registered. |
'''Commandline entry point.''' |
||||
import couchpotato.views |
|
||||
app.run(debug=True) |
# Options |
||||
|
parser = OptionParser('usage: %prog [options]') |
||||
|
parser.add_option('-l', '--logdir', dest = 'logdir', default = 'logs', help = 'log DIRECTORY (default ./logs)') |
||||
|
parser.add_option('-t', '--test', '--debug', action = 'store_true', dest = 'debug', help = 'Debug mode') |
||||
|
parser.add_option('-q', '--quiet', action = 'store_true', dest = 'quiet', help = "Don't log to console") |
||||
|
parser.add_option('-d', '--daemon', action = 'store_true', dest = 'daemon', help = 'Daemonize the app') |
||||
|
|
||||
|
(options, args) = parser.parse_args(sys.argv[1:]) |
||||
|
|
||||
|
|
||||
|
# Register settings |
||||
|
settings = Settings('settings.conf') |
||||
|
register = signal('settings_register') |
||||
|
register.connect(settings.registerDefaults) |
||||
|
|
||||
|
debug = options.debug or settings.get('environment') == 'development' |
||||
|
|
||||
|
# Logger |
||||
|
logger = logging.getLogger() |
||||
|
formatter = logging.Formatter('%(asctime)s %(levelname)s %(message)s', '%H:%M:%S') |
||||
|
level = logging.DEBUG if debug else logging.INFO |
||||
|
logger.setLevel(level) |
||||
|
|
||||
|
# Output logging information to screen |
||||
|
if not options.quiet: |
||||
|
hdlr = logging.StreamHandler(sys.stderr) |
||||
|
hdlr.setFormatter(formatter) |
||||
|
logger.addHandler(hdlr) |
||||
|
|
||||
|
# Output logging information to file |
||||
|
hdlr2 = handlers.RotatingFileHandler(os.path.join(options.logdir, 'CouchPotato.log'), 'a', 5000000, 4) |
||||
|
hdlr2.setFormatter(formatter) |
||||
|
logger.addHandler(hdlr2) |
||||
|
|
||||
|
|
||||
|
# Load config |
||||
|
from couchpotato.settings.loader import SettingsLoader |
||||
|
SettingsLoader(root = base_path) |
||||
|
|
||||
|
# Create app |
||||
|
app.run(host = settings.get('host'), port = int(settings.get('port')), debug = debug) |
||||
|
@ -0,0 +1,9 @@ |
|||||
|
config = ('global', { |
||||
|
'environment': 'production', |
||||
|
'host': '0.0.0.0', |
||||
|
'port': 5000, |
||||
|
'username': '', |
||||
|
'password': '', |
||||
|
'launch_browser': True, |
||||
|
'url_base': '', |
||||
|
}) |
@ -0,0 +1,21 @@ |
|||||
|
from couchpotato import app |
||||
|
|
||||
|
class CPLog(): |
||||
|
|
||||
|
context = '' |
||||
|
|
||||
|
def __init__(self, context = ''): |
||||
|
self.context = context |
||||
|
self.logger = app.logger |
||||
|
|
||||
|
def info(self, msg): |
||||
|
self.logger.info(self.addContext(msg)) |
||||
|
|
||||
|
def debug(self, msg): |
||||
|
self.logger.debug(self.addContext(msg)) |
||||
|
|
||||
|
def error(self, msg): |
||||
|
self.logger.error(self.addContext(msg)) |
||||
|
|
||||
|
def addContext(self, msg): |
||||
|
return '[%+25.25s] %s' % (self.context[-25:], msg) |
@ -0,0 +1 @@ |
|||||
|
|
@ -0,0 +1,4 @@ |
|||||
|
config = ('Renamer', { |
||||
|
'enabled': False, |
||||
|
'cleanup': False |
||||
|
}) |
@ -0,0 +1,3 @@ |
|||||
|
config = ('TheMovieDB', { |
||||
|
'key': '9b939aee0aaafc12a65bf448e4af9543' |
||||
|
}) |
@ -0,0 +1,74 @@ |
|||||
|
from __future__ import with_statement |
||||
|
from blinker import signal, Signal |
||||
|
from couchpotato.core.logger import CPLog |
||||
|
import ConfigParser |
||||
|
import time |
||||
|
|
||||
|
log = CPLog(__name__) |
||||
|
settings = signal('settings_register') |
||||
|
|
||||
|
class Settings(): |
||||
|
|
||||
|
on_save = Signal() |
||||
|
on_register = Signal() |
||||
|
|
||||
|
bool = {'true':True, 'false':False} |
||||
|
|
||||
|
def __init__(self, file): |
||||
|
self.file = file |
||||
|
|
||||
|
self.p = ConfigParser.RawConfigParser() |
||||
|
self.p.read(file) |
||||
|
|
||||
|
def parser(self): |
||||
|
return self.p |
||||
|
|
||||
|
def sections(self): |
||||
|
return self.s |
||||
|
|
||||
|
def registerDefaults(self, section_name, options): |
||||
|
|
||||
|
self.addSection(section_name) |
||||
|
for option, value in options.iteritems(): |
||||
|
self.setDefault(section_name, option, value) |
||||
|
|
||||
|
log.debug('Registered defaults %s: %s' % (section_name, options)) |
||||
|
self.on_register.send(self) |
||||
|
|
||||
|
self.save() |
||||
|
|
||||
|
def set(self, section, option, value): |
||||
|
return self.p.set(section, option, value) |
||||
|
|
||||
|
def get(self, option = '', section = 'global'): |
||||
|
value = self.p.get(section, option) |
||||
|
|
||||
|
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() |
||||
|
|
||||
|
def is_int(self, value): |
||||
|
try: |
||||
|
int(value) |
||||
|
return True |
||||
|
except ValueError: |
||||
|
return False |
||||
|
|
||||
|
def save(self): |
||||
|
with open(self.file, 'wb') as configfile: |
||||
|
self.p.write(configfile) |
||||
|
|
||||
|
log.debug('Saved settings') |
||||
|
self.on_save.send(self) |
||||
|
|
||||
|
def addSection(self, section): |
||||
|
if not self.p.has_section(section): |
||||
|
self.p.add_section(section) |
||||
|
|
||||
|
def setDefault(self, section, option, value): |
||||
|
if not self.p.has_option(section, option): |
||||
|
self.p.set(section, option, value) |
@ -0,0 +1,47 @@ |
|||||
|
from blinker import signal |
||||
|
from couchpotato.core.logger import CPLog |
||||
|
import glob |
||||
|
import os |
||||
|
import sys |
||||
|
|
||||
|
log = CPLog(__name__) |
||||
|
|
||||
|
class SettingsLoader: |
||||
|
|
||||
|
def __init__(self, root = ''): |
||||
|
|
||||
|
self.register = signal('settings_register') |
||||
|
|
||||
|
self.paths = { |
||||
|
'plugins' : ('couchpotato.core.plugins', os.path.join(root, 'couchpotato', 'core', 'plugins')), |
||||
|
'providers' : ('couchpotato.core.providers', os.path.join(root, 'couchpotato', 'core', 'providers')), |
||||
|
} |
||||
|
|
||||
|
for type, tuple in self.paths.iteritems(): |
||||
|
self.loadFromDir(tuple[0], tuple[1]) |
||||
|
|
||||
|
def loadFromDir(self, module, dir): |
||||
|
for file in glob.glob(os.path.join(dir, '*')): |
||||
|
plugin_name = os.path.basename(file) |
||||
|
plugin_dir = os.path.join(dir, plugin_name) |
||||
|
if os.path.isdir(plugin_dir): |
||||
|
self.loadConfig(module, plugin_name) |
||||
|
|
||||
|
def loadConfig(self, module, name): |
||||
|
module_name = '%s.%s' % (module, name) |
||||
|
try: |
||||
|
m = getattr(self.loadModule(module_name), name) |
||||
|
(section, options) = m.config |
||||
|
self.register.send(section, options = options) |
||||
|
except: |
||||
|
log.error("Failed loading config for %s" % name) |
||||
|
|
||||
|
def loadModule(self, name): |
||||
|
try: |
||||
|
m = __import__(name) |
||||
|
splitted = name.split('.') |
||||
|
for sub in splitted[1:-1]: |
||||
|
m = getattr(m, sub) |
||||
|
return m |
||||
|
except: |
||||
|
raise |
@ -0,0 +1 @@ |
|||||
|
|
Loading…
Reference in new issue