From 0db0ae5cd6ce68839cda0f1429daaa758be0436c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Laura=20Kl=C3=BCnder?= Date: Fri, 27 Dec 2024 01:14:52 +0100 Subject: [PATCH] finalize quest for finding ranging beacon bssids --- src/c3nav/locale/de/LC_MESSAGES/django.po | 55 ++++++++++++++++++++--- src/c3nav/mapdata/quests/positioning.py | 14 ++++-- src/c3nav/routing/schemas.py | 10 +++++ src/c3nav/site/static/site/js/c3nav.js | 28 +++++++++++- 4 files changed, 96 insertions(+), 11 deletions(-) diff --git a/src/c3nav/locale/de/LC_MESSAGES/django.po b/src/c3nav/locale/de/LC_MESSAGES/django.po index 87c7c836..cc435e52 100644 --- a/src/c3nav/locale/de/LC_MESSAGES/django.po +++ b/src/c3nav/locale/de/LC_MESSAGES/django.po @@ -7,8 +7,8 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2024-12-26 22:26+0100\n" -"PO-Revision-Date: 2024-12-26 22:25+0100\n" +"POT-Creation-Date: 2024-12-27 01:14+0100\n" +"PO-Revision-Date: 2024-12-27 01:14+0100\n" "Last-Translator: Laura Klünder \n" "Language-Team: \n" "Language: de\n" @@ -2137,10 +2137,8 @@ msgid "Node Number" msgstr "Node Nummer" #: c3nav/mapdata/models/geometry/space.py -#, fuzzy -#| msgid "WiFi BSSID" msgid "WiFi BSSIDs" -msgstr "WLAN BSSID" +msgstr "WLAN BSSIDs" #: c3nav/mapdata/models/geometry/space.py msgid "uses node's value if not set" @@ -2643,8 +2641,8 @@ msgid "default fill color" msgstr "Standardfüllfarbe" #: c3nav/mapdata/models/overlay.py -msgid "fill opacity" -msgstr "Füllopacity" +msgid "default fill opacity" +msgstr "Standard-Füllopacity" #: c3nav/mapdata/models/overlay.py msgid "cluster points together when zoomed out" @@ -2666,6 +2664,18 @@ msgstr "Header für pull http request (JSON objekt)" msgid "pull interval" msgstr "Pullintervall" +#: c3nav/mapdata/models/overlay.py +msgid "frontend update interval" +msgstr "Frontend Updateintervall" + +#: c3nav/mapdata/models/overlay.py +msgid "in seconds" +msgstr "in Sekunden" + +#: c3nav/mapdata/models/overlay.py +msgid "Editor Access Restriction" +msgstr "Editor Zugangs­beschränkung" + #: c3nav/mapdata/models/overlay.py msgid "Data Overlay" msgstr "Datenoverlay" @@ -2686,6 +2696,10 @@ msgstr "randdicke" msgid "fill color" msgstr "Füllfarbe" +#: c3nav/mapdata/models/overlay.py +msgid "fill opacity" +msgstr "Füllopacity" + #: c3nav/mapdata/models/overlay.py msgid "show label" msgstr "Label anzeigen" @@ -2973,6 +2987,33 @@ msgstr "Der AP sollte sich nicht 0m über dem Boden befinden." msgid "Ranging Beacon Altitude" msgstr "Höhe des Ranging Beacons" +#: c3nav/mapdata/quests/positioning.py +msgid "Need at least one bssid." +msgstr "Mindestens eine BSSID wird benötigt." + +#: c3nav/mapdata/quests/positioning.py +msgid "Ranging Beacon Identifier" +msgstr "Ranging Beacons Indentifizierung" + +#: c3nav/mapdata/quests/positioning.py +msgid "This quest only works in the app. It works fully automatically." +msgstr "" +"Dieser Quest funktioniert nur in der App. Er funktioniert vollautomatisch." + +#: c3nav/mapdata/quests/positioning.py +#, python-format +msgid "We are trying to find the BSSIDs broadcast by “%s”." +msgstr "Wir versuchen die BSSIDs von „%s“ zu finden." + +#: c3nav/mapdata/quests/positioning.py +#, python-format +msgid "Please stand near “%s” and wait for the submit button to appear." +msgstr "Bitte stell dich zu „%s“ und warte bis der Absendebutton erscheint." + +#: c3nav/mapdata/quests/positioning.py +msgid "This should happen within less than a minute." +msgstr "Dies sollte weniger als eine Minute dauern." + #: c3nav/mapdata/quests/route_descriptions.py msgid "Does this space qualify as “easily identifyable/findable”?" msgstr "Ist dieser Raum „einfach zu identifizieren/finden“?" diff --git a/src/c3nav/mapdata/quests/positioning.py b/src/c3nav/mapdata/quests/positioning.py index 18afa2a6..88af775a 100644 --- a/src/c3nav/mapdata/quests/positioning.py +++ b/src/c3nav/mapdata/quests/positioning.py @@ -1,6 +1,7 @@ from dataclasses import dataclass from django.core.exceptions import ValidationError +from django.forms import CharField, HiddenInput from django.utils.translation import gettext_lazy as _ from shapely import Point from shapely.geometry import mapping @@ -55,6 +56,12 @@ class RangingBeaconAltitudeQuest(Quest): class RangingBeaconBSSIDsQuestForm(ChangeSetModelForm): + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self.fields["look_for_ap"] = CharField(disabled=True, initial=self.instance.import_tag[4:], + widget=HiddenInput()) + self.fields["wifi_bssids"].widget = HiddenInput() + def clean_bssids(self): data = self.cleaned_data["wifi_bssids"] if not data: @@ -82,8 +89,9 @@ class RangingBeaconBSSIDsQuest(Quest): @property def quest_description(self) -> list[str]: return [ - _("This quest is only available in the app. It works fully automatically."), - _("Please stand near this access point and wait for the submit button to appear."), + _("This quest only works in the app. It works fully automatically."), + _("We are trying to find the BSSIDs broadcast by “%s”."), + _("Please stand near “%s” and wait for the submit button to appear.") % self.obj.title, _("This should happen within less than a minute."), ] @@ -93,4 +101,4 @@ class RangingBeaconBSSIDsQuest(Quest): @classmethod def _qs_for_request(cls, request): - return RangingBeacon.qs_for_request(request).filter(import_tag__startswith="noc:", bssids=[]) + return RangingBeacon.qs_for_request(request).filter(import_tag__startswith="noc:", wifi_bssids=[]) diff --git a/src/c3nav/routing/schemas.py b/src/c3nav/routing/schemas.py index 6b45d861..bc4131e6 100644 --- a/src/c3nav/routing/schemas.py +++ b/src/c3nav/routing/schemas.py @@ -9,6 +9,7 @@ from pydantic.types import NonNegativeInt, NonNegativeFloat from pydantic_extra_types.mac_address import MacAddress from c3nav.api.schema import BaseSchema +from c3nav.api.utils import NonEmptyStr class WifiPeerInformationElement(BaseSchema): @@ -69,6 +70,15 @@ class LocateWifiPeerSchema(BaseSchema): description="standard deviation of measurements in meters", example=1.23 ) + ap_name: Union[ + NonEmptyStr, + Annotated[None, APIField(title="null", description="AP name not available")] + ] = APIField( + default=None, + title="AP name", + description="as broadcasted, for example, by aruba APs", + example="AP042" + ) info_elems: list[WifiPeerInformationElement] = APIField( default=[], title="information elements / vendor data", diff --git a/src/c3nav/site/static/site/js/c3nav.js b/src/c3nav/site/static/site/js/c3nav.js index e6fe5fca..c918fd5e 100644 --- a/src/c3nav/site/static/site/js/c3nav.js +++ b/src/c3nav/site/static/site/js/c3nav.js @@ -1459,10 +1459,14 @@ c3nav = { } }, _set_modal_content: function (content, no_close) { - $('#modal').toggleClass('loading', !content) + const $modal = $('#modal'); + $modal.toggleClass('loading', !content) .find('#modal-content') .html((!no_close) ? '' : '') .append(content || '
'); + if ($modal.find('[name=look_for_ap]').length) { + $modal.find('button').hide(); + } }, _modal_click: function (e) { if (!c3nav.modal_noclose && (e.target.id === 'modal' || e.target.id === 'close-modal')) { @@ -2120,6 +2124,9 @@ c3nav = { if (c3nav.ssids) { peers = peers.filter(peer => c3nav.ssids.includes(peer.ssid)); } + let match_ap = $('[name=look_for_ap]').val(), + found_bssids = []; + for (const peer of peers) { if (peer.level !== undefined) { peer.rssi = peer.level; @@ -2130,6 +2137,25 @@ c3nav = { peer.distance_sd = peer.rtt.distance_std_dev_mm / 1000; delete peer.rtt; } + if (match_ap && peer.ap_name === match_ap) { + found_bssids.push(peer.bssid); + } + } + if (found_bssids.length) { + let $wifi_bssids = $('[name=wifi_bssids]'), + val = JSON.parse($wifi_bssids.val()), + added = 0; + for (let bssid of found_bssids) { + if (!val.includes(bssid)) { + val.push(bssid); + added++; + } + } + if (added) { + $wifi_bssids.val(JSON.stringify(val)); + } else { + $('#modal button[type=submit]').show(); + } } c3nav._last_wifi_peers = peers; c3nav._after_scan_results();