[ckan-changes] [okfn/ckan] c7d88f: new improved plugins.toolkit

GitHub noreply at github.com
Fri Apr 20 16:20:10 UTC 2012


  Branch: refs/heads/enhancement-2251-tracking
  Home:   https://github.com/okfn/ckan
  Commit: c7d88f37b04d3165974d87652f5cbb0d42a08aeb
      https://github.com/okfn/ckan/commit/c7d88f37b04d3165974d87652f5cbb0d42a08aeb
  Author: Toby <toby.junk at gmail.com>
  Date:   2012-04-20 (Fri, 20 Apr 2012)

  Changed paths:
    M ckan/plugins/__init__.py
    M ckan/plugins/toolkit.py

  Log Message:
  -----------
  new improved plugins.toolkit


diff --git a/ckan/plugins/__init__.py b/ckan/plugins/__init__.py
index e11e909..719a24a 100644
--- a/ckan/plugins/__init__.py
+++ b/ckan/plugins/__init__.py
@@ -1,19 +1,7 @@
 from ckan.plugins.core import *
 from ckan.plugins.interfaces import *
 
-
-class _Toolkit(object):
-    ''' This object allows us to avoid circular imports while making
-    functions/objects available to plugins. '''
-
-    def __init__(self):
-        self.toolkit = None
-
-    def __getattr__(self, name):
-        if not self.toolkit:
-            import toolkit
-            self.toolkit = toolkit
-        return getattr(self.toolkit, name)
-
-toolkit = _Toolkit()
-del _Toolkit
+# Expose the toolkit object without doing an import *
+import toolkit as _toolkit
+toolkit = _toolkit.toolkit
+del _toolkit
diff --git a/ckan/plugins/toolkit.py b/ckan/plugins/toolkit.py
index e635c43..c784eb0 100644
--- a/ckan/plugins/toolkit.py
+++ b/ckan/plugins/toolkit.py
@@ -1,10 +1,3 @@
-## This file is intended to make functions/objects consistently
-## available to plugins whilst giving developers the ability move code
-## around or change underlying frameworks etc. It should not be used
-## internally within ckan only by extensions. Functions should only be
-## removed from this file after reasonable depreciation notice has
-## been given.
-
 import inspect
 import os
 import re
@@ -13,122 +6,184 @@
 import paste.deploy.converters as converters
 import webhelpers.html.tags
 
-import ckan
-import ckan.lib.base as base
-import ckan.logic as logic
-import ckan.lib.cli as cli
-
-
-
-__all__ = [
-    ## Imported functions/objects ##
-    '_',                    # i18n translation
-    'c',                    # template context
-    'request',              # http request object
-    'render',               # template render function
-    'render_text',          # Genshi NewTextTemplate render function
-    'render_snippet',       # snippet render function
-    'asbool',               # converts an object to a boolean
-    'asint',                # converts an object to an integer
-    'aslist',               # converts an object to a list
-    'literal',              # stop tags in a string being escaped
-    'get_action',           # get logic action function
-    'check_access',         # check logic function authorisation
-    'ActionNotFound',       # action not found exception (ckan.logic.NotFound)
-    'NotAuthorized',        # action not authorized exception
-    'ValidationError',      # model update validation error
-    'CkanCommand',          # class for providing cli interfaces
-
-    ## Fully defined in this file ##
-    'add_template_directory',
-    'add_public_directory',
-    'requires_ckan_version',
-    'check_ckan_version',
-    'CkanVersionException',
-]
-
-_ = pylons.i18n._
-c = pylons.c
-request = pylons.request
-render = base.render
-render_text = base.render_text
-asbool = converters.asbool
-asint = converters.asint
-aslist = converters.aslist
-literal = webhelpers.html.tags.literal
-
-get_action = logic.get_action
-check_access = logic.check_access
-ActionNotFound = logic.NotFound  ## Name change intentional
-NotAuthorized = logic.NotAuthorized
-ValidationError = logic.ValidationError
-
-CkanCommand = cli.CkanCommand
-
-# wrappers
-def render_snippet(template, data=None):
-    data = data or {}
-    return base.render_snippet(template, **data)
-
-
-# new functions
-def add_template_directory(config, relative_path):
-    ''' Function to aid adding extra template paths to the config.
-    The path is relative to the file calling this function. '''
-    _add_served_directory(config, relative_path, 'extra_template_paths')
-
-def add_public_directory(config, relative_path):
-    ''' Function to aid adding extra public paths to the config.
-    The path is relative to the file calling this function. '''
-    _add_served_directory(config, relative_path, 'extra_public_paths')
-
-def _add_served_directory(config, relative_path, config_var):
-    ''' Add extra public/template directories to config. '''
-    assert config_var in ('extra_template_paths', 'extra_public_paths')
-    # we want the filename that of the function caller but they will
-    # have used one of the available helper functions
-    frame, filename, line_number, function_name, lines, index =\
-        inspect.getouterframes(inspect.currentframe())[2]
-
-    this_dir = os.path.dirname(filename)
-    absolute_path = os.path.join(this_dir, relative_path)
-    if absolute_path not in config.get(config_var, ''):
-        if config.get(config_var):
-            config[config_var] += ',' + absolute_path
-        else:
-            config[config_var] = absolute_path
+__all__ = ['toolkit']
 
 class CkanVersionException(Exception):
     ''' Exception raised if required ckan version is not available. '''
     pass
 
