Commit c27a895d59bd1c577f9130fdf5deaabeae9e4959
1 parent
5f82ae9f
Exists in
dev
add display of raw config file for devices, generic_devices and components on the device_detail page
Showing
4 changed files
with
177 additions
and
81 deletions
Show diff stats
src/core/pyros_django/obsconfig/templates/obsconfig/device_details.html
... | ... | @@ -15,8 +15,10 @@ th,td{ |
15 | 15 | {% with device_detail|get_item:"name" as device_name %} |
16 | 16 | {% for key,value in device_detail.items %} |
17 | 17 | <div> |
18 | - | |
19 | - {% if key == "device_config" %} | |
18 | + {% if key == "file" %} | |
19 | + <p>{{ key }} : {{ value }} <button id="see_device_file" class="btn btn-light fas fa-eye" value="{{ value }}"></button> </p> | |
20 | + | |
21 | + {% elif key == "device_config" %} | |
20 | 22 | |
21 | 23 | {% with device_detail|get_item:key as device_config %} |
22 | 24 | {% for key,value in device_config.items %} |
... | ... | @@ -27,11 +29,13 @@ th,td{ |
27 | 29 | |
28 | 30 | {% with element|get_item:"file" as attached_device_file %} |
29 | 31 | |
30 | - {% with file_name_to_device_name|get_item:attached_device_file as attached_device %} | |
31 | - <p> <a href="{% url 'device_details' attached_device %}">{{ attached_device }} </a> is attached to this device </p> | |
32 | - {% endwith %} | |
32 | + {% with file_name_to_device_name|get_item:attached_device_file as attached_device %} | |
33 | + <p> <a href="{% url 'device_details' attached_device %}">{{ attached_device }} </a> is attached to this device </p> | |
34 | + {% endwith %} | |
33 | 35 | {% endwith %} |
34 | 36 | {% endfor %} |
37 | + {% elif key == "generic" %} | |
38 | + <p>{{ key }} : {{ value }} <button id="see_device_generic_file" class="btn btn-light fas fa-eye" value="{{ value }}"></button> </p> | |
35 | 39 | {% else %} |
36 | 40 | <p>{{ key }} : {{ value }}</p> |
37 | 41 | {% endif %} |
... | ... | @@ -65,94 +69,149 @@ th,td{ |
65 | 69 | {% endif %} |
66 | 70 | |
67 | 71 | {% if capabilities %} |
68 | - <b>Capabilities : </b> | |
72 | + <h2>Capabilities : </h2> | |
69 | 73 | <ul> |
70 | 74 | {% for capability in capabilities %} |
71 | - | |
72 | - {% comment %} | |
73 | 75 | |
74 | - {% for information,information_value in capability.items %} | |
76 | + {% comment %} | |
77 | + | |
78 | + {% for information,information_value in capability.items %} | |
75 | 79 | |
76 | - <p>{{ information }} : {{ information_value }}</p> | |
80 | + <p>{{ information }} : {{ information_value }}</p> | |
77 | 81 | |
78 | - {% endfor %} | |
79 | - {% endcomment %} | |
80 | - | |
81 | - <li> <h3> Component : {{capability.component}} </h3> </li> | |
82 | - <br> | |
83 | - <b> attributes : </b> | |
84 | - <ul> | |
85 | - | |
86 | - {% for attribute in capability.attributes %} | |
87 | - {% with capability.attributes|get_item:attribute as attribute %} | |
88 | - {% if attribute.is_container %} | |
89 | - <li><b>{{ attribute.label }} :</li></b> | |
90 | - <table class="table-bordered table-hover table-striped" > | |
82 | + {% endfor %} | |
83 | + {% endcomment %} | |
84 | + | |
85 | + <li> <h3> Component : {{capability.component}} <button value="{{ capability.component }}" class="btn btn-light fas fa-eye see_component_generic_file"></button></h3> </li> | |
86 | + <br> | |
87 | + <b> attributes : </b> | |
88 | + <ul> | |
89 | + | |
90 | + {% for attribute in capability.attributes %} | |
91 | + {% with capability.attributes|get_item:attribute as attribute %} | |
92 | + {% if attribute.is_container %} | |
93 | + <li><b>{{ attribute.label }} :</li></b> | |
94 | + <table class="table-bordered table-hover table-striped" > | |
95 | + <thead> | |
96 | + <tr> | |
97 | + <th> Variable </th> | |
98 | + <th> Unit </th> | |
99 | + <th colspan="20"> Values </th> | |
100 | + </tr> | |
101 | + </thead> | |
102 | + <tbody> | |
103 | + {% for val_name in attribute.value %} | |
104 | + <tr> | |
105 | + <td> {{ val_name }} </td> | |
106 | + <td>{{ attribute.unit|get_item:val_name}} </td> | |
107 | + {% for value in attribute.value|get_item:val_name %} | |
108 | + | |
109 | + {% if value|get_type == 'list' %} | |
110 | + <td> | |
111 | + <table class="table-bordered"> | |
112 | + <tbody> | |
113 | + {% with value as values %} | |
114 | + <tr> | |
115 | + {% for value in values %} | |
116 | + <td> {{value}} </td> | |
117 | + {% endfor %} | |
118 | + </tr> | |
119 | + </tbody> | |
120 | + </table> | |
121 | + {% endwith %} | |
122 | + </td> | |
123 | + | |
124 | + {% else %} | |
125 | + <td> {{value}} </td> | |
126 | + {% endif %} | |
127 | + {% endfor %} | |
128 | + </tr> | |
129 | + {% endfor %} | |
130 | + </tbody> | |
131 | + </table> | |
132 | + {% elif attribute.is_enum %} | |
133 | + <li><b>{{ attribute.label }} :</li></b> | |
134 | + <table class="table-bordered table-hover table-striped" > | |
91 | 135 | <thead> |
92 | 136 | <tr> |
137 | + <tr> | |
93 | 138 | <th> Variable </th> |
94 | - <th> Unit </th> | |
95 | - <th colspan="20"> Values </th> | |
139 | + <th colspan="20"> Values (One of the following values)</th> | |
96 | 140 | </tr> |
97 | 141 | </thead> |
98 | 142 | <tbody> |
99 | - {% for val_name in attribute.value %} | |
100 | 143 | <tr> |
101 | - <td> {{ val_name }} </td> | |
102 | - <td>{{ attribute.unit|get_item:val_name}} </td> | |
103 | - {% for value in attribute.value|get_item:val_name %} | |
104 | - | |
105 | - {% if value|get_type == 'list' %} | |
106 | - <td> | |
107 | - <table class="table-bordered"> | |
108 | - <tbody> | |
109 | - {% with value as values %} | |
110 | - <tr> | |
111 | - {% for value in values %} | |
112 | - <td> {{value}} </td> | |
113 | - {% endfor %} | |
114 | - </tr> | |
115 | - </tbody> | |
116 | - </table> | |
117 | - {% endwith %} | |
118 | - </td> | |
119 | - | |
120 | - {% else %} | |
121 | - <td> {{value}} </td> | |
122 | - {% endif %} | |
123 | - {% endfor %} | |
124 | - </tr> | |
144 | + <td> {{ attribute.label}} </td> | |
145 | + {% for val in attribute.value %} | |
146 | + <td> {{ val }} </td> | |
125 | 147 | {% endfor %} |
148 | + </tr> | |
126 | 149 | </tbody> |
127 | - </table> | |
128 | - {% elif attribute.is_enum %} | |
129 | - <li><b>{{ attribute.label }} :</li></b> | |
130 | - <table class="table-bordered table-hover table-striped" > | |
131 | - <thead> | |
132 | - <tr> | |
133 | - <tr> | |
134 | - <th> Variable </th> | |
135 | - <th colspan="20"> Values (One of the following values)</th> | |
136 | - </tr> | |
137 | - </thead> | |
138 | - <tbody> | |
139 | - <tr> | |
140 | - <td> {{ attribute.label}} </td> | |
141 | - {% for val in attribute.value %} | |
142 | - <td> {{ val }} </td> | |
143 | - {% endfor %} | |
144 | - </tr> | |
145 | - </tbody> | |
146 | - </table> | |
147 | - {% else %} | |
148 | - <li>{{ attribute.label }} : {{ attribute.value}} {{ attribute.unit}} </li> | |
149 | - {% endif %} | |
150 | - {% endwith %} | |
151 | - {% endfor %} | |
152 | - </ul> | |
150 | + </table> | |
151 | + {% else %} | |
152 | + <li>{{ attribute.label }} : {{ attribute.value}} {{ attribute.unit}} </li> | |
153 | + {% endif %} | |
154 | + {% endwith %} | |
155 | + {% endfor %} | |
156 | + </ul> | |
153 | 157 | {% endfor %} |
154 | 158 | </ul> |
155 | 159 | {% endif %} |
156 | 160 | {% endwith %} |
157 | 161 | |
162 | + | |
163 | +{# modal for displaying raw yaml files #} | |
164 | + | |
165 | +<div class="modal" tabindex="-1" id="rawFileModal" role="dialog"> | |
166 | + <div class="modal-dialog modal-lg" role="document"> | |
167 | + <div class="modal-content"> | |
168 | + <div class="modal-header"> | |
169 | + <h5 id="#rawFileModal_title" class="modal-title"></h5> | |
170 | + <button type="button" class="close" data-dismiss="modal" aria-label="Close"> | |
171 | + <span aria-hidden="true">×</span> | |
172 | + </button> | |
173 | + </div> | |
174 | + <div class="modal-body"> | |
175 | + <pre id="view_raw_file"></pre> | |
176 | + </div> | |
177 | + <div class="modal-footer"> | |
178 | + <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button> | |
179 | + </div> | |
180 | + </div> | |
181 | + </div> | |
182 | +</div> | |
183 | + | |
184 | +<script> | |
185 | +$('.see_component_generic_file').on("click",function(){ | |
186 | + console.log($(this)); | |
187 | + console.log($(this).val()); | |
188 | + let file_name = $(this).val()+".yml"; | |
189 | + console.log(file_name); | |
190 | + $.post("{% url 'view_raw_component_config_file' %}",{"yaml_file":file_name},function(data){ | |
191 | + console.log(data); | |
192 | + $("#view_raw_file").html(data); | |
193 | + $(".modal-title").html(file_name); | |
194 | + $('#rawFileModal').modal('show'); | |
195 | + }) | |
196 | +}); | |
197 | + | |
198 | + | |
199 | +$('#see_device_generic_file').on("click",function(){ | |
200 | + let file_name = $("#see_device_generic_file").val(); | |
201 | + $.post("{% url 'view_raw_generic_device_config_file' %}",{"yaml_file":file_name},function(data){ | |
202 | + $("#view_raw_file").html(data); | |
203 | + $(".modal-title").html(file_name); | |
204 | + $('#rawFileModal').modal('show'); | |
205 | + }) | |
206 | +}); | |
207 | + | |
208 | +$('#see_device_file').on("click",function(){ | |
209 | + let file_name = $("#see_device_file").val(); | |
210 | + $.post("{% url 'view_raw_device_config_file' %}",{"yaml_file":file_name},function(data){ | |
211 | + $("#view_raw_file").html(data); | |
212 | + $(".modal-title").html(file_name); | |
213 | + $('#rawFileModal').modal('show'); | |
214 | + }) | |
215 | +}); | |
216 | +</script> | |
158 | 217 | {% endblock %} |
159 | 218 | \ No newline at end of file | ... | ... |
src/core/pyros_django/obsconfig/urls.py
... | ... | @@ -11,5 +11,8 @@ urlpatterns = [ |
11 | 11 | path('device_details/<str:device_name>', views.device_details, name='device_details'), |
12 | 12 | path('edit_config',views.edit_config,name="edit_config"), |
13 | 13 | path('verify_config',views.verify_config,name="verify_config"), |
14 | - path('save_config',views.save_config,name="save_config") | |
14 | + path('save_config',views.save_config,name="save_config"), | |
15 | + path("view_raw_component_config_file",views.view_raw_component_config_file,name="view_raw_component_config_file"), | |
16 | + path("view_raw_device_config_file",views.view_raw_device_config_file,name="view_raw_device_config_file"), | |
17 | + path("view_raw_generic_device_config_file",views.view_raw_generic_device_config_file,name="view_raw_generic_device_config_file"), | |
15 | 18 | ] |
16 | 19 | \ No newline at end of file | ... | ... |
src/core/pyros_django/obsconfig/views.py
... | ... | @@ -6,6 +6,7 @@ from src.core.pyros_django.dashboard.decorator import level_required |
6 | 6 | from django.contrib.auth.decorators import login_required |
7 | 7 | from django.http import HttpResponse |
8 | 8 | from datetime import datetime |
9 | +from django.views.decorators.csrf import csrf_exempt | |
9 | 10 | import re, yaml,tempfile,json,os |
10 | 11 | |
11 | 12 | def get_nested_dictionaries_as_list(dic,result=[]): |
... | ... | @@ -98,7 +99,7 @@ def computer_details(request,computer_name): |
98 | 99 | |
99 | 100 | |
100 | 101 | @login_required |
101 | -@level_required("Admin","Unit-PI","Operator","Observer") | |
102 | +@level_required("Admin","Unit-PI","Unit-board","Operator","Observer") | |
102 | 103 | def device_details(request,device_name): |
103 | 104 | config = ConfigPyros(os.environ["PATH_TO_OBSCONF_FILE"]) |
104 | 105 | # We're removing "_" at the beginning of each key : |
... | ... | @@ -117,7 +118,6 @@ def device_details(request,device_name): |
117 | 118 | |
118 | 119 | |
119 | 120 | device_detail = { re.sub("^_","",key):value for key,value in config.get_devices()[device_name].items()} |
120 | - | |
121 | 121 | #test_device= get_nested_dictionaries_as_list(device_detail,[]) |
122 | 122 | |
123 | 123 | if config.get_device_power(device_name) is not None: |
... | ... | @@ -282,4 +282,38 @@ def save_config(request): |
282 | 282 | obs_config_file.write(request.POST.get("config")) |
283 | 283 | |
284 | 284 | |
285 | - return HttpResponse("Ok !") | |
286 | 285 | \ No newline at end of file |
286 | + return HttpResponse("Ok !") | |
287 | + | |
288 | +@login_required | |
289 | +@level_required("Admin","Unit-PI","Unit-board","Operator","Observer") | |
290 | +@csrf_exempt | |
291 | +def view_raw_component_config_file(request): | |
292 | + COMPONENT_PATH = os.path.join(os.environ["DJANGO_PATH"],"../../../config/components/") | |
293 | + | |
294 | + if request.POST: | |
295 | + try: | |
296 | + yaml_file = open(COMPONENT_PATH+request.POST["yaml_file"]) | |
297 | + content = yaml_file.readlines() | |
298 | + except: | |
299 | + content = "Component defined within the device configuration file" | |
300 | + return HttpResponse(content) | |
301 | + | |
302 | +@login_required | |
303 | +@level_required("Admin","Unit-PI","Unit-board","Operator","Observer") | |
304 | +@csrf_exempt | |
305 | +def view_raw_generic_device_config_file(request): | |
306 | + GENERIC_DEVICES_PATH = os.path.join(os.environ["DJANGO_PATH"],"../../../config/devices/") | |
307 | + if request.POST: | |
308 | + yaml_file = open(GENERIC_DEVICES_PATH+request.POST["yaml_file"]) | |
309 | + content = yaml_file.readlines() | |
310 | + return HttpResponse(content) | |
311 | + | |
312 | +@login_required | |
313 | +@level_required("Admin","Unit-PI","Unit-board","Operator","Observer") | |
314 | +@csrf_exempt | |
315 | +def view_raw_device_config_file(request): | |
316 | + obs_folder = os.environ["PATH_TO_OBSCONF_FOLDER"] | |
317 | + if request.POST: | |
318 | + yaml_file = open(obs_folder+request.POST["yaml_file"]) | |
319 | + content = yaml_file.readlines() | |
320 | + return HttpResponse(content) | |
287 | 321 | \ No newline at end of file | ... | ... |
src/core/pyros_django/pyros/settings.py
... | ... | @@ -401,5 +401,5 @@ python_version = subprocess.run( "python --version | cut -d ' ' -f 2 | cut -d '. |
401 | 401 | python_version = python_version.stdout |
402 | 402 | today = datetime.utcnow().date() |
403 | 403 | django_version_major,django_version_minor = django.VERSION[:2][0],django.VERSION[:2][1] |
404 | -pyros_version = "0.2.6.0" | |
404 | +pyros_version = "0.2.7.0" | |
405 | 405 | VERSION_NUMBER = f"{pyros_version}_{django_version_major}.{django_version_minor}_{python_version}_{today}" |
406 | 406 | \ No newline at end of file | ... | ... |