# coding=utf-8
from logging import getLogger
from tempfile import mkdtemp
from zipfile import ZipFile
from path import path
from engineer.conf import settings
from engineer.exceptions import ThemeDirectoryNotFoundException
from engineer.plugins import ThemeProvider
from engineer.themes import Theme
__author__ = 'Tyler Butler <tyler@tylerbutler.com>'
logger = getLogger('engineer.finders')
#noinspection PyShadowingBuiltins
class BaseFinder(object):
@classmethod
def get_from_directory(cls, directory):
if not path(directory).exists():
raise ThemeDirectoryNotFoundException(directory)
themes = []
for file in directory.walkfiles('metadata.yaml'):
themes.append(Theme.from_yaml(file))
for zipped_file in directory.walkfiles('*.zip'):
temp = path(mkdtemp())
with ZipFile(zipped_file, 'r') as theme:
theme.extractall(path=temp)
logger.debug("Zipped theme %s unzipped to %s." % (zipped_file, temp))
themes.extend(cls.get_from_directory(temp))
return themes
@classmethod
def get_themes(cls):
return NotImplementedError()
[docs]class DefaultFinder(BaseFinder):
"""Locates and loads built-in Engineer themes."""
@classmethod
def get_themes(cls):
themes_path = settings.ENGINEER.THEMES_DIR
return cls.get_from_directory(themes_path)
[docs]class SiteFinder(BaseFinder):
"""
Loads themes from the ``/themes`` directory inside a site folder.
.. versionadded:: 0.2.3
"""
@classmethod
def get_themes(cls):
themes_path = settings.SETTINGS_DIR / 'themes'
if themes_path.exists():
return cls.get_from_directory(themes_path)
else:
return []
#noinspection PyShadowingBuiltins
[docs]class ThemeDirsFinder(BaseFinder):
"""
Loads themes from the directories specified in :attr:`~engineer.conf.EngineerConfiguration.THEME_DIRS`.
.. versionadded:: 0.2.3
"""
@classmethod
def get_themes(cls):
themes = []
for dir in settings.THEME_DIRS:
try:
themes.extend(cls.get_from_directory(dir))
except ThemeDirectoryNotFoundException as e:
logger.warning(e.message)
continue
return themes
[docs]class PluginFinder(BaseFinder):
"""
Loads themes from any installed :ref:`theme plugins`.
.. versionadded:: 0.2.4
"""
@classmethod
def get_themes(cls):
themes = []
for p in ThemeProvider.plugins:
for t in p.paths:
try:
themes.extend(cls.get_from_directory(t))
except ThemeDirectoryNotFoundException as e:
logger.warning(e.message)
continue
return themes