Custom plugin folder outside source. fix #2076
This commit is contained in:
1 parent
ae4e15286a
commit
333abd2486
4 files changed
+92
-19
No files matched your search
+27
-19
@@ -1,6 +1,8 @@
|
|||||||
from couchpotato.core.event import fireEvent
|
from couchpotato.core.event import fireEvent
|
||||||
from couchpotato.core.logger import CPLog
|
from couchpotato.core.logger import CPLog
|
||||||
|
from importlib import import_module
|
||||||
import os
|
import os
|
||||||
|
import sys
|
||||||
import traceback
|
import traceback
|
||||||
|
|
||||||
log = CPLog(__name__)
|
log = CPLog(__name__)
|
||||||
@@ -11,17 +13,6 @@ class Loader(object):
|
|||||||
providers = {}
|
providers = {}
|
||||||
modules = {}
|
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 = ''):
|
def preload(self, root = ''):
|
||||||
core = os.path.join(root, 'couchpotato', 'core')
|
core = os.path.join(root, 'couchpotato', 'core')
|
||||||
|
|
||||||
@@ -38,6 +29,13 @@ class Loader(object):
|
|||||||
# Add media to loader
|
# Add media to loader
|
||||||
self.addPath(root, ['couchpotato', 'core', 'media'], 25, recursive = True)
|
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():
|
for plugin_type, plugin_tuple in self.paths.iteritems():
|
||||||
priority, module, dir_name = plugin_tuple
|
priority, module, dir_name = plugin_tuple
|
||||||
self.addFromDir(plugin_type, priority, module, dir_name)
|
self.addFromDir(plugin_type, priority, module, dir_name)
|
||||||
@@ -45,8 +43,9 @@ class Loader(object):
|
|||||||
def run(self):
|
def run(self):
|
||||||
did_save = 0
|
did_save = 0
|
||||||
|
|
||||||
for priority in self.modules:
|
for priority in sorted(self.modules):
|
||||||
for module_name, plugin in sorted(self.modules[priority].iteritems()):
|
for module_name, plugin in sorted(self.modules[priority].iteritems()):
|
||||||
|
|
||||||
# Load module
|
# Load module
|
||||||
try:
|
try:
|
||||||
if plugin.get('name')[:2] == '__':
|
if plugin.get('name')[:2] == '__':
|
||||||
@@ -55,7 +54,6 @@ class Loader(object):
|
|||||||
m = self.loadModule(module_name)
|
m = self.loadModule(module_name)
|
||||||
if m is None:
|
if m is None:
|
||||||
continue
|
continue
|
||||||
m = getattr(m, plugin.get('name'))
|
|
||||||
|
|
||||||
log.info('Loading %s: %s', (plugin['type'], plugin['name']))
|
log.info('Loading %s: %s', (plugin['type'], plugin['name']))
|
||||||
|
|
||||||
@@ -77,10 +75,23 @@ class Loader(object):
|
|||||||
if did_save:
|
if did_save:
|
||||||
fireEvent('settings.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):
|
def addFromDir(self, plugin_type, priority, module, dir_name):
|
||||||
|
|
||||||
# Load dir module
|
# 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):
|
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')):
|
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):
|
if not self.modules.get(priority):
|
||||||
self.modules[priority] = {}
|
self.modules[priority] = {}
|
||||||
|
|
||||||
|
module = module.lstrip('.')
|
||||||
self.modules[priority][module] = {
|
self.modules[priority][module] = {
|
||||||
'priority': priority,
|
'priority': priority,
|
||||||
'module': module,
|
'module': module,
|
||||||
@@ -132,11 +144,7 @@ class Loader(object):
|
|||||||
|
|
||||||
def loadModule(self, name):
|
def loadModule(self, name):
|
||||||
try:
|
try:
|
||||||
m = __import__(name)
|
return import_module(name)
|
||||||
splitted = name.split('.')
|
|
||||||
for sub in splitted[1:-1]:
|
|
||||||
m = getattr(m, sub)
|
|
||||||
return m
|
|
||||||
except ImportError:
|
except ImportError:
|
||||||
log.debug('Skip loading module plugin %s: %s', (name, traceback.format_exc()))
|
log.debug('Skip loading module plugin %s: %s', (name, traceback.format_exc()))
|
||||||
return None
|
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