Custom plugin folder outside source. fix #2076
This commit is contained in:
+27
-19
@@ -1,6 +1,8 @@
|
||||
from couchpotato.core.event import fireEvent
|
||||
from couchpotato.core.logger import CPLog
|
||||
from importlib import import_module
|
||||
import os
|
||||
import sys
|
||||
import traceback
|
||||
|
||||
log = CPLog(__name__)
|
||||
@@ -11,17 +13,6 @@ class Loader(object):
|
||||
providers = {}
|
||||
modules = {}
|
||||
|
||||
def addPath(self, root, base_path, priority, recursive = False):
|
||||
for filename in os.listdir(os.path.join(root, *base_path)):
|
||||
path = os.path.join(os.path.join(root, *base_path), filename)
|
||||
if os.path.isdir(path) and filename[:2] != '__':
|
||||
if 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)
|
||||
|
||||
def preload(self, root = ''):
|
||||
core = os.path.join(root, 'couchpotato', 'core')
|
||||
|
||||
@@ -38,6 +29,13 @@ class Loader(object):
|
||||
# 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')
|
||||
sys.path.insert(0, custom_plugin_dir)
|
||||
self.paths['custom_plugins'] = (30, '', custom_plugin_dir)
|
||||
|
||||
# Loop over all paths and add to module list
|
||||
for plugin_type, plugin_tuple in self.paths.iteritems():
|
||||
priority, module, dir_name = plugin_tuple
|
||||
self.addFromDir(plugin_type, priority, module, dir_name)
|
||||
@@ -45,8 +43,9 @@ class Loader(object):
|
||||
def run(self):
|
||||
did_save = 0
|
||||
|
||||
for priority in self.modules:
|
||||
for priority in sorted(self.modules):
|
||||
for module_name, plugin in sorted(self.modules[priority].iteritems()):
|
||||
|
||||
# Load module
|
||||
try:
|
||||
if plugin.get('name')[:2] == '__':
|
||||
@@ -55,7 +54,6 @@ class Loader(object):
|
||||
m = self.loadModule(module_name)
|
||||
if m is None:
|
||||
continue
|
||||
m = getattr(m, plugin.get('name'))
|
||||
|
||||
log.info('Loading %s: %s', (plugin['type'], plugin['name']))
|
||||
|
||||
@@ -77,10 +75,23 @@ class Loader(object):
|
||||
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] != '__':
|
||||
if 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)
|
||||
|
||||
def addFromDir(self, plugin_type, priority, module, dir_name):
|
||||
|
||||
# Load dir module
|
||||
self.addModule(priority, plugin_type, module, os.path.basename(dir_name))
|
||||
if module and len(module) > 0:
|
||||
self.addModule(priority, plugin_type, module, os.path.basename(dir_name))
|
||||
|
||||
for name in os.listdir(dir_name):
|
||||
if os.path.isdir(os.path.join(dir_name, name)) and name != 'static' and os.path.isfile(os.path.join(dir_name, name, '__init__.py')):
|
||||
@@ -123,6 +134,7 @@ class Loader(object):
|
||||
if not self.modules.get(priority):
|
||||
self.modules[priority] = {}
|
||||
|
||||
module = module.lstrip('.')
|
||||
self.modules[priority][module] = {
|
||||
'priority': priority,
|
||||
'module': module,
|
||||
@@ -132,11 +144,7 @@ class Loader(object):
|
||||
|
||||
def loadModule(self, name):
|
||||
try:
|
||||
m = __import__(name)
|
||||
splitted = name.split('.')
|
||||
for sub in splitted[1:-1]:
|
||||
m = getattr(m, sub)
|
||||
return m
|
||||
return import_module(name)
|
||||
except ImportError:
|
||||
log.debug('Skip loading module plugin %s: %s', (name, traceback.format_exc()))
|
||||
return None
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
from .main import Custom
|
||||
|
||||
def start():
|
||||
return Custom()
|
||||
|
||||
config = []
|
||||
@@ -0,0 +1,21 @@
|
||||
from couchpotato.core.event import addEvent
|
||||
from couchpotato.core.logger import CPLog
|
||||
from couchpotato.core.plugins.base import Plugin
|
||||
from couchpotato.environment import Env
|
||||
import os
|
||||
|
||||
log = CPLog(__name__)
|
||||
|
||||
|
||||
class Custom(Plugin):
|
||||
|
||||
def __init__(self):
|
||||
addEvent('app.load', self.createStructure)
|
||||
|
||||
def createStructure(self):
|
||||
|
||||
custom_dir = os.path.join(Env.get('data_dir'), 'custom_plugins')
|
||||
|
||||
if not os.path.isdir(custom_dir):
|
||||
self.makeDir(custom_dir)
|
||||
self.createFile(os.path.join(custom_dir, '__init__.py'), '# Don\'t remove this file')
|
||||
@@ -0,0 +1,38 @@
|
||||
"""Backport of importlib.import_module from 3.x."""
|
||||
# While not critical (and in no way guaranteed!), it would be nice to keep this
|
||||
# code compatible with Python 2.3.
|
||||
import sys
|
||||
|
||||
def _resolve_name(name, package, level):
|
||||
"""Return the absolute name of the module to be imported."""
|
||||
if not hasattr(package, 'rindex'):
|
||||
raise ValueError("'package' not set to a string")
|
||||
dot = len(package)
|
||||
for x in xrange(level, 1, -1):
|
||||
try:
|
||||
dot = package.rindex('.', 0, dot)
|
||||
except ValueError:
|
||||
raise ValueError("attempted relative import beyond top-level "
|
||||
"package")
|
||||
return "%s.%s" % (package[:dot], name)
|
||||
|
||||
|
||||
def import_module(name, package=None):
|
||||
"""Import a module.
|
||||
|
||||
The 'package' argument is required when performing a relative import. It
|
||||
specifies the package to use as the anchor point from which to resolve the
|
||||
relative import to an absolute import.
|
||||
|
||||
"""
|
||||
if name.startswith('.'):
|
||||
if not package:
|
||||
raise TypeError("relative imports require the 'package' argument")
|
||||
level = 0
|
||||
for character in name:
|
||||
if character != '.':
|
||||
break
|
||||
level += 1
|
||||
name = _resolve_name(name[level:], package, level)
|
||||
__import__(name)
|
||||
return sys.modules[name]
|
||||
Reference in New Issue
Block a user