team-3/src/c3nav/mapdata/quests/positioning.py

106 lines
3.5 KiB
Python
Raw Normal View History

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
from c3nav.mapdata.models.geometry.space import RangingBeacon
from c3nav.mapdata.quests.base import ChangeSetModelForm, register_quest, Quest
class RangingBeaconAltitudeQuestForm(ChangeSetModelForm):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields["altitude"].label = (
_('How many meters above ground is the access point “%s” mounted?') % self.instance.comment
)
def clean_altitude(self):
data = self.cleaned_data["altitude"]
if not data:
raise ValidationError(_("The AP should not be 0m above ground."))
return data
class Meta:
model = RangingBeacon
fields = ("altitude", )
def save(self, *args, **kwargs):
self.instance.altitude_quest = False
return super().save(*args, **kwargs)
@property
def changeset_title(self):
return f'Altitude Quest: {self.instance.title}'
@register_quest
@dataclass
class RangingBeaconAltitudeQuest(Quest):
quest_type = "ranging_beacon_altitude"
quest_type_label = _('Ranging Beacon Altitude')
quest_type_icon = "router"
form_class = RangingBeaconAltitudeQuestForm
obj: RangingBeacon
@property
def point(self) -> Point:
return mapping(self.obj.geometry)
@classmethod
def _qs_for_request(cls, request):
return RangingBeacon.qs_for_request(request).select_related('space',
'space__level').filter(altitude_quest=True)
2024-12-26 22:43:19 +01:00
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()
2024-12-26 22:43:19 +01:00
def clean_bssids(self):
2024-12-26 23:07:47 +01:00
data = self.cleaned_data["wifi_bssids"]
2024-12-26 22:43:19 +01:00
if not data:
raise ValidationError(_("Need at least one bssid."))
return data
class Meta:
model = RangingBeacon
2024-12-26 23:07:47 +01:00
fields = ("wifi_bssids", )
2024-12-26 22:43:19 +01:00
@property
def changeset_title(self):
return f'Ranging Beacon BSSID Quest: {self.instance.title}'
@register_quest
@dataclass
class RangingBeaconBSSIDsQuest(Quest):
quest_type = "ranging_beacon_bssids"
quest_type_label = _('Ranging Beacon Identifier')
quest_type_icon = "wifi_find"
form_class = RangingBeaconBSSIDsQuestForm
obj: RangingBeacon
@property
def quest_description(self) -> list[str]:
return [
_("This quest only works in the app. It works fully automatically."),
2024-12-27 01:23:01 +01:00
_("We are trying to find the BSSIDs broadcast by “%s”.") % self.obj.title,
_("Please stand near “%s” and wait for the submit button to appear.") % self.obj.title,
_("Do not close this popup until then."),
2024-12-26 22:43:19 +01:00
_("This should happen within less than a minute."),
]
@property
def point(self) -> Point:
return mapping(self.obj.geometry)
@classmethod
def _qs_for_request(cls, request):
return RangingBeacon.qs_for_request(request).filter(import_tag__startswith="noc:", wifi_bssids=[])