convertstats

This commit is contained in:
Laura Klünder 2018-12-28 19:53:04 +01:00
parent e6afd91805
commit 0d59b6e7f4
2 changed files with 194 additions and 0 deletions

View file

@ -0,0 +1,19 @@
import argparse
import json
from django.core.management.base import BaseCommand
from django.utils.translation import ugettext_lazy as _
from c3nav.mapdata.utils.cache.stats import convert_stats
class Command(BaseCommand):
help = 'convert stats file'
def add_arguments(self, parser):
parser.add_argument('statsfile', type=argparse.FileType('r'), help=_('stats file to convert'))
def handle(self, *args, **options):
data = json.load(options['statsfile'])
result = convert_stats(data)
print(json.dumps(result, indent=4))

View file

@ -1,5 +1,15 @@
from operator import itemgetter
from django.contrib.auth import get_user_model
from django.core.cache import cache
from django.utils import timezone
from kombu.utils import cached_property
from c3nav.control.models import UserPermissions
from c3nav.mapdata.models import Level, LocationGroup, LocationSlug, Space
from c3nav.mapdata.models.geometry.space import POI, Area, WifiMeasurement
from c3nav.mapdata.models.locations import LocationRedirect
from c3nav.mapdata.utils.locations import CustomLocation, get_location_by_id_for_request
def increment_cache_key(cache_key):
@ -25,3 +35,168 @@ def stats_snapshot(reset=True):
'end_date': str(now),
'data': results
}
def _filter_stats(tag, stats, startswith=False):
if startswith:
return (([name[0][len(tag):]]+name[1:], value) for name, value in stats if name[0].startswith(tag))
return ((name[1:], value) for name, value in stats if name[0] == tag)
class FakeRequest():
@cached_property
def user(self):
return get_user_model().objects.filter(is_superuser=True).first()
@cached_property
def user_permissions(self):
return UserPermissions.get_for_user(self.user)
fake_request = FakeRequest()
def convert_stats(stats):
stats = [(name.split('__')[1:], value) for name, value in stats['data'].items()]
result = {}
result['locate'] = convert_locate(_filter_stats('locate', stats))
result['location_retrieve'] = convert_location(_filter_stats('location_retrieve', stats))
result['location_geometry'] = convert_location(_filter_stats('location_geometry', stats))
result['route_origin'] = convert_location(
(['pk']+name, value) for name, value in _filter_stats('route_origin_', stats, startswith=True)
)
result['route_destination'] = convert_location(
(['pk'] + name, value) for name, value in _filter_stats('route_destination_', stats, startswith=True)
)
return result
def _sort_count(map, key):
map[key] = dict(sorted(map[key].items(), key=itemgetter(1), reverse=True))
def convert_locate(data):
result = {
'total': 0,
'by_measurement_id': {},
'by_space': {},
'by_level': {},
}
measurement_lookup = {}
for measurement in WifiMeasurement.objects.all().select_related('space', 'space__level'):
pos = CustomLocation(measurement.space.level, measurement.geometry.x, measurement.geometry.y,
permissions=set()).pk
space_slug = measurement.space.get_slug()
level_label = measurement.space.level.short_label
measurement_lookup[pos] = (measurement.pk, space_slug, level_label)
result['by_measurement_id'][measurement.pk] = 0
result['by_space'][space_slug] = 0
result['by_level'][level_label] = 0
for name, value in data:
result['total'] += value
measurement = measurement_lookup.get(name[0], None)
if measurement:
result['by_measurement_id'][measurement[0]] += value
result['by_space'][measurement[1]] += value
result['by_level'][measurement[2]] += value
_sort_count(result, 'by_measurement_id')
_sort_count(result, 'by_space')
_sort_count(result, 'by_level')
return result
def convert_location(data):
result = {
'total': 0,
'invalid': 0,
'locations': {
'total': 0,
'by_type': {},
'by_space': {},
'by_level': {},
'by_group': {},
},
'coordinates': {
'total': 0,
'by_level': {},
'by_space': {},
'by_area': {},
'by_poi': {},
}
}
# fill up lists with zeros
location_slugs = {}
level_labels = {}
for location in LocationSlug.objects.all():
location = location.get_child()
if isinstance(location, LocationRedirect):
continue
result['locations']['by_type'].setdefault(location.__class__.__name__.lower(), {})[location.get_slug()] = 0
location_slugs[location.pk] = location.get_slug()
if isinstance(location, Level):
result['locations']['by_level'][location.short_label] = 0
result['coordinates']['by_level'][location.short_label] = 0
level_labels[location.pk] = location.short_label
if isinstance(location, Space):
result['locations']['by_space'][location.get_slug()] = 0
result['coordinates']['by_space'][location.get_slug()] = 0
if isinstance(location, Area):
if getattr(location, 'can_search', False) or getattr(location, 'can_describe', False):
result['coordinates']['by_area'][location.get_slug()] = 0
if isinstance(location, POI):
if getattr(location, 'can_search', False) or getattr(location, 'can_describe', False):
result['coordinates']['by_poi'][location.get_slug()] = 0
if isinstance(location, LocationGroup):
result['locations']['by_group'][location.get_slug()] = 0
for name, value in data:
if name[0] != 'pk' or name[0] == 'c:anywhere':
continue
location = get_location_by_id_for_request(name[1], fake_request)
result['total'] += value
if location is None:
result['invalid'] += value
continue
if isinstance(location, CustomLocation):
location.x += 1.5
location.y += 1.5
result['coordinates']['total'] += value
result['coordinates']['by_level'][location_slugs[location.level.pk]] += value
if location.space is None:
continue
result['coordinates']['by_space'][location_slugs[location.space.pk]] += value
for area in location.areas:
result['coordinates']['by_area'][location_slugs[area.pk]] += value
if location.near_area:
result['coordinates']['by_area'][location_slugs[location.near_area.pk]] += value
if location.near_poi:
result['coordinates']['by_poi'][location_slugs[location.near_poi.pk]] += value
else:
result['locations']['total'] += value
location = getattr(location, 'target', location)
result['locations']['by_type'].setdefault(location.__class__.__name__.lower(),
{})[location.get_slug()] += value
if hasattr(location, 'space_id'):
result['locations']['by_space'][location_slugs[location.space_id]] += value
if hasattr(location, 'level_id'):
result['locations']['by_level'][level_labels[location.level_id]] += value
if hasattr(location, 'groups'):
for group in location.groups.all():
result['locations']['by_group'][location_slugs[group.pk]] += value
_sort_count(result['locations']['by_type'], 'level')
_sort_count(result['locations']['by_type'], 'space')
_sort_count(result['locations']['by_type'], 'area')
_sort_count(result['locations']['by_type'], 'poi')
_sort_count(result['locations']['by_type'], 'locationgroup')
_sort_count(result['locations'], 'by_space')
_sort_count(result['locations'], 'by_level')
_sort_count(result['locations'], 'by_group')
_sort_count(result['coordinates'], 'by_level')
_sort_count(result['coordinates'], 'by_space')
_sort_count(result['coordinates'], 'by_area')
_sort_count(result['coordinates'], 'by_poi')
return result