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.
90 lines
2.5 KiB
90 lines
2.5 KiB
6 years ago
|
import inspect
|
||
|
import logging
|
||
|
import os
|
||
|
|
||
|
log = logging.getLogger(__name__)
|
||
|
|
||
|
UNC_PREFIX = '\\\\?\\'
|
||
|
|
||
|
|
||
|
class ObjectManager(object):
|
||
|
base_dir = None
|
||
|
objects_dir = None
|
||
|
objects_map = {}
|
||
|
|
||
|
ignore_files = [
|
||
|
'__init__.py'
|
||
|
]
|
||
|
ignore_paths = [
|
||
|
'plex\\objects\\core\\base.py',
|
||
|
'plex\\objects\\core\\manager.py'
|
||
|
]
|
||
|
|
||
|
@classmethod
|
||
|
def discover(cls):
|
||
|
cls.objects_dir = os.path.join(cls.base_dir, 'plex', 'objects')
|
||
|
|
||
|
# Walk plex/objects directory
|
||
|
for current, directories, files in os.walk(cls.objects_dir):
|
||
|
|
||
|
# Iterate files, yield valid paths
|
||
|
for filename in files:
|
||
|
if not filename.endswith('.py'):
|
||
|
continue
|
||
|
|
||
|
# Ensure filename is not in ignore list
|
||
|
if filename in cls.ignore_files:
|
||
|
continue
|
||
|
|
||
|
path = os.path.join(current, filename)
|
||
|
|
||
|
# Ensure path is not in ignore list
|
||
|
if not all([not path.endswith(p) for p in cls.ignore_paths]):
|
||
|
continue
|
||
|
|
||
|
# Remove UNC prefix (if it exists)
|
||
|
if path.startswith(UNC_PREFIX):
|
||
|
path = path[len(UNC_PREFIX):]
|
||
|
|
||
|
path = os.path.relpath(path, cls.base_dir)
|
||
|
name = os.path.splitext(path)[0].replace(os.path.sep, '.')
|
||
|
|
||
|
yield path, name
|
||
|
|
||
|
@classmethod
|
||
|
def load(cls):
|
||
|
for path, name in cls.discover():
|
||
|
try:
|
||
|
mod = __import__(name, fromlist=['*'])
|
||
|
except Exception as ex:
|
||
|
log.warn('Unable to import "%s" - %s', name, ex)
|
||
|
continue
|
||
|
|
||
|
# Get classes in module
|
||
|
classes = [
|
||
|
(key, getattr(mod, key)) for key in dir(mod)
|
||
|
if not key.startswith('_')
|
||
|
]
|
||
|
|
||
|
# Filter to module-specific classes
|
||
|
classes = [
|
||
|
(key, value) for (key, value) in classes
|
||
|
if inspect.isclass(value) and value.__module__ == name
|
||
|
]
|
||
|
|
||
|
yield classes
|
||
|
|
||
|
@classmethod
|
||
|
def construct(cls):
|
||
|
log.debug('Loading descriptors...')
|
||
|
|
||
|
cls.base_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '../../', '..'))
|
||
|
|
||
|
# Load modules, find descriptor classes
|
||
|
for classes in cls.load():
|
||
|
# Update object map
|
||
|
for key, value in classes:
|
||
|
cls.objects_map[key] = value
|
||
|
|
||
|
log.debug('Loaded %s descriptors (%s)', len(cls.objects_map), ', '.join(sorted(cls.objects_map.keys())))
|