Ejemplo n.º 1
0
    def _check_expired(self):
        """Checks each ExtensionManager for expired extension state.

        When the list of extensions on an ExtensionManager changes, or when
        the configuration of an extension changes, any other threads/processes
        holding onto extensions and configuration will go stale. This function
        will check each of those to see if they need to re-load their
        state.

        This is meant to be called before every HTTP request.
        """
        for extension_manager in get_extension_managers():
            # We're going to check the expiration, and then only lock if it's
            # expired. Following that, we'll check again.
            #
            # We do this in order to prevent locking unnecessarily, which could
            # impact performance or cause a problem if a thread is stuck.
            #
            # We're checking the expiration twice to prevent every blocked
            # thread from making its own attempt to reload the extensions once
            # the first thread holding the lock finishes the reload.
            if extension_manager.is_expired():
                with self._lock:
                    # Check again, since another thread may have already
                    # reloaded.
                    if extension_manager.is_expired():
                        extension_manager.load(full_reload=True)
Ejemplo n.º 2
0
    def find(self, path, all=False):
        """Finds the real path to a static file, given a static path.

        The path must start with "ext/<extension_id>/". The files within will
        map to files within the extension's "static" directory.
        """
        parts = path.split('/', 2)

        if len(parts) < 3 or parts[0] != 'ext':
            return []

        extension_id, path = parts[1:]

        for extension_manager in get_extension_managers():
            extension = extension_manager.get_enabled_extension(extension_id)

            if extension:
                match = self._find_in_extension(extension, path)

                if match:
                    # The static file support allows for the same name
                    # across many locations, but as we involve extension IDs,
                    # we know we'll only have one.
                    if all:
                        return [match]
                    else:
                        return match

                break

        return []
def _get_extension_bundles(extension_manager_key, context, bundle_attr,
                           renderer):
    """Returns media bundles that can be rendered on the current page.

    This will look through all enabled extensions and find any with static
    media bundles that should be included on the current page, as indicated
    by the context.

    All bundles marked "default" will be included, as will any with an
    ``apply_to`` field containing a URL name matching the current page.
    """
    request = context['request']

    if not getattr(request, 'resolver_match', None):
        return

    requested_url_name = request.resolver_match.url_name

    for manager in get_extension_managers():
        if manager.key != extension_manager_key:
            continue

        for extension in manager.get_enabled_extensions():
            bundles = getattr(extension, bundle_attr, {})

            for bundle_name, bundle in six.iteritems(bundles):
                if (bundle_name == 'default' or
                    requested_url_name in bundle.get('apply_to', [])):
                    yield renderer(context, extension, bundle_name)

        break
Ejemplo n.º 4
0
def _get_extension_bundles(extension_manager_key, context, bundle_attr,
                           renderer):
    """Returns media bundles that can be rendered on the current page.

    This will look through all enabled extensions and find any with static
    media bundles that should be included on the current page, as indicated
    by the context.

    All bundles marked "default" will be included, as will any with an
    ``apply_to`` field containing a URL name matching the current page.
    """
    request = context['request']

    if not getattr(request, 'resolver_match', None):
        return

    requested_url_name = request.resolver_match.url_name

    for manager in get_extension_managers():
        if manager.key != extension_manager_key:
            continue

        for extension in manager.get_enabled_extensions():
            bundles = getattr(extension, bundle_attr, {})

            for bundle_name, bundle in six.iteritems(bundles):
                if (bundle_name == 'default'
                        or requested_url_name in bundle.get('apply_to', [])):
                    yield renderer(context, extension, bundle_name)

        break
Ejemplo n.º 5
0
def init_js_extensions(context, extension_manager_key):
    """Initializes all JavaScript extensions.

    Each extension's required JavaScript files will be loaded in the page,
    and their JavaScript-side Extension subclasses will be instantiated.
    """
    url_name = context['request'].resolver_match.url_name

    for manager in get_extension_managers():
        if manager.key == extension_manager_key:
            js_extensions = []

            for extension in manager.get_enabled_extensions():
                for js_extension_cls in extension.js_extensions:
                    js_extension = js_extension_cls(extension)

                    if js_extension.applies_to(url_name):
                        js_extensions.append(js_extension)

            return {
                'url_name': url_name,
                'js_extensions': js_extensions,
            }

    return {}
