From 149dbf7b9d0dcf3614749237e0f33066e03927a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Laura=20Kl=C3=BCnder?= Date: Sun, 29 Dec 2024 20:11:34 +0100 Subject: [PATCH] permission for set_load and caching for get_load --- ...20_userpermissions_can_write_load_data.py} | 2 +- src/c3nav/control/models.py | 2 +- src/c3nav/mapdata/api/map.py | 29 ++++++++++++++----- 3 files changed, 23 insertions(+), 10 deletions(-) rename src/c3nav/control/migrations/{0020_userpermissions_can_write_laod_data.py => 0020_userpermissions_can_write_load_data.py} (91%) diff --git a/src/c3nav/control/migrations/0020_userpermissions_can_write_laod_data.py b/src/c3nav/control/migrations/0020_userpermissions_can_write_load_data.py similarity index 91% rename from src/c3nav/control/migrations/0020_userpermissions_can_write_laod_data.py rename to src/c3nav/control/migrations/0020_userpermissions_can_write_load_data.py index a3b117f0..30460538 100644 --- a/src/c3nav/control/migrations/0020_userpermissions_can_write_laod_data.py +++ b/src/c3nav/control/migrations/0020_userpermissions_can_write_load_data.py @@ -12,7 +12,7 @@ class Migration(migrations.Migration): operations = [ migrations.AddField( model_name='userpermissions', - name='can_write_laod_data', + name='can_write_load_data', field=models.BooleanField(default=False, verbose_name='write load data'), ), ] diff --git a/src/c3nav/control/models.py b/src/c3nav/control/models.py index ee25fb7a..8b9932d9 100644 --- a/src/c3nav/control/models.py +++ b/src/c3nav/control/models.py @@ -45,7 +45,7 @@ class UserPermissions(models.Model): quests: list[str] = SchemaField(schema=list[str], default=list) impolite_quests = models.BooleanField(default=False, verbose_name=_('dont say thanks after completing a quest')) passive_ap_name_scanning = models.BooleanField(default=False, verbose_name=_('passive ap name scanning')) - can_write_laod_data = models.BooleanField(default=False, verbose_name=_('write load data')) + can_write_load_data = models.BooleanField(default=False, verbose_name=_('write load data')) class Meta: verbose_name = _('User Permissions') diff --git a/src/c3nav/mapdata/api/map.py b/src/c3nav/mapdata/api/map.py index 18f0b064..983dd451 100644 --- a/src/c3nav/mapdata/api/map.py +++ b/src/c3nav/mapdata/api/map.py @@ -2,7 +2,9 @@ import json from typing import Annotated, Union, Optional from celery import chain +from django.core.cache import cache from django.core.serializers.json import DjangoJSONEncoder +from django.db import transaction from django.db.models import Prefetch, Q from django.shortcuts import redirect from django.utils import timezone @@ -444,6 +446,10 @@ Room load @map_api_router.get('/load/', summary="get load group loads", response={200: dict[PositiveInt, float], **auth_responses}) def get_load(request): + result = cache.get('mapdata:get_load', None) + if result is not None: + return result + load_groups = {g.pk: g for g in LoadGroup.objects.all()} # per group @@ -484,26 +490,33 @@ def get_load(request): max_values[load_group_id] += beacon.max_observed_num_clients current_values[load_group_id] += beacon.num_clients - return { + result = { pk: (min(1.0, current_values[pk] / (max_value*0.9)) if max_value else 0) for pk, max_value in max_values.items() } + cache.set('mapdata:get_load', result, 300) + return result class ApLoadSchema(BaseSchema): aps: dict[str, int] -@map_api_router.post('/load/', summary="update current load data", response={204: None, **auth_responses}) +@map_api_router.post('/load/', summary="update current load data", + response={204: None, **auth_permission_responses}) def post_load(request, parameters: ApLoadSchema): - # TODO: check if user has permission + if not request.user_permissions.can_write_load_data: + raise APIPermissionDenied() names = parameters.aps.keys() - for beacon in RangingBeacon.objects.filter(ap_name__in=names): - beacon.num_clients = parameters.aps[beacon.ap_name] - if beacon.num_clients > beacon.max_observed_num_clients: - beacon.max_observed_num_clients = beacon.num_clients - beacon.save() + with transaction.atomic(): + for beacon in RangingBeacon.objects.filter(ap_name__in=names): + beacon.num_clients = parameters.aps[beacon.ap_name] + if beacon.num_clients > beacon.max_observed_num_clients: + beacon.max_observed_num_clients = beacon.num_clients + beacon.save() + + cache.delete('mapdata:get_load') return 204, None