Source code for shuup.core.modules.interface

# -*- coding: utf-8 -*-
# This file is part of Shuup.
#
# Copyright (c) 2012-2017, Shoop Commerce Ltd. All rights reserved.
#
# This source code is licensed under the OSL-3.0 license found in the
# LICENSE file in the root directory of this source tree.
from __future__ import unicode_literals, with_statement

import six
from django.utils.translation import ugettext_lazy as _

from shuup.apps.provides import (
    get_provide_objects, get_provide_specs_and_objects
)
from shuup.utils.importing import load
from shuup.utils.text import force_ascii


[docs]class ModuleNotFound(ValueError): pass
[docs]class ModuleInterface(object): _cached_module_impl = None default_module_spec = None # Overridden on class level module_identifier = None # Overridden on class level module_options_field = "module_data" # May be overridden on class level module_provides_key = None def _load_module(self): spec = self.default_module_spec module_identifier = self.module_identifier if module_identifier: impls = self.get_module_implementation_map() if module_identifier not in impls: raise ModuleNotFound( "Invalid module identifier %r in %s" % (module_identifier, force_ascii(repr(self))) ) spec = impls[module_identifier] cls = load(spec, context_explanation="Loading module for %s" % force_ascii(repr(self))) options = getattr(self, self.module_options_field, None) or {} return cls(self, options) @property def module(self): if not getattr(self, "_cached_module_impl", None): self._cached_module_impl = self._load_module() return self._cached_module_impl @classmethod
[docs] def get_module_choices(cls, empty_label=None): if empty_label is None: empty_label = _('No Choice') choices = [("", empty_label)] for module in get_provide_objects(cls.module_provides_key): if module.identifier: choices.append(( module.identifier, getattr(module, "name", None) or module.identifier )) choices.sort() return choices
@classmethod
[docs] def get_module_implementation_map(cls): """ Get a dict that maps module spec identifiers (short strings) into actual spec names. As an example:: {"Eggs": "foo_package.bar_module:EggsClass"} :rtype: dict[str, str] """ identifier_to_spec = {} for spec, module in six.iteritems(get_provide_specs_and_objects(cls.module_provides_key)): if module.identifier: identifier_to_spec[module.identifier] = spec return identifier_to_spec