summaryrefslogtreecommitdiff
path: root/opendc/util/parameter_checker.py
blob: c60d26d37850c1bc8982ec71ca824858103858fb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
from opendc.util import database, exceptions


def _missing_parameter(params_required, params_actual, parent=''):
    """Recursively search for the first missing parameter."""

    for param_name in params_required:

        if param_name not in params_actual:
            return '{}.{}'.format(parent, param_name)

        param_required = params_required.get(param_name)
        param_actual = params_actual.get(param_name)

        if isinstance(param_required, dict):

            param_missing = _missing_parameter(
                param_required,
                param_actual,
                param_name
            )

            if param_missing is not None:
                return '{}.{}'.format(parent, param_missing)

    return None


def _incorrect_parameter(params_required, params_actual, parent=''):
    """Recursively make sure each parameter is of the correct type."""

    for param_name in params_required:

        param_required = params_required.get(param_name)
        param_actual = params_actual.get(param_name)

        if isinstance(param_required, dict):

            param_incorrect = _incorrect_parameter(
                param_required,
                param_actual,
                param_name
            )

            if param_incorrect is not None:
                return '{}.{}'.format(parent, param_incorrect)

        else:

            if param_required == 'datetime':
                try:
                    database.string_to_datetime(param_actual)
                except:
                    return '{}.{}'.format(parent, param_name)

            if param_required == 'int' and not isinstance(param_actual, int):
                return '{}.{}'.format(parent, param_name)

            if param_required == 'string' and not isinstance(param_actual, basestring):
                return '{}.{}'.format(parent, param_name)

            if param_required.startswith('list') and not isinstance(param_actual, list):
                return '{}.{}'.format(parent, param_name)


def _format_parameter(parameter):
    """Format the output of a parameter check."""

    parts = parameter.split('.')
    inner = ['["{}"]'.format(x) for x in parts[2:]]
    return parts[1] + ''.join(inner)


def check(request, **kwargs):
    """Return True if all required parameters are there."""

    for location, params_required in kwargs.iteritems():

        params_actual = getattr(request, 'params_{}'.format(location))

        missing_parameter = _missing_parameter(params_required, params_actual)
        if missing_parameter is not None:
            raise exceptions.MissingParameterError(
                _format_parameter(missing_parameter),
                location
            )

        incorrect_parameter = _incorrect_parameter(params_required, params_actual)
        if incorrect_parameter is not None:
            raise exceptions.IncorrectParameterError(
                _format_parameter(incorrect_parameter),
                location
            )