Ejemplo n.º 6
0
    def find(self, path, all=False):
        """Finds the real path to a static file, given a static path.

        The path must start with "ext/<extension_id>/". The files within will
        map to files within the extension's "static" directory.
        """
        parts = path.split('/', 2)

        if len(parts) < 3 or parts[0] != 'ext':
            return []

        extension_id, path = parts[1:]

        for extension_manager in get_extension_managers():
            extension = extension_manager.get_enabled_extension(extension_id)

            if extension:
                match = self._find_in_extension(extension, path)

                if match:
                    # The static file support allows for the same name
                    # across many locations, but as we involve extension IDs,
                    # we know we'll only have one.
                    if all:
                        return [match]
                    else:
                        return match

                break

        return []
Ejemplo n.º 7
0
    def _check_expired(self):
        """Checks each ExtensionManager for expired extension state.

        When the list of extensions on an ExtensionManager changes, or when
        the configuration of an extension changes, any other threads/processes
        holding onto extensions and configuration will go stale. This function
        will check each of those to see if they need to re-load their
        state.

        This is meant to be called before every HTTP request.
        """
        for extension_manager in get_extension_managers():
            # We're going to check the expiration, and then only lock if it's
            # expired. Following that, we'll check again.
            #
            # We do this in order to prevent locking unnecessarily, which could
            # impact performance or cause a problem if a thread is stuck.
            #
            # We're checking the expiration twice to prevent every blocked
            # thread from making its own attempt to reload the extensions once
            # the first thread holding the lock finishes the reload.
            if extension_manager.is_expired():
                with self._lock:
                    # Check again, since another thread may have already
                    # reloaded.
                    if extension_manager.is_expired():
                        extension_manager.load(full_reload=True)
Ejemplo n.º 8
0
def init_js_extensions(context, extension_manager_key):
    """Initializes all JavaScript extensions.

    Each extension's required JavaScript files will be loaded in the page,
    and their JavaScript-side Extension subclasses will be instantiated.
    """
    url_name = context['request'].resolver_match.url_name

    for manager in get_extension_managers():
        if manager.key == extension_manager_key:
            js_extensions = []

            for extension in manager.get_enabled_extensions():
                for js_extension_cls in extension.js_extensions:
                    js_extension = js_extension_cls(extension)

                    if js_extension.applies_to(url_name):
                        js_extensions.append(js_extension)

            return {
                'url_name': url_name,
                'js_extensions': js_extensions,
            }

    return {}
Ejemplo n.º 9
0
def _get_extension_bundles(extension_manager_key, context, bundle_attr,
                           default_bundles, renderer):
    """Yield media bundles that can be rendered on the current page.

    This will look through all enabled extensions and find any with static
    media bundles that should be included on the current page, as indicated
    by the context.

    All bundles marked "default" will be included, as will any with an
    ``apply_to`` field containing a URL name matching the current page.

    If a bundle has an ``include_bundles`` key, the referenced bundles will
    also be outputted. Note that this does not check for duplicates, and is
    not recursive.

    Args:
        extension_manager_key (unicode):
            The key for the extension manager for these bundles.

        context (django.template.Context):
            The template context.

        bundle_attr (unicode):
            The attribute name for the bundle on the extension class.

        default_bundles (unicode):
            A string containing a comma-separated list of bundles to always
            include.

        renderer (callable):
            The renderer function to call for each applicable bundle.

    Yields:
        tuple of (unicode or django.utils.safetext.SafeString):
        The HTML used to include the bundled content.
    """
    request = context['request']
    if not getattr(request, 'resolver_match', None):
        return

    requested_url_name = request.resolver_match.url_name
    default_bundles = set(default_bundles.split(','))

    for manager in get_extension_managers():
        if manager.key != extension_manager_key:
            continue

        for extension in manager.get_enabled_extensions():
            bundles = getattr(extension, bundle_attr, {})

            for bundle_name, bundle in six.iteritems(bundles):
                if (bundle_name in default_bundles
                        or requested_url_name in bundle.get('apply_to', [])):
                    for include_bundle in bundle.get('include_bundles', []):
                        yield renderer(context, extension, include_bundle)

                    yield (renderer(context, extension, bundle_name), )

        break