-
-def _version_str_2_list(v_str):
-    ''' conver a version string into a list of ints
-    eg 1.6.1b --> [1, 6, 1] '''
-    v_str = re.sub(r'[^0-9.]', '', v_str)
-    return [int(part) for part in v_str.split('.')]
-
-def check_ckan_version(min_version=None, max_version=None):
-    ''' Check that the ckan version is correct for the plugin. '''
-    current = _version_str_2_list(ckan.__version__)
-
-    if min_version:
-        min_required = _version_str_2_list(min_version)
-        if current < min_required:
-            return False
-    if max_version:
-        max_required = _version_str_2_list(max_version)
-        if current > max_required:
-            return False
-    return True
-
-def requires_ckan_version(min_version, max_version=None):
-    ''' Check that the ckan version is correct for the plugin. '''
-    if not check_ckan_version(min_version=min_version, max_version=max_version):
-        if not max_version:
-            error = 'Requires ckan version %s or higher' % min_version
+class _Toolkit(object):
+    '''This class is intended to make functions/objects consistently
+    available to plugins, whilst giving developers the ability move
+    code around or change underlying frameworks etc. This object allows
+    us to avoid circular imports while making functions/objects
+    available to plugins.
+
+    It should not be used internally within ckan only by extensions.
+
+    Functions should only be removed from this file after reasonable
+    depreciation notice has been given.'''
+
+    # contents should describe the available functions/objects. We check
+    # that this list matches the actual availables in the initialisation
+    contents = [
+        ## Imported functions/objects ##
+        '_',                    # i18n translation
+        'c',                    # template context
+        'request',              # http request object
+        'render',               # template render function
+        'render_text',          # Genshi NewTextTemplate render function
+        'render_snippet',       # snippet render function
+        'asbool',               # converts an object to a boolean
+        'asint',                # converts an object to an integer
+        'aslist',               # converts an object to a list
+        'literal',              # stop tags in a string being escaped
+        'get_action',           # get logic action function
+        'check_access',         # check logic function authorisation
+        'ActionNotFound',       # action not found exception (ckan.logic.NotFound)
+        'NotAuthorized',        # action not authorized exception
+        'ValidationError',      # model update validation error
+        'CkanCommand',          # class for providing cli interfaces
+
+        ## Fully defined in this file ##
+        'add_template_directory',
+        'add_public_directory',
+        'requires_ckan_version',
+        'check_ckan_version',
+        'CkanVersionException',
+    ]
+
+
+    def __init__(self):
+        self._toolkit = {}
+
+    def _initialize(self):
+        ''' get the required functions/objects, store them for later
+        access and check that they match the contents dict. '''
+
+        import ckan
+        import ckan.lib.base as base
+        import ckan.logic as logic
+        import ckan.lib.cli as cli
+
+        # Allow class
+        self.__class__.ckan = ckan
+        self.__class__.base = base
+
+        t = self._toolkit
+
+        # imported functions
+        t['_'] = pylons.i18n._
+        t['c'] = pylons.c
+        t['request'] = pylons.request
+        t['render'] = base.render
+        t['render_text'] = base.render_text
+        t['asbool'] = converters.asbool
+        t['asint'] = converters.asint
+        t['aslist'] = converters.aslist
+        t['literal'] = webhelpers.html.tags.literal
+
+        t['get_action'] = logic.get_action
+        t['check_access'] = logic.check_access
+        t['ActionNotFound'] = logic.NotFound  ## Name change intentional
+        t['NotAuthorized'] = logic.NotAuthorized
+        t['ValidationError'] = logic.ValidationError
+
+        t['CkanCommand'] = cli.CkanCommand
+
+        # class functions
+        t['render_snippet'] = self._render_snippet
+        t['add_template_directory'] = self._add_template_directory
+        t['add_public_directory'] = self._add_public_directory
+        t['requires_ckan_version'] = self._requires_ckan_version
+        t['check_ckan_version'] = self._check_ckan_version
+        t['CkanVersionException'] = CkanVersionException
+
+        # check contents list correct
+        errors = set(t).symmetric_difference(set(self.contents))
+        if errors:
+            raise Exception('Plugin toolkit error %s not matching' % errors)
+
+    # wrappers
+    @classmethod
+    def _render_snippet(cls, template, data=None):
+        ''' helper for the render_snippet function as it uses keywords
+        rather than dict to pass data '''
+        data = data or {}
+        return cls.base.render_snippet(template, **data)
+
+    # new functions
+    @classmethod
+    def _add_template_directory(cls, config, relative_path):
+        ''' Function to aid adding extra template paths to the config.
+        The path is relative to the file calling this function. '''
+        cls._add_served_directory(config, relative_path, 'extra_template_paths')
+
+    @classmethod
+    def _add_public_directory(cls, config, relative_path):
+        ''' Function to aid adding extra public paths to the config.
+        The path is relative to the file calling this function. '''
+        cls._add_served_directory(config, relative_path, 'extra_public_paths')
+
+    @classmethod
+    def _add_served_directory(cls, config, relative_path, config_var):
+        ''' Add extra public/template directories to config. '''
+        assert config_var in ('extra_template_paths', 'extra_public_paths')
+        # we want the filename that of the function caller but they will
+        # have used one of the available helper functions
+        frame, filename, line_number, function_name, lines, index =\
+            inspect.getouterframes(inspect.currentframe())[2]
+
+        this_dir = os.path.dirname(filename)
+        absolute_path = os.path.join(this_dir, relative_path)
+        if absolute_path not in config.get(config_var, ''):
+            if config.get(config_var):
+                config[config_var] += ',' + absolute_path
+            else:
+                config[config_var] = absolute_path
+
+    @classmethod
+    def _version_str_2_list(cls, v_str):
+        ''' convert a version string into a list of ints
+        eg 1.6.1b --> [1, 6, 1] '''
+        v_str = re.sub(r'[^0-9.]', '', v_str)
+        return [int(part) for part in v_str.split('.')]
+
+    @classmethod
+    def _check_ckan_version(cls, min_version=None, max_version=None):
+        ''' Check that the ckan version is correct for the plugin. '''
+        current = cls._version_str_2_list(cls.ckan.__version__)
+
+        if min_version:
+            min_required = cls._version_str_2_list(min_version)
+            if current < min_required:
+                return False
+        if max_version:
+            max_required = cls._version_str_2_list(max_version)
+            if current > max_required:
+                return False
+        return True
+
+    @classmethod
+    def _requires_ckan_version(cls, min_version, max_version=None):
+        ''' Check that the ckan version is correct for the plugin. '''
+        if not cls._check_ckan_version(min_version=min_version,
+                                       max_version=max_version):
+            if not max_version:
+                error = 'Requires ckan version %s or higher' % min_version
+            else:
+                error = 'Requires ckan version  between %s and %s' % \
+                            (min_version, max_version)
+            raise cls.CkanVersionException(error)
+
+    def __getattr__(self, name):
+        ''' return the function/object requested '''
+        if not self._toolkit:
+            self._initialize()
+        if name in self._toolkit:
+            return self._toolkit[name]
         else:
