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 |
|||
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.""" |
|||
# Make sure views are imported and registered. |
|||
import couchpotato.views |
|||
app.run(debug=True) |
|||
|
|||
def cmd_couchpotato(base_path): |
|||
'''Commandline entry point.''' |
|||
|
|||
# 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