Ejemplo n.º 10
0
def _get_extension_bundles(extension_manager_key, context, bundle_attr,
                           default_bundles, renderer):
    """Yield media bundles that can be rendered on the current page.

    This will look through all enabled extensions and find any with static
    media bundles that should be included on the current page, as indicated
    by the context.

    All bundles marked "default" will be included, as will any with an
    ``apply_to`` field containing a URL name matching the current page.

    If a bundle has an ``include_bundles`` key, the referenced bundles will
    also be outputted. Note that this does not check for duplicates, and is
    not recursive.

    Args:
        extension_manager_key (unicode):
            The key for the extension manager for these bundles.

        context (django.template.Context):
            The template context.

        bundle_attr (unicode):
            The attribute name for the bundle on the extension class.

        default_bundles (unicode):
            A string containing a comma-separated list of bundles to always
            include.

        renderer (callable):
            The renderer function to call for each applicable bundle.

    Yields:
        django.utils.safetext.SafeString:
        The HTML used to include the bundled content.
    """
    request = context['request']
    if not getattr(request, 'resolver_match', None):
        return

    requested_url_name = request.resolver_match.url_name
    default_bundles = set(default_bundles.split(','))

    for manager in get_extension_managers():
        if manager.key != extension_manager_key:
            continue

        for extension in manager.get_enabled_extensions():
            bundles = getattr(extension, bundle_attr, {})

            for bundle_name, bundle in six.iteritems(bundles):
                if (bundle_name in default_bundles or
                    requested_url_name in bundle.get('apply_to', [])):
                    for include_bundle in bundle.get('include_bundles', []):
                        yield renderer(context, extension, include_bundle)

                    yield renderer(context, extension, bundle_name)

        break
Ejemplo n.º 11
0
    def list(self, ignore_patterns):
        """Lists static files within all enabled extensions."""
        for extension_manager in get_extension_managers():
            for extension in extension_manager.get_enabled_extensions():
                storage = self._get_storage(extension)

                if storage and storage.exists(''):
                    for path in get_files(storage, ignore_patterns):
                        yield path, storage
Ejemplo n.º 12
0
    def list(self, ignore_patterns):
        """Lists static files within all enabled extensions."""
        for extension_manager in get_extension_managers():
            for extension in extension_manager.get_enabled_extensions():
                storage = self._get_storage(extension)

                if storage and storage.exists(''):
                    for path in get_files(storage, ignore_patterns):
                        yield path, storage
Ejemplo n.º 13
0
def load_extensions_js(context, extension_manager_key):
    """Loads all default JavaScript bundles from all enabled extensions."""
    for manager in get_extension_managers():
        if manager.key == extension_manager_key:
            return ''.join([
                _render_js_bundle(context, extension, 'default')
                for extension in manager.get_enabled_extensions()
                if 'default' in extension.js_bundles
            ])

    return ''
Ejemplo n.º 14
0
def load_extensions_js(context, extension_manager_key):
    """Loads all default JavaScript bundles from all enabled extensions."""
    for manager in get_extension_managers():
        if manager.key == extension_manager_key:
            return ''.join([
                _render_js_bundle(context, extension, 'default')
                for extension in manager.get_enabled_extensions()
                if 'default' in extension.js_bundles
            ])

    return ''
Ejemplo n.º 15
0
    def get_extension_manager(self):
        """Return the extension manager used for the tests.

        Subclasses may want to override this to pick a specific extension
        manager, if the project uses more than one. The default behavior is
        to return the first registered extension manager.

        Returns:
            djblets.extensions.manager.ExtensionManager:
            The extension manager used for tests.
        """
        return get_extension_managers()[0]
Ejemplo n.º 16
0
    def _check_expired(self):
        """Checks each ExtensionManager for expired extension state.

        When the list of extensions on an ExtensionManager changes, or when
        the configuration of an extension changes, any other threads/processes
        holding onto extensions and configuration will go stale. This function
        will check each of those to see if they need to re-load their
        state.

        This is meant to be called before every HTTP request.
        """
        for extension_manager in get_extension_managers():
            if extension_manager.is_expired():
                extension_manager.load(full_reload=True)
Ejemplo n.º 17
0
    def _check_expired(self):
        """Checks each ExtensionManager for expired extension state.

        When the list of extensions on an ExtensionManager changes, or when
        the configuration of an extension changes, any other threads/processes
        holding onto extensions and configuration will go stale. This function
        will check each of those to see if they need to re-load their
        state.

        This is meant to be called before every HTTP request.
        """
        for extension_manager in get_extension_managers():
            if extension_manager.is_expired():
                extension_manager.load(full_reload=True)
