##// END OF EJS Templates
Task #559: Vista de Summary (main: urls, views, experiment.html, experiment_summary.html)...
Fiorella Quino -
r151:7532782126ca
parent child
Show More
@@ -0,0 +1,125
1 {% extends "base.html" %}
2 {% load bootstrap3 %}
3 {% load static %}
4 {% load main_tags %}
5 {% block extra-head %}
6 <link href="{% static 'css/bootstrap-datetimepicker.min.css' %}" media="screen" rel="stylesheet">
7 {% endblock %}
8
9 {% block exp-active %}active{% endblock %}
10
11 {% block content-title %}{{title}}{% endblock %}
12 {% block content-suptitle %}{{suptitle}}{% endblock %}
13
14 {% block content %}
15
16 {% block menu-actions %}
17 <!-- <span class=" dropdown pull-right">
18 <a href="#" class="dropdown-toggle" data-toggle="dropdown"><span class="glyphicon glyphicon-menu-hamburger gi-2x" aria-hidden="true"></span></a>
19 <ul class="dropdown-menu" role="menu">
20 <li><a href="{% url 'url_edit_experiment' experiment.id %}"><span class="glyphicon glyphicon-pencil" aria-hidden="true"></span> Edit</a></li>
21 <li><a href="{% url 'url_delete_experiment' experiment.id %}"><span class="glyphicon glyphicon-remove" aria-hidden="true"></span> Delete</a></li>
22 <li><a href="{{ experiment.get_absolute_url_import }}"><span class="glyphicon glyphicon-import" aria-hidden="true"></span> Import </a></li>
23 <li><a href="{{ experiment.get_absolute_url_export }}"><span class="glyphicon glyphicon-export" aria-hidden="true"></span> Export </a></li>
24 {% block extra-menu-actions %}
25 {% endblock %}
26 <li><a>----------------</a></li>
27 <li><a href="{% url 'url_mix_experiment' experiment.id %}"><span class="glyphicon glyphicon-random" aria-hidden="true"></span> Mix RC Configurations </a></li>
28 <li><a href="{% url 'url_add_dev_conf' experiment.id %}"><span class="glyphicon glyphicon-plus-sign" aria-hidden="true"></span> Add Configuration</a></li>
29 <li><a href=#><span class="glyphicon glyphicon-check" aria-hidden="true"></span> Verify Parameters</a></li>
30
31 </ul>
32 </span> -->
33 {% endblock %}
34
35 <table class="table table-bordered">
36 {% for key in experiment_keys %}
37 <tr><th>{{key|title}}</th><td>{{experiment|attr:key}}</td></tr>
38 {% endfor %}
39 </table>
40
41 <div class="">
42 <h4 class="panel-title"><b> Parameters </b></h4>
43 <br>
44 </div>
45
46 <table class="table table-bordered">
47 {% for configuration in configurations %}
48 {% if configuration.device.device_type.name == 'dds' %}
49 <!--<h4 class="panel-title"> </h4>-->
50 <tr><th>dds</th><td>(=</td></tr>
51 {% endif %}
52
53 {% if configuration.device.device_type.name == 'rc' %}
54 <!--<h4 class="panel-title"> </h4>-->
55 <tr><th>IPP(km)</th><td>{{experiment_data.configurations.rc.ipp}}</td></tr>
56 <tr><th>NTX</th><td>{{experiment_data.configurations.rc.ntx}}</td></tr>
57 <tr><th>TX</th><td>{{tx}}</td></tr>
58 <tr><th>Code</th><td>{{code}}</td></tr>
59 <tr><th>Sampling Window</th><td>{{window|linebreaks}}</td></tr>
60 {% endif %}
61
62 {% if configuration.device.device_type.name == 'rc_mix' %}
63 <!--<h4 class="panel-title"> </h4>-->
64 <tr><th>rc_mix</th><td>(=</td></tr>
65 {% endif %}
66
67 {% if configuration.device.device_type.name == 'jars' %}
68 <!--<h4 class="panel-title"> JARS </h4>-->
69 <tr><th>Data Type</th><td>{{exp_type}}</td></tr>
70 <tr><th># Channels</th><td>{{configuration.channels_number}}</td></tr>
71 <tr><th>Coh Int</th><td>{{configuration.cohe_integr}}</td></tr>
72 <tr><th>FFT Points</th><td>{{configuration.fftpoints}}</td></tr>
73 {% if exp_type == 'PDATA'%}
74 <tr><th>Inc Int</th><td>{{configuration.incohe_integr}}</td></tr>
75 <tr><th>Spec. Comb.</th><td>{{configuration.spectral}}</td></tr>
76 {% endif %}
77 <tr><th>Acq Prof</th><td>{{configuration.acq_profiles}}</td></tr>
78 <tr><th>Prof x Block</th><td>{{configuration.profiles_block}}</td></tr>
79 <tr><th>Block x File</th><td>(=</td></tr>
80 {% endif %}
81
82 {% if configuration.device.device_type.name == 'usrp' %}
83 <!--<h4 class="panel-title"> </h4>-->
84 <tr><th>usrp</th><td>(=</td></tr>
85 {% endif %}
86
87 {% if configuration.device.device_type.name == 'cgs' %}
88 <!--<h4 class="panel-title"> CGS </h4>-->
89 <!--<tr><th>Frequency 0</th><td>{{configuration.freq0}}</td></tr>-->
90 <!--<tr><th>Frequency 1</th><td>{{configuration.freq1}}</td></tr>-->
91 <!--<tr><th>Frequency 2</th><td>{{configuration.freq2}}</td></tr>-->
92 <!--<tr><th>Frequency 3</th><td>{{configuration.freq3}}</td></tr>-->
93 {% endif %}
94
95 {% if configuration.device.device_type.name == 'abs' %}
96 <!--<h4 class="panel-title"> </h4>-->
97 <tr><th>abs</th><td>(=</td></tr>
98 {% endif %}
99 {% endfor %}
100 </table>
101
102 <div class="pull-right">
103 <button type="button" class="btn btn-primary" id="bt_back">Back</button>
104 <button type="button" class="btn btn-primary" id="bt_verify">Verify Parameters</button>
105 </div>
106
107 {% endblock %}
108
109 {% block sidebar%}
110 {% include "sidebar_devices.html" %}
111 {% endblock %}
112
113 {% block extra-js%}
114 <script type="text/javascript">
115
116 $(".clickable-row").click(function() {
117 document.location = $(this).data("href");
118 });
119
120 $("#bt_back").click(function() {
121 document.location = "{% url 'url_experiment' experiment.id%}";
122 });
123
124 </script>
125 {% endblock %} No newline at end of file
@@ -1,100 +1,101
1 1 {% extends "base.html" %}
2 2 {% load bootstrap3 %}
3 3 {% load static %}
4 4 {% load main_tags %}
5 5 {% block extra-head %}
6 6 <link href="{% static 'css/bootstrap-datetimepicker.min.css' %}" media="screen" rel="stylesheet">
7 7 {% endblock %}
8 8
9 9 {% block exp-active %}active{% endblock %}
10 10
11 11 {% block content-title %}{{title}}{% endblock %}
12 12 {% block content-suptitle %}{{suptitle}}{% endblock %}
13 13
14 14 {% block content %}
15 15
16 16 {% block menu-actions %}
17 17 <span class=" dropdown pull-right">
18 18 <a href="#" class="dropdown-toggle" data-toggle="dropdown"><span class="glyphicon glyphicon-menu-hamburger gi-2x" aria-hidden="true"></span></a>
19 19 <ul class="dropdown-menu" role="menu">
20 20 <li><a href="{% url 'url_edit_experiment' experiment.id %}"><span class="glyphicon glyphicon-pencil" aria-hidden="true"></span> Edit</a></li>
21 21 <li><a href="{% url 'url_delete_experiment' experiment.id %}"><span class="glyphicon glyphicon-remove" aria-hidden="true"></span> Delete</a></li>
22 22 <li><a href="{{ experiment.get_absolute_url_import }}"><span class="glyphicon glyphicon-import" aria-hidden="true"></span> Import </a></li>
23 23 <li><a href="{{ experiment.get_absolute_url_export }}"><span class="glyphicon glyphicon-export" aria-hidden="true"></span> Export </a></li>
24 24 {% block extra-menu-actions %}
25 25 {% endblock %}
26 26 <li><a>----------------</a></li>
27 27 <li><a href="{% url 'url_mix_experiment' experiment.id %}"><span class="glyphicon glyphicon-random" aria-hidden="true"></span> Mix RC Configurations </a></li>
28 28 <li><a href="{% url 'url_add_dev_conf' experiment.id %}"><span class="glyphicon glyphicon-plus-sign" aria-hidden="true"></span> Add Configuration</a></li>
29 <li><a href="{% url 'url_sum_experiment' experiment.id %}"><span class="glyphicon glyphicon-list-alt" aria-hidden="true"></span> Summary</a></li>
29 30
30 31 </ul>
31 32 </span>
32 33 {% endblock %}
33 34
34 35 <table class="table table-bordered">
35 36 {% for key in experiment_keys %}
36 37 <tr><th>{{key|title}}</th><td>{{experiment|attr:key}}</td></tr>
37 38 {% endfor %}
38 39 </table>
39 40 <br></br>
40 41 <br></br>
41 42
42 43 <div class="panel-group" id="accordion" role="tablist" aria-multiselectable="true">
43 44
44 45 <div class="panel panel-default">
45 46 <div class="panel-heading" role="tab" id="headingTwo">
46 47 <h4 class="panel-title">
47 48 <a class="collapsed" role="button" data-toggle="collapse" data-parent="#accordion" href="#collapseTwo" aria-expanded="false" aria-controls="collapseThree">
48 49 Device Configurations
49 50 </a>
50 51 </h4>
51 52 </div>
52 53 <div id="collapseTwo" class="panel-collapse collapse in" role="tabpanel" aria-labelledby="headingTwo">
53 54 <div class="panel-body">
54 55 <table class="table table-hover">
55 56 <tr>
56 57 <th>#</th>
57 58 {% for key in configuration_keys %}
58 59 <th>{{ key|title }}</th>
59 60 {% endfor%}
60 61 </tr>
61 62 {% for item in configurations %}
62 63 <tr class="clickable-row" data-href="{{item.get_absolute_url}}">
63 64 <td>{{ forloop.counter }}</td>
64 65 {% for key in configuration_keys %}
65 66 {% if key == 'device__status' %}
66 67 <td class="text-{{item.device.status_color}}">{{ item|value:key }}</td>
67 68 {% else %}
68 69 <td>{{ item|value:key }}</td>
69 70 {% endif %}
70 71 {% endfor %}
71 72 </tr>
72 73 {% endfor %}
73 74 </table>
74 75 </div>
75 76 </div>
76 77 </div>
77 78 </div>
78 79 {% endblock %}
79 80
80 81 {% block sidebar%}
81 82 {% include "sidebar_devices.html" %}
82 83 {% endblock %}
83 84
84 85 {% block extra-js%}
85 86 <script type="text/javascript">
86 87
87 88 $(".clickable-row").click(function() {
88 89 document.location = $(this).data("href");
89 90 });
90 91
91 92 $("#bt_edit").click(function() {
92 93 document.location = "{% url 'url_edit_experiment' experiment.id%}";
93 94 });
94 95
95 96 $("#bt_add_conf").click(function() {
96 97 document.location = "{% url 'url_add_dev_conf' experiment.id %}";
97 98 });
98 99
99 100 </script>
100 101 {% endblock %} No newline at end of file
@@ -1,57 +1,58
1 1 from django.conf.urls import url
2 2
3 3 urlpatterns = (
4 4 url(r'^location/new/$', 'apps.main.views.location_new', name='url_add_location'),
5 5 url(r'^location/$', 'apps.main.views.locations', name='url_locations'),
6 6 url(r'^location/(?P<id_loc>-?\d+)/$', 'apps.main.views.location', name='url_location'),
7 7 url(r'^location/(?P<id_loc>-?\d+)/edit/$', 'apps.main.views.location_edit', name='url_edit_location'),
8 8 url(r'^location/(?P<id_loc>-?\d+)/delete/$', 'apps.main.views.location_delete', name='url_delete_location'),
9 9
10 10 url(r'^device/new/$', 'apps.main.views.device_new', name='url_add_device'),
11 11 url(r'^device/$', 'apps.main.views.devices', name='url_devices'),
12 12 url(r'^device/(?P<id_dev>-?\d+)/$', 'apps.main.views.device', name='url_device'),
13 13 url(r'^device/(?P<id_dev>-?\d+)/edit/$', 'apps.main.views.device_edit', name='url_edit_device'),
14 14 url(r'^device/(?P<id_dev>-?\d+)/delete/$', 'apps.main.views.device_delete', name='url_delete_device'),
15 15
16 16 url(r'^campaign/new/$', 'apps.main.views.campaign_new', name='url_add_campaign'),
17 17 url(r'^campaign/$', 'apps.main.views.campaigns', name='url_campaigns'),
18 18 url(r'^campaign/(?P<id_camp>-?\d+)/$', 'apps.main.views.campaign', name='url_campaign'),
19 19 url(r'^campaign/(?P<id_camp>-?\d+)/edit/$', 'apps.main.views.campaign_edit', name='url_edit_campaign'),
20 20 url(r'^campaign/(?P<id_camp>-?\d+)/delete/$', 'apps.main.views.campaign_delete', name='url_delete_campaign'),
21 21 url(r'^campaign/(?P<id_camp>-?\d+)/export/$', 'apps.main.views.campaign_export', name='url_export_campaign'),
22 22 url(r'^campaign/(?P<id_camp>-?\d+)/import/$', 'apps.main.views.campaign_import', name='url_import_campaign'),
23 23
24 24 url(r'^experiment/new/$', 'apps.main.views.experiment_new', name='url_add_experiment'),
25 25 url(r'^experiment/$', 'apps.main.views.experiments', name='url_experiments'),
26 26 url(r'^experiment/(?P<id_exp>-?\d+)/$', 'apps.main.views.experiment', name='url_experiment'),
27 27 url(r'^experiment/(?P<id_exp>-?\d+)/edit/$', 'apps.main.views.experiment_edit', name='url_edit_experiment'),
28 28 url(r'^experiment/(?P<id_exp>-?\d+)/delete/$', 'apps.main.views.experiment_delete', name='url_delete_experiment'),
29 29 url(r'^experiment/(?P<id_exp>-?\d+)/export/$', 'apps.main.views.experiment_export', name='url_export_experiment'),
30 30 url(r'^experiment/(?P<id_exp>-?\d+)/import/$', 'apps.main.views.experiment_import', name='url_import_experiment'),
31 31 url(r'^experiment/(?P<id_exp>-?\d+)/mix/$', 'apps.main.views.experiment_mix', name='url_mix_experiment'),
32 32 url(r'^experiment/(?P<id_exp>-?\d+)/mix/delete/$', 'apps.main.views.experiment_mix_delete', name='url_delete_mix_experiment'),
33 url(r'^experiment/(?P<id_exp>-?\d+)/summary/$', 'apps.main.views.experiment_summary', name='url_sum_experiment'),
33 34
34 35 url(r'^experiment/(?P<id_exp>-?\d+)/new_dev_conf/$', 'apps.main.views.dev_conf_new', name='url_add_dev_conf'),
35 36 url(r'^experiment/(?P<id_exp>-?\d+)/new_dev_conf/(?P<id_dev>-?\d+)/$', 'apps.main.views.dev_conf_new', name='url_add_dev_conf'),
36 37 url(r'^dev_conf/$', 'apps.main.views.dev_confs', name='url_dev_confs'),
37 38 url(r'^dev_conf/(?P<id_conf>-?\d+)/$', 'apps.main.views.dev_conf', name='url_dev_conf'),
38 39 url(r'^dev_conf/(?P<id_conf>-?\d+)/edit/$', 'apps.main.views.dev_conf_edit', name='url_edit_dev_conf'),
39 40 url(r'^dev_conf/(?P<id_conf>-?\d+)/delete/$', 'apps.main.views.dev_conf_delete', name='url_delete_dev_conf'),
40 41
41 42 url(r'^dev_conf/(?P<id_conf>-?\d+)/write/$', 'apps.main.views.dev_conf_write', name='url_write_dev_conf'),
42 43 url(r'^dev_conf/(?P<id_conf>-?\d+)/read/$', 'apps.main.views.dev_conf_read', name='url_read_dev_conf'),
43 44 url(r'^dev_conf/(?P<id_conf>-?\d+)/import/$', 'apps.main.views.dev_conf_import', name='url_import_dev_conf'),
44 45 url(r'^dev_conf/(?P<id_conf>-?\d+)/export/$', 'apps.main.views.dev_conf_export', name='url_export_dev_conf'),
45 46 url(r'^dev_conf/(?P<id_conf>-?\d+)/start/$', 'apps.main.views.dev_conf_start', name='url_start_dev_conf'),
46 47 url(r'^dev_conf/(?P<id_conf>-?\d+)/stop/$', 'apps.main.views.dev_conf_stop', name='url_stop_dev_conf'),
47 48 url(r'^dev_conf/(?P<id_conf>-?\d+)/status/$', 'apps.main.views.dev_conf_status', name='url_status_dev_conf'),
48 49
49 50 url(r'^operation/$', 'apps.main.views.operation', name='url_operation'),
50 51 url(r'^operation/(?P<id_camp>-?\d+)/$', 'apps.main.views.operation', name='url_operation'),
51 52 url(r'^operation/search/$', 'apps.main.views.operation_search', name='url_operation_search'),
52 53 url(r'^operation/search/(?P<id_camp>-?\d+)/$', 'apps.main.views.operation_search', name='url_operation_search'),
53 54 url(r'^operation/(?P<id_camp>-?\d+)/radar/(?P<id_radar>-?\d+)/play/$', 'apps.main.views.radar_play', name='url_radar_play'),
54 55 url(r'^operation/(?P<id_camp>-?\d+)/radar/(?P<id_radar>-?\d+)/stop/$', 'apps.main.views.radar_stop', name='url_radar_stop'),
55 56 url(r'^operation/(?P<id_camp>-?\d+)/radar/(?P<id_radar>-?\d+)/refresh/$', 'apps.main.views.radar_refresh', name='url_radar_refresh'),
56 57
57 58 )
@@ -1,1429 +1,1482
1 1 from django.shortcuts import render, redirect, get_object_or_404, HttpResponse
2 2 from django.utils.safestring import mark_safe
3 3 from django.http import HttpResponseRedirect
4 4 from django.core.urlresolvers import reverse
5 5 from django.db.models import Q
6 6 from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
7 7 from django.contrib import messages
8 8 from datetime import datetime
9 9 import urllib
10 10
11 11 from .forms import CampaignForm, ExperimentForm, DeviceForm, ConfigurationForm, LocationForm, UploadFileForm, DownloadFileForm, OperationForm, NewForm
12 12 from .forms import OperationSearchForm, FilterForm
13 13 from apps.cgs.forms import CGSConfigurationForm
14 14 from apps.jars.forms import JARSConfigurationForm
15 15 from apps.usrp.forms import USRPConfigurationForm
16 16 from apps.abs.forms import ABSConfigurationForm
17 17 from apps.rc.forms import RCConfigurationForm, RCMixConfigurationForm
18 18 from apps.dds.forms import DDSConfigurationForm
19 19
20 20 from .models import Campaign, Experiment, Device, Configuration, Location, RunningExperiment
21 21 from apps.cgs.models import CGSConfiguration
22 from apps.jars.models import JARSConfiguration
22 from apps.jars.models import JARSConfiguration, EXPERIMENT_TYPE
23 23 from apps.usrp.models import USRPConfiguration
24 24 from apps.abs.models import ABSConfiguration
25 25 from apps.rc.models import RCConfiguration, RCLine, RCLineType
26 26 from apps.dds.models import DDSConfiguration
27 27 from django.http.request import QueryDict
28 28
29 29 # Create your views here.
30 30
31 31 CONF_FORMS = {
32 32 'rc': RCConfigurationForm,
33 33 'dds': DDSConfigurationForm,
34 34 'jars': JARSConfigurationForm,
35 35 'cgs': CGSConfigurationForm,
36 36 'abs': ABSConfigurationForm,
37 37 'usrp': USRPConfigurationForm,
38 38 }
39 39
40 40 CONF_MODELS = {
41 41 'rc': RCConfiguration,
42 42 'dds': DDSConfiguration,
43 43 'jars': JARSConfiguration,
44 44 'cgs': CGSConfiguration,
45 45 'abs': ABSConfiguration,
46 46 'usrp': USRPConfiguration,
47 47 }
48 48
49 49 MIX_MODES = {
50 50 '0': 'P',
51 51 '1': 'S',
52 52 }
53 53
54 54 MIX_OPERATIONS = {
55 55 '0': 'OR',
56 56 '1': 'XOR',
57 57 '2': 'AND',
58 58 '3': 'NAND',
59 59 }
60 60
61 61
62 62 def index(request):
63 63 kwargs = {}
64 64
65 65 return render(request, 'index.html', kwargs)
66 66
67 67
68 68 def locations(request):
69 69
70 70 page = request.GET.get('page')
71 71 order = ('name',)
72 72
73 73 kwargs = get_paginator(Location, page, order)
74 74
75 75 kwargs['keys'] = ['name', 'description']
76 76 kwargs['title'] = 'Radar System'
77 77 kwargs['suptitle'] = 'List'
78 78
79 79 return render(request, 'base_list.html', kwargs)
80 80
81 81
82 82 def location(request, id_loc):
83 83
84 84 location = get_object_or_404(Location, pk=id_loc)
85 85
86 86 kwargs = {}
87 87 kwargs['location'] = location
88 88 kwargs['location_keys'] = ['name', 'description']
89 89
90 90 kwargs['title'] = 'Location'
91 91 kwargs['suptitle'] = 'Details'
92 92
93 93 return render(request, 'location.html', kwargs)
94 94
95 95
96 96 def location_new(request):
97 97
98 98 if request.method == 'GET':
99 99 form = LocationForm()
100 100
101 101 if request.method == 'POST':
102 102 form = LocationForm(request.POST)
103 103
104 104 if form.is_valid():
105 105 form.save()
106 106 return redirect('url_locations')
107 107
108 108 kwargs = {}
109 109 kwargs['form'] = form
110 110 kwargs['title'] = 'Radar System'
111 111 kwargs['suptitle'] = 'New'
112 112 kwargs['button'] = 'Create'
113 113
114 114 return render(request, 'base_edit.html', kwargs)
115 115
116 116
117 117 def location_edit(request, id_loc):
118 118
119 119 location = get_object_or_404(Location, pk=id_loc)
120 120
121 121 if request.method=='GET':
122 122 form = LocationForm(instance=location)
123 123
124 124 if request.method=='POST':
125 125 form = LocationForm(request.POST, instance=location)
126 126
127 127 if form.is_valid():
128 128 form.save()
129 129 return redirect('url_locations')
130 130
131 131 kwargs = {}
132 132 kwargs['form'] = form
133 133 kwargs['title'] = 'Location'
134 134 kwargs['suptitle'] = 'Edit'
135 135 kwargs['button'] = 'Update'
136 136
137 137 return render(request, 'base_edit.html', kwargs)
138 138
139 139
140 140 def location_delete(request, id_loc):
141 141
142 142 location = get_object_or_404(Location, pk=id_loc)
143 143
144 144 if request.method=='POST':
145 145
146 146 if request.user.is_staff:
147 147 location.delete()
148 148 return redirect('url_locations')
149 149
150 150 messages.error(request, 'Not enough permission to delete this object')
151 151 return redirect(location.get_absolute_url())
152 152
153 153 kwargs = {
154 154 'title': 'Delete',
155 155 'suptitle': 'Location',
156 156 'object': location,
157 157 'previous': location.get_absolute_url(),
158 158 'delete': True
159 159 }
160 160
161 161 return render(request, 'confirm.html', kwargs)
162 162
163 163
164 164 def devices(request):
165 165
166 166 page = request.GET.get('page')
167 167 order = ('device_type', 'name')
168 168
169 169 kwargs = get_paginator(Device, page, order)
170 170 kwargs['keys'] = ['name', 'ip_address', 'port_address', 'device_type']
171 171 kwargs['title'] = 'Device'
172 172 kwargs['suptitle'] = 'List'
173 173
174 174 return render(request, 'base_list.html', kwargs)
175 175
176 176
177 177 def device(request, id_dev):
178 178
179 179 device = get_object_or_404(Device, pk=id_dev)
180 180
181 181 kwargs = {}
182 182 kwargs['device'] = device
183 183 kwargs['device_keys'] = ['device_type', 'name', 'ip_address', 'port_address', 'description']
184 184
185 185 kwargs['title'] = 'Device'
186 186 kwargs['suptitle'] = 'Details'
187 187
188 188 return render(request, 'device.html', kwargs)
189 189
190 190
191 191 def device_new(request):
192 192
193 193 if request.method == 'GET':
194 194 form = DeviceForm()
195 195
196 196 if request.method == 'POST':
197 197 form = DeviceForm(request.POST)
198 198
199 199 if form.is_valid():
200 200 form.save()
201 201 return redirect('url_devices')
202 202
203 203 kwargs = {}
204 204 kwargs['form'] = form
205 205 kwargs['title'] = 'Device'
206 206 kwargs['suptitle'] = 'New'
207 207 kwargs['button'] = 'Create'
208 208
209 209 return render(request, 'base_edit.html', kwargs)
210 210
211 211
212 212 def device_edit(request, id_dev):
213 213
214 214 device = get_object_or_404(Device, pk=id_dev)
215 215
216 216 if request.method=='GET':
217 217 form = DeviceForm(instance=device)
218 218
219 219 if request.method=='POST':
220 220 form = DeviceForm(request.POST, instance=device)
221 221
222 222 if form.is_valid():
223 223 form.save()
224 224 return redirect(device.get_absolute_url())
225 225
226 226 kwargs = {}
227 227 kwargs['form'] = form
228 228 kwargs['title'] = 'Device'
229 229 kwargs['suptitle'] = 'Edit'
230 230 kwargs['button'] = 'Update'
231 231
232 232 return render(request, 'base_edit.html', kwargs)
233 233
234 234
235 235 def device_delete(request, id_dev):
236 236
237 237 device = get_object_or_404(Device, pk=id_dev)
238 238
239 239 if request.method=='POST':
240 240
241 241 if request.user.is_staff:
242 242 device.delete()
243 243 return redirect('url_devices')
244 244
245 245 messages.error(request, 'Not enough permission to delete this object')
246 246 return redirect(device.get_absolute_url())
247 247
248 248 kwargs = {
249 249 'title': 'Delete',
250 250 'suptitle': 'Device',
251 251 'object': device,
252 252 'previous': device.get_absolute_url(),
253 253 'delete': True
254 254 }
255 255
256 256 return render(request, 'confirm.html', kwargs)
257 257
258 258
259 259 def campaigns(request):
260 260
261 261 page = request.GET.get('page')
262 262 order = ('start_date',)
263 263 filters = request.GET.copy()
264 264
265 265 kwargs = get_paginator(Campaign, page, order, filters)
266 266
267 267 form = FilterForm(initial=request.GET, extra_fields=['range_date', 'tags','template'])
268 268 kwargs['keys'] = ['name', 'start_date', 'end_date']
269 269 kwargs['title'] = 'Campaign'
270 270 kwargs['suptitle'] = 'List'
271 271 kwargs['form'] = form
272 272 filters.pop('page', None)
273 273 kwargs['q'] = urllib.urlencode(filters)
274 274
275 275 return render(request, 'base_list.html', kwargs)
276 276
277 277
278 278 def campaign(request, id_camp):
279 279
280 280 campaign = get_object_or_404(Campaign, pk=id_camp)
281 281 experiments = Experiment.objects.filter(campaign=campaign)
282 282
283 283 form = CampaignForm(instance=campaign)
284 284
285 285 kwargs = {}
286 286 kwargs['campaign'] = campaign
287 287 kwargs['campaign_keys'] = ['template', 'name', 'start_date', 'end_date', 'tags', 'description']
288 288
289 289 kwargs['experiments'] = experiments
290 290 kwargs['experiment_keys'] = ['name', 'radar_system', 'start_time', 'end_time']
291 291
292 292 kwargs['title'] = 'Campaign'
293 293 kwargs['suptitle'] = 'Details'
294 294
295 295 kwargs['form'] = form
296 296 kwargs['button'] = 'Add Experiment'
297 297
298 298 return render(request, 'campaign.html', kwargs)
299 299
300 300
301 301 def campaign_new(request):
302 302
303 303 kwargs = {}
304 304
305 305 if request.method == 'GET':
306 306
307 307 if 'template' in request.GET:
308 308 if request.GET['template']=='0':
309 309 form = NewForm(initial={'create_from':2},
310 310 template_choices=Campaign.objects.filter(template=True).values_list('id', 'name'))
311 311 else:
312 312 kwargs['button'] = 'Create'
313 313 kwargs['experiments'] = Configuration.objects.filter(experiment=request.GET['template'])
314 314 kwargs['experiment_keys'] = ['name', 'start_time', 'end_time']
315 315 camp = Campaign.objects.get(pk=request.GET['template'])
316 316 form = CampaignForm(instance=camp,
317 317 initial={'name':'{} [{:%Y/%m/%d}]'.format(camp.name, datetime.now()),
318 318 'template':False})
319 319 elif 'blank' in request.GET:
320 320 kwargs['button'] = 'Create'
321 321 form = CampaignForm()
322 322 else:
323 323 form = NewForm()
324 324
325 325 if request.method == 'POST':
326 326 kwargs['button'] = 'Create'
327 327 post = request.POST.copy()
328 328 experiments = []
329 329
330 330 for id_exp in post.getlist('experiments'):
331 331 exp = Experiment.objects.get(pk=id_exp)
332 332 new_exp = exp.clone(template=False)
333 333 experiments.append(new_exp)
334 334
335 335 post.setlist('experiments', [])
336 336
337 337 form = CampaignForm(post)
338 338
339 339 if form.is_valid():
340 340 campaign = form.save()
341 341 for exp in experiments:
342 342 campaign.experiments.add(exp)
343 343 campaign.save()
344 344 return redirect('url_campaign', id_camp=campaign.id)
345 345
346 346 kwargs['form'] = form
347 347 kwargs['title'] = 'Campaign'
348 348 kwargs['suptitle'] = 'New'
349 349
350 350 return render(request, 'campaign_edit.html', kwargs)
351 351
352 352
353 353 def campaign_edit(request, id_camp):
354 354
355 355 campaign = get_object_or_404(Campaign, pk=id_camp)
356 356
357 357 if request.method=='GET':
358 358 form = CampaignForm(instance=campaign)
359 359
360 360 if request.method=='POST':
361 361 exps = campaign.experiments.all().values_list('pk', flat=True)
362 362 post = request.POST.copy()
363 363 new_exps = post.getlist('experiments')
364 364 post.setlist('experiments', [])
365 365 form = CampaignForm(post, instance=campaign)
366 366
367 367 if form.is_valid():
368 368 camp = form.save()
369 369 for id_exp in new_exps:
370 370 if int(id_exp) in exps:
371 371 exps.pop(id_exp)
372 372 else:
373 373 exp = Experiment.objects.get(pk=id_exp)
374 374 if exp.template:
375 375 camp.experiments.add(exp.clone(template=False))
376 376 else:
377 377 camp.experiments.add(exp)
378 378
379 379 for id_exp in exps:
380 380 camp.experiments.remove(Experiment.objects.get(pk=id_exp))
381 381
382 382 return redirect('url_campaign', id_camp=id_camp)
383 383
384 384 kwargs = {}
385 385 kwargs['form'] = form
386 386 kwargs['title'] = 'Campaign'
387 387 kwargs['suptitle'] = 'Edit'
388 388 kwargs['button'] = 'Update'
389 389
390 390 return render(request, 'campaign_edit.html', kwargs)
391 391
392 392
393 393 def campaign_delete(request, id_camp):
394 394
395 395 campaign = get_object_or_404(Campaign, pk=id_camp)
396 396
397 397 if request.method=='POST':
398 398 if request.user.is_staff:
399 399
400 400 for exp in campaign.experiments.all():
401 401 for conf in Configuration.objects.filter(experiment=exp):
402 402 conf.delete()
403 403 exp.delete()
404 404 campaign.delete()
405 405
406 406 return redirect('url_campaigns')
407 407
408 408 messages.error(request, 'Not enough permission to delete this object')
409 409 return redirect(campaign.get_absolute_url())
410 410
411 411 kwargs = {
412 412 'title': 'Delete',
413 413 'suptitle': 'Campaign',
414 414 'object': campaign,
415 415 'previous': campaign.get_absolute_url(),
416 416 'delete': True
417 417 }
418 418
419 419 return render(request, 'confirm.html', kwargs)
420 420
421 421 def campaign_export(request, id_camp):
422 422
423 423 campaign = get_object_or_404(Campaign, pk=id_camp)
424 424 content = campaign.parms_to_dict()
425 425 content_type = 'application/json'
426 426 filename = '%s_%s.json' %(campaign.name, campaign.id)
427 427
428 428 response = HttpResponse(content_type=content_type)
429 429 response['Content-Disposition'] = 'attachment; filename="%s"' %filename
430 430 response.write(content)
431 431
432 432 return response
433 433
434 434
435 435 def campaign_import(request, id_camp):
436 436
437 437 campaign = get_object_or_404(Campaign, pk=id_camp)
438 438
439 439 if request.method == 'GET':
440 440 file_form = UploadFileForm()
441 441
442 442 if request.method == 'POST':
443 443 file_form = UploadFileForm(request.POST, request.FILES)
444 444
445 445 if file_form.is_valid():
446 446
447 447 parms = campaign.import_from_file(request.FILES['file'])
448 448
449 449 if parms:
450 450 parms['name'] = parms['campaign']
451 451
452 452 new_camp = campaign.dict_to_parms(parms, CONF_MODELS)
453 453
454 454 messages.success(request, "Parameters imported from: '%s'." %request.FILES['file'].name)
455 455
456 456 return redirect(new_camp.get_absolute_url_edit())
457 457
458 458 messages.error(request, "Could not import parameters from file")
459 459
460 460 kwargs = {}
461 461 kwargs['title'] = 'Campaign'
462 462 kwargs['form'] = file_form
463 463 kwargs['suptitle'] = 'Importing file'
464 464 kwargs['button'] = 'Import'
465 465
466 466 return render(request, 'campaign_import.html', kwargs)
467 467
468 468
469 469 def experiments(request):
470 470
471 471 page = request.GET.get('page')
472 472 order = ('location',)
473 473 filters = request.GET.copy()
474 474
475 475 kwargs = get_paginator(Experiment, page, order, filters)
476 476
477 477 form = FilterForm(initial=request.GET, extra_fields=['tags','template'])
478 478
479 479 kwargs['keys'] = ['name', 'radar_system', 'start_time', 'end_time']
480 480 kwargs['title'] = 'Experiment'
481 481 kwargs['suptitle'] = 'List'
482 482 kwargs['form'] = form
483 483 filters.pop('page', None)
484 484 kwargs['q'] = urllib.urlencode(filters)
485 485
486 486 return render(request, 'base_list.html', kwargs)
487 487
488 488
489 489 def experiment(request, id_exp):
490 490
491 491 experiment = get_object_or_404(Experiment, pk=id_exp)
492 492
493 493 configurations = Configuration.objects.filter(experiment=experiment, type=0)
494 494
495 495 kwargs = {}
496 496
497 497 kwargs['experiment_keys'] = ['template', 'radar_system', 'name', 'start_time', 'end_time']
498 498 kwargs['experiment'] = experiment
499 499
500 500 kwargs['configuration_keys'] = ['name', 'device__ip_address', 'device__port_address', 'device__status']
501 501 kwargs['configurations'] = configurations
502 502
503 503 kwargs['title'] = 'Experiment'
504 504 kwargs['suptitle'] = 'Details'
505 505
506 506 kwargs['button'] = 'Add Configuration'
507 507
508 508 ###### SIDEBAR ######
509 509 kwargs.update(sidebar(experiment=experiment))
510 510
511 511 return render(request, 'experiment.html', kwargs)
512 512
513 513
514 514 def experiment_new(request, id_camp=None):
515 515
516 516 kwargs = {}
517 517
518 518 if request.method == 'GET':
519 519 if 'template' in request.GET:
520 520 if request.GET['template']=='0':
521 521 form = NewForm(initial={'create_from':2},
522 522 template_choices=Experiment.objects.filter(template=True).values_list('id', 'name'))
523 523 else:
524 524 kwargs['button'] = 'Create'
525 525 kwargs['configurations'] = Configuration.objects.filter(experiment=request.GET['template'])
526 526 kwargs['configuration_keys'] = ['name', 'device__name', 'device__ip_address', 'device__port_address']
527 527 exp=Experiment.objects.get(pk=request.GET['template'])
528 528 form = ExperimentForm(instance=exp,
529 529 initial={'name': '{} [{:%Y/%m/%d}]'.format(exp.name, datetime.now()),
530 530 'template': False})
531 531 elif 'blank' in request.GET:
532 532 kwargs['button'] = 'Create'
533 533 form = ExperimentForm()
534 534 else:
535 535 form = NewForm()
536 536
537 537 if request.method == 'POST':
538 538 form = ExperimentForm(request.POST)
539 539 print form.data
540 540 if form.is_valid():
541 541 experiment = form.save()
542 542
543 543 if 'template' in request.GET:
544 544 configurations = Configuration.objects.filter(experiment=request.GET['template'], type=0)
545 545 for conf in configurations:
546 546 conf.clone(experiment=experiment, template=False)
547 547
548 548 return redirect('url_experiment', id_exp=experiment.id)
549 549
550 550 kwargs['form'] = form
551 551 kwargs['title'] = 'Experiment'
552 552 kwargs['suptitle'] = 'New'
553 553
554 554 return render(request, 'experiment_edit.html', kwargs)
555 555
556 556
557 557 def experiment_edit(request, id_exp):
558 558
559 559 experiment = get_object_or_404(Experiment, pk=id_exp)
560 560
561 561 if request.method == 'GET':
562 562 form = ExperimentForm(instance=experiment)
563 563
564 564 if request.method=='POST':
565 565 form = ExperimentForm(request.POST, instance=experiment)
566 566
567 567 if form.is_valid():
568 568 experiment = form.save()
569 569 return redirect('url_experiment', id_exp=experiment.id)
570 570
571 571 kwargs = {}
572 572 kwargs['form'] = form
573 573 kwargs['title'] = 'Experiment'
574 574 kwargs['suptitle'] = 'Edit'
575 575 kwargs['button'] = 'Update'
576 576
577 577 return render(request, 'experiment_edit.html', kwargs)
578 578
579 579
580 580 def experiment_delete(request, id_exp):
581 581
582 582 experiment = get_object_or_404(Experiment, pk=id_exp)
583 583
584 584 if request.method=='POST':
585 585 if request.user.is_staff:
586 586 for conf in Configuration.objects.filter(experiment=experiment):
587 587 conf.delete()
588 588 experiment.delete()
589 589 return redirect('url_experiments')
590 590
591 591 messages.error(request, 'Not enough permission to delete this object')
592 592 return redirect(experiment.get_absolute_url())
593 593
594 594 kwargs = {
595 595 'title': 'Delete',
596 596 'suptitle': 'Experiment',
597 597 'object': experiment,
598 598 'previous': experiment.get_absolute_url(),
599 599 'delete': True
600 600 }
601 601
602 602 return render(request, 'confirm.html', kwargs)
603 603
604 604
605 605 def experiment_export(request, id_exp):
606 606
607 607 experiment = get_object_or_404(Experiment, pk=id_exp)
608 608 content = experiment.parms_to_dict()
609 609 content_type = 'application/json'
610 610 filename = '%s_%s.json' %(experiment.name, experiment.id)
611 611
612 612 response = HttpResponse(content_type=content_type)
613 613 response['Content-Disposition'] = 'attachment; filename="%s"' %filename
614 614 response.write(content)
615 615
616 616 return response
617 617
618 618 def experiment_import(request, id_exp):
619 619
620 620 experiment = get_object_or_404(Experiment, pk=id_exp)
621 621 configurations = Configuration.objects.filter(experiment=experiment)
622 622
623 623 if request.method == 'GET':
624 624 file_form = UploadFileForm()
625 625
626 626 if request.method == 'POST':
627 627 file_form = UploadFileForm(request.POST, request.FILES)
628 628
629 629 if file_form.is_valid():
630 630
631 631 parms = experiment.import_from_file(request.FILES['file'])
632 632
633 633 if parms:
634 634
635 635 new_exp = experiment.dict_to_parms(parms, CONF_MODELS)
636 636
637 637 messages.success(request, "Parameters imported from: '%s'." %request.FILES['file'].name)
638 638
639 639 return redirect(new_exp.get_absolute_url_edit())
640 640
641 641 messages.error(request, "Could not import parameters from file")
642 642
643 643 kwargs = {}
644 644 kwargs['title'] = 'Experiment'
645 645 kwargs['form'] = file_form
646 646 kwargs['suptitle'] = 'Importing file'
647 647 kwargs['button'] = 'Import'
648 648
649 649 kwargs.update(sidebar(experiment=experiment))
650 650
651 651 return render(request, 'experiment_import.html', kwargs)
652 652
653 653 def experiment_mix(request, id_exp):
654 654
655 655 experiment = get_object_or_404(Experiment, pk=id_exp)
656 656 rc_confs = [conf for conf in RCConfiguration.objects.filter(experiment=id_exp,
657 657 mix=False)]
658 658
659 659 if len(rc_confs)<2:
660 660 messages.warning(request, 'You need at least two RC Configurations to make a mix')
661 661 return redirect(experiment.get_absolute_url())
662 662
663 663 mix_confs = RCConfiguration.objects.filter(experiment=id_exp, mix=True)
664 664
665 665 if mix_confs:
666 666 mix = mix_confs[0]
667 667 else:
668 668 mix = RCConfiguration(experiment=experiment,
669 669 device=rc_confs[0].device,
670 670 ipp=rc_confs[0].ipp,
671 671 clock_in=rc_confs[0].clock_in,
672 672 clock_divider=rc_confs[0].clock_divider,
673 673 mix=True,
674 674 parameters='')
675 675 mix.save()
676 676
677 677 line_type = RCLineType.objects.get(name='mix')
678 678 for i in range(len(rc_confs[0].get_lines())):
679 679 line = RCLine(rc_configuration=mix, line_type=line_type, channel=i)
680 680 line.save()
681 681
682 682 initial = {'name': mix.name,
683 683 'result': parse_mix_result(mix.parameters),
684 684 'delay': 0,
685 685 'mask': [0,1,2,3,4,5,6,7]
686 686 }
687 687
688 688 if request.method=='GET':
689 689 form = RCMixConfigurationForm(confs=rc_confs, initial=initial)
690 690
691 691 if request.method=='POST':
692 692 result = mix.parameters
693 693
694 694 if '{}|'.format(request.POST['experiment']) in result:
695 695 messages.error(request, 'Configuration already added')
696 696 else:
697 697 if 'operation' in request.POST:
698 698 operation = MIX_OPERATIONS[request.POST['operation']]
699 699 else:
700 700 operation = ' '
701 701
702 702 mode = MIX_MODES[request.POST['mode']]
703 703
704 704 if result:
705 705 result = '{}-{}|{}|{}|{}|{}'.format(mix.parameters,
706 706 request.POST['experiment'],
707 707 mode,
708 708 operation,
709 709 float(request.POST['delay']),
710 710 parse_mask(request.POST.getlist('mask'))
711 711 )
712 712 else:
713 713 result = '{}|{}|{}|{}|{}'.format(request.POST['experiment'],
714 714 mode,
715 715 operation,
716 716 float(request.POST['delay']),
717 717 parse_mask(request.POST.getlist('mask'))
718 718 )
719 719
720 720 mix.parameters = result
721 721 mix.name = request.POST['name']
722 722 mix.save()
723 723 mix.update_pulses()
724 724
725 725 initial['result'] = parse_mix_result(result)
726 726 initial['name'] = mix.name
727 727
728 728 form = RCMixConfigurationForm(initial=initial, confs=rc_confs)
729 729
730 730
731 731 kwargs = {
732 732 'title': 'Experiment',
733 733 'suptitle': 'Mix Configurations',
734 734 'form' : form,
735 735 'extra_button': 'Delete',
736 736 'button': 'Add',
737 737 'cancel': 'Back',
738 738 'previous': experiment.get_absolute_url(),
739 739 'id_exp':id_exp,
740 740
741 741 }
742 742
743 743 return render(request, 'experiment_mix.html', kwargs)
744 744
745 745
746 746 def experiment_mix_delete(request, id_exp):
747 747
748 748 conf = RCConfiguration.objects.get(experiment=id_exp, mix=True)
749 749 values = conf.parameters.split('-')
750 750 conf.parameters = '-'.join(values[:-1])
751 751 conf.save()
752 752
753 753 return redirect('url_mix_experiment', id_exp=id_exp)
754 754
755 755
756 def experiment_summary(request, id_exp):
757
758 import json
759
760 experiment = get_object_or_404(Experiment, pk=id_exp)
761 experiment_data = json.loads(experiment.parms_to_dict())
762 configurations = Configuration.objects.filter(experiment=experiment, type=0)
763
764 kwargs = {}
765
766 kwargs['experiment_keys'] = ['template', 'radar_system', 'name', 'start_time', 'end_time']
767 kwargs['experiment'] = experiment
768
769 kwargs['configuration_keys'] = ['name', 'device__ip_address', 'device__port_address', 'device__status']
770 kwargs['configurations'] = configurations
771 kwargs['experiment_data'] = experiment_data
772
773 kwargs['title'] = 'Experiment Summary'
774 kwargs['suptitle'] = 'Details'
775
776 kwargs['button'] = 'Verify Parameters'
777
778 for configuration in configurations:
779 if configuration.device.device_type.name == 'jars':
780 kwargs['exp_type'] = EXPERIMENT_TYPE[configuration.exp_type][1]
781
782 if configuration.device.device_type.name == 'rc':
783 rc_lines = experiment_data['configurations']['rc']['lines']
784 code = rc_lines[3]['code']
785
786 window_data = rc_lines[6]['params'][0]
787 h0 = str(window_data['first_height'])
788 dh = str(window_data['resolution'])
789 nsa = str(window_data['number_of_samples'])
790 window = 'Ho='+h0+'km\nDH='+dh+'km\nNSA='+nsa
791
792 tx = ''
793 if float(rc_lines[1]['delays']) == 0:
794 tx = rc_lines[2]['pulse_width']
795 elif float(rc_lines[2]['delays']) == 0:
796 tx = rc_lines[1]['pulse_width']
797 else:
798 tx = rc_lines[1]['pulse_width']+' | '+rc_lines[2]['pulse_width']
799
800 kwargs['tx'] = tx
801 kwargs['code'] = code
802 kwargs['window'] = window
803
804 ###### SIDEBAR ######
805 kwargs.update(sidebar(experiment=experiment))
806
807 return render(request, 'experiment_summary.html', kwargs)
808
809
756 810 def parse_mix_result(s):
757 811
758 812 values = s.split('-')
759 813 html = 'EXP MOD OPE DELAY MASK\r\n'
760 814
761 815 if not values or values[0] in ('', ' '):
762 816 return mark_safe(html)
763 817
764 818 for i, value in enumerate(values):
765 819 if not value:
766 820 continue
767 821 pk, mode, operation, delay, mask = value.split('|')
768 822 conf = RCConfiguration.objects.get(pk=pk)
769 823 if i==0:
770 824 html += '{:20.18}{:3}{:4}{:9}km{:>6}\r\n'.format(
771 825 conf.name,
772 826 mode,
773 827 ' ',
774 828 delay,
775 829 mask)
776 830 else:
777 831 html += '{:20.18}{:3}{:4}{:9}km{:>6}\r\n'.format(
778 832 conf.name,
779 833 mode,
780 834 operation,
781 835 delay,
782 836 mask)
783 837
784 838 return mark_safe(html)
785 839
786 840 def parse_mask(l):
787 841
788 842 values = []
789 843
790 844 for x in range(8):
791 845 if '{}'.format(x) in l:
792 846 values.append(1)
793 847 else:
794 848 values.append(0)
795 849
796 850 values.reverse()
797 851
798 852 return int(''.join([str(x) for x in values]), 2)
799 853
800 854
801 855 def dev_confs(request):
802 856
803 857
804 858 page = request.GET.get('page')
805 859 order = ('type', 'device__device_type', 'experiment')
806 860 filters = request.GET.copy()
807 861
808 862 kwargs = get_paginator(Configuration, page, order, filters)
809 863
810 864 form = FilterForm(initial=request.GET, extra_fields=['tags','template'])
811 865 kwargs['keys'] = ['name', 'experiment', 'type', 'programmed_date']
812 866 kwargs['title'] = 'Configuration'
813 867 kwargs['suptitle'] = 'List'
814 868 kwargs['form'] = form
815 869 filters.pop('page', None)
816 870 kwargs['q'] = urllib.urlencode(filters)
817 871
818 872 return render(request, 'base_list.html', kwargs)
819 873
820 874
821 875 def dev_conf(request, id_conf):
822 876
823 877 conf = get_object_or_404(Configuration, pk=id_conf)
824 878
825 879 return redirect(conf.get_absolute_url())
826 880
827 881
828 882 def dev_conf_new(request, id_exp=0, id_dev=0):
829 883
830 884 initial = {}
831 885 kwargs = {}
832 886
833 887 if id_exp<>0:
834 888 initial['experiment'] = id_exp
835 889
836 890 if id_dev<>0:
837 891 initial['device'] = id_dev
838 892
839 893 if request.method == 'GET':
840 894
841 895 if id_dev:
842 896 kwargs['button'] = 'Create'
843 897 device = Device.objects.get(pk=id_dev)
844 898 DevConfForm = CONF_FORMS[device.device_type.name]
845 899 initial['name'] = request.GET['name']
846 900 form = DevConfForm(initial=initial)
847 901 else:
848 902 if 'template' in request.GET:
849 903 if request.GET['template']=='0':
850 904 choices = [(conf.pk, '{}'.format(conf)) for conf in Configuration.objects.filter(template=True)]
851 905 form = NewForm(initial={'create_from':2},
852 906 template_choices=choices)
853 907 else:
854 908 kwargs['button'] = 'Create'
855 909 conf = Configuration.objects.get(pk=request.GET['template'])
856 910 id_dev = conf.device.pk
857 911 DevConfForm = CONF_FORMS[conf.device.device_type.name]
858 912 form = DevConfForm(instance=conf,
859 913 initial={'name': '{} [{:%Y/%m/%d}]'.format(conf.name, datetime.now()),
860 914 'template': False,
861 915 'experiment':id_exp})
862 916 elif 'blank' in request.GET:
863 917 kwargs['button'] = 'Create'
864 918 form = ConfigurationForm(initial=initial)
865 919 else:
866 920 form = NewForm()
867 921
868 922 if request.method == 'POST':
869 923
870 924 device = Device.objects.get(pk=request.POST['device'])
871 925 DevConfForm = CONF_FORMS[device.device_type.name]
872 926
873 927 form = DevConfForm(request.POST)
874 928 kwargs['button'] = 'Create'
875 929 if form.is_valid():
876 930 conf = form.save()
877 931
878 932 if 'template' in request.GET and conf.device.device_type.name=='rc':
879 933 lines = RCLine.objects.filter(rc_configuration=request.GET['template'])
880 934 for line in lines:
881 935 line.clone(rc_configuration=conf)
882 936
883 937 if conf.device.device_type.name=='jars':
884 938 conf.add_parms_to_filter()
885 939
886 940 return redirect('url_dev_conf', id_conf=conf.pk)
887 941
888 942 kwargs['id_exp'] = id_exp
889 943 kwargs['form'] = form
890 944 kwargs['title'] = 'Configuration'
891 945 kwargs['suptitle'] = 'New'
892 946
893 947
894 948 if id_dev != 0:
895 949 device = Device.objects.get(pk=id_dev)
896 950 kwargs['device'] = device.device_type.name
897 951
898 952 return render(request, 'dev_conf_edit.html', kwargs)
899 953
900 954
901 955 def dev_conf_edit(request, id_conf):
902 956
903 957 conf = get_object_or_404(Configuration, pk=id_conf)
904 958
905 959 DevConfModel = CONF_MODELS[conf.device.device_type.name]
906 960 DevConfForm = CONF_FORMS[conf.device.device_type.name]
907 961
908 962 dev_conf = DevConfModel.objects.get(pk=id_conf)
909 963
910 964 if request.method=='GET':
911 965 form = DevConfForm(instance=dev_conf)
912 966
913 967 if request.method=='POST':
914 968 form = DevConfForm(request.POST, instance=dev_conf)
915 969
916 970 if form.is_valid():
917 971 form.save()
918 972 return redirect('url_dev_conf', id_conf=id_conf)
919 973
920 974 kwargs = {}
921 975 kwargs['form'] = form
922 976 kwargs['title'] = 'Device Configuration'
923 977 kwargs['suptitle'] = 'Edit'
924 978 kwargs['button'] = 'Update'
925 979
926 980 ###### SIDEBAR ######
927 981 kwargs.update(sidebar(conf=conf))
928 982
929 983 return render(request, '%s_conf_edit.html' % conf.device.device_type.name, kwargs)
930 984
931 985
932 986 def dev_conf_start(request, id_conf):
933 987
934 988 conf = get_object_or_404(Configuration, pk=id_conf)
935 989
936 990 DevConfModel = CONF_MODELS[conf.device.device_type.name]
937 991
938 992 conf = DevConfModel.objects.get(pk=id_conf)
939 993
940 994 if conf.start_device():
941 995 messages.success(request, conf.message)
942 996 else:
943 997 messages.error(request, conf.message)
944 998
945 999 conf.status_device()
946 1000
947 1001 return redirect(conf.get_absolute_url())
948 1002
949 1003
950 1004 def dev_conf_stop(request, id_conf):
951 1005
952 1006 conf = get_object_or_404(Configuration, pk=id_conf)
953 1007
954 1008 DevConfModel = CONF_MODELS[conf.device.device_type.name]
955 1009
956 1010 conf = DevConfModel.objects.get(pk=id_conf)
957 1011
958 1012 if conf.stop_device():
959 1013 messages.success(request, conf.message)
960 1014 else:
961 1015 messages.error(request, conf.message)
962 1016
963 1017 conf.status_device()
964 1018
965 1019 return redirect(conf.get_absolute_url())
966 1020
967 1021
968 1022 def dev_conf_status(request, id_conf):
969 1023
970 1024 conf = get_object_or_404(Configuration, pk=id_conf)
971 1025
972 1026 DevConfModel = CONF_MODELS[conf.device.device_type.name]
973 1027
974 1028 conf = DevConfModel.objects.get(pk=id_conf)
975 1029
976 1030 if conf.status_device():
977 1031 messages.success(request, conf.message)
978 1032 else:
979 1033 messages.error(request, conf.message)
980 1034
981 1035 return redirect(conf.get_absolute_url())
982 1036
983 1037
984 1038 def dev_conf_write(request, id_conf):
985 1039
986 1040 conf = get_object_or_404(Configuration, pk=id_conf)
987 1041
988 1042 DevConfModel = CONF_MODELS[conf.device.device_type.name]
989 1043
990 1044 conf = DevConfModel.objects.get(pk=id_conf)
991 1045
992 1046 answer = conf.write_device()
993 1047 conf.status_device()
994 1048
995 1049 if answer:
996 1050 messages.success(request, conf.message)
997 1051
998 1052 #Creating a historical configuration
999 1053 conf.clone(type=0, template=False)
1000 1054
1001 1055 #Original configuration
1002 1056 conf = DevConfModel.objects.get(pk=id_conf)
1003 1057 else:
1004 1058 messages.error(request, conf.message)
1005 1059
1006 1060 return redirect(conf.get_absolute_url())
1007 1061
1008 1062
1009 1063 def dev_conf_read(request, id_conf):
1010 1064
1011 1065 conf = get_object_or_404(Configuration, pk=id_conf)
1012 1066
1013 1067 DevConfModel = CONF_MODELS[conf.device.device_type.name]
1014 1068 DevConfForm = CONF_FORMS[conf.device.device_type.name]
1015 1069
1016 1070 conf = DevConfModel.objects.get(pk=id_conf)
1017 1071
1018 1072 if request.method=='GET':
1019 1073
1020 1074 parms = conf.read_device()
1021 1075 conf.status_device()
1022 1076
1023 1077 if not parms:
1024 1078 messages.error(request, conf.message)
1025 1079 return redirect(conf.get_absolute_url())
1026 1080
1027 1081 form = DevConfForm(initial=parms, instance=conf)
1028 1082
1029 1083 if request.method=='POST':
1030 1084 form = DevConfForm(request.POST, instance=conf)
1031 1085
1032 1086 if form.is_valid():
1033 1087 form.save()
1034 1088 return redirect(conf.get_absolute_url())
1035 1089
1036 1090 messages.error(request, "Parameters could not be saved")
1037 1091
1038 1092 kwargs = {}
1039 1093 kwargs['id_dev'] = conf.id
1040 1094 kwargs['form'] = form
1041 1095 kwargs['title'] = 'Device Configuration'
1042 1096 kwargs['suptitle'] = 'Parameters read from device'
1043 1097 kwargs['button'] = 'Save'
1044 1098
1045 1099 ###### SIDEBAR ######
1046 1100 kwargs.update(sidebar(conf=conf))
1047 1101
1048 1102 return render(request, '%s_conf_edit.html' %conf.device.device_type.name, kwargs)
1049 1103
1050 1104
1051 1105 def dev_conf_import(request, id_conf):
1052 1106
1053 1107 conf = get_object_or_404(Configuration, pk=id_conf)
1054 1108
1055 1109 DevConfModel = CONF_MODELS[conf.device.device_type.name]
1056 1110 DevConfForm = CONF_FORMS[conf.device.device_type.name]
1057 1111 conf = DevConfModel.objects.get(pk=id_conf)
1058 1112
1059 1113 if request.method == 'GET':
1060 1114 file_form = UploadFileForm()
1061 1115
1062 1116 if request.method == 'POST':
1063 1117 file_form = UploadFileForm(request.POST, request.FILES)
1064 1118
1065 1119 if file_form.is_valid():
1066 1120
1067 1121 parms = conf.import_from_file(request.FILES['file'])
1068 1122
1069 1123 if parms:
1070 1124 messages.success(request, "Parameters imported from: '%s'." %request.FILES['file'].name)
1071 1125 form = DevConfForm(initial=parms, instance=conf)
1072 1126
1073 1127 kwargs = {}
1074 1128 kwargs['id_dev'] = conf.id
1075 1129 kwargs['form'] = form
1076 1130 kwargs['title'] = 'Device Configuration'
1077 1131 kwargs['suptitle'] = 'Parameters imported'
1078 1132 kwargs['button'] = 'Save'
1079 1133 kwargs['action'] = conf.get_absolute_url_edit()
1080 1134 kwargs['previous'] = conf.get_absolute_url()
1081 1135
1082 1136 ###### SIDEBAR ######
1083 1137 kwargs.update(sidebar(conf=conf))
1084 1138
1085 1139 return render(request, '%s_conf_edit.html' % conf.device.device_type.name, kwargs)
1086 1140
1087 1141 messages.error(request, "Could not import parameters from file")
1088 1142
1089 1143 kwargs = {}
1090 1144 kwargs['id_dev'] = conf.id
1091 1145 kwargs['title'] = 'Device Configuration'
1092 1146 kwargs['form'] = file_form
1093 1147 kwargs['suptitle'] = 'Importing file'
1094 1148 kwargs['button'] = 'Import'
1095 1149
1096 1150 kwargs.update(sidebar(conf=conf))
1097 1151
1098 1152 return render(request, 'dev_conf_import.html', kwargs)
1099 1153
1100 1154
1101 1155 def dev_conf_export(request, id_conf):
1102 1156
1103 1157 conf = get_object_or_404(Configuration, pk=id_conf)
1104 1158
1105 1159 DevConfModel = CONF_MODELS[conf.device.device_type.name]
1106 1160
1107 1161 conf = DevConfModel.objects.get(pk=id_conf)
1108 1162
1109 1163 if request.method == 'GET':
1110 1164 file_form = DownloadFileForm(conf.device.device_type.name)
1111 1165
1112 1166 if request.method == 'POST':
1113 1167 file_form = DownloadFileForm(conf.device.device_type.name, request.POST)
1114 1168
1115 1169 if file_form.is_valid():
1116 1170 fields = conf.export_to_file(format = file_form.cleaned_data['format'])
1117 1171
1118 1172 response = HttpResponse(content_type=fields['content_type'])
1119 1173 response['Content-Disposition'] = 'attachment; filename="%s"' %fields['filename']
1120 1174 response.write(fields['content'])
1121 1175
1122 1176 return response
1123 1177
1124 1178 messages.error(request, "Could not export parameters")
1125 1179
1126 1180 kwargs = {}
1127 1181 kwargs['id_dev'] = conf.id
1128 1182 kwargs['title'] = 'Device Configuration'
1129 1183 kwargs['form'] = file_form
1130 1184 kwargs['suptitle'] = 'Exporting file'
1131 1185 kwargs['button'] = 'Export'
1132 1186
1133 1187 return render(request, 'dev_conf_export.html', kwargs)
1134 1188
1135 1189
1136 1190 def dev_conf_delete(request, id_conf):
1137 1191
1138 1192 conf = get_object_or_404(Configuration, pk=id_conf)
1139 1193
1140 1194 if request.method=='POST':
1141 1195 if request.user.is_staff:
1142 1196 conf.delete()
1143 1197 return redirect('url_dev_confs')
1144 1198
1145 1199 messages.error(request, 'Not enough permission to delete this object')
1146 1200 return redirect(conf.get_absolute_url())
1147 1201
1148 1202 kwargs = {
1149 1203 'title': 'Delete',
1150 1204 'suptitle': 'Experiment',
1151 1205 'object': conf,
1152 1206 'previous': conf.get_absolute_url(),
1153 1207 'delete': True
1154 1208 }
1155 1209
1156 1210 return render(request, 'confirm.html', kwargs)
1157 1211
1158 1212
1159 1213 def sidebar(**kwargs):
1160 1214
1161 1215 side_data = {}
1162 1216
1163 1217 conf = kwargs.get('conf', None)
1164 1218 experiment = kwargs.get('experiment', None)
1165 1219
1166 1220 if not experiment:
1167 1221 experiment = conf.experiment
1168 1222
1169 1223 if experiment:
1170 1224 side_data['experiment'] = experiment
1171 1225 campaign = experiment.campaign_set.all()
1172 1226 if campaign:
1173 1227 side_data['campaign'] = campaign[0]
1174 1228 experiments = campaign[0].experiments.all()
1175 1229 else:
1176 1230 experiments = [experiment]
1177 1231 configurations = experiment.configuration_set.filter(type=0)
1178 1232 side_data['side_experiments'] = experiments
1179 1233 side_data['side_configurations'] = configurations
1180 1234
1181 1235 return side_data
1182 1236
1183 1237 def get_paginator(model, page, order, filters={}, n=10):
1184 1238
1185 1239 kwargs = {}
1186 1240 query = Q()
1187 1241 if isinstance(filters, QueryDict):
1188 1242 filters = filters.dict()
1189 1243 [filters.pop(key) for key in filters.keys() if filters[key] in ('', ' ')]
1190 1244 filters.pop('page', None)
1191 1245
1192 1246 if 'start_date' in filters:
1193 1247 filters['start_date__gte'] = filters.pop('start_date')
1194 1248 if 'end_date' in filters:
1195 1249 filters['start_date__lte'] = filters.pop('end_date')
1196 1250 if 'tags' in filters:
1197 1251 tags = filters.pop('tags')
1198 1252 if 'tags' in model._meta.get_all_field_names():
1199 1253 query = query | Q(tags__icontains=tags)
1200 1254 if 'name' in model._meta.get_all_field_names():
1201 1255 query = query | Q(name__icontains=tags)
1202 1256 if 'location' in model._meta.get_all_field_names():
1203 1257 query = query | Q(location__name__icontains=tags)
1204 1258 if 'device' in model._meta.get_all_field_names():
1205 1259 query = query | Q(device__name__icontains=tags)
1206 1260
1207 1261 object_list = model.objects.filter(query, **filters).order_by(*order)
1208 1262 paginator = Paginator(object_list, n)
1209 1263
1210 1264 try:
1211 1265 objects = paginator.page(page)
1212 1266 except PageNotAnInteger:
1213 1267 objects = paginator.page(1)
1214 1268 except EmptyPage:
1215 1269 objects = paginator.page(paginator.num_pages)
1216 1270
1217 1271 kwargs['objects'] = objects
1218 1272 kwargs['offset'] = (int(page)-1)*n if page else 0
1219 1273
1220 1274 return kwargs
1221 1275
1222 1276 def operation(request, id_camp=None):
1223 1277
1224 1278 if not id_camp:
1225 1279 campaigns = Campaign.objects.all().order_by('-start_date')
1226 1280
1227 1281 if not campaigns:
1228 1282 kwargs = {}
1229 1283 kwargs['title'] = 'No Campaigns'
1230 1284 kwargs['suptitle'] = 'Empty'
1231 1285 return render(request, 'operation.html', kwargs)
1232 1286
1233 1287 id_camp = campaigns[0].id
1234 1288
1235 1289 campaign = get_object_or_404(Campaign, pk = id_camp)
1236 1290
1237 1291 if request.method=='GET':
1238 1292 form = OperationForm(initial={'campaign': campaign.id}, length = 5)
1239 1293
1240 1294 if request.method=='POST':
1241 1295 form = OperationForm(request.POST, initial={'campaign':campaign.id}, length = 5)
1242 1296
1243 1297 if form.is_valid():
1244 1298 return redirect('url_operation', id_camp=campaign.id)
1245 1299 #locations = Location.objects.filter(experiment__campaign__pk = campaign.id).distinct()
1246 1300 experiments = Experiment.objects.filter(campaign__pk=campaign.id)
1247 1301 #for exs in experiments:
1248 1302 # exs.get_status()
1249 1303 locations= Location.objects.filter(experiment=experiments).distinct()
1250 1304 #experiments = [Experiment.objects.filter(location__pk=location.id).filter(campaign__pk=campaign.id) for location in locations]
1251 1305 kwargs = {}
1252 1306 #---Campaign
1253 1307 kwargs['campaign'] = campaign
1254 1308 kwargs['campaign_keys'] = ['name', 'start_date', 'end_date', 'tags', 'description']
1255 1309 #---Experiment
1256 1310 keys = ['id', 'name', 'start_time', 'end_time', 'status']
1257 1311 kwargs['experiment_keys'] = keys[1:]
1258 1312 kwargs['experiments'] = experiments
1259 1313 #---Radar
1260 1314 kwargs['locations'] = locations
1261 1315 #---Else
1262 1316 kwargs['title'] = 'Campaign'
1263 1317 kwargs['suptitle'] = campaign.name
1264 1318 kwargs['form'] = form
1265 1319 kwargs['button'] = 'Search'
1266 1320 kwargs['details'] = True
1267 1321 kwargs['search_button'] = True
1268 1322
1269 1323 return render(request, 'operation.html', kwargs)
1270 1324
1271 1325
1272 1326 def operation_search(request, id_camp=None):
1273 1327
1274 1328
1275 1329 if not id_camp:
1276 1330 campaigns = Campaign.objects.all().order_by('-start_date')
1277 1331
1278 1332 if not campaigns:
1279 1333 return render(request, 'operation.html', {})
1280 1334
1281 1335 id_camp = campaigns[0].id
1282 1336 campaign = get_object_or_404(Campaign, pk = id_camp)
1283 1337
1284 1338 if request.method=='GET':
1285 1339 form = OperationSearchForm(initial={'campaign': campaign.id})
1286 1340
1287 1341 if request.method=='POST':
1288 1342 form = OperationSearchForm(request.POST, initial={'campaign':campaign.id})
1289 1343
1290 1344 if form.is_valid():
1291 1345 return redirect('url_operation', id_camp=campaign.id)
1292 1346
1293 1347 #locations = Location.objects.filter(experiment__campaign__pk = campaign.id).distinct()
1294 1348 experiments = Experiment.objects.filter(campaign__pk=campaign.id)
1295 1349 #for exs in experiments:
1296 1350 # exs.get_status()
1297 1351 locations= Location.objects.filter(experiment=experiments).distinct()
1298 1352 form = OperationSearchForm(initial={'campaign': campaign.id})
1299 1353
1300 1354 kwargs = {}
1301 1355 #---Campaign
1302 1356 kwargs['campaign'] = campaign
1303 1357 kwargs['campaign_keys'] = ['name', 'start_date', 'end_date', 'tags', 'description']
1304 1358 #---Experiment
1305 1359 keys = ['id', 'name', 'start_time', 'end_time', 'status']
1306 1360 kwargs['experiment_keys'] = keys[1:]
1307 1361 kwargs['experiments'] = experiments
1308 1362 #---Radar
1309 1363 kwargs['locations'] = locations
1310 1364 #---Else
1311 1365 kwargs['title'] = 'Campaign'
1312 1366 kwargs['suptitle'] = campaign.name
1313 1367 kwargs['form'] = form
1314 1368 kwargs['button'] = 'Select'
1315 1369 kwargs['details'] = True
1316 1370 kwargs['search_button'] = False
1317 1371
1318 1372 return render(request, 'operation.html', kwargs)
1319 1373
1320 1374
1321 1375 def radar_play(request, id_camp, id_radar):
1322 1376 campaign = get_object_or_404(Campaign, pk = id_camp)
1323 1377 radar = get_object_or_404(Location, pk = id_radar)
1324 1378 today = datetime.today()
1325 1379 now = today.time()
1326 1380
1327 1381 #--Clear Old Experiments From RunningExperiment Object
1328 1382 running_experiment = RunningExperiment.objects.filter(radar=radar)
1329 1383 if running_experiment:
1330 1384 running_experiment = running_experiment[0]
1331 1385 running_experiment.running_experiment.clear()
1332 1386 running_experiment.save()
1333 1387
1334 1388 #--If campaign datetime is ok:
1335 1389 if today >= campaign.start_date and today <= campaign.end_date:
1336 1390 experiments = Experiment.objects.filter(campaign=campaign).filter(location=radar)
1337 1391 for exp in experiments:
1338 1392 #--If experiment time is ok:
1339 1393 if now >= exp.start_time and now <= exp.end_time:
1340 1394 configurations = Configuration.objects.filter(experiment = exp)
1341 1395 for conf in configurations:
1342 1396 if 'cgs' in conf.device.device_type.name:
1343 1397 conf.status_device()
1344 1398 else:
1345 1399 answer = conf.start_device()
1346 1400 conf.status_device()
1347 1401 #--Running Experiment
1348 1402 old_running_experiment = RunningExperiment.objects.filter(radar=radar)
1349 1403 #--If RunningExperiment element exists
1350 1404 if old_running_experiment:
1351 1405 old_running_experiment = old_running_experiment[0]
1352 1406 old_running_experiment.running_experiment.add(exp)
1353 1407 old_running_experiment.status = 3
1354 1408 old_running_experiment.save()
1355 1409 #--Create a new Running_Experiment Object
1356 1410 else:
1357 1411 new_running_experiment = RunningExperiment(
1358 1412 radar = radar,
1359 1413 status = 3,
1360 1414 )
1361 1415 new_running_experiment.save()
1362 1416 new_running_experiment.running_experiment.add(exp)
1363 1417 new_running_experiment.save()
1364 1418
1365 1419 if answer:
1366 1420 messages.success(request, conf.message)
1367 1421 exp.status=2
1368 1422 exp.save()
1369 1423 else:
1370 1424 messages.error(request, conf.message)
1371 1425 else:
1372 1426 if exp.status == 1 or exp.status == 3:
1373 1427 exp.status=3
1374 1428 exp.save()
1375 1429
1376 1430
1377 1431 route = request.META['HTTP_REFERER']
1378 1432 route = str(route)
1379 1433 if 'search' in route:
1380 1434 return HttpResponseRedirect(reverse('url_operation_search', args=[id_camp]))
1381 1435 else:
1382 1436 return HttpResponseRedirect(reverse('url_operation', args=[id_camp]))
1383 1437
1384 1438
1385 1439 def radar_stop(request, id_camp, id_radar):
1386 1440 campaign = get_object_or_404(Campaign, pk = id_camp)
1387 1441 radar = get_object_or_404(Location, pk = id_radar)
1388 1442 experiments = Experiment.objects.filter(campaign=campaign).filter(location=radar)
1389 1443
1390 1444 for exp in experiments:
1391 1445 configurations = Configuration.objects.filter(experiment = exp)
1392 1446 for conf in configurations:
1393 1447 if 'cgs' in conf.device.device_type.name:
1394 1448 conf.status_device()
1395 1449 else:
1396 1450 answer = conf.stop_device()
1397 1451 conf.status_device()
1398 1452
1399 1453 if answer:
1400 1454 messages.success(request, conf.message)
1401 1455 exp.status=1
1402 1456 exp.save()
1403 1457 else:
1404 1458 messages.error(request, conf.message)
1405 1459
1406 1460
1407 1461 route = request.META['HTTP_REFERER']
1408 1462 route = str(route)
1409 1463 if 'search' in route:
1410 1464 return HttpResponseRedirect(reverse('url_operation_search', args=[id_camp]))
1411 1465 else:
1412 1466 return HttpResponseRedirect(reverse('url_operation', args=[id_camp]))
1413 1467
1414 1468
1415 1469 def radar_refresh(request, id_camp, id_radar):
1416 1470
1417 1471 campaign = get_object_or_404(Campaign, pk = id_camp)
1418 1472 radar = get_object_or_404(Location, pk = id_radar)
1419 1473 experiments = Experiment.objects.filter(campaign=campaign).filter(location=radar)
1420 1474 for exs in experiments:
1421 1475 exs.get_status()
1422 1476
1423 1477 route = request.META['HTTP_REFERER']
1424 1478 route = str(route)
1425 1479 if 'search' in route:
1426 1480 return HttpResponseRedirect(reverse('url_operation_search', args=[id_camp]))
1427 1481 else:
1428 1482 return HttpResponseRedirect(reverse('url_operation', args=[id_camp]))
1429
General Comments 0
You need to be logged in to leave comments. Login now