json.py 5.73 KB
Newer Older
1
from jinja2 import Environment, BaseLoader, Template
2
3
from textwrap import dedent

4
5
from . import directives

6
7
8
9
# set locale in order to have french date for output string
import locale
locale.setlocale(locale.LC_TIME, "fr_FR.UTF-8")

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
def jinja2_splitlines(s):
    """ Split string by lines """
    return s.splitlines()

def jinja2_rst_options(options):
    """ Return lines of rst representation of given options """
    for key, value in options.items():
        yield f":{key}: {list_head(value)}"
        for line in list_tail(value):
            yield f"    {line}"

def list_head(l):
    """ Return first element of a list, itself if it is not a list """
    if isinstance(l, list):
        return l[0] if len(l) > 0 else None
    else:
        return l

def list_tail(l):
    """ Return elements other than the first of a list, empty list if it is not a list """
    if isinstance(l, list):
        return l[1:]
    else:
        return []

def filter_options(directive, options):
    """ Filters keys of given dict depending on option_sep of the directive """
    return dict(((key, value) for key, value in options.items() if key.lower() in directive.option_spec))

39

40
41
42
43
44
def build_meso(meso):
    """ Filters and formats attributes of a meso depending on the Meso directive """
    return {
        'name': meso['name'],
        'options': filter_options(directives.Meso, meso),
45
        'cluster_list': list(map(build_cluster, meso.get('clusterList', []))),
46
        'storage_list': list(map(build_storage, meso.get('storageList', []))),
47
48
49
    }

def build_cluster(cluster):
50
    """ Filters and formats attributes of a cluster depending on the Cluster directive """
51
52
53
    return {
        'name': cluster.get('name', ''),
        'options': filter_options(directives.Cluster, cluster),
54
55
        'storage_list': list(map(build_storage, cluster.get('storageType', []))),
        'node_type_list': list(map(build_node_type, cluster.get('nodeType', []))),
56
57
    }

58
59
60
61
62
63
64
65
66
67
68
69
70
def build_storage(storage):
    """ Filters and formats attributes of a storage depending on the Storage directive """
    return {
        'name': storage.get('name', ''),
        'options': filter_options(directives.Storage, storage),
    }

def build_node_type(node_type):
    """ Filters and formats attributes of a node type depending on the NodeType directive """
    return {
        'name': node_type.get('name', ''),
        'options': filter_options(directives.NodeType, node_type),
    }
71

72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
def json_mesolist_to_rst(url):
    """
    Parses a json file containing the list of mesocenters and returns an rst like describing them.

    Parameters
    ----------
    url: url
        url of the json file

    Returns
    -------
    string: the list of the mesocenters in a rst format

    """
    from datetime import datetime, date, time
    import maya
    import collections
    from urllib.request import urlopen
    import json

    response = urlopen(url).read()
    data = json.loads(response.decode('utf-8'))

95
96
97
    meso_list = {}
    for meso in data['mesocentreList']:
        region = meso['location']
98
        meso_list.setdefault(region, []).append(build_meso(meso))
99
  
100
101
    result = _json_mesolist_rst_template.render(meso_by_region=meso_list)
    return result
102
103


104
# Pre-loading Jinja2 template as static variable
105
106
107
108
109
110
111
112
_json_mesolist_rst_env = Environment(loader=BaseLoader)
_json_mesolist_rst_env.filters.update({
    'splitlines': jinja2_splitlines,
    'rst_options': jinja2_rst_options,
})
_json_mesolist_rst_template = _json_mesolist_rst_env.from_string(dedent("""
            {% for region, mesolist in meso_by_region.items() -%}
            .. region:: {{ region }}
113

114
115
116
117
                {% for meso in mesolist %}
                .. meso:: {{ meso['name'] }}
                    {%- for l in meso["options"] | rst_options %}
                    {{ l }}
118
                    {%- endfor %}
119

120
                    {% if(meso['cluster_list']) %}
121
122
123
124
125
126
127
128
                    .. cluster_list::

                        {% for cluster in meso["cluster_list"] %}
                        .. cluster:: {{ cluster['name'] }}
                            {%- for l in cluster["options"] | rst_options %}
                            {{ l }}
                            {%- endfor %}

129
                            {% if(cluster['node_type_list']) %}
130
131
132
133
134
135
136
137
138
                            .. node_type_list::

                                {% for node_type in cluster["node_type_list"] %}
                                .. node_type:: {{ node_type['name'] }}
                                    {%- for l in node_type["options"] | rst_options %}
                                    {{ l }}
                                    {%- endfor %}

                                {% endfor %}
139
                            {% endif %}
140

141
                            {% if(cluster['storage_list']) %}
Fabrice Roy's avatar
Fabrice Roy committed
142
                            .. cluster_storage_list::
143
144

                                {% for storage in cluster["storage_list"] %}
Fabrice Roy's avatar
Fabrice Roy committed
145
                                .. cluster_storage:: {{ storage['name'] }}
146
147
148
149
150
                                    {%- for l in storage["options"] | rst_options %}
                                    {{ l }}
                                    {%- endfor %}

                                {% endfor %}
151
                            {% endif %}
152
153

                        {% endfor %}
154
                    {% endif %}
155

156
                    {% if(meso['storage_list']) %}
157
158
159
160
161
162
163
                    .. storage_list::

                        {% for storage in meso["storage_list"] %}
                        .. storage:: {{ storage['name'] }}
                            {%- for l in storage["options"] | rst_options %}
                            {{ l }}
                            {%- endfor %}
164

165
                        {% endfor %}
166
                    {% endif %}
167

168
169
170
171
                {%- endfor %}

            {% endfor %}
"""))