Ejemplo n.º 18
0
def load_template_source(template_name, template_dirs=None):
    """Loads templates from enabled extensions."""
    if manager:
        resource = "templates/" + template_name

        for extmgr in get_extension_managers():
            for ext in extmgr.get_enabled_extensions():
                package = ext.info.app_name

                try:
                    return (manager.resource_string(package, resource),
                            'extension:%s:%s ' % (package, resource))
                except Exception:
                    pass

    raise TemplateDoesNotExist(template_name)
Ejemplo n.º 19
0
def init_js_extensions(context, extension_manager_key):
    """Initializes all JavaScript extensions.

    Each extension's required JavaScript files will be loaded in the page,
    and their JavaScript-side Extension subclasses will be instantiated.
    """
    for manager in get_extension_managers():
        if manager.key == extension_manager_key:
            return {
                'extensions': [
                    extension
                    for extension in manager.get_enabled_extensions()
                    if extension.js_model_class
                ],
            }

    return {}
Ejemplo n.º 20
0
def init_js_extensions(context, extension_manager_key):
    """Initializes all JavaScript extensions.

    Each extension's required JavaScript files will be loaded in the page,
    and their JavaScript-side Extension subclasses will be instantiated.
    """
    for manager in get_extension_managers():
        if manager.key == extension_manager_key:
            return {
                'extensions': [
                    extension
                    for extension in manager.get_enabled_extensions()
                    if extension.js_model_class
                ],
            }

    return {}
Ejemplo n.º 21
0
def init_js_extensions(context, extension_manager_key):
    """Initializes all JavaScript extensions.

    Each extension's required JavaScript files will be loaded in the page,
    and their JavaScript-side Extension subclasses will be instantiated.
    """
    request = context['request']
    url_name = request.resolver_match.url_name

    for manager in get_extension_managers():
        if manager.key == extension_manager_key:
            js_extensions = []

            for extension in manager.get_enabled_extensions():
                for js_extension_cls in extension.js_extensions:
                    js_extension = js_extension_cls(extension)

                    if js_extension.applies_to(url_name):
                        js_extensions.append(js_extension)

            js_extension_items = []

            for js_extension in js_extensions:
                arg_spec = inspect.getargspec(js_extension.get_model_data)

                if arg_spec.keywords is None:
                    warnings.warn(
                        '%s.get_model_data will need to take keyword '
                        'arguments. The old function signature is deprecated.'
                        % js_extension_cls.__name__)

                    model_data = js_extension.get_model_data()
                else:
                    model_data = js_extension.get_model_data(request=request)

                js_extension_items.append({
                    'js_extension': js_extension,
                    'model_data': model_data,
                })

            return {
                'url_name': url_name,
                'js_extension_items': js_extension_items,
            }

    return {}
Ejemplo n.º 22
0
def init_js_extensions(context, extension_manager_key):
    """Initializes all JavaScript extensions.

    Each extension's required JavaScript files will be loaded in the page,
    and their JavaScript-side Extension subclasses will be instantiated.
    """
    request = context['request']
    url_name = request.resolver_match.url_name

    for manager in get_extension_managers():
        if manager.key == extension_manager_key:
            js_extensions = []

            for extension in manager.get_enabled_extensions():
                for js_extension_cls in extension.js_extensions:
                    js_extension = js_extension_cls(extension)

                    if js_extension.applies_to(url_name):
                        js_extensions.append(js_extension)

            js_extension_items = []

            for js_extension in js_extensions:
                arg_spec = inspect.getargspec(js_extension.get_model_data)

                if arg_spec.keywords is None:
                    warnings.warn(
                        '%s.get_model_data will need to take keyword '
                        'arguments. The old function signature is deprecated.'
                        % js_extension_cls.__name__)

                    model_data = js_extension.get_model_data()
                else:
                    model_data = js_extension.get_model_data(request=request)

                js_extension_items.append({
                    'js_extension': js_extension,
                    'model_data': model_data,
                })

            return {
                'url_name': url_name,
                'js_extension_items': js_extension_items,
            }

    return {}
Ejemplo n.º 23
0
    def _middleware_funcs(self, func_name, reverse=False):
        """Generator yielding the given middleware function for all extensions.

        If an extension's middleware does not implement 'func_name', it is
        skipped.
        """
        middleware = []

        for mgr in get_extension_managers():
            middleware.extend(mgr.middleware)

        if reverse:
            middleware.reverse()

        for m in middleware:
            f = getattr(m, func_name, None)

            if f:
                yield f