-            error = 'Requires ckan version  between %s and %s' % \
-                        (min_version, max_version)
-        raise CkanVersionException(error)
+            raise Exception('`%s` not found in plugins toolkit' % name)
+
+toolkit = _Toolkit()
+del _Toolkit


================================================================
  Commit: a9a0c6964497d35a4d9c873e3adcbd930d9eebe2
      https://github.com/okfn/ckan/commit/a9a0c6964497d35a4d9c873e3adcbd930d9eebe2
  Author: Toby <toby.junk at gmail.com>
  Date:   2012-04-20 (Fri, 20 Apr 2012)

  Changed paths:
    M ckan/plugins/toolkit.py

  Log Message:
  -----------
  [xs] comment corrections


diff --git a/ckan/plugins/toolkit.py b/ckan/plugins/toolkit.py
index c784eb0..3eb8983 100644
--- a/ckan/plugins/toolkit.py
+++ b/ckan/plugins/toolkit.py
@@ -21,7 +21,7 @@ class _Toolkit(object):
 
     It should not be used internally within ckan only by extensions.
 
-    Functions should only be removed from this file after reasonable
+    Functions/objects should only be removed after reasonable
     depreciation notice has been given.'''
 
     # contents should describe the available functions/objects. We check
@@ -66,7 +66,7 @@ def _initialize(self):
         import ckan.logic as logic
         import ckan.lib.cli as cli
 
-        # Allow class
+        # Allow class access to these modules
         self.__class__.ckan = ckan
         self.__class__.base = base
 


================================================================
  Commit: fd1d45698b738d3e55e361de903aa876c07cc91a
      https://github.com/okfn/ckan/commit/fd1d45698b738d3e55e361de903aa876c07cc91a
  Author: Toby <toby.junk at gmail.com>
  Date:   2012-04-20 (Fri, 20 Apr 2012)

  Changed paths:
    M ckan/plugins/__init__.py
    M ckan/plugins/toolkit.py

  Log Message:
  -----------
  Merge branch 'master' into enhancement-2251-tracking


diff --git a/ckan/plugins/__init__.py b/ckan/plugins/__init__.py
index e11e909..719a24a 100644
--- a/ckan/plugins/__init__.py
+++ b/ckan/plugins/__init__.py
@@ -1,19 +1,7 @@
 from ckan.plugins.core import *
 from ckan.plugins.interfaces import *
 
-
-class _Toolkit(object):
-    ''' This object allows us to avoid circular imports while making
-    functions/objects available to plugins. '''
-
-    def __init__(self):
-        self.toolkit = None
-
-    def __getattr__(self, name):
-        if not self.toolkit:
-            import toolkit
-            self.toolkit = toolkit
-        return getattr(self.toolkit, name)
-
-toolkit = _Toolkit()
-del _Toolkit
+# Expose the toolkit object without doing an import *
+import toolkit as _toolkit
+toolkit = _toolkit.toolkit
+del _toolkit
diff --git a/ckan/plugins/toolkit.py b/ckan/plugins/toolkit.py
index e635c43..3eb8983 100644
--- a/ckan/plugins/toolkit.py
+++ b/ckan/plugins/toolkit.py
@@ -1,10 +1,3 @@
-## This file is intended to make functions/objects consistently
-## available to plugins whilst giving developers the ability move code
-## around or change underlying frameworks etc. It should not be used
-## internally within ckan only by extensions. Functions should only be
-## removed from this file after reasonable depreciation notice has
-## been given.
-
 import inspect
 import os
 import re
@@ -13,122 +6,184 @@
 import paste.deploy.converters as converters
 import webhelpers.html.tags
 
-import ckan
-import ckan.lib.base as base
-import ckan.logic as logic
-import ckan.lib.cli as cli
-
-
-
-__all__ = [
-    ## Imported functions/objects ##
-    '_',                    # i18n translation
-    'c',                    # template context
-    'request',              # http request object
-    'render',               # template render function
-    'render_text',          # Genshi NewTextTemplate render function
-    'render_snippet',       # snippet render function
-    'asbool',               # converts an object to a boolean
-    'asint',                # converts an object to an integer
-    'aslist',               # converts an object to a list
-    'literal',              # stop tags in a string being escaped
-    'get_action',           # get logic action function
-    'check_access',         # check logic function authorisation
-    'ActionNotFound',       # action not found exception (ckan.logic.NotFound)
-    'NotAuthorized',        # action not authorized exception
-    'ValidationError',      # model update validation error
-    'CkanCommand',          # class for providing cli interfaces
-
-    ## Fully defined in this file ##
-    'add_template_directory',
-    'add_public_directory',
-    'requires_ckan_version',
-    'check_ckan_version',
-    'CkanVersionException',
-]
-
-_ = pylons.i18n._
-c = pylons.c
-request = pylons.request
-render = base.render
-render_text = base.render_text
-asbool = converters.asbool
-asint = converters.asint
-aslist = converters.aslist
-literal = webhelpers.html.tags.literal
-
-get_action = logic.get_action
-check_access = logic.check_access
-ActionNotFound = logic.NotFound  ## Name change intentional
-NotAuthorized = logic.NotAuthorized
-ValidationError = logic.ValidationError
-
-CkanCommand = cli.CkanCommand
-
-# wrappers
-def render_snippet(template, data=None):
-    data = data or {}
-    return base.render_snippet(template, **data)
-
-
-# new functions
-def add_template_directory(config, relative_path):
-    ''' Function to aid adding extra template paths to the config.
-    The path is relative to the file calling this function. '''
-    _add_served_directory(config, relative_path, 'extra_template_paths')
-
-def add_public_directory(config, relative_path):
-    ''' Function to aid adding extra public paths to the config.
-    The path is relative to the file calling this function. '''
-    _add_served_directory(config, relative_path, 'extra_public_paths')
-
-def _add_served_directory(config, relative_path, config_var):
-    ''' Add extra public/template directories to config. '''
-    assert config_var in ('extra_template_paths', 'extra_public_paths')
-    # we want the filename that of the function caller but they will
-    # have used one of the available helper functions
-    frame, filename, line_number, function_name, lines, index =\
-        inspect.getouterframes(inspect.currentframe())[2]
-
-    this_dir = os.path.dirname(filename)
-    absolute_path = os.path.join(this_dir, relative_path)
-    if absolute_path not in config.get(config_var, ''):
-        if config.get(config_var):
-            config[config_var] += ',' + absolute_path
-        else:
-            config[config_var] = absolute_path
+__all__ = ['toolkit']
 
 class CkanVersionException(Exception):
     ''' Exception raised if required ckan version is not available. '''
     pass
 
-
-def _version_str_2_list(v_str):
-    ''' conver a version string into a list of ints
-    eg 1.6.1b --> [1, 6, 1] '''
-    v_str = re.sub(r'[^0-9.]', '', v_str)
-    return [int(part) for part in v_str.split('.')]
-
-def check_ckan_version(min_version=None, max_version=None):
-    ''' Check that the ckan version is correct for the plugin. '''
-    current = _version_str_2_list(ckan.__version__)
-
-    if min_version:
-        min_required = _version_str_2_list(min_version)
-        if current < min_required:
-            return False
-    if max_version:
-        max_required = _version_str_2_list(max_version)
-        if current > max_required:
-            return False
-    return True
-
-def requires_ckan_version(min_version, max_version=None):
-    ''' Check that the ckan version is correct for the plugin. '''
-    if not check_ckan_version(min_version=min_version, max_version=max_version):
-        if not max_version:
-            error = 'Requires ckan version %s or higher' % min_version
+class _Toolkit(object):
+    '''This class is intended to make functions/objects consistently
+    available to plugins, whilst giving developers the ability move
+    code around or change underlying frameworks etc. This object allows
+    us to avoid circular imports while making functions/objects
+    available to plugins.
+
+    It should not be used internally within ckan only by extensions.
+
+    Functions/objects should only be removed after reasonable
+    depreciation notice has been given.'''
+
+    # contents should describe the available functions/objects. We check
+    # that this list matches the actual availables in the initialisation
+    contents = [
+        ## Imported functions/objects ##
+        '_',                    # i18n translation
+        'c',                    # template context
+        'request',              # http request object
+        'render',               # template render function
+        'render_text',          # Genshi NewTextTemplate render function
+        'render_snippet',       # snippet render function
+        'asbool',               # converts an object to a boolean
+        'asint',                # converts an object to an integer
+        'aslist',               # converts an object to a list
+        'literal',              # stop tags in a string being escaped
+        'get_action',           # get logic action function
+        'check_access',         # check logic function authorisation
+        'ActionNotFound',       # action not found exception (ckan.logic.NotFound)
+        'NotAuthorized',        # action not authorized exception
+        'ValidationError',      # model update validation error
+        'CkanCommand',          # class for providing cli interfaces
+
+        ## Fully defined in this file ##
+        'add_template_directory',
+        'add_public_directory',
+        'requires_ckan_version',
+        'check_ckan_version',
+        'CkanVersionException',
+    ]
+
+
+    def __init__(self):
+        self._toolkit = {}
+
+    def _initialize(self):
+        ''' get the required functions/objects, store them for later
+        access and check that they match the contents dict. '''
+
+        import ckan
+        import ckan.lib.base as base
+        import ckan.logic as logic
+        import ckan.lib.cli as cli
+
+        # Allow class access to these modules
+        self.__class__.ckan = ckan
+        self.__class__.base = base
+
+        t = self._toolkit
+
+        # imported functions
+        t['_'] = pylons.i18n._
+        t['c'] = pylons.c
+        t['request'] = pylons.request
+        t['render'] = base.render
+        t['render_text'] = base.render_text
+        t['asbool'] = converters.asbool
+        t['asint'] = converters.asint
+        t['aslist'] = converters.aslist
+        t['literal'] = webhelpers.html.tags.literal
+
+        t['get_action'] = logic.get_action
+        t['check_access'] = logic.check_access
+        t['ActionNotFound'] = logic.NotFound  ## Name change intentional
+        t['NotAuthorized'] = logic.NotAuthorized
+        t['ValidationError'] = logic.ValidationError
+
+        t['CkanCommand'] = cli.CkanCommand
+
+        # class functions
+        t['render_snippet'] = self._render_snippet
+        t['add_template_directory'] = self._add_template_directory
+        t['add_public_directory'] = self._add_public_directory
+        t['requires_ckan_version'] = self._requires_ckan_version
+        t['check_ckan_version'] = self._check_ckan_version
+        t['CkanVersionException'] = CkanVersionException
+
+        # check contents list correct
+        errors = set(t).symmetric_difference(set(self.contents))
+        if errors:
+            raise Exception('Plugin toolkit error %s not matching' % errors)
+
+    # wrappers
+    @classmethod
+    def _render_snippet(cls, template, data=None):
+        ''' helper for the render_snippet function as it uses keywords
+        rather than dict to pass data '''
+        data = data or {}
+        return cls.base.render_snippet(template, **data)
+
+    # new functions
+    @classmethod
+    def _add_template_directory(cls, config, relative_path):
+        ''' Function to aid adding extra template paths to the config.
+        The path is relative to the file calling this function. '''
+        cls._add_served_directory(config, relative_path, 'extra_template_paths')
+
+    @classmethod
+    def _add_public_directory(cls, config, relative_path):
+        ''' Function to aid adding extra public paths to the config.
+        The path is relative to the file calling this function. '''
+        cls._add_served_directory(config, relative_path, 'extra_public_paths')
+
+    @classmethod
+    def _add_served_directory(cls, config, relative_path, config_var):
+        ''' Add extra public/template directories to config. '''
+        assert config_var in ('extra_template_paths', 'extra_public_paths')
+        # we want the filename that of the function caller but they will
+        # have used one of the available helper functions
+        frame, filename, line_number, function_name, lines, index =\
+            inspect.getouterframes(inspect.currentframe())[2]
+
+        this_dir = os.path.dirname(filename)
+        absolute_path = os.path.join(this_dir, relative_path)
+        if absolute_path not in config.get(config_var, ''):
+            if config.get(config_var):
+                config[config_var] += ',' + absolute_path
+            else:
+                config[config_var] = absolute_path
+
+    @classmethod
+    def _version_str_2_list(cls, v_str):
+        ''' convert a version string into a list of ints
+        eg 1.6.1b --> [1, 6, 1] '''
+        v_str = re.sub(r'[^0-9.]', '', v_str)
+        return [int(part) for part in v_str.split('.')]
+
+    @classmethod
+    def _check_ckan_version(cls, min_version=None, max_version=None):
+        ''' Check that the ckan version is correct for the plugin. '''
+        current = cls._version_str_2_list(cls.ckan.__version__)
+
+        if min_version:
+            min_required = cls._version_str_2_list(min_version)
+            if current < min_required:
+                return False
+        if max_version:
+            max_required = cls._version_str_2_list(max_version)
+            if current > max_required:
+                return False
+        return True
+
+    @classmethod
+    def _requires_ckan_version(cls, min_version, max_version=None):
+        ''' Check that the ckan version is correct for the plugin. '''
+        if not cls._check_ckan_version(min_version=min_version,
+                                       max_version=max_version):
+            if not max_version:
+                error = 'Requires ckan version %s or higher' % min_version
+            else:
+                error = 'Requires ckan version  between %s and %s' % \
+                            (min_version, max_version)
+            raise cls.CkanVersionException(error)
+
+    def __getattr__(self, name):
+        ''' return the function/object requested '''
+        if not self._toolkit:
+            self._initialize()
+        if name in self._toolkit:
+            return self._toolkit[name]
         else:
-            error = 'Requires ckan version  between %s and %s' % \
-                        (min_version, max_version)
-        raise CkanVersionException(error)
+            raise Exception('`%s` not found in plugins toolkit' % name)
+
+toolkit = _Toolkit()
+del _Toolkit


================================================================
Compare: https://github.com/okfn/ckan/compare/1183793...fd1d456


More information about the ckan-changes mailing list