Restructuring

Logging
Basic config loading from plugins/providers
This commit is contained in:
Ruud committed 2011-02-12 20:34:15 +01:00
1 parent 8be7cba417
commit 722731c8bc
14 files changed
+229 -22

No files matched your search

+2
View File
@@ -0,0 +1,2 @@
/settings.conf
/logs/*.log
+8 -9
View File
@@ -1,16 +1,21 @@
#!/usr/bin/env python #!/usr/bin/env python
"""Wrapper for the command line interface.""" """Wrapper for the command line interface."""
import os
from os.path import dirname, isfile from os.path import dirname, isfile
import os
import subprocess import subprocess
import sys import sys
import traceback import traceback
# Root path
base_path = dirname(os.path.abspath(__file__))
# Insert local directories into path
sys.path.insert(0, os.path.join(base_path, 'libs'))
try: try:
from couchpotato import cli from couchpotato import cli
except ImportError: except ImportError, e:
print "Checking local dependencies..." print "Checking local dependencies..."
if isfile(__file__): if isfile(__file__):
cwd = dirname(__file__) cwd = dirname(__file__)
@@ -31,12 +36,6 @@ except ImportError:
print "=" * 78 print "=" * 78
print stderr print stderr
print "=" * 78 print "=" * 78
print "Registering libraries..."
# Insert local directories into path
lib_path = os.path.join(os.path.abspath(cwd), 'libs')
src_path = os.path.join(os.path.abspath(cwd), 'src')
sys.path.insert(0, lib_path)
sys.path.insert(0, src_path)
print "Passing execution to couchpotato..." print "Passing execution to couchpotato..."
try: try:
@@ -53,4 +52,4 @@ except ImportError:
raise NotImplementedError("Don't know how to do that.") raise NotImplementedError("Don't know how to do that.")
if __name__ == "__main__": if __name__ == "__main__":
cli.cmd_couchpotato() cli.cmd_couchpotato(base_path)
+52 -6
View File
@@ -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)
+9
View File
@@ -0,0 +1,9 @@
config = ('global', {
'environment': 'production',
'host': '0.0.0.0',
'port': 5000,
'username': '',
'password': '',
'launch_browser': True,
'url_base': '',
})
+21
View File
@@ -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)
+1
View File
@@ -0,0 +1 @@
@@ -0,0 +1,4 @@
config = ('Renamer', {
'enabled': False,
'cleanup': False
})
Whitespace-only changes.
@@ -0,0 +1,3 @@
config = ('TheMovieDB', {
'key': '9b939aee0aaafc12a65bf448e4af9543'
})
+74
View File
@@ -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)
File renamed without changes.
+47
View File
@@ -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
@@ -1,7 +1,7 @@
from sqlalchemy.orm import scoped_session, sessionmaker
from sqlalchemy import create_engine
from sqlalchemy.schema import ThreadLocalMetaData
from elixir import * from elixir import *
from sqlalchemy import create_engine
from sqlalchemy.orm import scoped_session, sessionmaker
from sqlalchemy.schema import ThreadLocalMetaData
# We would like to be able to create this schema in a specific database at # We would like to be able to create this schema in a specific database at
# will, so we can test it easily. # will, so we can test it easily.
@@ -30,19 +30,19 @@ class Release(Entity):
class File(Entity): class File(Entity):
"""File that belongs to a release.""" """File that belongs to a release."""
history = OneToMany('RenameHistory') history = OneToMany('RenameHistory')
path = Field(UnicodeString(255), nullable=False, unique=True) path = Field(UnicodeString(255), nullable = False, unique = True)
# Subtitles can have multiple parts, too # Subtitles can have multiple parts, too
part = Field(Integer) part = Field(Integer)
release = ManyToOne('Release') release = ManyToOne('Release')
# Let's remember the size so we know about offline media. # Let's remember the size so we know about offline media.
size = Field(Integer, nullable=False) size = Field(Integer, nullable = False)
type = ManyToOne('FileType') type = ManyToOne('FileType')
class FileType(Entity): class FileType(Entity):
"""Types could be trailer, subtitle, movie, partial movie etc.""" """Types could be trailer, subtitle, movie, partial movie etc."""
identifier = Field(String(20), unique=True) identifier = Field(String(20), unique = True)
name = Field(UnicodeString(255), nullable=False) name = Field(UnicodeString(255), nullable = False)
files = OneToMany('File') files = OneToMany('File')
+1
View File
@@ -0,0 +1 @@