1# Copyright 2013 The Distro Tracker Developers
2# See the COPYRIGHT file at the top-level directory of this distribution and
3# at https://deb.li/DTAuthors
4#
5# This file is part of Distro Tracker. It is subject to the license terms
6# in the LICENSE file found in the top-level directory of this
7# distribution and at https://deb.li/DTLicense. No part of Distro Tracker,
8# including this file, may be copied, modified, propagated, or distributed
9# except according to the terms contained in the LICENSE file.
11"""
12A module which defines functions to allow other parts of Distro Tracker to hook
13into the vendor-specific functionality.
14"""
15from django.conf import settings
18class InvalidPluginException(Exception):
19 pass
22class PluginProcessingError(RuntimeError):
23 pass
26def get_callable(name):
27 """
28 Returns a callable object from the vendor-provided module based on the
29 string name given as the parameter.
30 If no callable object with the given name is found in the vendor module
31 an exception is raised.
33 :param name: The name of the callable which should be returned
34 :type name: string
35 """
36 import importlib
37 if (not hasattr(settings, 'DISTRO_TRACKER_VENDOR_RULES') or
38 not settings.DISTRO_TRACKER_VENDOR_RULES):
39 raise InvalidPluginException("No vendor specific module set.")
41 vendor_module = \
42 importlib.import_module(settings.DISTRO_TRACKER_VENDOR_RULES)
44 function = getattr(vendor_module, name, None)
45 if not function: 45 ↛ 46line 45 didn't jump to line 46, because the condition on line 45 was never true
46 raise InvalidPluginException("{name} not found in {module}".format(
47 name=name, module=settings.DISTRO_TRACKER_VENDOR_RULES))
48 if not callable(function): 48 ↛ 49line 48 didn't jump to line 49, because the condition on line 48 was never true
49 raise InvalidPluginException("{name} is not callable.".format(
50 name=name))
52 return function
55def call(name, *args, **kwargs):
56 """
57 Function which executes the vendor-specific function with the given name by
58 passing it the given arguments.
60 It returns a tuple ``(result, implemented)`` where the values represent:
62 - result -- the corresponding function's return value. If the function was
63 not found, ``None`` is given.
64 - implemented -- a Boolean indicating whether the package implements the
65 given function. This way clients can differentiate between functions with
66 no return value and non-implemented functions.
68 :param name: The name of the vendor-specific function that should be
69 called.
70 """
71 try:
72 func = get_callable(name)
73 except (ImportError, InvalidPluginException):
74 return None, False
76 return func(*args, **kwargs), True