Blame view

src/core/pyros_django/obs_config/views.py 18.2 KB
1ba49504   Alexis Koralewski   fixing CSS and JS...
1
from collections import OrderedDict
cc4e5a62   Alexis Koralewski   Add ConfigPyrosv2...
2
3
from django import conf
from django.shortcuts import render
a2dbbde1   Alexis Koralewski   Adding new config...
4
from .obsconfig_class import OBSConfig
cc4e5a62   Alexis Koralewski   Add ConfigPyrosv2...
5
6
7
from django.conf import settings
from src.core.pyros_django.dashboard.decorator import level_required
from django.contrib.auth.decorators import login_required
d0501f5e   Alexis Koralewski   use environment v...
8
9
from django.http import HttpResponse
from datetime import datetime
c27a895d   Alexis Koralewski   add display of ra...
10
from django.views.decorators.csrf import csrf_exempt
1ba49504   Alexis Koralewski   fixing CSS and JS...
11
12
13
14
15
import re
import yaml
import tempfile
import json
import os
cc4e5a62   Alexis Koralewski   Add ConfigPyrosv2...
16

1ba49504   Alexis Koralewski   fixing CSS and JS...
17
18
19
20

def get_nested_dictionaries_as_list(dic, result=[]):
    for key, value in dic.items():
        print(value, type(value))
6686d675   Alexis Koralewski   new version of ob...
21
22
23
        print(result)
        if isinstance(value, dict):
            print("recursive call")
1ba49504   Alexis Koralewski   fixing CSS and JS...
24
25
26
            get_nested_dictionaries_as_list(value, result)
        elif isinstance(value, list) and key == "CAPABILITIES":
            print("VALUE OF LIST =======          ", value)
6686d675   Alexis Koralewski   new version of ob...
27
            for element in value:
1ba49504   Alexis Koralewski   fixing CSS and JS...
28
29
30
31
                # print(element)
                if isinstance(element, dict):
                    get_nested_dictionaries_as_list(element, result)

6686d675   Alexis Koralewski   new version of ob...
32
        else:
1ba49504   Alexis Koralewski   fixing CSS and JS...
33
            result.append((key, value))
6686d675   Alexis Koralewski   new version of ob...
34
    return result
cc4e5a62   Alexis Koralewski   Add ConfigPyrosv2...
35

1ba49504   Alexis Koralewski   fixing CSS and JS...
36

cc4e5a62   Alexis Koralewski   Add ConfigPyrosv2...
37
@login_required
1ba49504   Alexis Koralewski   fixing CSS and JS...
38
@level_required("Admin", "Observer", "Management", "Operator", "Unit-PI")
cc4e5a62   Alexis Koralewski   Add ConfigPyrosv2...
39
def obs_global_config(request):
1ba49504   Alexis Koralewski   fixing CSS and JS...
40
41
    config = OBSConfig(
        os.environ["PATH_TO_OBSCONF_FILE"], os.environ["unit_name"])
cc4e5a62   Alexis Koralewski   Add ConfigPyrosv2...
42
    units_names = list(config.get_units().keys())
d0501f5e   Alexis Koralewski   use environment v...
43
    pickle_file_mtime = os.path.getmtime(config.CONFIG_PATH+config.pickle_file)
1ba49504   Alexis Koralewski   fixing CSS and JS...
44
45
46
47
48
49
50
51
52
    pickle_datetime = datetime.utcfromtimestamp(
        pickle_file_mtime).strftime("%Y/%m/%d %H:%M:%S")
    CAN_EDIT_CONFIG = request.session.get("role") in (
        "Admin", "Operator", "Unit-PI", "Unit-board")
    CAN_VIEW_HARDWARE_CONFIG = request.session.get("role") in (
        "Admin", "Operator", "Unit-PI", "Unit-board")
    CAN_VIEW_ASTRONOMER_CONFIG = request.session.get("role") in (
        "Admin", "Operator", "Unit-PI", "Observer", "Management board manager", "Unit-board")
    CAN_VIEW_AGENTS_CONFIG = request.session.get("role") == "Admin"