Ejemplo n.º 24
0
    def _middleware_funcs(self, func_name, reverse=False):
        """Generator yielding the given middleware function for all extensions.

        If an extension's middleware does not implement 'func_name', it is
        skipped.
        """
        middleware = []

        for mgr in get_extension_managers():
            middleware.extend(mgr.middleware)

        if reverse:
            middleware.reverse()

        for m in middleware:
            f = getattr(m, func_name, None)

            if f:
                yield f
Ejemplo n.º 25
0
    def handle(self, *args, **options):
        managers = get_extension_managers()

        force_install = options['force']

        if options['extension_id']:
            extensions = [
                self._find_extension(options['extension_id'], managers)
            ]
        else:
            extensions = chain(
                (extension, manager) for manager in managers
                for extension in manager.get_enabled_extensions())

        for extension, manager in extensions:
            try:
                manager.install_extension_media(extension, force_install)
            except InstallExtensionError as e:
                raise CommandError('Could not install extension media: %s' % e)
Ejemplo n.º 26
0
    def handle(self, *args, **options):
        managers = get_extension_managers()

        force_install = options['force']

        if options['extension_id']:
            extensions = [self._find_extension(options['extension_id'],
                                               managers)]
        else:
            extensions = chain(
                (extension, manager)
                for manager in managers
                for extension in manager.get_enabled_extensions()
            )

        for extension, manager in extensions:
            try:
                manager.install_extension_media(extension, force_install)
            except InstallExtensionError as e:
                raise CommandError('Could not install extension media: %s'
                                   % e)
Ejemplo n.º 27
0
    def get_extension_class(self):
        """Retrieves the python object for the extensions class."""
        if not hasattr(self, '_extension_class'):
            cls = None

            try:
                # Import the function here to avoid a mutual
                # dependency.
                from djblets.extensions.manager import get_extension_managers

                for manager in get_extension_managers():
                    try:
                        cls = manager.get_installed_extension(self.class_name)
                        break
                    except InvalidExtensionError:
                        continue
            except:
                return None

            self._extension_class = cls

        return self._extension_class
Ejemplo n.º 28
0
    def __init__(self, *args, **kwargs):
        """Initialize the scope dictionary.

        This adds signal handlers to ensure the dictionary stays up to date
        when extensions are initialized and uninitialized.

        Args:
            *args (tuple):
                Positional arguments to pass to the parent class.

            **kwargs (dict):
                Keyword arguments to pass to the the parent class.
        """
        super(ExtensionEnabledWebAPIScopeDictionary, self).__init__(*args,
                                                                    **kwargs)

        extension_enabled.connect(self._on_extension_enabled)
        extension_disabled.connect(self._on_extension_disabled)

        for manager in get_extension_managers():
            for extension in manager.get_enabled_extensions():
                self._on_extension_enabled(extension=extension)
Ejemplo n.º 29
0
    def __init__(self, *args, **kwargs):
        """Initialize the scope dictionary.

        This adds signal handlers to ensure the dictionary stays up to date
        when extensions are initialized and uninitialized.

        Args:
            *args (tuple):
                Positional arguments to pass to the parent class.

            **kwargs (dict):
                Keyword arguments to pass to the the parent class.
        """
        super(ExtensionEnabledWebAPIScopeDictionary,
              self).__init__(*args, **kwargs)

        extension_enabled.connect(self._on_extension_enabled)
        extension_disabled.connect(self._on_extension_disabled)

        for manager in get_extension_managers():
            for extension in manager.get_enabled_extensions():
                self._on_extension_enabled(extension=extension)
Ejemplo n.º 30
0
    def get_extension_class(self):
        """Retrieves the python object for the extensions class."""
        if not hasattr(self, '_extension_class'):
            cls = None

            try:
                # Import the function here to avoid a mutual
                # dependency.
                from djblets.extensions.manager import get_extension_managers

                for manager in get_extension_managers():
                    try:
                        cls = manager.get_installed_extension(self.class_name)
                        break
                    except InvalidExtensionError:
                        continue
            except:
                return None

            self._extension_class = cls

        return self._extension_class
Ejemplo n.º 31
0
 def test_added_to_extension_managers(self):
     """Testing ExtensionManager registration"""
     self.manager = TestExtensionManager([], '')
     self.assertIn(self.manager, get_extension_managers())
Ejemplo n.º 32
0
 def test_added_to_extension_managers(self):
     """Testing ExtensionManager registration"""
     self.assertIn(self.manager, get_extension_managers())