def post_source_attribute(source_uuid: SourceId, source_attribute: str, database: Database): """Set a source attribute.""" data_model = latest_datamodel(database) reports = latest_reports(database) data = SourceData(data_model, reports, source_uuid) value = dict(bottle.request.json)[source_attribute] old_value: Any if source_attribute == "position": old_value, value = move_item(data, value, "source") else: old_value = data.source.get(source_attribute) or "" data.source[source_attribute] = value if old_value == value: return dict(ok=True) # Nothing to do delta_description = ( f"{{user}} changed the {source_attribute} of source '{data.source_name}' of metric '{data.metric_name}' of " f"subject '{data.subject_name}' in report '{data.report_name}' from '{old_value}' to '{value}'." ) uuids = [ data.report_uuid, data.subject_uuid, data.metric_uuid, source_uuid ] if source_attribute == "type": data.source["parameters"] = default_source_parameters( database, data.metric["type"], value) return insert_new_report(database, delta_description, (data.report, uuids))
def post_move_source(source_uuid: SourceId, target_metric_uuid: MetricId, database: Database): """Move the source to another metric.""" data_model = latest_datamodel(database) reports = latest_reports(database) source = SourceData(data_model, reports, source_uuid) target = MetricData(data_model, reports, target_metric_uuid) delta_description = ( f"{{user}} moved the source '{source.source_name}' from metric '{source.metric_name}' of subject " f"'{source.subject_name}' in report '{source.report_name}' to metric '{target.metric_name}' of subject " f"'{target.subject_name}' in report '{target.report_name}'." ) target.metric["sources"][source_uuid] = source.source target_uuids: List[Union[Optional[ReportId], Optional[SubjectId], Optional[MetricId], Optional[SourceId]]] = [ target.report_uuid ] reports_to_insert = [(target.report, target_uuids)] if target.report_uuid == source.report_uuid: # Source is moved within the same report del target.report["subjects"][source.subject_uuid]["metrics"][source.metric_uuid]["sources"][source_uuid] if target.subject_uuid != source.subject_uuid: # Source is moved from one subject to another subject, include both subject uuids in the delta target_uuids.append(source.subject_uuid) target_uuids.extend([target.subject_uuid, source.metric_uuid]) else: # Source is moved from one report to another, update both del source.metric["sources"][source_uuid] source_uuids = [source.report_uuid, source.subject_uuid, source.metric_uuid, source_uuid] reports_to_insert.append((source.report, source_uuids)) target_uuids.append(target.subject_uuid) target_uuids.extend([target_metric_uuid, source_uuid]) return insert_new_report(database, delta_description, *reports_to_insert)
def set_entity_attribute(metric_uuid: MetricId, source_uuid: SourceId, entity_key: str, attribute: str, database: Database) -> dict: """Set an entity attribute.""" data = SourceData(latest_datamodel(database), latest_reports(database), source_uuid) old_measurement = latest_measurement(database, metric_uuid) new_measurement = old_measurement.copy() source = [ s for s in new_measurement["sources"] if s["source_uuid"] == source_uuid ][0] entity = [e for e in source["entities"] if e["key"] == entity_key][0] entity_description = "/".join( [entity[key] for key in entity.keys() if key not in ("key", "url")]) old_value = source.get("entity_user_data", {}).get(entity_key, {}).get(attribute) or "" new_value = dict(bottle.request.json)[attribute] source.setdefault("entity_user_data", {}).setdefault(entity_key, {})[attribute] = new_value user = sessions.user(database) new_measurement["delta"] = dict( uuids=[data.report_uuid, data.subject_uuid, metric_uuid, source_uuid], description= f"{user['user']} changed the {attribute} of '{entity_description}' from '{old_value}' to " f"'{new_value}'.", email=user["email"], ) return insert_new_measurement(database, data.datamodel, data.metric, new_measurement, old_measurement)
def post_source_parameter(source_uuid: SourceId, parameter_key: str, database: Database): """Set the source parameter.""" data = SourceData(latest_datamodel(database), latest_reports(database), source_uuid) new_value = new_parameter_value(data, parameter_key) old_value = data.source["parameters"].get(parameter_key) or "" if old_value == new_value: return dict(ok=True) # Nothing to do edit_scope = cast(EditScope, dict(bottle.request.json).get("edit_scope", "source")) changed_ids = change_source_parameter(data, parameter_key, old_value, new_value, edit_scope) if is_password_parameter(data.datamodel, data.source["type"], parameter_key): new_value, old_value = "*" * len(new_value), "*" * len(old_value) source_description = _source_description(data, edit_scope, parameter_key, old_value) delta_description = ( f"{{user}} changed the {parameter_key} of {source_description} from '{old_value}' to '{new_value}'." ) reports_to_insert = [(report, changed_ids) for report in data.reports if report["report_uuid"] in changed_ids] result = insert_new_report(database, delta_description, *reports_to_insert) if availability_checks := _availability_checks(data, parameter_key): result["availability"] = availability_checks
def post_source_copy(source_uuid: SourceId, metric_uuid: MetricId, database: Database): """Add a copy of the source to the metric (new in v3).""" data_model = latest_datamodel(database) reports = latest_reports(database) source = SourceData(data_model, reports, source_uuid) target = MetricData(data_model, reports, metric_uuid) target.metric["sources"][(source_copy_uuid := uuid())] = copy_source(source.source, source.datamodel) user = sessions.user(database) target.report["delta"] = dict( uuids=[ target.report_uuid, target.subject_uuid, target.metric_uuid, source_copy_uuid ], email=user["email"], description= f"{user['user']} copied the source '{source.source_name}' of metric " f"'{source.metric_name}' of subject '{source.subject_name}' from report '{source.report_name}' to " f"metric '{target.metric_name}' of subject '{target.subject_name}' in report " f"'{target.report_name}'.") result = insert_new_report(database, target.report) result["new_source_uuid"] = source_copy_uuid return result
def delete_source(source_uuid: SourceId, database: Database): """Delete a source.""" data_model = latest_datamodel(database) reports = latest_reports(database) data = SourceData(data_model, reports, source_uuid) user = sessions.user(database) data.report["delta"] = dict( uuids=[ data.report_uuid, data.subject_uuid, data.metric_uuid, source_uuid ], email=user["email"], description= f"{user['user']} deleted the source '{data.source_name}' from metric " f"'{data.metric_name}' of subject '{data.subject_name}' in report '{data.report_name}'." ) del data.metric["sources"][source_uuid] return insert_new_report(database, data.report)
def delete_source(source_uuid: SourceId, database: Database): """Delete a source.""" data_model = latest_datamodel(database) reports = latest_reports(database) data = SourceData(data_model, reports, source_uuid) delta_description = ( f"{{user}} deleted the source '{data.source_name}' from metric " f"'{data.metric_name}' of subject '{data.subject_name}' in report '{data.report_name}'." ) uuids = [data.report_uuid, data.subject_uuid, data.metric_uuid, source_uuid] del data.metric["sources"][source_uuid] return insert_new_report(database, delta_description, (data.report, uuids))
def post_move_source(source_uuid: SourceId, target_metric_uuid: MetricId, database: Database): """Move the source to another metric.""" data_model = latest_datamodel(database) reports = latest_reports(database) source = SourceData(data_model, reports, source_uuid) target = MetricData(data_model, reports, target_metric_uuid) user = sessions.user(database) delta_description = f"{user['user']} moved the source '{source.source_name}' from metric " \ f"'{source.metric_name}' of subject '{source.subject_name}' in report '{source.report_name}' " \ f"to metric '{target.metric_name}' of subject '{target.subject_name}' in report " \ f"'{target.report_name}'." target.metric["sources"][source_uuid] = source.source target_uuids: List[Union[Optional[ReportId], Optional[SubjectId], Optional[MetricId], Optional[SourceId]]] = \ [target.report_uuid] reports_to_insert = [target.report] if target.report_uuid == source.report_uuid: # Source is moved within the same report del target.report["subjects"][source.subject_uuid]["metrics"][ source.metric_uuid]["sources"][source_uuid] if target.subject_uuid != source.subject_uuid: # Source is moved from one subject to another subject, include both subject uuids in the delta target_uuids.append(source.subject_uuid) target_uuids.extend([target.subject_uuid, source.metric_uuid]) else: # Source is moved from one report to another, update both reports_to_insert.append(source.report) del source.metric["sources"][source_uuid] source.report["delta"] = dict(uuids=[ source.report_uuid, source.subject_uuid, source.metric_uuid, source_uuid ], email=user["email"], description=delta_description) target_uuids.append(target.subject_uuid) target.report["delta"] = dict(uuids=target_uuids + [target_metric_uuid, source_uuid], email=user["email"], description=delta_description) return insert_new_report(database, *reports_to_insert)
def post_source_copy(source_uuid: SourceId, metric_uuid: MetricId, database: Database): """Add a copy of the source to the metric (new in v3).""" data_model = latest_datamodel(database) reports = latest_reports(database) source = SourceData(data_model, reports, source_uuid) target = MetricData(data_model, reports, metric_uuid) target.metric["sources"][(source_copy_uuid := uuid())] = copy_source(source.source, source.datamodel) delta_description = ( f"{{user}} copied the source '{source.source_name}' of metric '{source.metric_name}' of subject " f"'{source.subject_name}' from report '{source.report_name}' to metric '{target.metric_name}' of subject " f"'{target.subject_name}' in report '{target.report_name}'." ) uuids = [target.report_uuid, target.subject_uuid, target.metric_uuid, source_copy_uuid] result = insert_new_report(database, delta_description, (target.report, uuids)) result["new_source_uuid"] = source_copy_uuid return result