def show_deployment_cms(request): """ This does 3 queries: * Facilities, organized by organization. * Devices, organized by organization. * Organizations, organized by organization. It then combines results from these 3 queries to create a list of: * All Users that have facilities, have devices but no facilities, and have no devices. """ # Query 1: Organizations deployment_data = OrderedDict([(org["id"], { "org_name": org["name"], "owner": org["owner__username"], "total_users": 0, "sync_sessions": 0, "models_synced": 0, }) for org in list(Organization.objects.values("id", "name", "owner__username"))]) # Query 2: Organizations with users for org in list(Organization.objects.values("id", "users__username", "users__first_name", "users__last_name")): org_id = org["id"] deployment_data[org_id]["users"] = deployment_data[org_id].get("users", {}) deployment_data[org_id]["users"][org["users__username"]] = { "first_name": org["users__first_name"], "last_name": org["users__last_name"], "email": org["users__username"], } # Query 3: Organizations with devices device_data = DeviceZone.objects \ .annotate( \ n_sessions=Count("device__client_sessions"), \ n_models=Sum("device__client_sessions__models_uploaded")) \ .values("n_sessions", "n_models", "device__id", "device__name", "zone__id", "zone__name", "zone__organization__id") \ .order_by("zone__name", "-n_models", "-n_sessions") for devzone in list(device_data): org_id = devzone["zone__organization__id"] if not org_id: continue deployment_data[org_id]["devices"] = deployment_data[org_id].get("devices", {}) deployment_data[org_id]["devices"][devzone["device__id"]] = { "id": devzone["device__id"], "name": devzone["device__name"], "zone_name": devzone["zone__name"], "zone_id": devzone["zone__id"], "models_synced": devzone["n_models"], "sync_sessions": devzone["n_sessions"], } deployment_data[org_id]["models_synced"] += devzone["n_models"] or 0 deployment_data[org_id]["sync_sessions"] += devzone["n_sessions"] or 0 # Query 4: Organizations with facilities facilities_by_org = list(Facility.objects \ .filter(signed_by__devicemetadata__is_demo_device=False) \ .annotate( \ n_actual_users=Count("facilityuser")) \ .values( \ "n_actual_users", \ "name", "address", \ "latitude", "longitude", \ "contact_email", "contact_name", \ "user_count", \ "zone_fallback__organization__id", \ "signed_by__devicezone__zone__organization__id",) \ .order_by("-n_actual_users")) for fac in list(facilities_by_org): org_id = fac["signed_by__devicezone__zone__organization__id"] or fac["zone_fallback__organization__id"] deployment_data[org_id]["facilities"] = deployment_data[org_id].get("facilities", {}) deployment_data[org_id]["facilities"][fac["name"]] = fac deployment_data[org_id]["total_users"] += fac["n_actual_users"] or 0 # Combine all data into a single data store. sort_fn = lambda dep: (dep["total_users"], dep["models_synced"], dep["sync_sessions"]) paged_data, page_urls = paginate_data(request, sorted(deployment_data.values(), key=sort_fn, reverse=True), page=int(request.GET.get("cur_page", 1)), per_page=int(request.GET.get("per_page", 25))) return { "pages": paged_data, "page_urls": page_urls, "title": _("Deployments CMS"), }
def zone_management(request, zone_id="None"): context = control_panel_context(request, zone_id=zone_id) own_device = Device.get_own_device() if not context["zone"] and (zone_id != "None" or own_device.get_zone() or settings.CENTRAL_SERVER): raise Http404() # on distributed server, we can make due if they're not registered. # Denote the zone as headless or not if context["zone"]: is_headless_zone = re.search(r"Zone for public key ", context["zone"].name) else: is_headless_zone = False # Accumulate device data device_data = OrderedDict() if context["zone"]: devices = Device.objects.filter(devicezone__zone=context["zone"]) else: devices = Device.objects.filter(devicemetadata__is_own_device=True) for device in list(devices.order_by("devicemetadata__is_demo_device", "name")): user_activity = UserLogSummary.objects.filter(device=device) sync_sessions = SyncSession.objects.filter(client_device=device) if ( not settings.CENTRAL_SERVER and device.id != own_device.id ): # Non-local sync sessions unavailable on distributed server sync_sessions = None exercise_activity = ExerciseLog.objects.filter(signed_by=device) device_data[device.id] = { "name": device.name or device.id, "num_times_synced": sync_sessions.count() if sync_sessions is not None else None, "last_time_synced": sync_sessions.aggregate(Max("timestamp"))["timestamp__max"] if sync_sessions is not None else None, "is_demo_device": device.get_metadata().is_demo_device, "is_own_device": device.get_metadata().is_own_device and not settings.CENTRAL_SERVER, "last_time_used": exercise_activity.order_by("-completion_timestamp")[0:1] if user_activity.count() == 0 else user_activity.order_by("-last_activity_datetime", "-end_datetime")[0], "counter": device.get_counter_position(), "is_registered": device.is_registered(), } # Accumulate facility data facility_data = OrderedDict() if context["zone"]: facilities = Facility.objects.by_zone(context["zone"]) else: facilities = Facility.objects.all() for facility in list(facilities.order_by("name")): user_activity = UserLogSummary.objects.filter(user__facility=facility) exercise_activity = ExerciseLog.objects.filter(user__facility=facility) facility_data[facility.id] = { "name": facility.name, "num_users": FacilityUser.objects.filter(facility=facility).count(), "num_groups": FacilityGroup.objects.filter(facility=facility).count(), "id": facility.id, "meta_data_in_need": check_meta_data(facility), "last_time_used": exercise_activity.order_by("-completion_timestamp")[0:1] if user_activity.count() == 0 else user_activity.order_by("-last_activity_datetime", "-end_datetime")[0], } context.update( { "is_headless_zone": is_headless_zone, "facilities": facility_data, "missing_meta": any([facility["meta_data_in_need"] for facility in facility_data.values()]), "devices": device_data, "upload_form": UploadFileForm(), "own_device_is_trusted": Device.get_own_device().get_metadata().is_trusted, } ) if not settings.CENTRAL_SERVER: context["base_template"] = "distributed/base_manage.html" return context
def show_deployment_cms(request): """ This does 3 queries: * Facilities, organized by organization. * Devices, organized by organization. * Organizations, organized by organization. It then combines results from these 3 queries to create a list of: * All Users that have facilities, have devices but no facilities, and have no devices. """ # Query 1: Organizations deployment_data = OrderedDict([(org["id"], { "org_name": org["name"], "owner": org["owner__username"], "total_users": 0, "sync_sessions": 0, "models_synced": 0, }) for org in list( Organization.objects.values("id", "name", "owner__username"))]) # Query 2: Organizations with users for org in list( Organization.objects.values("id", "users__username", "users__first_name", "users__last_name")): org_id = org["id"] deployment_data[org_id]["users"] = deployment_data[org_id].get( "users", {}) deployment_data[org_id]["users"][org["users__username"]] = { "first_name": org["users__first_name"], "last_name": org["users__last_name"], "email": org["users__username"], } # Query 3: Organizations with devices device_data = DeviceZone.objects \ .annotate( \ n_sessions=Count("device__client_sessions"), \ n_models=Sum("device__client_sessions__models_uploaded")) \ .values("n_sessions", "n_models", "device__id", "device__name", "zone__id", "zone__name", "zone__organization__id") \ .order_by("zone__name", "-n_models", "-n_sessions") for devzone in list(device_data): org_id = devzone["zone__organization__id"] if not org_id: continue deployment_data[org_id]["devices"] = deployment_data[org_id].get( "devices", {}) deployment_data[org_id]["devices"][devzone["device__id"]] = { "id": devzone["device__id"], "name": devzone["device__name"], "zone_name": devzone["zone__name"], "zone_id": devzone["zone__id"], "models_synced": devzone["n_models"], "sync_sessions": devzone["n_sessions"], } deployment_data[org_id]["models_synced"] += devzone["n_models"] or 0 deployment_data[org_id]["sync_sessions"] += devzone["n_sessions"] or 0 # Query 4: Organizations with facilities facilities_by_org = list(Facility.objects \ .filter(signed_by__devicemetadata__is_demo_device=False) \ .annotate( \ n_actual_users=Count("facilityuser")) \ .values( \ "n_actual_users", \ "name", "address", \ "latitude", "longitude", \ "contact_email", "contact_name", \ "user_count", \ "zone_fallback__organization__id", \ "signed_by__devicezone__zone__organization__id",) \ .order_by("-n_actual_users")) for fac in list(facilities_by_org): org_id = fac["signed_by__devicezone__zone__organization__id"] or fac[ "zone_fallback__organization__id"] deployment_data[org_id]["facilities"] = deployment_data[org_id].get( "facilities", {}) deployment_data[org_id]["facilities"][fac["name"]] = fac deployment_data[org_id]["total_users"] += fac["n_actual_users"] or 0 # Combine all data into a single data store. sort_fn = lambda dep: (dep["total_users"], dep["models_synced"], dep[ "sync_sessions"]) paged_data, page_urls = paginate_data( request, sorted(deployment_data.values(), key=sort_fn, reverse=True), page=int(request.GET.get("cur_page", 1)), per_page=int(request.GET.get("per_page", 25))) return { "pages": paged_data, "page_urls": page_urls, "title": _("Deployments CMS"), }
def zone_management(request, zone_id="None"): context = control_panel_context(request, zone_id=zone_id) own_device = Device.get_own_device() if not context["zone"] and (zone_id != "None" or own_device.get_zone() or settings.CENTRAL_SERVER): raise Http404( ) # on distributed server, we can make due if they're not registered. # Denote the zone as headless or not if context["zone"]: is_headless_zone = re.search(r'Zone for public key ', context["zone"].name) else: is_headless_zone = False # Accumulate device data device_data = OrderedDict() if context["zone"]: devices = Device.objects.filter(devicezone__zone=context["zone"]) else: devices = Device.objects.filter(devicemetadata__is_own_device=True) for device in list( devices.order_by("devicemetadata__is_demo_device", "name")): user_activity = UserLogSummary.objects.filter(device=device) sync_sessions = SyncSession.objects.filter(client_device=device) if not settings.CENTRAL_SERVER and device.id != own_device.id: # Non-local sync sessions unavailable on distributed server sync_sessions = None exercise_activity = ExerciseLog.objects.filter(signed_by=device) device_data[device.id] = { "name": device.name or device.id, "num_times_synced": sync_sessions.count() if sync_sessions is not None else None, "last_time_synced": sync_sessions.aggregate(Max("timestamp"))["timestamp__max"] if sync_sessions is not None else None, "is_demo_device": device.get_metadata().is_demo_device, "is_own_device": device.get_metadata().is_own_device and not settings.CENTRAL_SERVER, "last_time_used": exercise_activity.order_by("-completion_timestamp")[0:1] if user_activity.count() == 0 else user_activity.order_by( "-last_activity_datetime", "-end_datetime")[0], "counter": device.get_counter_position(), "is_registered": device.is_registered(), } # Accumulate facility data facility_data = OrderedDict() if context["zone"]: facilities = Facility.objects.by_zone(context["zone"]) else: facilities = Facility.objects.all() for facility in list(facilities.order_by("name")): user_activity = UserLogSummary.objects.filter(user__facility=facility) exercise_activity = ExerciseLog.objects.filter(user__facility=facility) facility_data[facility.id] = { "name": facility.name, "num_users": FacilityUser.objects.filter(facility=facility).count(), "num_groups": FacilityGroup.objects.filter(facility=facility).count(), "id": facility.id, "meta_data_in_need": check_meta_data(facility), "last_time_used": exercise_activity.order_by("-completion_timestamp")[0:1] if user_activity.count() == 0 else user_activity.order_by( "-last_activity_datetime", "-end_datetime")[0], } context.update({ "is_headless_zone": is_headless_zone, "facilities": facility_data, "missing_meta": any([ facility['meta_data_in_need'] for facility in facility_data.values() ]), "devices": device_data, "upload_form": UploadFileForm(), "own_device_is_trusted": Device.get_own_device().get_metadata().is_trusted, }) if not settings.CENTRAL_SERVER: context["base_template"] = "distributed/base_manage.html" context.update(set_clock_context(request)) return context