You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

164 lines
6.2 KiB

import os
import sys
import traceback
11 years ago
from couchpotato.core.event import fireEvent
from couchpotato.core.logger import CPLog
from importhelper import import_module
11 years ago
import six
11 years ago
log = CPLog(__name__)
class Loader(object):
plugins = {}
providers = {}
modules = {}
def preload(self, root = ''):
core = os.path.join(root, 'couchpotato', 'core')
self.paths = {
'core': (0, 'couchpotato.core._base', os.path.join(core, '_base')),
'plugin': (1, 'couchpotato.core.plugins', os.path.join(core, 'plugins')),
'notifications': (20, 'couchpotato.core.notifications', os.path.join(core, 'notifications')),
'downloaders': (20, 'couchpotato.core.downloaders', os.path.join(core, 'downloaders')),
}
# Add media to loader
self.addPath(root, ['couchpotato', 'core', 'media'], 25, recursive = True)
# Add custom plugin folder
from couchpotato.environment import Env
custom_plugin_dir = os.path.join(Env.get('data_dir'), 'custom_plugins')
if os.path.isdir(custom_plugin_dir):
sys.path.insert(0, custom_plugin_dir)
self.paths['custom_plugins'] = (30, '', custom_plugin_dir)
# Loop over all paths and add to module list
11 years ago
for plugin_type, plugin_tuple in self.paths.items():
13 years ago
priority, module, dir_name = plugin_tuple
self.addFromDir(plugin_type, priority, module, dir_name)
def run(self):
did_save = 0
for priority in sorted(self.modules):
11 years ago
for module_name, plugin in sorted(self.modules[priority].items()):
# Load module
try:
if plugin.get('name')[:2] == '__':
continue
m = self.loadModule(module_name)
if m is None:
continue
log.info('Loading %s: %s', (plugin['type'], plugin['name']))
# Save default settings for plugin/provider
did_save += self.loadSettings(m, module_name, save = False)
self.loadPlugins(m, plugin.get('name'))
except ImportError as e:
# todo:: subclass ImportError for missing requirements.
12 years ago
if e.message.lower().startswith("missing"):
log.error(e.message)
pass
# todo:: this needs to be more descriptive.
log.error('Import error, remove the empty folder: %s', plugin.get('module'))
log.debug('Can\'t import %s: %s', (module_name, traceback.format_exc()))
except:
log.error('Can\'t import %s: %s', (module_name, traceback.format_exc()))
if did_save:
fireEvent('settings.save')
def addPath(self, root, base_path, priority, recursive = False):
root_path = os.path.join(root, *base_path)
for filename in os.listdir(root_path):
path = os.path.join(root_path, filename)
if os.path.isdir(path) and filename[:2] != '__':
11 years ago
if six.u('__init__.py') in os.listdir(path):
new_base_path = ''.join(s + '.' for s in base_path) + filename
self.paths[new_base_path.replace('.', '_')] = (priority, new_base_path, path)
if recursive:
self.addPath(root, base_path + [filename], priority, recursive = True)
13 years ago
def addFromDir(self, plugin_type, priority, module, dir_name):
# Load dir module
if module and len(module) > 0:
self.addModule(priority, plugin_type, module, os.path.basename(dir_name))
for name in os.listdir(dir_name):
path = os.path.join(dir_name, name)
ext = os.path.splitext(path)[1]
ext_length = len(ext)
if name != 'static' and ((os.path.isdir(path) and os.path.isfile(os.path.join(path, '__init__.py')))
or (os.path.isfile(path) and ext == '.py')):
name = name[:-ext_length] if ext_length > 0 else name
module_name = '%s.%s' % (module, name)
13 years ago
self.addModule(priority, plugin_type, module_name, name)
def loadSettings(self, module, name, save = True):
if not hasattr(module, 'config'):
#log.debug('Skip loading settings for plugin %s as it has no config section' % module.__file__)
return False
try:
for section in module.config:
14 years ago
fireEvent('settings.options', section['name'], section)
options = {}
for group in section['groups']:
for option in group['options']:
options[option['name']] = option
14 years ago
fireEvent('settings.register', section_name = section['name'], options = options, save = save)
return True
13 years ago
except:
log.debug('Failed loading settings for "%s": %s', (name, traceback.format_exc()))
return False
def loadPlugins(self, module, name):
if not hasattr(module, 'autoload'):
11 years ago
#log.debug('Skip startup for plugin %s as it has no start section' % module.__file__)
return False
try:
# Load single file plugin
if isinstance(module.autoload, (str, unicode)):
getattr(module, module.autoload)()
# Load folder plugin
else:
module.autoload()
return True
12 years ago
except:
log.error('Failed loading plugin "%s": %s', (module.__file__, traceback.format_exc()))
return False
13 years ago
def addModule(self, priority, plugin_type, module, name):
if not self.modules.get(priority):
self.modules[priority] = {}
module = module.lstrip('.')
self.modules[priority][module] = {
'priority': priority,
'module': module,
13 years ago
'type': plugin_type,
'name': name,
}
def loadModule(self, name):
try:
return import_module(name)
except ImportError:
log.debug('Skip loading module plugin %s: %s', (name, traceback.format_exc()))
return None
except:
raise