b95a693f   Alexis Koralewski   restructuration d...
53
    return render(request, "obs_config/global_obs_configuration.html", {
1ba49504   Alexis Koralewski   fixing CSS and JS...
54
        "units_names": units_names,
b755ff73   Alexis Koralewski   adding variables ...
55
        "obs_name": config.get_obs_name(),
1ba49504   Alexis Koralewski   fixing CSS and JS...
56
57
        "last_modification_time": pickle_datetime,
        "CAN_EDIT_CONFIG": CAN_EDIT_CONFIG,
b755ff73   Alexis Koralewski   adding variables ...
58
        "CAN_VIEW_HARDWARE_CONFIG": CAN_VIEW_HARDWARE_CONFIG,
1ba49504   Alexis Koralewski   fixing CSS and JS...
59
60
        "CAN_VIEW_ASTRONOMER_CONFIG": CAN_VIEW_ASTRONOMER_CONFIG,
        "CAN_VIEW_AGENTS_CONFIG": CAN_VIEW_AGENTS_CONFIG
b755ff73   Alexis Koralewski   adding variables ...
61
    })
cc4e5a62   Alexis Koralewski   Add ConfigPyrosv2...
62
63


cc4e5a62   Alexis Koralewski   Add ConfigPyrosv2...
64
@login_required
1ba49504   Alexis Koralewski   fixing CSS and JS...
65
@level_required("Admin", "Unit-PI", "Operator")
cc4e5a62   Alexis Koralewski   Add ConfigPyrosv2...
66
def obs_hardware_config(request):
1ba49504   Alexis Koralewski   fixing CSS and JS...
67
68
    config = OBSConfig(
        os.environ["PATH_TO_OBSCONF_FILE"], os.environ["unit_name"])
cc4e5a62   Alexis Koralewski   Add ConfigPyrosv2...
69
70
71
72
73
74
75
76
77
78
79
80
    devices = config.get_devices()
    active_devices = config.get_active_devices()
    computers = config.get_computers()
    active_computers = config.get_active_computers()
    # give for a device name (key) the unit name where it is used (value)
    device_to_unit = {}
    # give for a computer name (key) the unit name where it is used (value)
    computer_to_unit = {}
    for device in active_devices:
        device_to_unit[device] = config.get_unit_of_device(device)
    for computer in active_computers:
        computer_to_unit[computer] = config.get_unit_of_computer(computer)
a2f47fb6   Alexis Koralewski   updating display ...
81
    devices_links = config.devices_links
b95a693f   Alexis Koralewski   restructuration d...
82
    return render(request, 'obs_config/obs_hardware_configuration.html', {'devices': devices, "active_devices": active_devices, "computers": computers, "active_computers": active_computers, "device_to_unit": device_to_unit, "computer_to_unit": computer_to_unit, "devices_links": devices_links})
1ba49504   Alexis Koralewski   fixing CSS and JS...
83
84


cc4e5a62   Alexis Koralewski   Add ConfigPyrosv2...
85
@login_required
1ba49504   Alexis Koralewski   fixing CSS and JS...
86
87
88
89
@level_required("Admin", "Unit-PI", "Operator")
def unit_hardware_configuration(request, unit_name):
    config = OBSConfig(
        os.environ["PATH_TO_OBSCONF_FILE"], os.environ["unit_name"])
cc4e5a62   Alexis Koralewski   Add ConfigPyrosv2...
90
    devices = config.get_devices()
1ba49504   Alexis Koralewski   fixing CSS and JS...
91

b95a693f   Alexis Koralewski   restructuration d...
92
    return render(request, 'obs_config/unit_hardware_configuration.html', {'config': config})
1ba49504   Alexis Koralewski   fixing CSS and JS...
93
94


