def facility_management(request, facility, group_id=None, zone_id=None, per_page=25): if request.method == "POST" and request.GET.get("format") == "csv": try: return facility_management_csv(request, facility=facility, group_id=group_id, zone_id=zone_id) except Exception as e: messages.error(request, e) context = control_panel_context(request, zone_id=zone_id, facility_id=facility.id) #Get pagination details coach_page = request.REQUEST.get("coaches_page", "1") coach_per_page = request.REQUEST.get("coaches_per_page", "5") student_page = request.REQUEST.get("students_page", "1") student_per_page = request.REQUEST.get("students_per_page", "25" if group_id else "10") # Basic data group = group_id and get_object_or_None(FacilityGroup, id=group_id) groups = FacilityGroup.objects.filter(facility=context["facility"]).order_by("name") coaches = get_users_from_group(user_type="coaches", group_id=group_id, facility=facility) students = get_users_from_group(user_type="students", group_id=group_id, facility=facility) (student_data, group_data) = _get_user_usage_data(students, groups, group_id=group_id) (coach_data, coach_group_data) = _get_user_usage_data(coaches) coach_pages, coach_urls = paginate_data(request, coach_data.values(), data_type="coaches", page=coach_page, per_page=coach_per_page) student_pages, student_urls = paginate_data(request, student_data.values(), data_type="students", page=student_page, per_page=student_per_page) # Now prep the CSV form (even though we won't process it) form = DateRangeForm(data=request.POST) if request.method == "POST" else DateRangeForm() frequency = request.GET.get("frequency", "months") period_start = form.data.get("period_start") period_end = form.data.get("period_end") (period_start, period_end) = _get_date_range(frequency, period_start, period_end) context.update({ "form": form, "date_range": [str(period_start), str(period_end)], "group": group, "group_id": group_id, "groups": group_data.values(), "student_pages": student_pages, # paginated data "coach_pages": coach_pages, # paginated data "page_urls": { "coaches": coach_urls, "students": student_urls, }, }) return context
def device_management(request, device_id, zone_id=None, per_page=None, cur_page=None): context = control_panel_context(request, zone_id=zone_id, device_id=device_id) #Get pagination details cur_page = cur_page or request.REQUEST.get("cur_page", "1") per_page = per_page or request.REQUEST.get("per_page", "10") # Retrieve sync sessions all_sessions = SyncSession.objects.filter(client_device=context["device"]) total_sessions = all_sessions.count() shown_sessions = list(all_sessions.order_by("-timestamp").values("timestamp", "ip", "models_uploaded", "models_downloaded", "errors")) session_pages, page_urls = paginate_data(request, shown_sessions, page=cur_page, per_page=per_page) context.update({ "session_pages": session_pages, "page_urls": page_urls, "total_sessions": total_sessions, "device_version": total_sessions and all_sessions[0].client_version or None, "device_os": total_sessions and all_sessions[0].client_os or None, "is_own_device": not settings.CENTRAL_SERVER and device_id == Device.get_own_device().id, }) # If local (and, for security purposes, a distributed server), get device metadata if context["is_own_device"]: context.update(local_install_context(request)) return context
def device_management(request, device_id, zone_id=None, per_page=None, cur_page=None): context = control_panel_context(request, zone_id=zone_id, device_id=device_id) #Get pagination details cur_page = cur_page or request.REQUEST.get("cur_page", "1") per_page = per_page or request.REQUEST.get("per_page", "10") # Retrieve sync sessions all_sessions = SyncSession.objects.filter(client_device=context["device"]) total_sessions = all_sessions.count() shown_sessions = list( all_sessions.order_by("-timestamp").values("timestamp", "ip", "models_uploaded", "models_downloaded", "errors")) session_pages, page_urls = paginate_data(request, shown_sessions, page=cur_page, per_page=per_page) sync_job = get_object_or_None(Job, command="syncmodels") context.update({ "session_pages": session_pages, "page_urls": page_urls, "total_sessions": total_sessions, "device_version": total_sessions and all_sessions[0].client_version or None, "device_os": total_sessions and all_sessions[0].client_os or None, "is_own_device": not settings.CENTRAL_SERVER and device_id == Device.get_own_device().id, "sync_job": sync_job, }) # If local (and, for security purposes, a distributed server), get device metadata if context["is_own_device"]: context.update(local_install_context(request)) return context
def device_management(request, device_id, zone_id=None, per_page=None, cur_page=None): context = control_panel_context(request, zone_id=zone_id, device_id=device_id) # Get pagination details cur_page = cur_page or request.REQUEST.get("cur_page", "1") per_page = per_page or request.REQUEST.get("per_page", "10") # Retrieve sync sessions all_sessions = SyncSession.objects.filter(client_device=context["device"]) total_sessions = all_sessions.count() shown_sessions = list( all_sessions.order_by("-timestamp").values("timestamp", "ip", "models_uploaded", "models_downloaded", "errors") ) session_pages, page_urls = paginate_data(request, shown_sessions, page=cur_page, per_page=per_page) sync_job = get_object_or_None(Job, command="syncmodels") context.update( { "session_pages": session_pages, "page_urls": page_urls, "total_sessions": total_sessions, "device_version": total_sessions and all_sessions[0].client_version or None, "device_os": total_sessions and all_sessions[0].client_os or None, "is_own_device": not settings.CENTRAL_SERVER and device_id == Device.get_own_device().id, "sync_job": sync_job, } ) # If local (and, for security purposes, a distributed server), get device metadata if context["is_own_device"]: database_path = settings.DATABASES["default"]["NAME"] current_version = request.GET.get("version", VERSION) # allows easy development by passing a different version context.update( { "software_version": current_version, "software_release_date": VERSION_INFO().get(current_version, {}).get("release_date", "Unknown"), "install_dir": settings.SOURCE_DIR if settings.IS_SOURCE else "Not applicable (not a source installation)", "database_last_updated": datetime.datetime.fromtimestamp(os.path.getctime(database_path)), "database_size": os.stat(settings.DATABASES["default"]["NAME"]).st_size / float(1024 ** 2), } ) return context
def device_management(request, device_id, zone_id=None, per_page=None, cur_page=None): context = control_panel_context(request, zone_id=zone_id, device_id=device_id) # Get pagination details cur_page = cur_page or request.REQUEST.get("cur_page", "1") per_page = per_page or request.REQUEST.get("per_page", "10") # Retrieve sync sessions all_sessions = SyncSession.objects.filter(client_device=context["device"]) total_sessions = all_sessions.count() shown_sessions = list(all_sessions.order_by("-timestamp").values("timestamp", "ip", "models_uploaded", "models_downloaded", "errors")) session_pages, page_urls = paginate_data(request, shown_sessions, page=cur_page, per_page=per_page) sync_job = get_object_or_None(Job, command="syncmodels") context.update({ "session_pages": session_pages, "page_urls": page_urls, "total_sessions": total_sessions, "device_version": total_sessions and all_sessions[0].client_version or None, "device_os": total_sessions and all_sessions[0].client_os or None, "is_own_device": not settings.CENTRAL_SERVER and device_id == Device.get_own_device().id, "sync_job": sync_job, }) # If local (and, for security purposes, a distributed server), get device metadata if context["is_own_device"]: database_path = settings.DATABASES["default"]["NAME"] current_version = request.GET.get("version", VERSION) # allows easy development by passing a different version context.update({ "software_version": current_version, "install_dir": PACKAGE_PATH, "database_last_updated": datetime.datetime.fromtimestamp(os.path.getctime(database_path)), "database_size": os.stat(settings.DATABASES["default"]["NAME"]).st_size / float(1024 ** 2), }) 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 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 facility_management(request, ds, facility, group_id=None, zone_id=None, per_page=25): ungrouped_id = UNGROUPED if request.method == "POST" and request.GET.get("format") == "csv": try: return facility_management_csv(request, facility=facility, group_id=group_id, zone_id=zone_id) except Exception as e: messages.error(request, e) context = control_panel_context(request, zone_id=zone_id, facility_id=facility.id) # Get pagination details coach_page = request.REQUEST.get("coaches_page", "1") coach_per_page = request.REQUEST.get("coaches_per_page", "5") student_page = request.REQUEST.get("students_page", "1") student_per_page = request.REQUEST.get("students_per_page", "25" if group_id else "10") # Basic data group = group_id and get_object_or_None(FacilityGroup, id=group_id) groups = FacilityGroup.objects.filter(facility=context["facility"]).order_by("name") coaches = get_users_from_group(user_type="coaches", group_id=group_id, facility=facility) students = get_users_from_group(user_type="students", group_id=group_id, facility=facility) (student_data, group_data) = _get_user_usage_data(students, groups, group_id=group_id) (coach_data, coach_group_data) = _get_user_usage_data(coaches) coach_pages, coach_urls = paginate_data( request, coach_data.values(), data_type="coaches", page=coach_page, per_page=coach_per_page ) student_pages, student_urls = paginate_data( request, student_data.values(), data_type="students", page=student_page, per_page=student_per_page ) # Now prep the CSV form (even though we won't process it) form = DateRangeForm(data=request.POST) if request.method == "POST" else DateRangeForm() frequency = request.GET.get("frequency", "months") period_start = form.data.get("period_start") period_end = form.data.get("period_end") (period_start, period_end) = _get_date_range(frequency, period_start, period_end) # Collate data for all groups groups = group_data.values() # If group_id exists, extract data for that group if group_id: if group_id == ungrouped_id: group_data = group_data[None] else: group_data = group_data[group_id] else: group_data = {} context.update( { "form": form, "date_range": [str(period_start), str(period_end)], "group": group, "group_id": group_id, "group_data": group_data, "groups": groups, # sends dict if group page, list of group data otherwise "student_pages": student_pages, # paginated data "coach_pages": coach_pages, # paginated data "ds": ds, "page_urls": {"coaches": coach_urls, "students": student_urls}, "ungrouped_id": ungrouped_id, } ) if not settings.CENTRAL_SERVER: context["base_template"] = "distributed/base_manage.html" return context
def facility_management(request, ds, facility, group_id=None, zone_id=None, per_page=25): ungrouped_id = UNGROUPED if request.method == "POST" and request.GET.get("format") == "csv": try: return facility_management_csv(request, facility=facility, group_id=group_id, zone_id=zone_id) except Exception as e: messages.error(request, e) context = control_panel_context(request, zone_id=zone_id, facility_id=facility.id) #Get pagination details coach_page = request.REQUEST.get("coaches_page", "1") coach_per_page = request.REQUEST.get("coaches_per_page", "5") student_page = request.REQUEST.get("students_page", "1") student_per_page = request.REQUEST.get("students_per_page", "25" if group_id else "10") # Basic data group = group_id and get_object_or_None(FacilityGroup, id=group_id) groups = FacilityGroup.objects.filter( facility=context["facility"]).order_by("name") coaches = get_users_from_group(user_type="coaches", group_id=group_id, facility=facility) students = get_users_from_group(user_type="students", group_id=group_id, facility=facility) (student_data, group_data) = _get_user_usage_data(students, groups, group_id=group_id) (coach_data, coach_group_data) = _get_user_usage_data(coaches) coach_pages, coach_urls = paginate_data(request, coach_data.values(), data_type="coaches", page=coach_page, per_page=coach_per_page) student_pages, student_urls = paginate_data(request, student_data.values(), data_type="students", page=student_page, per_page=student_per_page) # Now prep the CSV form (even though we won't process it) form = DateRangeForm( data=request.POST) if request.method == "POST" else DateRangeForm() frequency = request.GET.get("frequency", "months") period_start = form.data.get("period_start") period_end = form.data.get("period_end") (period_start, period_end) = _get_date_range(frequency, period_start, period_end) # Collate data for all groups groups = group_data.values() # If group_id exists, extract data for that group if group_id: if group_id == ungrouped_id: group_id_index = next(index for (index, d) in enumerate(group_data.values()) if d["name"] == _(UNGROUPED)) else: group_id_index = next(index for (index, d) in enumerate(group_data.values()) if d["id"] == group_id) group_data = group_data.values()[group_id_index] else: group_data = {} context.update({ "form": form, "date_range": [str(period_start), str(period_end)], "group": group, "group_id": group_id, "group_data": group_data, "groups": groups, # sends dict if group page, list of group data otherwise "student_pages": student_pages, # paginated data "coach_pages": coach_pages, # paginated data "ds": ds, "page_urls": { "coaches": coach_urls, "students": student_urls, }, "ungrouped_id": ungrouped_id }) return context