conf.py 4.11 KB

import os
import sys
import logging
import importlib

from django.core.exceptions import ImproperlyConfigured

logger = logging.getLogger('colab.init')
if os.environ.get('COLAB_DEBUG'):
    logger.addHandler(logging.StreamHandler())
    logger.setLevel(logging.DEBUG)


class InaccessibleSettings(ImproperlyConfigured):
    """Settings.py is Inaccessible.

    Check if the file exists and if you have read permissions."""


class DatabaseUndefined(ImproperlyConfigured):
    """Default database is not set.

    When DEBUG is set to True a local sqlite database can be used for
    developement porposes but otherwise the `default` database must
    be set."""


def _load_py_file(py_path, path):
    original_path = sys.path

    sys.path = [path]
    try:
        py_settings = importlib.import_module(py_path)

    except IOError:
        msg = ('Could not open settings file {}. Please '
               'check if the file exists and if user '
               'has read rights.').format(py_path)
        raise InaccessibleSettings(msg)

    except SyntaxError as excpt:
        msg = ('Syntax Error: {}'.format(excpt))
        raise InaccessibleSettings(msg)

    finally:
        sys.path = original_path

    py_setting = {var: getattr(py_settings, var) for var in dir(py_settings)
                  if not var.startswith('__')}

    return py_setting


def load_py_settings():
    settings_file = os.getenv('COLAB_SETTINGS', '/etc/colab/settings.py')
    settings_module = settings_file.split('.')[-2].split('/')[-1]
    py_path = "/".join(settings_file.split('/')[:-1])

    logger.info('Settings file: %s', settings_file)

    if not os.path.exists(py_path):
        msg = "The py file {} does not exist".format(py_path)
        raise InaccessibleSettings(msg)

    py_settings = _load_py_file(settings_module, py_path)

    # Read settings from settings.d
    settings_dir = '/etc/colab/settings.d'
    logger.info('Settings directory: %s', settings_dir)

    if not os.path.exists(settings_dir):
        return py_settings

    for file_name in os.listdir(settings_dir):
        if not file_name.endswith('.py'):
            continue

        file_module = file_name.split('.')[0]
        py_settings_d = _load_py_file(file_module, settings_dir)
        py_settings.update(py_settings_d)
        logger.info('Loaded %s/%s', settings_dir, file_name)

    return py_settings


def load_colab_apps():
    plugins_dir = os.getenv('COLAB_PLUGINS', '/etc/colab/plugins.d/')
    logger.info('Plugin settings directory: %s', plugins_dir)

    COLAB_APPS = {}

    # Try to read settings from plugins.d
    if not os.path.exists(plugins_dir):
        return {'COLAB_APPS': COLAB_APPS}

    for file_name in os.listdir(plugins_dir):
        file_module = file_name.split('.')[0]

        logger.info('Loaded plugin settings: %s%s', plugins_dir, file_name)
        py_settings_d = _load_py_file(file_module, plugins_dir)

        if os.path.isdir(os.path.join(plugins_dir, file_name)):
            app_name = file_name

        elif file_name.endswith('.py'):
            app_name = py_settings_d.get('name').split('.')[-1]

        if not app_name:
            logger.warning("Plugin missing name variable (%s)", file_name)
            continue

        try:
            importlib.import_module(app_name)
        except ImportError:
            logger.warning("Cannot import plugin %s (%s)", app_name, file_name)
            continue

        COLAB_APPS[app_name] = {}
        COLAB_APPS[app_name]['menu_title'] = py_settings_d.get('menu_title')

        fields = ['verbose_name', 'upstream', 'urls',
                  'menu_urls', 'middlewares', 'dependencies',
                  'context_processors', 'private_token', 'name']

        for key in fields:
            value = py_settings_d.get(key)
            if value:
                COLAB_APPS[app_name][key] = value

    return {'COLAB_APPS': COLAB_APPS}


def validate_database(database_dict, default_db, debug):
    db_name = database_dict.get('default', {}).get('NAME')
    if not debug and db_name == default_db:
        msg = ('Since DEBUG is set to False DATABASE must be set on '
               'Colab settings')
        raise DatabaseUndefined(msg)