cc4e5a62   Alexis Koralewski   Add ConfigPyrosv2...
95
@login_required
1ba49504   Alexis Koralewski   fixing CSS and JS...
96
97
98
99
@level_required("Admin", "Unit-PI", "Operator")
def computer_details(request, computer_name):
    config = OBSConfig(
        os.environ["PATH_TO_OBSCONF_FILE"], os.environ["unit_name"])
6686d675   Alexis Koralewski   new version of ob...
100
101
    computer_detail = yaml.dump(config.get_computers()[computer_name])
    """
1ba49504   Alexis Koralewski   fixing CSS and JS...
102
103
    computer_detail = { re.sub("^_","",key):value for key,
                               value in config.get_computers()[computer_name].items() }
6686d675   Alexis Koralewski   new version of ob...
104
105

     # We're removing "_" at the beginning of each key :
1ba49504   Alexis Koralewski   fixing CSS and JS...
106
107
108
    power = { re.sub("^_","",key):value for key,
                     value in config.get_computer_power(computer_name).items() }

6686d675   Alexis Koralewski   new version of ob...
109
110
    computer_config = computer_detail["computer_config"]
    # We're removing "_" at the beginning of each key :
1ba49504   Alexis Koralewski   fixing CSS and JS...
111
112
113
    computer_detail["computer_config"] = {
        re.sub("^_","",key):value for key,value in computer_config.items() }
    # Remove power key as we have this information in the same
6686d675   Alexis Koralewski   new version of ob...
114
115
    if power is not None:
        computer_detail["computer_config"].pop("power")
b95a693f   Alexis Koralewski   restructuration d...
116
    return render(request,"obs_config/computer_details.html", {"computer_detail" : computer_detail, "power" : power})
6686d675   Alexis Koralewski   new version of ob...
117
    """
b95a693f   Alexis Koralewski   restructuration d...
118
    return render(request, "obs_config/computer_details.html", {"computer_detail": computer_detail})
cc4e5a62   Alexis Koralewski   Add ConfigPyrosv2...
119

cc4e5a62   Alexis Koralewski   Add ConfigPyrosv2...
120

cc4e5a62   Alexis Koralewski   Add ConfigPyrosv2...
121
@login_required
a61943b5   Alexis Koralewski   Reworking Unit-bo...
122
@level_required("Admin", "Unit-PI",  "Operator", "Observer")
1ba49504   Alexis Koralewski   fixing CSS and JS...
123
124
125
def device_details(request, device_name):
    config = OBSConfig(
        os.environ["PATH_TO_OBSCONF_FILE"], os.environ["unit_name"])
6686d675   Alexis Koralewski   new version of ob...
126
127
    # We're removing "_" at the beginning of each key :
    device = config.get_devices()[device_name]
1ba49504   Alexis Koralewski   fixing CSS and JS...
128
129
    # device_detail  = yaml.dump(device)
    # config_device = open(config.CONFIG_PATH+device["file"],"r").read()
a2f47fb6   Alexis Koralewski   updating display ...
130
    devices_links = config.devices_links
1ba49504   Alexis Koralewski   fixing CSS and JS...
131
132
    file_name_to_device_name = {
        v: k for k, v in config.get_devices_names_and_file().items()}
a2f47fb6   Alexis Koralewski   updating display ...
133
    active_devices = config.get_active_devices()
6686d675   Alexis Koralewski   new version of ob...
134
135
    """
    Alternative solutions:
1ba49504   Alexis Koralewski   fixing CSS and JS...
136
        - test_device -> we're using a recursive function to get all nested dicitonaries but we loose a level of
6686d675   Alexis Koralewski   new version of ob...
137
138
        "precision" (no separations of capabilities for example)
        - device_detail -> we use multiple function to get specific value (not global enougth, if we had another key we have to change the code)
ee2a5e47   Alexis Koralewski   New version of ob...
139
    """
6686d675   Alexis Koralewski   new version of ob...
140

1ba49504   Alexis Koralewski   fixing CSS and JS...
141
142
143
    device_detail = {re.sub("^_", "", key): value for key,
                     value in config.get_devices()[device_name].items()}
    # test_device=  get_nested_dictionaries_as_list(device_detail,[])
