Add results and datetime filters for observations
parent
8ec5bfbeda
commit
5d7f39b06a
|
@ -515,6 +515,17 @@ class Observation(models.Model):
|
|||
def is_failed(self):
|
||||
return self.vetted_status == 'failed'
|
||||
|
||||
@property
|
||||
def has_waterfall(self):
|
||||
"""Run some checks on the waterfall for existence of data."""
|
||||
if self.waterfall is None:
|
||||
return False
|
||||
if not os.path.isfile(os.path.join(settings.MEDIA_ROOT, self.waterfall.name)):
|
||||
return False
|
||||
if self.waterfall.size == 0:
|
||||
return False
|
||||
return True
|
||||
|
||||
@property
|
||||
def has_audio(self):
|
||||
"""Run some checks on the payload for existence of data."""
|
||||
|
|
|
@ -116,6 +116,8 @@ class ObservationListView(ListView):
|
|||
norad_cat_id = self.request.GET.get('norad', '')
|
||||
observer = self.request.GET.get('observer', '')
|
||||
station = self.request.GET.get('station', '')
|
||||
start_time = self.request.GET.get('start-time', '')
|
||||
end_time = self.request.GET.get('end-time', '')
|
||||
self.filtered = False
|
||||
|
||||
bad = self.request.GET.get('bad', '1')
|
||||
|
@ -143,8 +145,24 @@ class ObservationListView(ListView):
|
|||
failed = False
|
||||
else:
|
||||
failed = True
|
||||
waterfall = self.request.GET.get('waterfall', '0')
|
||||
if waterfall == '1':
|
||||
waterfall = False
|
||||
else:
|
||||
waterfall = True
|
||||
audio = self.request.GET.get('audio', '0')
|
||||
if audio == '1':
|
||||
audio = False
|
||||
else:
|
||||
audio = True
|
||||
data = self.request.GET.get('data', '0')
|
||||
if data == '1':
|
||||
data = False
|
||||
else:
|
||||
data = True
|
||||
|
||||
if False in (bad, good, unvetted, future, failed):
|
||||
if False in (bad, good, unvetted, future, failed,
|
||||
waterfall, audio, data):
|
||||
self.filtered = True
|
||||
|
||||
observations = Observation.objects.all()
|
||||
|
@ -160,6 +178,14 @@ class ObservationListView(ListView):
|
|||
observations = observations.filter(
|
||||
ground_station_id=station)
|
||||
self.filtered = True
|
||||
if not start_time == '':
|
||||
observations = observations.filter(
|
||||
start__gt=start_time)
|
||||
self.filtered = True
|
||||
if not end_time == '':
|
||||
observations = observations.filter(
|
||||
end__lt=end_time)
|
||||
self.filtered = True
|
||||
|
||||
if not bad:
|
||||
observations = observations.exclude(vetted_status='bad')
|
||||
|
@ -174,6 +200,15 @@ class ObservationListView(ListView):
|
|||
if not future:
|
||||
observations = observations.exclude(id__in=(o.id for
|
||||
o in observations if o.is_future))
|
||||
if not waterfall:
|
||||
observations = observations.filter(id__in=(o.id for
|
||||
o in observations if o.has_waterfall))
|
||||
if not audio:
|
||||
observations = observations.filter(id__in=(o.id for
|
||||
o in observations if o.has_audio))
|
||||
if not data:
|
||||
observations = observations.filter(id__in=(o.id for
|
||||
o in observations if o.has_demoddata))
|
||||
return observations
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
|
@ -189,11 +224,16 @@ class ObservationListView(ListView):
|
|||
norad_cat_id = self.request.GET.get('norad', None)
|
||||
observer = self.request.GET.get('observer', None)
|
||||
station = self.request.GET.get('station', None)
|
||||
start_time = self.request.GET.get('start-time', None)
|
||||
end_time = self.request.GET.get('end-time', None)
|
||||
context['future'] = self.request.GET.get('future', '1')
|
||||
context['bad'] = self.request.GET.get('bad', '1')
|
||||
context['good'] = self.request.GET.get('good', '1')
|
||||
context['unvetted'] = self.request.GET.get('unvetted', '1')
|
||||
context['failed'] = self.request.GET.get('failed', '1')
|
||||
context['waterfall'] = self.request.GET.get('waterfall', '0')
|
||||
context['audio'] = self.request.GET.get('audio', '0')
|
||||
context['data'] = self.request.GET.get('data', '0')
|
||||
context['filtered'] = self.filtered
|
||||
if norad_cat_id is not None and norad_cat_id != '':
|
||||
context['norad'] = int(norad_cat_id)
|
||||
|
@ -201,6 +241,10 @@ class ObservationListView(ListView):
|
|||
context['observer_id'] = int(observer)
|
||||
if station is not None and station != '':
|
||||
context['station_id'] = int(station)
|
||||
if start_time is not None and start_time != '':
|
||||
context['start_time'] = start_time
|
||||
if end_time is not None and end_time != '':
|
||||
context['end_time'] = end_time
|
||||
if 'scheduled' in self.request.session:
|
||||
context['scheduled'] = self.request.session['scheduled']
|
||||
try:
|
||||
|
|
|
@ -35,7 +35,8 @@
|
|||
}
|
||||
}
|
||||
|
||||
#data-selector {
|
||||
#status-selector,
|
||||
#results-selector {
|
||||
display: block;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,37 +1,43 @@
|
|||
$(document).ready(function() {
|
||||
'use strict';
|
||||
|
||||
$('.selectpicker').selectpicker();
|
||||
|
||||
$('#observation-filter').submit(function () {
|
||||
var the_form = $(this);
|
||||
|
||||
the_form.find('input[type="checkbox"]').each( function () {
|
||||
var the_checkbox = $(this);
|
||||
|
||||
if( the_checkbox.is(':checked') === true ) {
|
||||
the_checkbox.attr('value','1');
|
||||
} else {
|
||||
the_checkbox.prop('checked',true);
|
||||
// Check the checkbox but change it's value to 0
|
||||
the_checkbox.attr('value','0');
|
||||
}
|
||||
$(function () {
|
||||
$('#datetimepicker-start').datetimepicker({
|
||||
useCurrent: false //https://github.com/Eonasdan/bootstrap-datetimepicker/issues/1075
|
||||
});
|
||||
$('#datetimepicker-end').datetimepicker({
|
||||
useCurrent: false //https://github.com/Eonasdan/bootstrap-datetimepicker/issues/1075
|
||||
});
|
||||
$('#datetimepicker-start').on('dp.change', function (e) {
|
||||
$('#datetimepicker-end').data('DateTimePicker').minDate(e.date);
|
||||
});
|
||||
$('#datetimepicker-end').on('dp.change', function (e) {
|
||||
$('#datetimepicker-start').data('DateTimePicker').maxDate(e.date);
|
||||
});
|
||||
});
|
||||
$('.selectpicker').selectpicker();
|
||||
|
||||
// Filters submits
|
||||
$('.filter-section input[type=checkbox]').change(function() {
|
||||
$('#observation-filter').submit();
|
||||
|
||||
$('.filter-section #status-selector label').click(function() {
|
||||
var checkbox = $(this);
|
||||
var input = checkbox.find('input[type="checkbox"]');
|
||||
|
||||
if (input.prop('checked')) {
|
||||
checkbox.removeClass('btn-inactive');
|
||||
} else {
|
||||
checkbox.addClass('btn-inactive');
|
||||
}
|
||||
});
|
||||
|
||||
$('#satellite-selection').bind('keyup change', function() {
|
||||
$('#observation-filter').submit();
|
||||
});
|
||||
$('#observer-selection').bind('keyup change', function() {
|
||||
$('#observation-filter').submit();
|
||||
});
|
||||
$('#station-selection').bind('keyup change', function() {
|
||||
$('#observation-filter').submit();
|
||||
$('.filter-section #results-selector label').click(function() {
|
||||
var checkbox = $(this);
|
||||
var input = checkbox.find('input[type="checkbox"]');
|
||||
|
||||
if (input.prop('checked')) {
|
||||
checkbox.addClass('btn-inactive');
|
||||
} else {
|
||||
checkbox.removeClass('btn-inactive');
|
||||
}
|
||||
});
|
||||
|
||||
// Check if filters should be displayed
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
{% block title %} - Observations{% endblock %}
|
||||
|
||||
{% block css %}
|
||||
<link href="{% static 'lib/eonasdan-bootstrap-datetimepicker/build/css/bootstrap-datetimepicker.min.css' %}" rel="stylesheet">
|
||||
<link rel="stylesheet" href="{% static 'lib/bootstrap-select/dist/css/bootstrap-select.min.css' %}">
|
||||
{% endblock css %}
|
||||
|
||||
|
@ -53,53 +54,54 @@
|
|||
</div>
|
||||
|
||||
<div class="collapse{% if norad %} in{% endif %}" id="collapseFilters" data-filtered="{{ filtered }}">
|
||||
<div class="filter-section row">
|
||||
<div class="filter-section well well-sm row">
|
||||
<form id="observation-filter" class="form" methon="get" action="{% url 'base:observations_list' %}">
|
||||
<div class="form-group status-filter col-md-3">
|
||||
<label for="data-selector">Status</label>
|
||||
<div id="data-selector" class="btn-group" data-toggle="buttons">
|
||||
<label class="btn btn-future btn-sm {% if future == '1' %}active{% else %}btn-inactive{% endif %}"
|
||||
<label for="status-selector">Status</label>
|
||||
<div id="status-selector" class="btn-group" data-toggle="buttons">
|
||||
<label class="btn btn-future btn-sm {% if future == '0' %}active btn-inactive{% endif %}"
|
||||
aria-expanded="true"
|
||||
aria-controls="future"
|
||||
data-toggle="tooltip"
|
||||
data-placement="bottom"
|
||||
title="Future">
|
||||
<input type="checkbox" name="future" {% if future == '1' %}checked{% endif %} autocomplete="off">
|
||||
<input type="checkbox" name="future" value="0" {% if future == '0' %}checked{% endif %} autocomplete="off">
|
||||
<span class="glyphicon glyphicon-time" aria-hidden="true"></span>
|
||||
</label>
|
||||
<label class="btn btn-good btn-sm {% if good == '1' %}active{% else %}btn-inactive{% endif %}"
|
||||
<label class="btn btn-good btn-sm {% if good == '0' %}active btn-inactive{% endif %}"
|
||||
aria-expanded="true"
|
||||
aria-controls="good"
|
||||
data-toggle="tooltip"
|
||||
data-placement="bottom"
|
||||
title="Good">
|
||||
<input type="checkbox" name="good" {% if good == '1' %}checked{% endif %} autocomplete="off">
|
||||
<input type="checkbox" name="good" value="0" {% if good == '0' %}checked{% endif %} autocomplete="off">
|
||||
<span class="glyphicon glyphicon-ok" aria-hidden="true"></span>
|
||||
</label>
|
||||
<label class="btn btn-bad btn-sm {% if bad == '1' %}active{% else %}btn-inactive{% endif %}"
|
||||
<label class="btn btn-bad btn-sm {% if bad == '0' %}active btn-inactive{% endif %}"
|
||||
aria-expanded="true"
|
||||
aria-controls="bad"
|
||||
data-toggle="tooltip"
|
||||
data-placement="bottom"
|
||||
title="Bad">
|
||||
<input type="checkbox" name="bad" {% if bad == '1' %}checked{% endif %} autocomplete="off">
|
||||
<input type="checkbox" name="bad" value="0" {% if bad == '0' %}checked{% endif %} autocomplete="off">
|
||||
<span class="glyphicon glyphicon-remove" aria-hidden="true"></span>
|
||||
</label>
|
||||
<label class="btn btn-unknown btn-sm {% if unvetted == '1' %}active{% else %}btn-inactive{% endif %}"
|
||||
<label class="btn btn-unknown btn-sm {% if unvetted == '0' %}active btn-inactive{% endif %}"
|
||||
aria-expanded="true"
|
||||
aria-controls="unvetted"
|
||||
data-toggle="tooltip"
|
||||
data-placement="bottom"
|
||||
title="Unvetted">
|
||||
<input type="checkbox" name="unvetted" {% if unvetted == '1' %}checked{% endif %} autocomplete="off">?
|
||||
<input type="checkbox" name="unvetted" value="0" {% if unvetted == '0' %}checked{% endif %} autocomplete="off">
|
||||
<span class="glyphicon glyphicon-question-sign" aria-hidden="true"></span>
|
||||
</label>
|
||||
<label class="btn btn-failed btn-sm {% if failed == '1' %}active{% else %}btn-inactive{% endif %}"
|
||||
<label class="btn btn-failed btn-sm {% if failed == '0' %}active btn-inactive{% endif %}"
|
||||
aria-expanded="true"
|
||||
aria-controls="failed"
|
||||
data-toggle="tooltip"
|
||||
data-placement="bottom"
|
||||
title="Failed">
|
||||
<input type="checkbox" name="failed" {% if failed == '1' %}checked{% endif %} autocomplete="off">
|
||||
<input type="checkbox" name="failed" value="0" {% if failed == '0' %}checked{% endif %} autocomplete="off">
|
||||
<span class="glyphicon glyphicon-alert" aria-hidden="true"></span>
|
||||
</label>
|
||||
</div>
|
||||
|
@ -140,6 +142,73 @@
|
|||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group status-filter col-md-3">
|
||||
<label for="results-selector">Results</label>
|
||||
<div id="results-selector" class="btn-group" data-toggle="buttons">
|
||||
<label class="btn btn-default btn-sm {% if waterfall == '1' %}active{% else %}btn-inactive{% endif %}"
|
||||
aria-expanded="true"
|
||||
aria-controls="waterfall"
|
||||
data-toggle="tooltip"
|
||||
data-placement="bottom"
|
||||
title="Waterfall">
|
||||
<input type="checkbox" name="waterfall" value="1" {% if waterfall == '1' %}checked{% endif %} autocomplete="off">
|
||||
<span class="glyphicon glyphicon-picture" aria-hidden="true"></span>
|
||||
</label>
|
||||
<label class="btn btn-default btn-sm {% if audio == '1' %}active{% else %}btn-inactive{% endif %}"
|
||||
aria-expanded="true"
|
||||
aria-controls="audio"
|
||||
data-toggle="tooltip"
|
||||
data-placement="bottom"
|
||||
title="Audio">
|
||||
<input type="checkbox" name="audio" value="1" {% if audio == '1' %}checked{% endif %} autocomplete="off">
|
||||
<span class="glyphicon glyphicon-volume-up" aria-hidden="true"></span>
|
||||
</label>
|
||||
<label class="btn btn-default btn-sm {% if data == '1' %}active{% else %}btn-inactive{% endif %}"
|
||||
aria-expanded="true"
|
||||
aria-controls="data"
|
||||
data-toggle="tooltip"
|
||||
data-placement="bottom"
|
||||
title="Data">
|
||||
<input type="checkbox" name="data" value="1" {% if data == '1' %}checked{% endif %} autocomplete="off">
|
||||
<span class="glyphicon glyphicon-file" aria-hidden="true"></span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group col-sm-3 ">
|
||||
<label class="control-label">Start Time</label>
|
||||
<div class='input-group date' id="datetimepicker-start">
|
||||
<input type="text"
|
||||
class="form-control"
|
||||
name="start-time"
|
||||
data-date-format="YYYY-MM-DD HH:mm"
|
||||
{% if start_time is not None %}
|
||||
value = "{{ start_time }}"
|
||||
{% endif %}
|
||||
autocomplete="off"/>
|
||||
<span class="input-group-addon">
|
||||
<span class="glyphicon glyphicon-calendar"></span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group col-sm-3 ">
|
||||
<label class="control-label">End Time</label>
|
||||
<div class='input-group date' id="datetimepicker-end">
|
||||
<input type="text"
|
||||
class="form-control"
|
||||
name="end-time"
|
||||
data-date-format="YYYY-MM-DD HH:mm"
|
||||
{% if end_time is not None %}
|
||||
value = "{{ end_time }}"
|
||||
{% endif %}
|
||||
autocomplete="off"/>
|
||||
<span class="input-group-addon">
|
||||
<span class="glyphicon glyphicon-calendar"></span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group col-sm-12">
|
||||
<button type="submit" class="btn btn-primary pull-right">Update filters</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -195,7 +264,7 @@
|
|||
</span>
|
||||
</td>
|
||||
<td>
|
||||
{% if observation.waterfall %}
|
||||
{% if observation.has_waterfall %}
|
||||
<span class="glyphicon glyphicon-picture" aria-hidden="true"
|
||||
data-toggle="tooltip" data-placement="bottom"
|
||||
title="Waterfall uploaded"></span>
|
||||
|
@ -239,6 +308,8 @@
|
|||
{% endblock content %}
|
||||
|
||||
{% block javascript %}
|
||||
<script src="{% static 'lib/moment/min/moment.min.js' %}"></script>
|
||||
<script src="{% static 'lib/eonasdan-bootstrap-datetimepicker/build/js/bootstrap-datetimepicker.min.js' %}"></script>
|
||||
<script src="{% static 'lib/bootstrap-select/dist/js/bootstrap-select.min.js' %}"></script>
|
||||
<script src="{% static 'js/observations.js' %}"></script>
|
||||
<script src="{% static 'js/satellite.js' %}"></script>
|
||||
|
|
Loading…
Reference in New Issue