diff --git a/src/c3nav/editor/api.py b/src/c3nav/editor/api.py
index b31de59d..fe1266bb 100644
--- a/src/c3nav/editor/api.py
+++ b/src/c3nav/editor/api.py
@@ -196,6 +196,7 @@ class EditorViewSet(ViewSet):
space.lineobstacles.all(),
space.columns.all(),
space.altitudemarkers.all(),
+ space.wifi_measurements.all(),
space.pois.filter(POI.q_for_request(request)).prefetch_related('groups'),
other_spaces_upper,
graphedges,
@@ -224,6 +225,7 @@ class EditorViewSet(ViewSet):
'graphnode': '#009900',
'graphedge': '#00CC00',
'altitudemarker': '#0000FF',
+ 'wifimeasurement': '#DDDD00',
})
@list_route(methods=['get'])
diff --git a/src/c3nav/editor/forms.py b/src/c3nav/editor/forms.py
index c9762ce1..af9b1f09 100644
--- a/src/c3nav/editor/forms.py
+++ b/src/c3nav/editor/forms.py
@@ -25,6 +25,10 @@ class EditorFormBase(I18nModelFormMixin, ModelForm):
super().__init__(*args, **kwargs)
creating = not self.instance.pk
+ if hasattr(self.instance, 'author_id'):
+ if self.instance.author_id is None:
+ self.instance.author = request.user
+
if 'level' in self.fields:
# hide level widget
self.fields['level'].widget = HiddenInput()
@@ -186,7 +190,7 @@ def create_editor_form(editor_model):
'ordering', 'category', 'width', 'groups', 'color', 'priority', 'icon_name',
'base_altitude', 'waytype', 'access_restriction', 'height', 'default_height', 'door_height',
'outside', 'can_search', 'can_describe', 'geometry', 'single', 'altitude', 'short_label',
- 'origin_space', 'target_space',
+ 'origin_space', 'target_space', 'data', 'comment',
'extra_seconds', 'speed', 'description', 'speed_up', 'description_up',
'allow_levels', 'allow_spaces', 'allow_areas', 'allow_pois', 'left', 'top', 'right', 'bottom']
field_names = [field.name for field in editor_model._meta.get_fields() if not field.one_to_many]
diff --git a/src/c3nav/editor/static/editor/css/editor.css b/src/c3nav/editor/static/editor/css/editor.css
index f4a38409..fb9f2468 100644
--- a/src/c3nav/editor/static/editor/css/editor.css
+++ b/src/c3nav/editor/static/editor/css/editor.css
@@ -74,7 +74,8 @@ nav.navbar .navbar-nav > li > a {
}
/* sidebar contents */
-#sidebar form.creation-lock .btn.btn-primary {
+#sidebar form.creation-lock [type=submit].btn.btn-primary,
+#sidebar form.scan-lock [type=submit].btn.btn-primary{
display:none;
}
#sidebar h3 {
@@ -317,3 +318,42 @@ h4 {
.btn + .btn {
margin-left: 5px;
}
+
+textarea.form-control {
+ resize: none;
+ height: 75px;
+}
+
+.wificollector {
+ padding: 10px;
+ height: auto;
+}
+body > .wificollector {
+ display: none;
+}
+.wificollector:not(.empty) .btn.start,
+.wificollector:not(.running) .btn.stop,
+.wificollector:not(.done) .btn.reset,
+.wificollector.empty .count-line {
+ display: none;
+}
+.wificollector .btn {
+ margin: 0 5px 0 0;
+}
+.wificollector p {
+ height: 26px;
+ margin: 0;
+}
+.wificollector table {
+ width: 100%;
+}
+.wificollector table td {
+ padding: 5px 5px 0 0;
+}
+.wificollector table td:last-child {
+ padding-right: 0;
+ text-align: right;
+}
+.wificollector table tr td {
+ color: #666666;
+}
diff --git a/src/c3nav/editor/static/editor/js/editor.js b/src/c3nav/editor/static/editor/js/editor.js
index 048c2196..8489fd8e 100644
--- a/src/c3nav/editor/static/editor/js/editor.js
+++ b/src/c3nav/editor/static/editor/js/editor.js
@@ -53,6 +53,7 @@ editor = {
editor._sublevel_control_container = $(editor._sublevel_control._container);
editor.init_geometries();
+ editor.init_wificollector();
},
_onbeforeunload: function(e) {
if ($('#sidebar').find('[data-onbeforeunload]').length) {
@@ -229,6 +230,13 @@ editor = {
editor._level_control.hide();
editor._sublevel_control.hide();
}
+
+ var data_field = $('form [name=data]');
+ if (data_field.length) {
+ data_field.hide();
+ data_field.after($('body .wificollector')[0].outerHTML);
+ data_field.closest('form').addClass('scan-lock');
+ }
},
_sidebar_error: function(data) {
$('#sidebar').removeClass('loading').find('.content').html('
Error '+data.status+'
'+data.statusText);
@@ -256,7 +264,7 @@ editor = {
_sidebar_submit: function(e) {
// listener for form submits in the sidebar.
e.preventDefault();
- if (editor._loading_geometry || $(this).is('.creation-lock')) return;
+ if (editor._loading_geometry || $(this).is('.creation-lock') || $(this).is('.scan-lock')) return;
var data = $(this).serialize();
var btn = $(this).data('btn');
if (btn !== undefined && btn !== null) {
@@ -829,9 +837,78 @@ editor = {
if (editor._editing_layer !== null) {
$('#id_geometry').val(JSON.stringify(editor._editing_layer.toGeoJSON().geometry));
}
+ },
+
+ init_wificollector: function () {
+ // init geometries and edit listeners
+ editor._highlight_layer = L.layerGroup().addTo(editor.map);
+
+ $('#sidebar').on('click', '.wificollector .start', editor._wificollector_start)
+ .on('click', '.wificollector .stop', editor._wificollector_stop)
+ .on('click', '.wificollector .reset', editor._wificollector_reset);
+ editor._wificollector_scan_perhaps();
+ },
+ _wificollector_data: [],
+ _wificollector_start: function () {
+ var $collector = $('#sidebar').find('.wificollector');
+ $collector.removeClass('empty').addClass('running');
+ editor._wificollector_data = [];
+ $collector.find('.count').text(0);
+ },
+ _wificollector_stop: function () {
+ var $collector = $('#sidebar').find('.wificollector');
+ $collector.removeClass('running').delay(1000).queue(function(n) {
+ $(this).addClass('done');
+ n();
+ });
+ $collector.closest('form').removeClass('scan-lock');
+ },
+ _wificollector_reset: function () {
+ var $collector = $('#sidebar').find('.wificollector');
+ $collector.removeClass('done').addClass('empty').find('table').html('');
+ $collector.siblings('[name=data]').val('');
+ $collector.closest('form').addClass('scan-lock');
+ },
+ _wificollector_result: function(data) {
+ var $collector = $('#sidebar').find('.wificollector.running'),
+ $table = $collector.find('table'),
+ item, i, line, apid, color;
+ editor._wificollector_scan_perhaps();
+ $table.find('tr').addClass('old');
+ for (i=0; i < data.length; i++) {
+ item = data[i];
+ apid = 'ap-'+item.bssid.replace(/:/g, '-');
+ line = $table.find('tr.'+apid);
+ console.log(line);
+ color = Math.max(0, Math.min(50, item.level+80))
+ color = 'rgb('+String(250-color*5)+', '+String(color*4)+', 0)';
+ if (line.length) {
+ line.removeClass('old').find(':last-child').text(item.level).css('color', color);
+ } else {
+ line = $('').addClass(apid);
+ line.append($('').text(item.bssid));
+ line.append($(' | ').text(item.ssid));
+ line.append($(' | ').text(item.level).css('color', color));
+ $table.append(line);
+ }
+ }
+ editor._wificollector_data.push(data);
+ $collector.find('.count').text(editor._wificollector_data.length);
+ $collector.siblings('[name=data]').val(JSON.stringify(editor._wificollector_data));
+ },
+ _wificollector_scan_perhaps: function() {
+ if ($('#sidebar').find('.wificollector.running').length) {
+ mobileclient.scanNow();
+ } else {
+ window.setTimeout(editor._wificollector_scan_perhaps, 1000);
+ }
}
};
+function nearby_stations_available() {
+ editor._wificollector_result(JSON.parse(mobileclient.getNearbyStations()));
+}
+
LevelControl = L.Control.extend({
options: {
diff --git a/src/c3nav/editor/templates/editor/base.html b/src/c3nav/editor/templates/editor/base.html
index 2f8705f1..531f3994 100644
--- a/src/c3nav/editor/templates/editor/base.html
+++ b/src/c3nav/editor/templates/editor/base.html
@@ -44,6 +44,16 @@
{% endblock %}
+
+
{% include 'site/fragment_fakemobileclient.html' %}
{% compress js %}
diff --git a/src/c3nav/editor/urls.py b/src/c3nav/editor/urls.py
index 9a0c1820..9c3a592f 100644
--- a/src/c3nav/editor/urls.py
+++ b/src/c3nav/editor/urls.py
@@ -68,3 +68,4 @@ urlpatterns.extend(add_editor_urls('POI', 'Space'))
urlpatterns.extend(add_editor_urls('AltitudeMarker', 'Space'))
urlpatterns.extend(add_editor_urls('LeaveDescription', 'Space'))
urlpatterns.extend(add_editor_urls('CrossDescription', 'Space'))
+urlpatterns.extend(add_editor_urls('WifiMeasurement', 'Space'))
diff --git a/src/c3nav/editor/views/edit.py b/src/c3nav/editor/views/edit.py
index 52cde339..911b4b26 100644
--- a/src/c3nav/editor/views/edit.py
+++ b/src/c3nav/editor/views/edit.py
@@ -89,7 +89,8 @@ def space_detail(request, level, pk):
'child_models': [child_model(request, model_name, kwargs={'space': pk}, parent=space)
for model_name in ('POI', 'Area', 'Obstacle', 'LineObstacle', 'Stair', 'Ramp', 'Column',
- 'Hole', 'AltitudeMarker', 'LeaveDescription', 'CrossDescription')],
+ 'Hole', 'AltitudeMarker', 'LeaveDescription', 'CrossDescription',
+ 'WifiMeasurement')],
'geometry_url': '/api/editor/geometries/?space='+pk,
})
diff --git a/src/c3nav/editor/wrappers.py b/src/c3nav/editor/wrappers.py
index d9da05f1..ee26363f 100644
--- a/src/c3nav/editor/wrappers.py
+++ b/src/c3nav/editor/wrappers.py
@@ -51,7 +51,7 @@ class BaseWrapper:
return instance
instance = instance._obj
assert isinstance(instance, models.Model)
- return self._wrap_model(type(instance)).create_wrapped_model_class()(self._changeset, instance)
+ return self._wrap_model(instance.__class__).create_wrapped_model_class()(self._changeset, instance)
def _wrap_manager(self, manager):
"""
|