6686d675   Alexis Koralewski   new version of ob...
144

6686d675   Alexis Koralewski   new version of ob...
145
146
    if config.get_device_power(device_name) is not None:
        # We're removing "_" at the beginning of each key :
1ba49504   Alexis Koralewski   fixing CSS and JS...
147
148
149
        power = {re.sub("^_", "", key): value for key,
                 value in config.get_device_power(device_name).items()}
    else:
6686d675   Alexis Koralewski   new version of ob...
150
151
152
        power = None
    if config.get_device_connector(device_name) is not None:
        # We're removing "_" at the beginning of each key :
1ba49504   Alexis Koralewski   fixing CSS and JS...
153
154
        connector = {re.sub("^_", "", key): value for key,
                     value in config.get_device_connector(device_name).items()}
6686d675   Alexis Koralewski   new version of ob...
155
156
    else:
        connector = None
1ba49504   Alexis Koralewski   fixing CSS and JS...
157

6686d675   Alexis Koralewski   new version of ob...
158
159
160
161
162
    capabilities = []
    if config.get_device_capabilities(device_name) is not None:
        copy_capabilities = config.get_device_capabilities(device_name)
        for capability in copy_capabilities:
            # We're removing "_" at the beginning of each key :
1ba49504   Alexis Koralewski   fixing CSS and JS...
163
164
165
            capabilities.append(
                {re.sub("^_", "", key): value for key, value in capability.items()})

6686d675   Alexis Koralewski   new version of ob...
166
167
    device_config = device_detail["device_config"]
    # We're removing "_" at the beginning of each key :
1ba49504   Alexis Koralewski   fixing CSS and JS...
168
169
170
    device_detail["device_config"] = {
        re.sub("^_", "", key): value for key, value in device_config.items()}
    # Remove power key as we have this information in the same
6686d675   Alexis Koralewski   new version of ob...
171
172
173
174
    if power is not None:
        device_detail["device_config"].pop("power")
    if connector is not None:
        device_detail["device_config"].pop("connector")
1ba49504   Alexis Koralewski   fixing CSS and JS...
175
    if len(capabilities) != 0:
6686d675   Alexis Koralewski   new version of ob...
176
        device_detail["device_config"].pop("CAPABILITIES")
b95a693f   Alexis Koralewski   restructuration d...
177
    return render(request, "obs_config/device_details.html", {"device_detail": device_detail, "power": power, "connector": connector, "capabilities": capabilities, "devices_links": devices_links, "file_name_to_device_name": file_name_to_device_name, "active_devices": active_devices})
1ba49504   Alexis Koralewski   fixing CSS and JS...
178

b95a693f   Alexis Koralewski   restructuration d...
179
    # return render(request,"obs_config/device_details.html", { "device_detail" : device_detail, "config" : config_device })
1ba49504   Alexis Koralewski   fixing CSS and JS...
180

cc4e5a62   Alexis Koralewski   Add ConfigPyrosv2...
181

cc4e5a62   Alexis Koralewski   Add ConfigPyrosv2...
182
@login_required
1ba49504   Alexis Koralewski   fixing CSS and JS...
183
@level_required("Admin", "Observer", "Management", "Operator", "Unit-PI", "TAC")
cc4e5a62   Alexis Koralewski   Add ConfigPyrosv2...
184
def obs_astronomer_config(request):
1ba49504   Alexis Koralewski   fixing CSS and JS...
185
186
    config = OBSConfig(
        os.environ["PATH_TO_OBSCONF_FILE"], os.environ["unit_name"])
cc4e5a62   Alexis Koralewski   Add ConfigPyrosv2...
187
188
189
190
    units = config.get_units()
    units_topologies = {}
    # for each unit
    for unit_name in units:
1ba49504   Alexis Koralewski   fixing CSS and JS...
191

4290c2cf   Alexis Koralewski   adding unit choic...
192
        units_topologies[unit_name] = config.get_topology(unit_name)
