# Copyright 2013 The Distro Tracker Developers
# See the COPYRIGHT file at the top-level directory of this distribution and
# at https://deb.li/DTAuthors
#
# This file is part of Distro Tracker. It is subject to the license terms
# in the LICENSE file found in the top-level directory of this
# distribution and at https://deb.li/DTLicense. No part of Distro Tracker,
# including this file, may be copied, modified, propagated, or distributed
# except according to the terms contained in the LICENSE file.
"""
A module which defines functions to allow other parts of Distro Tracker to hook
into the vendor-specific functionality.
"""
from django.conf import settings
class InvalidPluginException(Exception):
pass
class PluginProcessingError(RuntimeError):
pass
def get_callable(name):
"""
Returns a callable object from the vendor-provided module based on the
string name given as the parameter.
If no callable object with the given name is found in the vendor module
an exception is raised.
:param name: The name of the callable which should be returned
:type name: string
"""
import importlib
if (not hasattr(settings, 'DISTRO_TRACKER_VENDOR_RULES') or
not settings.DISTRO_TRACKER_VENDOR_RULES):
raise InvalidPluginException("No vendor specific module set.")
vendor_module = \
importlib.import_module(settings.DISTRO_TRACKER_VENDOR_RULES)
function = getattr(vendor_module, name, None)
if not function:
raise InvalidPluginException("{name} not found in {module}".format(
name=name, module=settings.DISTRO_TRACKER_VENDOR_RULES))
if not callable(function):
raise InvalidPluginException("{name} is not callable.".format(
name=name))
return function
[docs]def call(name, *args, **kwargs):
"""
Function which executes the vendor-specific function with the given name by
passing it the given arguments.
It returns a tuple ``(result, implemented)`` where the values represent:
- result -- the corresponding function's return value. If the function was
not found, ``None`` is given.
- implemented -- a Boolean indicating whether the package implements the
given function. This way clients can differentiate between functions with
no return value and non-implemented functions.
:param name: The name of the vendor-specific function that should be
called.
"""
try:
func = get_callable(name)
except (ImportError, InvalidPluginException):
return None, False
return func(*args, **kwargs), True