a2dbbde1   Alexis Koralewski   Adding new config...
193
194
        layouts = units_topologies[unit_name].pop("LAYOUTS")["layouts"]
        albums = units_topologies[unit_name].pop("ALBUMS")["albums"]
cc4e5a62   Alexis Koralewski   Add ConfigPyrosv2...
195
196
197
198
199
        # for each category (security, mount, channels)
        for category in units_topologies[unit_name]:
            if category != "CHANNELS":
                # Security and Mount are directly a dictionary containing the attributes of those categories
                # However, component_agents is a list so we need to iterate through this list
1f9d6215   Alexis Koralewski   Update agents & a...
200
                for index, component_agent in enumerate(units_topologies[unit_name][category]["COMPONENT_AGENTS"]):
cc4e5a62   Alexis Koralewski   Add ConfigPyrosv2...
201
202
                    component_name = list(component_agent.keys())[0]
                    agent = component_agent[component_name]
1ba49504   Alexis Koralewski   fixing CSS and JS...
203
204
                    device_of_agent = config.get_device_for_agent(
                        unit_name, agent)
cc4e5a62   Alexis Koralewski   Add ConfigPyrosv2...
205
206
207
                    units_topologies[unit_name][category]["COMPONENT_AGENTS"][index][component_name] = device_of_agent
            else:
                # Channels is composed of a list of channel, we're looping through it
1f9d6215   Alexis Koralewski   Update agents & a...
208
                # We want to list every component for each channels
1ba49504   Alexis Koralewski   fixing CSS and JS...
209
                for channel_name in units_topologies[unit_name]["CHANNELS"]:
1f9d6215   Alexis Koralewski   Update agents & a...
210
211
212
                    units_topologies[unit_name]["CHANNELS"][channel_name]["DEVICES"] = []
                    for index, agent in enumerate(units_topologies[unit_name]["CHANNELS"][channel_name]["AGENTS"]):
                        device = config.get_device_for_agent(
1ba49504   Alexis Koralewski   fixing CSS and JS...
213
                            unit_name, agent)
1f9d6215   Alexis Koralewski   Update agents & a...
214
215
216
217
218
219
220
221
                        if device is None:
                            # Agent is not an AgentDevice
                            continue
                        else:
                            units_topologies[unit_name]["CHANNELS"][channel_name]["DEVICES"].append(device)
                    for index, device in enumerate(units_topologies[unit_name]["CHANNELS"][channel_name]["COMPONENTS"]):
                        device = config.get_device_information(device)
                        units_topologies[unit_name]["CHANNELS"][channel_name]["DEVICES"].append(device)
1ba49504   Alexis Koralewski   fixing CSS and JS...
222
        # Re add layouts and albums
a2dbbde1   Alexis Koralewski   Adding new config...
223
        units_topologies[unit_name]["LAYOUTS"] = layouts
1ba49504   Alexis Koralewski   fixing CSS and JS...
224
225
226
227
228
        units_topologies[unit_name]["ALBUMS"] = albums
        order_of_keys = ["SECURITY", "MOUNT", "LAYOUTS", "ALBUMS", "CHANNELS"]
        list_of_tuples = [(key, units_topologies[unit_name][key])
                          for key in order_of_keys]
        units_topologies[unit_name] = OrderedDict(list_of_tuples)
b95a693f   Alexis Koralewski   restructuration d...
229
    return render(request, "obs_config/obs_astronomer_config.html", {
1ba49504   Alexis Koralewski   fixing CSS and JS...
230
        "units_topologies": units_topologies,
a2dbbde1   Alexis Koralewski   Adding new config...
231
    })
cc4e5a62   Alexis Koralewski   Add ConfigPyrosv2...
232
233


1ba49504   Alexis Koralewski   fixing CSS and JS...
234
235
@ login_required
@ level_required("Admin")
cc4e5a62   Alexis Koralewski   Add ConfigPyrosv2...
236
def obs_agents_config(request):
1ba49504   Alexis Koralewski   fixing CSS and JS...
237
238
    config = OBSConfig(
        os.environ["PATH_TO_OBSCONF_FILE"], os.environ["unit_name"])
cc4e5a62   Alexis Koralewski   Add ConfigPyrosv2...
239
240
241
242
243
    units = config.get_units()
    units_topologies = {}
    active_agents_by_unit = {}
    # for each unit
    for unit_name in units:
4290c2cf   Alexis Koralewski   adding unit choic...
244
        agents = config.get_agents(unit_name)
cc4e5a62   Alexis Koralewski   Add ConfigPyrosv2...
245
        # list of active agents of the current unit
4290c2cf   Alexis Koralewski   adding unit choic...
246
        active_agents_by_unit[unit_name] = config.get_active_agents(unit_name)
cc4e5a62   Alexis Koralewski   Add ConfigPyrosv2...
247
        # topology of the current unit
4290c2cf   Alexis Koralewski   adding unit choic...
248
        units_topologies[unit_name] = config.get_topology(unit_name)
a2dbbde1   Alexis Koralewski   Adding new config...
249
250
251
        # removing albums and layouts, not useful in this view
        units_topologies[unit_name].pop("LAYOUTS")
        units_topologies[unit_name].pop("ALBUMS")
cc4e5a62   Alexis Koralewski   Add ConfigPyrosv2...
252
253
254
255
256
257
        for category in units_topologies[unit_name]:
            if category != "CHANNELS":
                # Security and Mount are directly a dictionary containing the attributes of those categories
                # However, component_agents is a list so we need to iterate through this list
                for component_agent in units_topologies[unit_name][category]["COMPONENT_AGENTS"]:
                    component_name = list(component_agent.keys())[0]
b7becde4   Alexis Koralewski   Updating UI (foot...
258
                    agent = agents[component_agent[component_name]]
1ba49504   Alexis Koralewski   fixing CSS and JS...
259
260
261
                    # get the index of the current component, agent couple
                    index = units_topologies[unit_name][category]["COMPONENT_AGENTS"].index(
                        component_agent)
cc4e5a62   Alexis Koralewski   Add ConfigPyrosv2...
262
263
                    units_topologies[unit_name][category]["COMPONENT_AGENTS"][index][component_name] = agent
            else:
1ba49504   Alexis Koralewski   fixing CSS and JS...
264
                for channel_name in units_topologies[unit_name]["CHANNELS"]:
1f9d6215   Alexis Koralewski   Update agents & a...
265
266
267
268
269
270
271
272
273
274
                    units_topologies[unit_name]["CHANNELS"][channel_name]["CAPABILITIES"] = {}
                    for index, agent in enumerate(units_topologies[unit_name]["CHANNELS"][channel_name]["AGENTS"]):
                        # get agent informations
                        if type(agent) == str:
                            agent = config.get_agent_information(unit_name, agent)
                            if agent is None: 
                                # agent missing link, not defined in agents list in obs config
                                pass
                            device = agent.get("device")
                            if device:
1f9d6215   Alexis Koralewski   Update agents & a...
275
                                capabilities = config.get_device_capabilities(device)
1f9d6215   Alexis Koralewski   Update agents & a...
276
277
                                units_topologies[unit_name]["CHANNELS"][channel_name]["CAPABILITIES"][device] = capabilities
                            units_topologies[unit_name]["CHANNELS"][channel_name]["AGENTS"][index] = agent
cc4e5a62   Alexis Koralewski   Add ConfigPyrosv2...
278

0901eb9b   Alexis Koralewski   Add agent per com...
279
280
281
282
283
        agents = config.get_agents_per_computer(config.unit_name)
        computers = {}
        for computer in config.get_computers():
            computers[config.get_computers().get(computer).get("computer_config").get("hostname")] = computer
        units_topologies[unit_name]["COMPUTERS"] = agents
b95a693f   Alexis Koralewski   restructuration d...
284
    return render(request, "obs_config/obs_agents_config.html", {"units_topologies": units_topologies, "active_agents_by_unit": active_agents_by_unit,"computers":computers})
d0501f5e   Alexis Koralewski   use environment v...
285
286


1ba49504   Alexis Koralewski   fixing CSS and JS...
287
288
@ login_required
@ level_required("Admin", "Operator", "Unit-PI", "Unit-board")
d0501f5e   Alexis Koralewski   use environment v...
289
def edit_config(request):
1ba49504   Alexis Koralewski   fixing CSS and JS...
290
291
    config = OBSConfig(
        os.environ["PATH_TO_OBSCONF_FILE"], os.environ["unit_name"])
b95a693f   Alexis Koralewski   restructuration d...
292
    return render(request, "obs_config/edit_config.html", {"config_file": config.raw_config})
d0501f5e   Alexis Koralewski   use environment v...
293

1ba49504   Alexis Koralewski   fixing CSS and JS...
294
295
296

@ login_required
@ level_required("Admin", "Operator", "Unit-PI", "Unit-board")
d0501f5e   Alexis Koralewski   use environment v...
297
298
def verify_config(request):
    if request.POST.get("config"):
1ba49504   Alexis Koralewski   fixing CSS and JS...
299
300
        temp_config_file = tempfile.NamedTemporaryFile(
            mode='w+', suffix=".yml")
d0501f5e   Alexis Koralewski   use environment v...
301
302
303
        temp_config_file.write(request.POST.get("config"))
        temp_config_file.seek(0)
        response_data = {}
81f42637   Alexis Koralewski   F14 : When editin...
304
305
306
307
308
309
        try:
            config_file = yaml.safe_load(temp_config_file.read())
        except yaml.YAMLError as exc:
            if hasattr(exc, 'problem_mark'):
                yaml_error_message = ""
                if exc.context != None:
1ba49504   Alexis Koralewski   fixing CSS and JS...
310
311
                    yaml_error_message += str(exc.problem_mark) + \
                        '\n  ' + str(exc.problem) + ' ' + str(exc.context)
81f42637   Alexis Koralewski   F14 : When editin...
312
                else:
1ba49504   Alexis Koralewski   fixing CSS and JS...
313
314
                    yaml_error_message = str(
                        exc.problem_mark.name) + '\n  ' + str(exc.problem)
81f42637   Alexis Koralewski   F14 : When editin...
315
316
317
                response_data["is_valid"] = False
                response_data["yaml_error_message"] = yaml_error_message
            return HttpResponse(json.dumps(response_data), content_type="application/json")
d0501f5e   Alexis Koralewski   use environment v...
318
319
320
321
        temp_config_file.seek(0)
        schema = config_file["schema"]
        errors = []
        if schema == None:
b755ff73   Alexis Koralewski   adding variables ...
322
            response_data["is_valid"] = False
d0501f5e   Alexis Koralewski   use environment v...
323
            response_data["message"] = "Missing schema"
1ba49504   Alexis Koralewski   fixing CSS and JS...
324
        schema_path = os.path.join(
18b8672d   Alexis Koralewski   Change config fol...
325
            os.environ["DJANGO_PATH"], "../../../config/observatory/general/schemas/")
1ba49504   Alexis Koralewski   fixing CSS and JS...
326
327
        config = OBSConfig.check_config(
            temp_config_file.name, schema_path+schema)
d0501f5e   Alexis Koralewski   use environment v...
328
329
        if type(config) == bool and config:
            response_data["is_valid"] = True
1ba49504   Alexis Koralewski   fixing CSS and JS...
330
        else:
d0501f5e   Alexis Koralewski   use environment v...
331
332
            response_data["is_valid"] = False
            for error in config:
1ba49504   Alexis Koralewski   fixing CSS and JS...
333
334
                errors.append(
                    (f"Error : {str(error).split('. Path')[0]}", f"Path to error : '{error.path}'"))
d0501f5e   Alexis Koralewski   use environment v...
335
336
337
338
            response_data["message"] = errors
        temp_config_file.close()
        return HttpResponse(json.dumps(response_data), content_type="application/json")

1ba49504   Alexis Koralewski   fixing CSS and JS...
339
340
341

@ login_required
@ level_required("Admin", "Operator", "Unit-PI", "Unit-board")
d0501f5e   Alexis Koralewski   use environment v...
342
343
344
def save_config(request):
    if request.POST:
        if request.POST["config"]:
1ba49504   Alexis Koralewski   fixing CSS and JS...
345
            with open(os.environ["PATH_TO_OBSCONF_FILE"], "w") as obs_config_file:
d0501f5e   Alexis Koralewski   use environment v...
346
347
                obs_config_file.write(request.POST.get("config"))

c27a895d   Alexis Koralewski   add display of ra...
348
349
            return HttpResponse("Ok !")

1ba49504   Alexis Koralewski   fixing CSS and JS...
350
351

@ login_required
a61943b5   Alexis Koralewski   Reworking Unit-bo...
352
@ level_required("Admin", "Unit-PI",  "Operator", "Observer")
1ba49504   Alexis Koralewski   fixing CSS and JS...
353
@ csrf_exempt
c27a895d   Alexis Koralewski   add display of ra...
354
def view_raw_component_config_file(request):
1ba49504   Alexis Koralewski   fixing CSS and JS...
355
356
    COMPONENT_PATH = os.path.join(
        os.environ["DJANGO_PATH"], "../../../config/components/")
c27a895d   Alexis Koralewski   add display of ra...
357
358
359
360
361
362
363
364
365

    if request.POST:
        try:
            yaml_file = open(COMPONENT_PATH+request.POST["yaml_file"])
            content = yaml_file.readlines()
        except:
            content = "Component defined within the device configuration file"
        return HttpResponse(content)

1ba49504   Alexis Koralewski   fixing CSS and JS...
366
367

@ login_required
a61943b5   Alexis Koralewski   Reworking Unit-bo...
368
@ level_required("Admin", "Unit-PI",  "Operator", "Observer")
1ba49504   Alexis Koralewski   fixing CSS and JS...
369
@ csrf_exempt
c27a895d   Alexis Koralewski   add display of ra...
370
def view_raw_generic_device_config_file(request):
1ba49504   Alexis Koralewski   fixing CSS and JS...
371
    GENERIC_DEVICES_PATH = os.path.join(
110a6a83   Alexis Koralewski   Add collapsible c...
372
        os.environ["DJANGO_PATH"], "../../../config/observatory/general/devices/")
c27a895d   Alexis Koralewski   add display of ra...
373
374
375
376
377
    if request.POST:
        yaml_file = open(GENERIC_DEVICES_PATH+request.POST["yaml_file"])
        content = yaml_file.readlines()
        return HttpResponse(content)

1ba49504   Alexis Koralewski   fixing CSS and JS...
378
379

@ login_required
a61943b5   Alexis Koralewski   Reworking Unit-bo...
380
@ level_required("Admin", "Unit-PI",  "Operator", "Observer")
1ba49504   Alexis Koralewski   fixing CSS and JS...
381
@ csrf_exempt
c27a895d   Alexis Koralewski   add display of ra...
382
383
384
385
386
def view_raw_device_config_file(request):
    obs_folder = os.environ["PATH_TO_OBSCONF_FOLDER"]
    if request.POST:
        yaml_file = open(obs_folder+request.POST["yaml_file"])
        content = yaml_file.readlines()
53ce3372   Alexis Koralewski   add diagrams that...
387
388
        return HttpResponse(content)

1ba49504   Alexis Koralewski   fixing CSS and JS...
389
390

@ login_required
a61943b5   Alexis Koralewski   Reworking Unit-bo...
391
@ level_required("Admin", "Unit-PI",  "Operator", "Observer")
53ce3372   Alexis Koralewski   add diagrams that...
392
def obs_config_help(request):
b95a693f   Alexis Koralewski   restructuration d...
393
    return render(request, "obs_config/obs_config_help.html")