class RegisteredDataService:
    """
    Object to handle logic of registered data requests

    Attributes:
    graph_api_service (GraphApiService): Service used to communicate with Graph API
    """
    graph_api_service = GraphApiService()

    def save_registered_data(self, registered_data: RegisteredDataIn):
        """
        Send request to graph api to create new registered data node

        Args:
            registered_data (RegisteredDataIn): Registered data to be added

        Returns:
            Result of request as registered data object
        """
        node_response = self.graph_api_service.create_node("`Registered Data`")

        if node_response["errors"] is not None:
            return RegisteredDataOut(**registered_data.dict(),
                                     errors=node_response["errors"])

        registered_data_id = node_response["id"]
        properties_response = self.graph_api_service.create_properties(
            registered_data_id, registered_data)
        if properties_response["errors"] is not None:
            return RegisteredDataOut(**registered_data.dict(),
                                     errors=properties_response["errors"])

        return RegisteredDataOut(**registered_data.dict(),
                                 id=registered_data_id)

    def get_registered_data_nodes(self):
        """
        Send request to graph api to get registered_data_nodes

        Returns:
            Result of request as list of registered_data_nodes objects
        """
        get_response = self.graph_api_service.get_nodes("`Registered Data`")

        registered_data_nodes = []

        for registered_data_node in get_response["nodes"]:
            properties = {
                'id': registered_data_node['id'],
                'additional_properties': []
            }
            for property in registered_data_node["properties"]:
                if property["key"] == "source":
                    properties[property["key"]] = property["value"]
                else:
                    properties['additional_properties'].append({
                        'key':
                        property['key'],
                        'value':
                        property['value']
                    })
            registered_data = BasicRegisteredDataOut(**properties)
            registered_data_nodes.append(registered_data)

        return RegisteredDataNodesOut(
            registered_data_nodes=registered_data_nodes)

    def get_registered_data(self, registered_data_id: int):
        """
        Send request to graph api to get given registered data

        Args:
        registered_data_id (int): Id of registered data

        Returns:
            Result of request as registered data object
        """
        get_response = self.graph_api_service.get_node(registered_data_id)

        if get_response["errors"] is not None:
            return NotFoundByIdModel(id=registered_data_id,
                                     errors=get_response["errors"])
        if get_response["labels"][0] != "Registered Data":
            return NotFoundByIdModel(id=registered_data_id,
                                     errors="Node not found.")

        registered_data = {
            'id': get_response['id'],
            'additional_properties': [],
            'relations': [],
            'reversed_relations': []
        }
        for property in get_response["properties"]:
            if property["key"] == "source":
                registered_data[property["key"]] = property["value"]
            else:
                registered_data['additional_properties'].append({
                    'key':
                    property['key'],
                    'value':
                    property['value']
                })

        relations_response = self.graph_api_service.get_node_relationships(
            registered_data_id)

        for relation in relations_response["relationships"]:
            if relation["start_node"] == registered_data_id:
                registered_data['relations'].append(
                    RelationInformation(second_node_id=relation["end_node"],
                                        name=relation["name"],
                                        relation_id=relation["id"]))
            else:
                registered_data['reversed_relations'].append(
                    RelationInformation(second_node_id=relation["start_node"],
                                        name=relation["name"],
                                        relation_id=relation["id"]))

        return RegisteredDataOut(**registered_data)

    def delete_registered_data(self, registered_data_id: int):
        """
        Send request to graph api to delete given registered data

        Args:
        registered_data_id (int): Id of registered data

        Returns:
            Result of request as registered data object
        """
        get_response = self.get_registered_data(registered_data_id)

        if type(get_response) is NotFoundByIdModel:
            return get_response

        self.graph_api_service.delete_node(registered_data_id)
        return get_response

    def update_registered_data(self, registered_data_id: int,
                               registered_data: RegisteredDataIn):
        """
        Send request to graph api to update given registered data

        Args:
        registered_data_id (int): Id of registered data
        registered_data (RegisteredDataIn): Properties to update

        Returns:
            Result of request as registered data object
        """
        get_response = self.get_registered_data(registered_data_id)

        if type(get_response) is NotFoundByIdModel:
            return get_response

        self.graph_api_service.delete_node_properties(registered_data_id)
        self.graph_api_service.create_properties(registered_data_id,
                                                 registered_data)

        registered_data_result = {
            'id': registered_data_id,
            'relations': get_response.relations,
            'reversed_relations': get_response.reversed_relations
        }
        registered_data_result.update(registered_data.dict())

        return RegisteredDataOut(**registered_data_result)
class ExperimentService:
    """
    Object to handle logic of experiments requests

    Attributes:
    graph_api_service (GraphApiService): Service used to communicate with Graph API
    """
    graph_api_service = GraphApiService()
    
    def save_experiment(self, experiment: ExperimentIn):
        """
        Send request to graph api to create new experiment

        Args:
            experiment (ExperimentIn): Experiment to be added

        Returns:
            Result of request as experiment object
        """
        node_response_experiment = self.graph_api_service.create_node("Experiment")

        if node_response_experiment["errors"] is not None:
            return ExperimentOut(**experiment.dict(), errors=node_response_experiment["errors"])

        experiment_id = node_response_experiment["id"]
        properties_response = self.graph_api_service.create_properties(experiment_id, experiment)
        if properties_response["errors"] is not None:
            return ExperimentOut(**experiment.dict(), errors=properties_response["errors"])

        return ExperimentOut(**experiment.dict(), id=experiment_id)

    def get_experiments(self):
        """
        Send request to graph api to get experiments

        Returns:
            Result of request as list of experiments objects
        """
        get_response = self.graph_api_service.get_nodes("Experiment")

        experiments = []

        for experiment_node in get_response["nodes"]:
            properties = {'id': experiment_node['id'], 'additional_properties': []}
            for property in experiment_node["properties"]:
                if property["key"] == "experiment_name":
                    properties[property["key"]] = property["value"]
                else:
                    properties['additional_properties'].append({'key': property['key'], 'value': property['value']})
            experiment = BasicExperimentOut(**properties)
            experiments.append(experiment)

        return ExperimentsOut(experiments=experiments)

    def get_experiment(self, experiment_id: int):
        """
        Send request to graph api to get given experiment

        Args:
        experiment_id (int): Id of experiment

        Returns:
            Result of request as experiment object
        """
        get_response = self.graph_api_service.get_node(experiment_id)

        if get_response["errors"] is not None:
            return NotFoundByIdModel(id=experiment_id, errors=get_response["errors"])
        if get_response["labels"][0] != "Experiment":
            return NotFoundByIdModel(id=experiment_id, errors="Node not found.")

        experiment = {'id': get_response['id'], 'additional_properties': [], 'relations': [], 'reversed_relations': []}
        for property in get_response["properties"]:
            if property["key"] == "experiment_name":
                experiment[property["key"]] = property["value"]
            else:
                experiment['additional_properties'].append({'key': property['key'], 'value': property['value']})

        relations_response = self.graph_api_service.get_node_relationships(experiment_id)

        for relation in relations_response["relationships"]:
            if relation["start_node"] == experiment_id:
                experiment['relations'].append(RelationInformation(second_node_id=relation["end_node"],
                                                                   name=relation["name"], relation_id=relation["id"]))
            else:
                experiment['reversed_relations'].append(RelationInformation(second_node_id=relation["start_node"],
                                                                            name=relation["name"],
                                                                            relation_id=relation["id"]))

        return ExperimentOut(**experiment)

    def delete_experiment(self, experiment_id: int):
        """
        Send request to graph api to delete given experiment

        Args:
        experiment_id (int): Id of experiment

        Returns:
            Result of request as experiment object
        """
        get_response = self.get_experiment(experiment_id)

        if type(get_response) is NotFoundByIdModel:
            return get_response

        self.graph_api_service.delete_node(experiment_id)
        return get_response

    def update_experiment(self, experiment_id: int, experiment: ExperimentIn):
        """
        Send request to graph api to update given experiment

        Args:
        experiment_id (int): Id of experiment
        experiment (ExperimentIn): Properties to update

        Returns:
            Result of request as experiment object
        """
        get_response = self.get_experiment(experiment_id)

        if type(get_response) is NotFoundByIdModel:
            return get_response

        self.graph_api_service.delete_node_properties(experiment_id)
        self.graph_api_service.create_properties(experiment_id, experiment)

        experiment_result = {'id': experiment_id, 'relations': get_response.relations,
                             'reversed_relations': get_response.reversed_relations}
        experiment_result.update(experiment.dict())

        return ExperimentOut(**experiment_result)
class ActivityExecutionService:
    """
    Object to handle logic of activities requests

    Attributes:
    graph_api_service (GraphApiService): Service used to communicate with Graph API
    activity_service (ActivityService): Service used to communicate with Activity
    arrangement_service (ArrangementService): Service used to communicate with Arrangement
    """
    graph_api_service = GraphApiService()
    activity_service = ActivityService()
    arrangement_service = ArrangementService()

    def save_activity_execution(self, activity_execution: ActivityExecutionIn):
        """
        Send request to graph api to create new activity execution

        Args:
            activity_execution (ActivityExecutionIn): Activity execution to be added

        Returns:
            Result of request as activity execution object
        """
        node_response = self.graph_api_service.create_node("`Activity Execution`")

        if node_response["errors"] is not None:
            return ActivityExecutionOut(**activity_execution.dict(), errors=node_response["errors"])

        activity_execution_id = node_response["id"]

        if activity_execution.activity_id is not None and \
                type(self.activity_service.get_activity(activity_execution.activity_id)) is not NotFoundByIdModel:
            self.graph_api_service.create_relationships(start_node=activity_execution_id,
                                                        end_node=activity_execution.activity_id,
                                                        name="hasActivity")

        if activity_execution.arrangement_id is not None and \
                type(self.arrangement_service.get_arrangement(activity_execution.arrangement_id)) \
                is not NotFoundByIdModel:

            self.graph_api_service.create_relationships(start_node=activity_execution_id,
                                                        end_node=activity_execution.arrangement_id,
                                                        name="hasArrangement")

        activity_execution.activity_id = activity_execution.arrangement_id = None
        self.graph_api_service.create_properties(activity_execution_id, activity_execution)

        return self.get_activity_execution(activity_execution_id)

    def get_activity_executions(self):
        """
        Send request to graph api to get activity executions

        Returns:
            Result of request as list of activity executions objects
        """
        get_response = self.graph_api_service.get_nodes("`Activity Execution`")

        activity_executions = []
        for activity_execution_node in get_response["nodes"]:
            properties = {'id': activity_execution_node['id'], 'additional_properties': []}
            for property in activity_execution_node["properties"]:
                properties['additional_properties'].append({'key': property['key'], 'value': property['value']})
            activity_execution = BasicActivityExecutionOut(**properties)
            activity_executions.append(activity_execution)

        return ActivityExecutionsOut(activity_executions=activity_executions)

    def get_activity_execution(self, activity_execution_id: int):
        """
        Send request to graph api to get given activity execution

        Args:
            activity_execution_id (int): Id of activity execution

        Returns:
            Result of request as activity execution object
        """
        get_response = self.graph_api_service.get_node(activity_execution_id)

        if get_response["errors"] is not None:
            return NotFoundByIdModel(id=activity_execution_id, errors=get_response["errors"])
        if get_response["labels"][0] != "Activity Execution":
            return NotFoundByIdModel(id=activity_execution_id, errors="Node not found.")

        activity_execution = {'id': get_response['id'], 'additional_properties': [], 'relations': [],
                              'reversed_relations': []}
        for property in get_response["properties"]:
            activity_execution['additional_properties'].append({'key': property['key'], 'value': property['value']})

        relations_response = self.graph_api_service.get_node_relationships(activity_execution_id)

        for relation in relations_response["relationships"]:
            if relation["start_node"] == activity_execution_id:
                activity_execution['relations'].append(RelationInformation(second_node_id=relation["end_node"],
                                                                           name=relation["name"],
                                                                           relation_id=relation["id"]))
            else:
                activity_execution['reversed_relations'].append(
                    RelationInformation(second_node_id=relation["start_node"],
                                        name=relation["name"],
                                        relation_id=relation["id"]))

        return ActivityExecutionOut(**activity_execution)

    def delete_activity_execution(self, activity_execution_id: int):
        """
        Send request to graph api to delete given activity execution
        Args:
            activity_execution_id (int): Id of activity execution
        Returns:
            Result of request as activity execution object
        """
        get_response = self.get_activity_execution(activity_execution_id)

        if type(get_response) is NotFoundByIdModel:
            return get_response

        self.graph_api_service.delete_node(activity_execution_id)
        return get_response

    def update_activity_execution(self, activity_execution_id: int, activity_execution: ActivityExecutionPropertyIn):
        """
        Send request to graph api to update given participant state
        Args:
            activity_execution_id (int): Id of participant state
            activity_execution (ActivityExecutionPropertyIn): Properties to update
        Returns:
            Result of request as participant state object
        """
        get_response = self.get_activity_execution(activity_execution_id)

        if type(get_response) is NotFoundByIdModel:
            return get_response

        self.graph_api_service.delete_node_properties(activity_execution_id)
        self.graph_api_service.create_properties(activity_execution_id, activity_execution)

        activity_execution_result = {"id": activity_execution_id, "relations": get_response.relations,
                                     "reversed_relations": get_response.reversed_relations}
        activity_execution_result.update(activity_execution.dict())

        return ActivityExecutionOut(**activity_execution_result)

    def update_activity_execution_relationships(self, activity_execution_id: int,
                                                activity_execution: ActivityExecutionRelationIn):
        """
        Send request to graph api to update given activity execution relationships
        Args:
            activity_execution_id (int): Id of activity execution
            activity_execution (ActivityExecutionIn): Relationships to update
        Returns:
            Result of request as activity execution object
        """
        get_response = self.get_activity_execution(activity_execution_id)

        if type(get_response) is NotFoundByIdModel:
            return get_response

        if activity_execution.activity_id is not None and \
                type(self.activity_service.get_activity(activity_execution.activity_id)) is not NotFoundByIdModel:
            self.graph_api_service.create_relationships(start_node=activity_execution_id,
                                                        end_node=activity_execution.activity_id,
                                                        name="hasActivity")
        if activity_execution.arrangement_id is not None and \
                type(self.arrangement_service.get_arrangement(activity_execution.arrangement_id)) \
                is not NotFoundByIdModel:
            self.graph_api_service.create_relationships(start_node=activity_execution_id,
                                                        end_node=activity_execution.arrangement_id,
                                                        name="hasArrangement")

        return self.get_activity_execution(activity_execution_id)
Esempio n. 4
0
class PersonalityService:
    """
    Object to handle logic of personality requests

    Attributes:
        graph_api_service (GraphApiService): Service used to communicate with Graph API
    """
    graph_api_service = GraphApiService()

    def save_personality_big_five(self, personality: PersonalityBigFiveIn):
        """
        Send request to graph api to create new personality big five model

        Args:
            personality (PersonalityBigFiveIn): Personality big five to be added

        Returns:
            Result of request as personality big five object
        """

        if not 0 <= personality.agreeableness <= 1 or not 0 <= personality.conscientiousness <= 1 or \
           not 0 <= personality.extroversion <= 1 or not 0 <= personality.neuroticism <= 1 or \
           not 0 <= personality.openess <= 1:
            return PersonalityBigFiveOut(**personality.dict(),
                                         errors="Value not between 0 and 1")

        node_response = self.graph_api_service.create_node("Personality")
        personality_id = node_response["id"]
        self.graph_api_service.create_properties(personality_id, personality)
        return PersonalityBigFiveOut(**personality.dict(), id=personality_id)

    def save_personality_panas(self, personality: PersonalityPanasIn):
        """
        Send request to graph api to create new personality panas model

        Args:
            personality (PersonalityPanasIn): Personality to be added

        Returns:
            Result of request as personality panas object
        """
        if not 0 <= personality.negative_affect <= 1 or not 0 <= personality.positive_affect <= 1:
            return PersonalityPanasOut(**personality.dict(),
                                       errors="Value not between 0 and 1")

        node_response = self.graph_api_service.create_node("Personality")
        personality_id = node_response["id"]
        self.graph_api_service.create_properties(personality_id, personality)

        return PersonalityPanasOut(**personality.dict(), id=personality_id)

    def get_personality(self, personality_id: int):
        """
        Send request to graph api to get given personality

        Args:
            personality_id (int): Id of personality

        Returns:
            Result of request as personality object
        """
        get_response = self.graph_api_service.get_node(personality_id)

        if get_response["errors"] is not None:
            return NotFoundByIdModel(id=personality_id,
                                     errors=get_response["errors"])
        if get_response["labels"][0] != "Personality":
            return NotFoundByIdModel(id=personality_id,
                                     errors="Node not found.")

        personality = {
            'id': personality_id,
            'relations': [],
            'reversed_relations': []
        }
        personality.update({
            property["key"]: property["value"]
            for property in get_response["properties"]
        })

        relations_response = self.graph_api_service.get_node_relationships(
            personality_id)

        for relation in relations_response["relationships"]:
            if relation["start_node"] == personality_id:
                personality["relations"].append(
                    RelationInformation(second_node_id=relation["end_node"],
                                        name=relation["name"],
                                        relation_id=relation["id"]))
            else:
                personality["reversed_relations"].append(
                    RelationInformation(second_node_id=relation["start_node"],
                                        name=relation["name"],
                                        relation_id=relation["id"]))

        return PersonalityPanasOut(**personality) if "negative_affect" in personality.keys() \
            else PersonalityBigFiveOut(**personality)

    def get_personalities(self):
        """
        Send request to graph api to get personalities

        Returns:
            Result of request as list of personalities objects
        """
        get_response = self.graph_api_service.get_nodes("Personality")

        personalities = []

        for personality_node in get_response["nodes"]:
            properties = {
                property["key"]: property["value"]
                for property in personality_node["properties"]
            }
            properties["id"] = personality_node["id"]
            personality = BasicPersonalityPanasOut(**properties) if "negative_affect" in properties.keys() \
                else BasicPersonalityBigFiveOut(**properties)
            personalities.append(personality)

        return PersonalitiesOut(personalities=personalities)

    def delete_personality(self, personality_id: int):
        """
        Send request to graph api to delete given personality

        Args:
            personality_id (int): Id of personality

        Returns:
            Result of request as personality object
        """
        get_response = self.get_personality(personality_id)

        if type(get_response) is NotFoundByIdModel:
            return get_response
        self.graph_api_service.delete_node(personality_id)
        return get_response

    def update_personality_big_five(self, personality_id: int,
                                    personality: PersonalityBigFiveIn):
        """
        Send request to graph api to update given personality big five model

        Args:
            personality_id (int): Id of personality
            personality (PersonalityBigFiveIn): Properties to update

        Returns:
            Result of request as personality object
        """
        if not 0 <= personality.agreeableness <= 1 or not 0 <= personality.conscientiousness <= 1 or \
           not 0 <= personality.extroversion <= 1 or not 0 <= personality.neuroticism <= 1 or \
           not 0 <= personality.openess <= 1:
            return PersonalityBigFiveOut(**personality.dict(),
                                         errors="Value not between 0 and 1")

        get_response = self.get_personality(personality_id)
        if type(get_response) is NotFoundByIdModel:
            return get_response
        if type(get_response) is PersonalityPanasOut:
            return NotFoundByIdModel(id=personality_id,
                                     errors="Node not found.")

        self.graph_api_service.create_properties(personality_id, personality)
        personality_response = get_response.dict()
        personality_response.update(personality)
        return PersonalityBigFiveOut(**personality_response)

    def update_personality_panas(self, personality_id: int,
                                 personality: PersonalityPanasIn):
        """
        Send request to graph api to update given personality panas model

        Args:
            personality_id (int): Id of personality
            personality (PersonalityPanasIn): Properties to update

        Returns:
            Result of request as personality object
        """
        if not 0 <= personality.negative_affect <= 1 or not 0 <= personality.positive_affect <= 1:
            return PersonalityPanasOut(**personality.dict(),
                                       errors="Value not between 0 and 1")

        get_response = self.get_personality(personality_id)
        if type(get_response) is NotFoundByIdModel:
            return get_response
        if type(get_response) is PersonalityBigFiveOut:
            return NotFoundByIdModel(id=personality_id,
                                     errors="Node not found.")

        self.graph_api_service.create_properties(personality_id, personality)

        personality_response = get_response.dict()
        personality_response.update(personality)
        return PersonalityPanasOut(**personality_response)
class DatabaseServiceTestCase(unittest.TestCase):

    def setUp(self):
        self.graph_api_service = GraphApiService()
        self.response_content = {'id': 1, 'errors': [], 'links': {}}
        self.response = Response()
        self.response._content = json.dumps(self.response_content).encode('utf-8')

    @mock.patch('graph_api_service.requests')
    def test_post(self, requests_mock):
        requests_mock.post.return_value = self.response
        url_part = '/nodes'
        node = {}

        result = self.graph_api_service.post(url_part, node)

        self.assertEqual(result, self.response_content)
        requests_mock.post.assert_called_with(url=self.graph_api_service.graph_api_url + url_part,
                                              json=node)

    @mock.patch('graph_api_service.requests')
    def test_get(self, requests_mock):
        requests_mock.get.return_value = self.response
        url_part = '/nodes'
        params = {'label': 'Test'}

        result = self.graph_api_service.get(url_part, params)

        self.assertEqual(result, self.response_content)
        requests_mock.get.assert_called_with(url=self.graph_api_service.graph_api_url + url_part,
                                             params=params)

    @mock.patch('graph_api_service.requests')
    def test_delete(self, requests_mock):
        requests_mock.delete.return_value = self.response
        url_part = '/nodes'
        params = {'label': 'Test'}

        result = self.graph_api_service.delete(url_part, params)

        self.assertEqual(result, self.response_content)
        requests_mock.delete.assert_called_with(url=self.graph_api_service.graph_api_url + url_part,
                                             params=params)

    @mock.patch.object(GraphApiService, 'post')
    def test_create_node(self, post_mock):
        post_mock.return_value = self.response_content
        label = 'Test'

        result = self.graph_api_service.create_node(label)

        self.assertEqual(result, self.response_content)
        post_mock.assert_called_with('/nodes', {"labels": [label]})

    @mock.patch.object(GraphApiService, 'get')
    def test_get_nodes(self, get_mock):
        get_mock.return_value = self.response_content
        label = 'Test'

        result = self.graph_api_service.get_nodes(label)

        self.assertEqual(result, self.response_content)
        get_mock.assert_called_with('/nodes', {"label": label})

    @mock.patch.object(GraphApiService, 'get')
    def test_get_node_relationships(self, get_mock):
        get_mock.return_value = self.response_content
        node_id = 1

        result = self.graph_api_service.get_node_relationships(node_id)

        self.assertEqual(result, self.response_content)
        get_mock.assert_called_with('/nodes/1/relationships', {})

    @mock.patch.object(GraphApiService, 'delete')
    def test_delete_node(self, delete_mock):
        delete_mock.return_value = self.response_content
        node_id = 1

        result = self.graph_api_service.delete_node(node_id)

        self.assertEqual(result, self.response_content)
        delete_mock.assert_called_with('/nodes/1', {})

    @mock.patch.object(GraphApiService, 'post')
    def test_create_properties(self, post_mock):
        post_mock.return_value = self.response_content
        node_id = 1
        node_model = ActivityExecutionIn(activity_id=1, arrangement_id=2,
                                         identifier=1, additional_properties=[{'key': 'test', 'value': 'test'}])

        result = self.graph_api_service.create_properties(node_id, node_model)

        self.assertEqual(result, self.response_content)
        post_mock.assert_called_with("/nodes/1/properties", [{'key': 'activity_id', 'value': 1},
                                                             {'key':'arrangement_id', 'value': 2},
                                                             {'key': 'test', 'value': 'test'}])

    @mock.patch.object(GraphApiService, 'post')
    def test_create_relationships(self, post_mock):
        post_mock.return_value = self.response_content
        start_node = 1
        end_node = 2
        name = 'hasNode'

        result = self.graph_api_service.create_relationships(start_node, end_node, name)

        self.assertEqual(result, self.response_content)
        post_mock.assert_called_with("/relationships", {"start_node": 1, "end_node": 2, "name": 'hasNode'})

    @mock.patch.object(GraphApiService, 'delete')
    def test_delete_relationship(self, delete_mock):
        delete_mock.return_value = self.response_content
        relationship_id = 1

        result = self.graph_api_service.delete_relationship(relationship_id)

        self.assertEqual(result, self.response_content)
        delete_mock.assert_called_with('/relationships/1', {})

    def test_create_additional_properties(self):
        property_dict = {'additional_properties': [{'key': 'test', 'value': 'test'},
                                                   {'key': 'key', 'value': 'value'}]}

        result = self.graph_api_service.create_additional_properties(property_dict)

        self.assertEqual(result, [{'key': 'test', 'value': 'test'}, {'key': 'key', 'value': 'value'}])
Esempio n. 6
0
class ParticipantService:
    """
    Object to handle logic of participants requests

    Attributes:
        graph_api_service (GraphApiService): Service used to communicate with Graph API
    """
    graph_api_service = GraphApiService()

    def save_participant(self, participant: ParticipantIn):
        """
        Send request to graph api to create new participant

        Args:
            participant (ParticipantIn): Participant to be added

        Returns:
            Result of request as participant object
        """
        node_response = self.graph_api_service.create_node("Participant")

        if node_response["errors"] is not None:
            return ParticipantOut(**participant.dict(), errors=node_response["errors"])

        participant_id = node_response["id"]
        properties_response = self.graph_api_service.create_properties(participant_id, participant)
        if properties_response["errors"] is not None:
            return ParticipantOut(**participant.dict(), errors=properties_response["errors"])

        return ParticipantOut(**participant.dict(), id=participant_id)

    def get_participants(self):
        """
        Send request to graph api to get participants

        Returns:
            Result of request as list of participants objects
        """
        get_response = self.graph_api_service.get_nodes("Participant")

        participants = []

        for participant_node in get_response["nodes"]:
            properties = {'id': participant_node['id'], 'additional_properties': []}
            for property in participant_node["properties"]:
                if property["key"] in ["name", "date_of_birth", "sex", "disorder"]:
                    properties[property["key"]] = property["value"]
                else:
                    properties['additional_properties'].append({'key': property['key'], 'value': property['value']})
            participant = BasicParticipantOut(**properties)
            participants.append(participant)

        return ParticipantsOut(participants=participants)

    def get_participant(self, participant_id: int):
        """
        Send request to graph api to get given participant

        Args:
            participant_id (int): Id of participant

        Returns:
            Result of request as participant object
        """
        get_response = self.graph_api_service.get_node(participant_id)

        if get_response["errors"] is not None:
            return NotFoundByIdModel(id=participant_id, errors=get_response["errors"])
        if get_response["labels"][0] != "Participant":
            return NotFoundByIdModel(id=participant_id, errors="Node not found.")

        participant = {'id': get_response['id'], 'additional_properties': [], 'relations': [], 'reversed_relations': []}
        for property in get_response["properties"]:
            if property["key"] in ["name", "date_of_birth", "sex", "disorder"]:
                participant[property["key"]] = property["value"]
            else:
                participant['additional_properties'].append({'key': property['key'], 'value': property['value']})

        relations_response = self.graph_api_service.get_node_relationships(participant_id)

        for relation in relations_response["relationships"]:
            if relation["start_node"] == participant_id:
                participant['relations'].append(RelationInformation(second_node_id=relation["end_node"],
                                                                    name=relation["name"], relation_id=relation["id"]))
            else:
                participant['reversed_relations'].append(RelationInformation(second_node_id=relation["start_node"],
                                                                             name=relation["name"],
                                                                             relation_id=relation["id"]))

        return ParticipantOut(**participant)

    def delete_participant(self, participant_id: int):
        """
        Send request to graph api to delete given participant

        Args:
            participant_id (int): Id of participant

        Returns:
            Result of request as participant object
        """
        get_response = self.get_participant(participant_id)

        if type(get_response) is NotFoundByIdModel:
            return get_response

        self.graph_api_service.delete_node(participant_id)
        return get_response

    def update_participant(self, participant_id: int, participant: ParticipantIn):
        """
        Send request to graph api to update given participant

        Args:
            participant_id (int): Id of participant
            participant (ParticipantIn): Properties to update

        Returns:
            Result of request as participant object
        """
        get_response = self.get_participant(participant_id)

        if type(get_response) is NotFoundByIdModel:
            return get_response

        if participant.date_of_birth is not None:
            participant.date_of_birth = participant.date_of_birth.__str__()

        self.graph_api_service.delete_node_properties(participant_id)
        self.graph_api_service.create_properties(participant_id, participant)

        participant_result = {"id": participant_id, 'relations': get_response.relations,
                              'reversed_relations': get_response.reversed_relations}
        participant_result.update(participant.dict())

        return ParticipantOut(**participant_result)
Esempio n. 7
0
class TimeSeriesService:
    """
    Object to handle logic of time series requests

    Attributes:
        graph_api_service (GraphApiService): Service used to communicate with Graph API
        measure_service (MeasureService): Service to manage measure models
        observable_information_service (ObservableInformationService): Service to manage observable information models
    """
    graph_api_service = GraphApiService()
    measure_service = MeasureService()
    observable_information_service = ObservableInformationService()

    def save_time_series(self, time_series: TimeSeriesIn):
        """
        Send request to graph api to create new time series

        Args:
            time_series (TimeSeriesIn): Time series to be added

        Returns:
            Result of request as time series object
        """
        node_response = self.graph_api_service.create_node("`Time Series`")

        if node_response["errors"] is not None:
            return TimeSeriesOut(**time_series.dict(), errors=node_response["errors"])

        time_series_id = node_response["id"]

        if time_series.observable_information_id is not None and \
                type(self.observable_information_service.get_observable_information(
                    time_series.observable_information_id)) is not NotFoundByIdModel:
            self.graph_api_service.create_relationships(start_node=time_series_id,
                                                        end_node=time_series.observable_information_id,
                                                        name="hasObservableInformation")
        if time_series.measure_id is not None and \
                type(self.measure_service.get_measure(time_series.measure_id)) is not NotFoundByIdModel:
            self.graph_api_service.create_relationships(start_node=time_series_id,
                                                        end_node=time_series.measure_id,
                                                        name="hasMeasure")

        time_series.observable_information_id = time_series.measure_id = None
        self.graph_api_service.create_properties(time_series_id, time_series)

        return self.get_time_series(time_series_id)

    def get_time_series_nodes(self):
        """
        Send request to graph api to get time series nodes

        Returns:
            Result of request as list of time series nodes objects
        """
        get_response = self.graph_api_service.get_nodes("`Time Series`")

        time_series_nodes = []

        for time_series_node in get_response["nodes"]:
            properties = {'id': time_series_node['id'], 'additional_properties': []}
            for property in time_series_node["properties"]:
                if property["key"] in ["type", "source"]:
                    properties[property["key"]] = property["value"]
                else:
                    properties['additional_properties'].append({'key': property['key'], 'value': property['value']})
            time_series = BasicTimeSeriesOut(**properties)
            time_series_nodes.append(time_series)

        return TimeSeriesNodesOut(time_series_nodes=time_series_nodes)

    def get_time_series(self, time_series_id: int):
        """
        Send request to graph api to get given time series

        Args:
            time_series_id (int): Id of time series

        Returns:
            Result of request as time series object
        """
        get_response = self.graph_api_service.get_node(time_series_id)

        if get_response["errors"] is not None:
            return NotFoundByIdModel(id=time_series_id, errors=get_response["errors"])
        if get_response["labels"][0] != "Time Series":
            return NotFoundByIdModel(id=time_series_id, errors="Node not found.")

        time_series = {'id': get_response['id'], 'additional_properties': [], 'relations': [],
                             'reversed_relations': []}
        for property in get_response["properties"]:
            if property["key"] in ["type", "source"]:
                time_series[property["key"]] = property["value"]
            else:
                time_series['additional_properties'].append({'key': property['key'], 'value': property['value']})

        relations_response = self.graph_api_service.get_node_relationships(time_series_id)

        for relation in relations_response["relationships"]:
            if relation["start_node"] == time_series_id:
                time_series['relations'].append(RelationInformation(second_node_id=relation["end_node"],
                                                                          name=relation["name"],
                                                                          relation_id=relation["id"]))
            else:
                time_series['reversed_relations'].append(RelationInformation(second_node_id=relation["start_node"],
                                                                                   name=relation["name"],
                                                                                   relation_id=relation["id"]))

        return TimeSeriesOut(**time_series)

    def delete_time_series(self, time_series_id: int):
        """
        Send request to graph api to delete given time series

        Args:
            time_series_id (int): Id of time series

        Returns:
            Result of request as time series object
        """
        get_response = self.get_time_series(time_series_id)

        if type(get_response) is NotFoundByIdModel:
            return get_response

        self.graph_api_service.delete_node(time_series_id)
        return get_response

    def update_time_series(self, time_series_id: int, time_series: TimeSeriesPropertyIn):
        """
        Send request to graph api to update given time series

        Args:
            time_series_id (int): Id of time series
            time_series (TimeSeriesPropertyIn): Properties to update

        Returns:
            Result of request as time series object
        """
        get_response = self.get_time_series(time_series_id)

        if type(get_response) is NotFoundByIdModel:
            return get_response

        self.graph_api_service.delete_node_properties(time_series_id)
        self.graph_api_service.create_properties(time_series_id, time_series)

        time_series_result = {"id": time_series_id, "relations": get_response.relations,
                                    "reversed_relations": get_response.reversed_relations}
        time_series_result.update(time_series.dict())

        return TimeSeriesOut(**time_series_result)

    def update_time_series_relationships(self, time_series_id: int,
                                               time_series: TimeSeriesRelationIn):
        """
        Send request to graph api to update given time series

        Args:
            time_series_id (int): Id of time series
            time_series (TimeSeriesRelationIn): Relationships to update

        Returns:
            Result of request as time series object
        """
        get_response = self.get_time_series(time_series_id)

        if type(get_response) is NotFoundByIdModel:
            return get_response

        if time_series.observable_information_id is not None and \
                type(self.observable_information_service.get_observable_information(
                    time_series.observable_information_id)) is not NotFoundByIdModel:
            self.graph_api_service.create_relationships(start_node=time_series_id,
                                                        end_node=time_series.observable_information_id,
                                                        name="hasObservableInformation")
        if time_series.measure_id is not None and \
                type(self.measure_service.get_measure(time_series.measure_id)) is not NotFoundByIdModel:
            self.graph_api_service.create_relationships(start_node=time_series_id,
                                                        end_node=time_series.personality_id,
                                                        name="hasMeasure")

        return self.get_time_series(time_series_id)
class MeasureService:
    """
    Object to handle logic of measure requests

    Attributes:
        graph_api_service (GraphApiService): Service used to communicate with Graph API
        measure_name_service (MeasureNameService): Service to manage measure name models
    """
    graph_api_service = GraphApiService()
    measure_name_service = MeasureNameService()

    def save_measure(self, measure: MeasureIn):
        """
        Send request to graph api to create new measure

        Args:
            measure (MeasureIn): Measure to be added

        Returns:
            Result of request as measure object
        """
        node_response = self.graph_api_service.create_node("`Measure`")

        if node_response["errors"] is not None:
            return MeasureOut(**measure.dict(), errors=node_response["errors"])

        measure_id = node_response["id"]

        if measure.measure_name_id is not None and \
                type(self.measure_name_service.get_measure_name(measure.measure_name_id)) is not NotFoundByIdModel:
            self.graph_api_service.create_relationships(
                start_node=measure_id,
                end_node=measure.measure_name_id,
                name="hasMeasureName")

        measure.measure_name_id = None
        self.graph_api_service.create_properties(measure_id, measure)

        return self.get_measure(measure_id)

    def get_measures(self):
        """
        Send request to graph api to get measures

        Returns:
            Result of request as list of measures objects
        """
        get_response = self.graph_api_service.get_nodes("`Measure`")

        measures = []

        for measure_node in get_response["nodes"]:
            properties = {'id': measure_node['id']}
            for property in measure_node["properties"]:
                if property["key"] in ["datatype", "range", "unit"]:
                    properties[property["key"]] = property["value"]

            measure = BasicMeasureOut(**properties)
            measures.append(measure)

        return MeasuresOut(measures=measures)

    def get_measure(self, measure_id: int):
        """
        Send request to graph api to get given measure

        Args:
            measure_id (int): Id of measure

        Returns:
            Result of request as measure object
        """
        get_response = self.graph_api_service.get_node(measure_id)

        if get_response["errors"] is not None:
            return NotFoundByIdModel(id=measure_id,
                                     errors=get_response["errors"])
        if get_response["labels"][0] != "Measure":
            return NotFoundByIdModel(id=measure_id, errors="Node not found.")

        measure = {
            'id': get_response['id'],
            'relations': [],
            'reversed_relations': []
        }
        for property in get_response["properties"]:
            if property["key"] in ["datatype", "range", "unit"]:
                measure[property["key"]] = property["value"]

        relations_response = self.graph_api_service.get_node_relationships(
            measure_id)

        for relation in relations_response["relationships"]:
            if relation["start_node"] == measure_id:
                measure['relations'].append(
                    RelationInformation(second_node_id=relation["end_node"],
                                        name=relation["name"],
                                        relation_id=relation["id"]))
            else:
                measure['reversed_relations'].append(
                    RelationInformation(second_node_id=relation["start_node"],
                                        name=relation["name"],
                                        relation_id=relation["id"]))

        return MeasureOut(**measure)

    def delete_measure(self, measure_id: int):
        """
        Send request to graph api to delete given measure

        Args:
            measure_id (int): Id of measure

        Returns:
            Result of request as measure object
        """
        get_response = self.get_measure(measure_id)

        if type(get_response) is NotFoundByIdModel:
            return get_response

        self.graph_api_service.delete_node(measure_id)
        return get_response

    def update_measure(self, measure_id: int, measure: MeasurePropertyIn):
        """
        Send request to graph api to update given measure

        Args:
            measure_id (int): Id of measure
            measure (MeasurePropertyIn): Properties to update

        Returns:
            Result of request as measure object
        """
        get_response = self.get_measure(measure_id)

        if type(get_response) is NotFoundByIdModel:
            return get_response

        self.graph_api_service.delete_node_properties(measure_id)
        self.graph_api_service.create_properties(measure_id, measure)

        measure_result = {
            "id": measure_id,
            "relations": get_response.relations,
            "reversed_relations": get_response.reversed_relations
        }
        measure_result.update(measure.dict())

        return MeasureOut(**measure_result)

    def update_measure_relationships(self, measure_id: int,
                                     measure: MeasureRelationIn):
        """
        Send request to graph api to update given measure

        Args:
            measure_id (int): Id of measure
            measure (MeasureRelationIn): Relationships to update

        Returns:
            Result of request as measure object
        """
        get_response = self.get_measure(measure_id)

        if type(get_response) is NotFoundByIdModel:
            return get_response

        if measure.measure_name_id is not None and \
                type(self.measure_name_service.get_measure_name(
                    measure.measure_name_id)) is not NotFoundByIdModel:
            self.graph_api_service.create_relationships(
                start_node=measure_id,
                end_node=measure.measure_name_id,
                name="hasMeasureName")
        return self.get_measure(measure_id)
Esempio n. 9
0
class ArrangementService:
    """
    Object to handle logic of arrangement requests

    Attributes:
    graph_api_service (GraphApiService): Service used to communicate with Graph API
    """
    graph_api_service = GraphApiService()

    def save_arrangement(self, arrangement: ArrangementIn):
        """
        Send request to graph api to create new arrangement

        Args:
            arrangement (ArrangementIn): Arrangement to be added

        Returns:
            Result of request as arrangement object
        """

        node_response = self.graph_api_service.create_node("Arrangement")

        if node_response["errors"] is not None:
            return ArrangementOut(arrangement_type=arrangement.arrangement_type,
                                  arrangement_distance=arrangement.arrangement_distance, errors=node_response["errors"])

        arrangement_id = node_response["id"]

        properties_response = self.graph_api_service.create_properties(arrangement_id, arrangement)
        if properties_response["errors"] is not None:
            return ArrangementOut(arrangement_type=arrangement.arrangement_type,
                                  arrangement_distance=arrangement.arrangement_distance,
                                  errors=properties_response["errors"])

        return ArrangementOut(arrangement_type=arrangement.arrangement_type,
                              arrangement_distance=arrangement.arrangement_distance, id=arrangement_id)

    def get_arrangements(self):
        """
        Send request to graph api to get all arrangements

        Returns:
            Result of request as list of arrangement objects
        """
        get_response = self.graph_api_service.get_nodes("Arrangement")
        if get_response["errors"] is not None:
            return ArrangementsOut(errors=get_response["errors"])

        arrangements = []
        for arrangement in get_response["nodes"]:
            if arrangement["properties"][0]["key"] == 'arrangement_distance':
                arrangements.append(BasicArrangementOut(id=arrangement["id"],
                                                        arrangement_type=arrangement["properties"][1]["value"],
                                                        arrangement_distance=arrangement["properties"][0]["value"]))
            else:
                arrangements.append(BasicArrangementOut(id=arrangement["id"],
                                                        arrangement_type=arrangement["properties"][0]["value"],
                                                        arrangement_distance=None))

        return ArrangementsOut(arrangements=arrangements)

    def get_arrangement(self, arrangement_id: int):
        """
        Send request to graph api to get given arrangement

        Args:
            arrangement_id (int): Id of arrangement

        Returns:
            Result of request as arrangement object
        """
        get_response = self.graph_api_service.get_node(arrangement_id)

        if get_response["errors"] is not None:
            return NotFoundByIdModel(id=arrangement_id, errors=get_response["errors"])
        if get_response["labels"][0] != "Arrangement":
            return NotFoundByIdModel(id=arrangement_id, errors="Node not found.")

        arrangement = {'id': get_response['id'], 'relations': [], 'reversed_relations': []}
        for property in get_response["properties"]:
            arrangement[property["key"]] = property["value"]

        relations_response = self.graph_api_service.get_node_relationships(arrangement_id)

        for relation in relations_response["relationships"]:
            if relation["start_node"] == arrangement_id:
                arrangement['relations'].append(RelationInformation(second_node_id=relation["end_node"],
                                                                    name=relation["name"], relation_id=relation["id"]))
            else:
                arrangement['reversed_relations'].append(RelationInformation(second_node_id=relation["start_node"],
                                                                             name=relation["name"],
                                                                             relation_id=relation["id"]))

        return ArrangementOut(**arrangement)
class RecordingService:
    """
    Object to handle logic of recording requests

    Attributes:
    graph_api_service (GraphApiService): Service used to communicate with Graph API
    participation_service (ParticipationService): Service to send participation requests
    registered_channel_service(RegisteredChannelService): Service to send registered channel requests
    """
    graph_api_service = GraphApiService()
    participation_service = ParticipationService()
    registered_channel_service = RegisteredChannelService()

    def save_recording(self, recording: RecordingIn):
        """
        Send request to graph api to create new recording node

        Args:
            recording (RecordingIn): Recording to be added

        Returns:
            Result of request as recording object
        """
        node_response = self.graph_api_service.create_node("Recording")

        if node_response["errors"] is not None:
            return RecordingOut(**recording.dict(),
                                errors=node_response["errors"])

        recording_id = node_response["id"]

        if recording.participation_id is not None and \
                type(self.participation_service.get_participation(recording.participation_id)) is not NotFoundByIdModel:
            self.graph_api_service.create_relationships(
                start_node=recording_id,
                end_node=recording.participation_id,
                name="hasParticipation")
        if recording.registered_channel_id is not None and \
                type(self.registered_channel_service.get_registered_channel(recording.registered_channel_id)) \
                is not NotFoundByIdModel:
            self.graph_api_service.create_relationships(
                start_node=recording_id,
                end_node=recording.registered_channel_id,
                name="hasRegisteredChannel")
        recording.participation_id = recording.registered_channel_id = None
        self.graph_api_service.create_properties(recording_id, recording)

        return self.get_recording(recording_id)

    def get_recordings(self):
        """
        Send request to graph api to get recordings
        Returns:
            Result of request as list of recordings objects
        """
        get_response = self.graph_api_service.get_nodes("Recording")

        recordings = []

        for recording_node in get_response["nodes"]:
            properties = {
                'id': recording_node['id'],
                'additional_properties': []
            }
            for property in recording_node["properties"]:
                properties['additional_properties'].append({
                    'key':
                    property['key'],
                    'value':
                    property['value']
                })
            recording = BasicRecordingOut(**properties)
            recordings.append(recording)

        return RecordingsOut(recordings=recordings)

    def get_recording(self, recording_id: int):
        """
        Send request to graph api to get given recording
        Args:
            recording_id (int): Id of recording
        Returns:
            Result of request as recording object
        """
        get_response = self.graph_api_service.get_node(recording_id)

        if get_response["errors"] is not None:
            return NotFoundByIdModel(id=recording_id,
                                     errors=get_response["errors"])
        if get_response["labels"][0] != "Recording":
            return NotFoundByIdModel(id=recording_id, errors="Node not found.")

        recording = {
            'id': get_response['id'],
            'additional_properties': [],
            'relations': [],
            'reversed_relations': []
        }

        for property in get_response["properties"]:
            recording['additional_properties'].append({
                'key':
                property['key'],
                'value':
                property['value']
            })

        relations_response = self.graph_api_service.get_node_relationships(
            recording_id)

        for relation in relations_response["relationships"]:
            if relation["start_node"] == recording_id:
                recording['relations'].append(
                    RelationInformation(second_node_id=relation["end_node"],
                                        name=relation["name"],
                                        relation_id=relation["id"]))
            else:
                recording['reversed_relations'].append(
                    RelationInformation(second_node_id=relation["start_node"],
                                        name=relation["name"],
                                        relation_id=relation["id"]))

        return RecordingOut(**recording)

    def delete_recording(self, recording_id: int):
        """
        Send request to graph api to delete given recording
        Args:
            recording_id (int): Id of recording
        Returns:
            Result of request as recording object
        """
        get_response = self.get_recording(recording_id)

        if type(get_response) is NotFoundByIdModel:
            return get_response

        self.graph_api_service.delete_node(recording_id)
        return get_response

    def update_recording(self, recording_id: int,
                         recording: RecordingPropertyIn):
        """
        Send request to graph api to update given participant state
        Args:
            recording_id (int): Id of participant state
            recording (RecordingPropertyIn): Properties to update
        Returns:
            Result of request as participant state object
        """
        get_response = self.get_recording(recording_id)

        if type(get_response) is NotFoundByIdModel:
            return get_response

        self.graph_api_service.delete_node_properties(recording_id)
        self.graph_api_service.create_properties(recording_id, recording)

        recording_result = {
            "id": recording_id,
            "relations": get_response.relations,
            "reversed_relations": get_response.reversed_relations
        }
        recording_result.update(recording.dict())

        return RecordingOut(**recording_result)

    def update_recording_relationships(self, recording_id: int,
                                       recording: RecordingIn):
        """
        Send request to graph api to update given recording
        Args:
            recording_id (int): Id of recording
            recording (RecordingIn): Relationships to update
        Returns:
            Result of request as recording object
        """
        get_response = self.get_recording(recording_id)

        if type(get_response) is NotFoundByIdModel:
            return get_response

        if recording.participation_id is not None and \
                type(self.participation_service.get_participation(recording.participation_id)) is not NotFoundByIdModel:
            self.graph_api_service.create_relationships(
                start_node=recording_id,
                end_node=recording.participation_id,
                name="hasParticipation")
        if recording.registered_channel_id is not None and \
                type(self.registered_channel_service.get_registered_channel(recording.registered_channel_id)) \
                is not NotFoundByIdModel:
            self.graph_api_service.create_relationships(
                start_node=recording_id,
                end_node=recording.registered_channel_id,
                name="hasRegisteredChannel")

        return self.get_recording(recording_id)
Esempio n. 11
0
class ScenarioService:
    """
    Object to handle logic of scenarios requests

    Attributes:
    graph_api_service (GraphApiService): Service used to communicate with Graph API
    activity_execution_service (ActivityExecutionService): Service used to communicate with ActivityExecution
    experiment_service (ExperimentService): Service used to communicate with Experiment
    """
    graph_api_service = GraphApiService()
    activity_execution_service = ActivityExecutionService()
    experiment_service = ExperimentService()

    def save_scenario(self, scenario: ScenarioIn):
        """
        Send request to graph api to create new scenario

        Args:
            scenario (ScenarioIn): Scenario to be added

        Returns:
            Result of request as scenario object
        """
        activity_executions = [
            self.activity_execution_service.save_activity_execution(
                activity_execution=activity_execution)
            for activity_execution in scenario.activity_executions
        ]
        self.graph_api_service.create_relationships(scenario.experiment_id,
                                                    activity_executions[0].id,
                                                    'hasScenario')
        [
            self.graph_api_service.create_relationships(
                activity_executions[index - 1].id,
                activity_executions[index].id, 'nextActivityExecution')
            for index in range(1, len(activity_executions))
        ]

        return ScenarioOut(experiment_id=scenario.experiment_id,
                           activity_executions=activity_executions)

    def add_activity_execution(self, previous_id: int,
                               activity_execution: ActivityExecutionIn):
        """
        Send request to graph api to add activity_execution to scenario

        Args:
            previous_id (int): Id of previous activity_execution or experiment
            activity_execution (ActivityExecutionIn): ActivityExecution to be added

        Returns:
            Result of request as activity_execution object
        """
        relationships = self.graph_api_service.get_node_relationships(
            previous_id)['relationships']
        activity_execution_result = self.activity_execution_service.save_activity_execution(
            activity_execution)

        if previous_id in [
                relation['start_node'] for relation in relationships
                if relation['name'] == 'hasScenario'
        ]:
            self.graph_api_service.create_relationships(
                previous_id, activity_execution_result.id, 'hasScenario')
        else:
            self.graph_api_service.create_relationships(
                previous_id, activity_execution_result.id,
                'nextActivityExecution')

        try:
            next_id, relation_id = [
                (relation['end_node'], relation['id'])
                for relation in relationships if
                relation['name'] in ['hasScenario', 'nextActivityExecution']
                and relation['start_node'] == previous_id
            ][0]
        except IndexError:
            return activity_execution_result

        self.graph_api_service.create_relationships(
            activity_execution_result.id, next_id, 'nextActivityExecution')
        self.graph_api_service.delete_relationship(relation_id)

        return activity_execution_result

    def change_order_middle_with_last(self, middle_id, last_id,
                                      middle_relationships,
                                      last_relationships):
        """
            Changes order of the middle node and the last node

            Args:
                middle_id (int): Id of the middle node
                last_id (ActivityExecutionIn): Id of the last node
                middle_relationships: Relationships of the middle node
                last_relationships: Relationships of the last node
            Returns:
        """
        start_node, end_node, relation_name = (
            middle_relationships[0]['start_node'], last_id,
            middle_relationships[0]['name'])
        self.graph_api_service.create_relationships(start_node, end_node,
                                                    relation_name)

        if middle_relationships[1] == last_relationships[0]:
            # nodes are next to each other
            start_node, end_node, relation_name = (
                last_id, middle_relationships[1]['start_node'],
                middle_relationships[1]['name'])
            self.graph_api_service.create_relationships(
                start_node, end_node, relation_name)

            return

        # nodes are separated by other nodes
        start_node, end_node, relation_name = (
            last_id, middle_relationships[1]['end_node'],
            middle_relationships[1]['name'])
        self.graph_api_service.create_relationships(start_node, end_node,
                                                    relation_name)

        start_node, end_node, relation_name = (
            last_relationships[0]['start_node'], middle_id,
            last_relationships[0]['name'])
        if start_node != end_node:
            self.graph_api_service.create_relationships(
                start_node, end_node, relation_name)

        return

    def change_order_middle_with_middle(self, middle_id, last_id,
                                        middle_relationships,
                                        last_relationships):
        """
            Changes order of the two middle nodes

            Args:
                middle_id (int): Id of the middle node
                last_id (ActivityExecutionIn): Id of the middle node but second in order
                middle_relationships: Relationships of the middle node
                last_relationships: Relationships of the last node
            Returns:
        """
        start_node, end_node, relation_name = (
            middle_relationships[0]['start_node'], last_id,
            middle_relationships[0]['name'])
        self.graph_api_service.create_relationships(start_node, end_node,
                                                    relation_name)

        if middle_relationships[1] == last_relationships[0]:
            # nodes are next to each other
            start_node, end_node, relation_name = (
                last_id, middle_id, middle_relationships[1]['name'])
            self.graph_api_service.create_relationships(
                start_node, end_node, relation_name)

            start_node, end_node, relation_name = (
                middle_id, last_relationships[1]['end_node'],
                last_relationships[1]['name'])
            self.graph_api_service.create_relationships(
                start_node, end_node, relation_name)

            return

        start_node, end_node, relation_name = (
            last_id, middle_relationships[1]['end_node'],
            middle_relationships[1]['name'])
        self.graph_api_service.create_relationships(start_node, end_node,
                                                    relation_name)

        start_node, end_node, relation_name = (
            last_relationships[0]['start_node'], middle_id,
            last_relationships[0]['name'])
        if start_node != end_node:
            self.graph_api_service.create_relationships(
                start_node, end_node, relation_name)

        start_node, end_node, relation_name = (
            middle_id, last_relationships[1]['end_node'],
            last_relationships[1]['name'])
        self.graph_api_service.create_relationships(start_node, end_node,
                                                    relation_name)

        return

    def what_order(self, previous_relationships,
                   activity_execution_relationships):
        """
            Finds which node is in which order (starting from experiment) in the scenario

            Args:
                previous_relationships: Relationships of the previous node
                activity_execution_relationships: Relationships of the activity execution node
            Returns:
                True when is the first in order
                False when is the second in order
        """
        p_relationships = previous_relationships
        p_count = False
        a_relationships = activity_execution_relationships
        a_count = False
        while True:
            if p_relationships[0]['name'] is not None and p_relationships[0][
                    'name'] in ['hasScenario']:
                p_count = True
                break
            if a_relationships[0]['name'] is not None and a_relationships[0][
                    'name'] in ['hasScenario']:
                a_count = True
                break
            p_id = p_relationships[0]['start_node']
            p_relationships = self.graph_api_service.get_node_relationships(
                p_id)['relationships']
            p_relationships = [
                relation for relation in p_relationships if
                relation['name'] in ['nextActivityExecution', 'hasScenario']
                and relation['end_node'] == p_id
            ]
            a_id = a_relationships[0]['start_node']
            a_relationships = self.graph_api_service.get_node_relationships(
                a_id)['relationships']
            a_relationships = [
                relation for relation in a_relationships if
                relation['name'] in ['nextActivityExecution', 'hasScenario']
                and relation['end_node'] == a_id
            ]

        return p_count, a_count

    def swap_order_in_relationships_array(self, relationships, node_id):
        """
            Swaps order of relationships list so they are saved in order starting from experiment
            Args:
                relationships: List of relationships
                node_id: Id of node, that relationships belong to
            Returns:
                relationships: List of relationships in specified order
        """
        if relationships[0]['start_node'] == node_id:
            relationships[0], relationships[1] = relationships[
                1], relationships[0]

        return relationships

    def change_order(self, order_change: OrderChangeIn):
        """
        Send request to graph api to change order in scenario

        Args:
            order_change (OrderChangeIn): Ids of activity_executions to change order by

        Returns:
            Result of request as changed order ids
        """
        # save all relationships in lists
        previous_relationships = self.graph_api_service.get_node_relationships(
            order_change.previous_id)['relationships']
        activity_execution_relationships = \
            self.graph_api_service.get_node_relationships(order_change.activity_execution_id)['relationships']

        # check which node is before the other
        previous_first, activity_execution_first = self.what_order(
            previous_relationships, activity_execution_relationships)

        # delete nextActivityExecution and hasScenario relationships
        [
            self.graph_api_service.delete_relationship(relation['id'])
            for relation in previous_relationships
            if relation['name'] in ['nextActivityExecution', 'hasScenario']
        ]
        [
            self.graph_api_service.delete_relationship(relation['id'])
            for relation in activity_execution_relationships
            if relation['name'] in ['nextActivityExecution', 'hasScenario']
        ]

        # save nextActivityExecution and hasScenario relationships
        previous_relationships = [
            relation for relation in previous_relationships
            if relation['name'] in ['nextActivityExecution', 'hasScenario']
        ]
        activity_execution_relationships = [
            relation for relation in activity_execution_relationships
            if relation['name'] in ['nextActivityExecution', 'hasScenario']
        ]

        # swap order of relationships if needed
        previous_relationships = self.swap_order_in_relationships_array(
            previous_relationships, order_change.previous_id)
        activity_execution_relationships = self.swap_order_in_relationships_array(
            activity_execution_relationships,
            order_change.activity_execution_id)

        if len(activity_execution_relationships) == 1:
            # change order when activity execution node is last
            self.change_order_middle_with_last(
                middle_id=order_change.previous_id,
                last_id=order_change.activity_execution_id,
                middle_relationships=previous_relationships,
                last_relationships=activity_execution_relationships)

        elif len(previous_relationships) == 1:
            # change order when previous node is last
            self.change_order_middle_with_last(
                middle_id=order_change.activity_execution_id,
                last_id=order_change.previous_id,
                middle_relationships=activity_execution_relationships,
                last_relationships=previous_relationships)

        elif len(previous_relationships) == 2 and len(
                activity_execution_relationships) == 2:
            if previous_first is True:
                # change order when previous node is before activity execution node
                self.change_order_middle_with_middle(
                    middle_id=order_change.previous_id,
                    last_id=order_change.activity_execution_id,
                    middle_relationships=previous_relationships,
                    last_relationships=activity_execution_relationships)
            elif activity_execution_first is True:
                # change order when activity execution node is before previous node
                self.change_order_middle_with_middle(
                    middle_id=order_change.activity_execution_id,
                    last_id=order_change.previous_id,
                    middle_relationships=activity_execution_relationships,
                    last_relationships=previous_relationships)

        return OrderChangeOut(
            previous_id=order_change.previous_id,
            activity_execution_id=order_change.activity_execution_id)

    def delete_activity_execution(self, activity_execution_id: int):
        """
        Send request to graph api to delete activity_execution from scenario

        Args:
            activity_execution_id (int): Id of activity_execution to delete

        Returns:
            Result of request as activity_execution object
        """
        relationships = self.graph_api_service.get_node_relationships(
            activity_execution_id)['relationships']
        if len(relationships) == 0:
            return ActivityExecutionOut(errors='Relationships not found')

        activity_execution = self.graph_api_service.delete_node(
            activity_execution_id)

        properties = {
            p['key']: p['value']
            for p in activity_execution['properties']
        }
        additional_properties = [
            PropertyIn(key=key, value=value)
            for key, value in properties.items() if key not in ['activity']
        ]
        activity_execution_response = ActivityExecutionOut(
            id=activity_execution['id'],
            activity=properties['activity'],
            additional_properties=additional_properties)

        if len([
                relationship for relationship in relationships
                if relationship['name'] in
            ['hasScenario', 'nextActivityExecution']
        ]) == 1:
            return activity_execution_response

        start_node = [
            relationship['start_node'] for relationship in relationships
            if relationship['end_node'] == activity_execution_id and
            relationship['name'] in ['hasScenario', 'nextActivityExecution']
        ][0]
        end_node = [
            relationship['end_node'] for relationship in relationships
            if relationship['start_node'] == activity_execution_id
            and relationship['name'] == 'nextActivityExecution'
        ][0]
        self.graph_api_service.create_relationships(start_node, end_node,
                                                    relationships[0]['name'])

        return activity_execution_response

    def get_scenario(self, node_id: int):
        """
        Send request to graph api to get activity executions and experiment from scenario

        Args:
            node_id (int): Id of experiment or activity execution which is included in scenario

        Returns:
            Result of request as Scenario object
        """
        get_response = self.graph_api_service.get_node(node_id)

        if get_response["errors"] is not None:
            return NotFoundByIdModel(id=node_id, errors=get_response["errors"])
        if get_response["labels"][0] not in [
                "Activity Execution", "Experiment"
        ]:
            return NotFoundByIdModel(id=node_id, errors="Node not found.")

        if get_response["labels"][0] == "Activity Execution":
            return self.get_scenario_by_activity_execution(node_id)
        elif get_response["labels"][0] == "Experiment":
            return self.get_scenario_by_experiment(node_id)

    def get_scenario_by_experiment(self, experiment_id: int):
        """
        Send request to graph api to get activity_executions from scenario which starts in experiment

        Args:
            experiment_id (int): Id of experiment where scenario starts

        Returns:
            Result of request as Scenario object
        """
        activity_executions = []

        experiment = self.experiment_service.get_experiment(experiment_id)
        if type(experiment) is NotFoundByIdModel:
            return experiment

        scenario = {'experiment_id': experiment_id, 'activity_executions': []}

        for relation in experiment.relations:
            if relation.name == "hasScenario":
                self.get_scenario_after_activity_execution(
                    relation.second_node_id, activity_executions)

        [
            scenario['activity_executions'].append(a)
            for a in activity_executions
            if a not in scenario['activity_executions']
        ]

        return ScenarioOut(**scenario)

    def get_scenario_by_activity_execution(self, activity_execution_id: int):
        """
        Send request to graph api to get activity_executions from scenario which has activity execution id incuded

        Args:
            activity_execution_id (int): Id of activity execution included in scenario

        Returns:
            Result of request as Scenario object
        """
        activity_executions = []
        activity_executions_before = []

        activity_execution = self.activity_execution_service.get_activity_execution(
            activity_execution_id)
        if type(activity_execution) is NotFoundByIdModel:
            return activity_execution

        experiment_id = self.get_scenario_before_activity_execution(
            activity_execution_id, activity_executions_before)
        [
            activity_executions.append(a) for a in activity_executions_before
            if a not in activity_executions
        ]

        activity_executions_after = []

        self.get_scenario_after_activity_execution(activity_execution_id,
                                                   activity_executions_after)
        [
            activity_executions.append(a) for a in activity_executions_after
            if a not in activity_executions
        ]

        scenario = {'experiment_id': experiment_id, 'activity_executions': []}

        [
            scenario['activity_executions'].append(a)
            for a in activity_executions
        ]

        return ScenarioOut(**scenario)

    def get_scenario_after_activity_execution(self, activity_execution_id: int,
                                              activity_executions: []):
        """
        Gets activity executions from scenario which are saved after activity_execution_id

        Args:
            activity_execution_id (int): Id of activity execution included in scenario
            activity_executions: List of activity executions in scenario
        """
        activity_execution = self.activity_execution_service.get_activity_execution(
            activity_execution_id)

        if type(activity_execution) is NotFoundByIdModel:
            return activity_execution

        activity_executions.append(activity_execution)

        for relation in activity_execution.relations:
            if relation.name == "nextActivityExecution":
                activity_execution = self.activity_execution_service.get_activity_execution(
                    relation.second_node_id)

                if type(activity_execution) is NotFoundByIdModel:
                    return activity_execution

                activity_executions.append(activity_execution)
                [
                    self.get_scenario_after_activity_execution(
                        activity_execution.id, activity_executions)
                    for r in activity_execution.relations
                    if r.name == "nextActivityExecution"
                ]

    def get_scenario_before_activity_execution(self,
                                               activity_execution_id: int,
                                               activity_executions: []):
        """
        Gets activity executions from scenario which are saved before activity_execution_id

        Args:
            activity_execution_id (int): Id of activity execution included in scenario
            activity_executions: List of activity executions in scenario
        """
        activity_execution = self.activity_execution_service.get_activity_execution(
            activity_execution_id)
        if type(activity_execution) is NotFoundByIdModel:
            return activity_execution

        activity_executions.append(activity_execution)

        for relation in activity_execution.reversed_relations:

            if relation.name == "nextActivityExecution":
                activity_execution = self.activity_execution_service.get_activity_execution(
                    relation.second_node_id)
                if type(activity_execution) is NotFoundByIdModel:
                    return activity_execution

                activity_executions.append(activity_execution)
                return self.get_scenario_before_activity_execution(
                    activity_execution.id, activity_executions)

            elif relation.name == "hasScenario":
                experiment = self.experiment_service.get_experiment(
                    relation.second_node_id)
                if type(experiment) is NotFoundByIdModel:
                    return experiment

                return experiment.id
Esempio n. 12
0
class ParticipantStateService:
    """
    Object to handle logic of participant state requests

    Attributes:
        graph_api_service (GraphApiService): Service used to communicate with Graph API
        participant_service (ParticipantService): Service to manage participant models
        appearance_service (AppearanceService): Service to manage appearance models
        personality_service (PersonalityService): Service to manage personality models
    """
    graph_api_service = GraphApiService()
    participant_service = ParticipantService()
    appearance_service = AppearanceService()
    personality_service = PersonalityService()

    def save_participant_state(self, participant_state: ParticipantStateIn):
        """
        Send request to graph api to create new participant state

        Args:
            participant_state (ParticipantStateIn): Participant state to be added

        Returns:
            Result of request as participant state object
        """
        node_response = self.graph_api_service.create_node(
            "`Participant State`")

        if node_response["errors"] is not None:
            return ParticipantStateOut(**participant_state.dict(),
                                       errors=node_response["errors"])

        participant_state_id = node_response["id"]

        if participant_state.participant_id is not None and \
                type(self.participant_service.get_participant(participant_state.participant_id)) is not NotFoundByIdModel:
            self.graph_api_service.create_relationships(
                start_node=participant_state_id,
                end_node=participant_state.participant_id,
                name="hasParticipant")
        if participant_state.personality_id is not None and \
                type(self.personality_service.get_personality(participant_state.personality_id)) is not NotFoundByIdModel:
            self.graph_api_service.create_relationships(
                start_node=participant_state_id,
                end_node=participant_state.personality_id,
                name="hasPersonality")
        if participant_state.appearance_id is not None and \
                type(self.appearance_service.get_appearance(participant_state.appearance_id)) is not NotFoundByIdModel:
            self.graph_api_service.create_relationships(
                start_node=participant_state_id,
                end_node=participant_state.appearance_id,
                name="hasAppearance")

        participant_state.participant_id = participant_state.personality_id = participant_state.appearance_id = None
        self.graph_api_service.create_properties(participant_state_id,
                                                 participant_state)

        return self.get_participant_state(participant_state_id)

    def get_participant_states(self):
        """
        Send request to graph api to get participant states

        Returns:
            Result of request as list of participant states objects
        """
        get_response = self.graph_api_service.get_nodes("`Participant State`")

        participant_states = []

        for participant_state_node in get_response["nodes"]:
            properties = {
                'id': participant_state_node['id'],
                'additional_properties': []
            }
            for property in participant_state_node["properties"]:
                if property["key"] == "age":
                    properties[property["key"]] = property["value"]
                else:
                    properties['additional_properties'].append({
                        'key':
                        property['key'],
                        'value':
                        property['value']
                    })
            participant_state = BasicParticipantStateOut(**properties)
            participant_states.append(participant_state)

        return ParticipantStatesOut(participant_states=participant_states)

    def get_participant_state(self, participant_state_id: int):
        """
        Send request to graph api to get given participant state

        Args:
            participant_state_id (int): Id of participant state

        Returns:
            Result of request as participant state object
        """
        get_response = self.graph_api_service.get_node(participant_state_id)

        if get_response["errors"] is not None:
            return NotFoundByIdModel(id=participant_state_id,
                                     errors=get_response["errors"])
        if get_response["labels"][0] != "Participant State":
            return NotFoundByIdModel(id=participant_state_id,
                                     errors="Node not found.")

        participant_state = {
            'id': get_response['id'],
            'additional_properties': [],
            'relations': [],
            'reversed_relations': []
        }
        for property in get_response["properties"]:
            if property["key"] == "age":
                participant_state[property["key"]] = property["value"]
            else:
                participant_state['additional_properties'].append({
                    'key':
                    property['key'],
                    'value':
                    property['value']
                })

        relations_response = self.graph_api_service.get_node_relationships(
            participant_state_id)

        for relation in relations_response["relationships"]:
            if relation["start_node"] == participant_state_id:
                participant_state['relations'].append(
                    RelationInformation(second_node_id=relation["end_node"],
                                        name=relation["name"],
                                        relation_id=relation["id"]))
            else:
                participant_state['reversed_relations'].append(
                    RelationInformation(second_node_id=relation["start_node"],
                                        name=relation["name"],
                                        relation_id=relation["id"]))

        return ParticipantStateOut(**participant_state)

    def delete_participant_state(self, participant_state_id: int):
        """
        Send request to graph api to delete given participant state

        Args:
            participant_state_id (int): Id of participant state

        Returns:
            Result of request as participant state object
        """
        get_response = self.get_participant_state(participant_state_id)

        if type(get_response) is NotFoundByIdModel:
            return get_response

        self.graph_api_service.delete_node(participant_state_id)
        return get_response

    def update_participant_state(
            self, participant_state_id: int,
            participant_state: ParticipantStatePropertyIn):
        """
        Send request to graph api to update given participant state

        Args:
            participant_state_id (int): Id of participant state
            participant_state (ParticipantStatePropertyIn): Properties to update

        Returns:
            Result of request as participant state object
        """
        get_response = self.get_participant_state(participant_state_id)

        if type(get_response) is NotFoundByIdModel:
            return get_response

        self.graph_api_service.delete_node_properties(participant_state_id)
        self.graph_api_service.create_properties(participant_state_id,
                                                 participant_state)

        participant_state_result = {
            "id": participant_state_id,
            "relations": get_response.relations,
            "reversed_relations": get_response.reversed_relations
        }
        participant_state_result.update(participant_state.dict())

        return ParticipantStateOut(**participant_state_result)

    def update_participant_state_relationships(
            self, participant_state_id: int,
            participant_state: ParticipantStateRelationIn):
        """
        Send request to graph api to update given participant state

        Args:
            participant_state_id (int): Id of participant state
            participant_state (ParticipantStateRelationIn): Relationships to update

        Returns:
            Result of request as participant state object
        """
        get_response = self.get_participant_state(participant_state_id)

        if type(get_response) is NotFoundByIdModel:
            return get_response

        if participant_state.participant_id is not None and \
                type(self.participant_service.get_participant(
                    participant_state.participant_id)) is not NotFoundByIdModel:
            self.graph_api_service.create_relationships(
                start_node=participant_state_id,
                end_node=participant_state.participant_id,
                name="hasParticipant")
        if participant_state.personality_id is not None and \
                type(self.personality_service.get_personality(participant_state.personality_id)) is not NotFoundByIdModel:
            self.graph_api_service.create_relationships(
                start_node=participant_state_id,
                end_node=participant_state.personality_id,
                name="hasPersonality")
        if participant_state.appearance_id is not None and \
                type(self.appearance_service.get_appearance(participant_state.appearance_id)) is not NotFoundByIdModel:
            self.graph_api_service.create_relationships(
                start_node=participant_state_id,
                end_node=participant_state.appearance_id,
                name="hasAppearance")

        return self.get_participant_state(participant_state_id)
Esempio n. 13
0
class RegisteredChannelService:
    """
    Object to handle logic of registered channels requests

    Attributes:
    graph_api_service (GraphApiService): Service used to communicate with Graph API
    channel_service (ChannelService): Service to send channel requests
    registered_data_service (RegisteredDataService): Service to send registered data requests
    """
    graph_api_service = GraphApiService()
    channel_service = ChannelService()
    registered_data_service = RegisteredDataService()

    def save_registered_channel(self, registered_channel: RegisteredChannelIn):
        """
        Send request to graph api to create new registered channel

        Args:
            registered_channel (RegisteredChannelIn): Registered channel to be added

        Returns:
            Result of request as registered channel object
        """
        node_response = self.graph_api_service.create_node(
            "`Registered Channel`")

        if node_response["errors"] is not None:
            return RegisteredChannelOut(errors=node_response["errors"])
        registered_channel_id = node_response["id"]

        if registered_channel.channel_id is not None and \
                type(self.channel_service.get_channel(registered_channel.channel_id)) is not NotFoundByIdModel:
            self.graph_api_service.create_relationships(
                start_node=registered_channel_id,
                end_node=registered_channel.channel_id,
                name="hasChannel")
        if registered_channel.registered_data_id is not None and \
                type(self.registered_data_service.get_registered_data(registered_channel.registered_data_id)) \
                is not NotFoundByIdModel:
            self.graph_api_service.create_relationships(
                start_node=registered_channel_id,
                end_node=registered_channel.registered_data_id,
                name="hasRegisteredData")

        return self.get_registered_channel(registered_channel_id)

    def get_registered_channels(self):
        """
        Send request to graph api to get registered channels

        Returns:
            Result of request as list of registered channels objects
        """
        get_response = self.graph_api_service.get_nodes("`Registered Channel`")

        registered_channels = []

        for registered_channel_node in get_response["nodes"]:
            properties = {'id': registered_channel_node['id']}
            for property in registered_channel_node["properties"]:
                if property["key"] == "age":
                    properties[property["key"]] = property["value"]
            registered_channel = BasicRegisteredChannelOut(**properties)
            registered_channels.append(registered_channel)

        return RegisteredChannelsOut(registered_channels=registered_channels)

    def get_registered_channel(self, registered_channel_id: int):
        """
        Send request to graph api to get given registered channel

        Args:
            registered_channel_id (int): Id of registered channel

        Returns:
            Result of request as registered channel object
        """
        get_response = self.graph_api_service.get_node(registered_channel_id)

        if get_response["errors"] is not None:
            return NotFoundByIdModel(id=registered_channel_id,
                                     errors=get_response["errors"])
        if get_response["labels"][0] != "Registered Channel":
            return NotFoundByIdModel(id=registered_channel_id,
                                     errors="Node not found.")

        registered_channel = {
            'id': get_response['id'],
            'relations': [],
            'reversed_relations': []
        }
        for property in get_response["properties"]:
            if property["key"] == "age":
                registered_channel[property["key"]] = property["value"]

        relations_response = self.graph_api_service.get_node_relationships(
            registered_channel_id)

        for relation in relations_response["relationships"]:
            if relation["start_node"] == registered_channel_id:
                registered_channel['relations'].append(
                    RelationInformation(second_node_id=relation["end_node"],
                                        name=relation["name"],
                                        relation_id=relation["id"]))
            else:
                registered_channel['reversed_relations'].append(
                    RelationInformation(second_node_id=relation["start_node"],
                                        name=relation["name"],
                                        relation_id=relation["id"]))

        return RegisteredChannelOut(**registered_channel)

    def delete_registered_channel(self, registered_channel_id: int):
        """
        Send request to graph api to delete given registered channel

        Args:
            registered_channel_id (int): Id of registered channel

        Returns:
            Result of request as registered channel object
        """
        get_response = self.get_registered_channel(registered_channel_id)

        if type(get_response) is NotFoundByIdModel:
            return get_response

        self.graph_api_service.delete_node(registered_channel_id)
        return get_response

    def update_registered_channel_relationships(
            self, registered_channel_id: int,
            registered_channel: RegisteredChannelIn):
        """
        Send request to graph api to update given registered channel

        Args:
            registered_channel_id (int): Id of registered channel
            registered_channel (RegisteredChannelIn): Relationships to update

        Returns:
            Result of request as registered channel object
        """
        get_response = self.get_registered_channel(registered_channel_id)

        if type(get_response) is NotFoundByIdModel:
            return get_response

        if registered_channel.channel_id is not None and \
                type(self.channel_service.get_channel(registered_channel.channel_id)) is not NotFoundByIdModel:
            self.graph_api_service.create_relationships(
                start_node=registered_channel_id,
                end_node=registered_channel.channel_id,
                name="hasChannel")
        if registered_channel.registered_data_id is not None and \
                type(self.registered_data_service.get_registered_data(registered_channel.registered_data_id)) \
                is not NotFoundByIdModel:
            self.graph_api_service.create_relationships(
                start_node=registered_channel_id,
                end_node=registered_channel.registered_data_id,
                name="hasRegisteredData")

        return self.get_registered_channel(registered_channel_id)
class MeasureNameService:
    """
    Object to handle logic of measure name requests

    Attributes:
        graph_api_service (GraphApiService): Service used to communicate with Graph API
    """
    graph_api_service = GraphApiService()

    def save_measure_name(self, measure_name: MeasureNameIn):
        """
        Send request to graph api to create new measure name

        Args:
            measure_name (MeasureNameIn): Measure name to be added

        Returns:
            Result of request as measure name object
        """
        create_response = self.graph_api_service.create_node("`Measure Name`")

        if create_response["errors"] is not None:
            return MeasureNameOut(name=measure_name.name,
                                  type=measure_name.type,
                                  errors=create_response["errors"])

        measure_name_id = create_response["id"]
        properties_response = self.graph_api_service.create_properties(
            measure_name_id, measure_name)
        if properties_response["errors"] is not None:
            return MeasureNameOut(name=measure_name.name,
                                  type=measure_name.type,
                                  errors=properties_response["errors"])

        return MeasureNameOut(name=measure_name.name,
                              type=measure_name.type,
                              id=measure_name_id)

    def get_measure_names(self):
        """
        Send request to graph api to get all measure names

        Returns:
            Result of request as list of measure name objects
        """
        get_response = self.graph_api_service.get_nodes("`Measure Name`")
        if get_response["errors"] is not None:
            return MeasureNamesOut(errors=get_response["errors"])
        measure_names = [
            BasicMeasureNameOut(id=measure_name["id"],
                                **{
                                    measure_name["properties"][0]["key"]:
                                    measure_name["properties"][0]["value"],
                                    measure_name["properties"][1]["key"]:
                                    measure_name["properties"][1]["value"]
                                }) for measure_name in get_response["nodes"]
        ]

        return MeasureNamesOut(measure_names=measure_names)

    def get_measure_name(self, measure_name_id: int):
        """
        Send request to graph api to get given measure name

        Args:
        measure_name_id (int): Id of measure name

        Returns:
            Result of request as measure name object
        """
        get_response = self.graph_api_service.get_node(measure_name_id)

        if get_response["errors"] is not None:
            return NotFoundByIdModel(id=measure_name_id,
                                     errors=get_response["errors"])
        if get_response["labels"][0] != "Measure Name":
            return NotFoundByIdModel(id=measure_name_id,
                                     errors="Node not found.")

        measure_name = {
            'id': get_response['id'],
            'relations': [],
            'reversed_relations': []
        }
        for property in get_response["properties"]:
            measure_name[property["key"]] = property["value"]

        relations_response = self.graph_api_service.get_node_relationships(
            measure_name_id)

        for relation in relations_response["relationships"]:
            if relation["start_node"] == measure_name_id:
                measure_name['relations'].append(
                    RelationInformation(second_node_id=relation["end_node"],
                                        name=relation["name"],
                                        relation_id=relation["id"]))
            else:
                measure_name['reversed_relations'].append(
                    RelationInformation(second_node_id=relation["start_node"],
                                        name=relation["name"],
                                        relation_id=relation["id"]))

        return MeasureNameOut(**measure_name)
class ModalityService:
    """
    Object to handle logic of modality requests

    Attributes:
        graph_api_service (GraphApiService): Service used to communicate with Graph API
    """
    graph_api_service = GraphApiService()

    def save_modality(self, modality: ModalityIn):
        """
        Send request to graph api to create new modality

        Args:
            modality (ModalityIn): Modality to be added

        Returns:
            Result of request as modality object
        """

        node_response = self.graph_api_service.create_node("Modality")

        if node_response["errors"] is not None:
            return ModalityOut(modality=modality.modality, errors=node_response["errors"])

        modality_id = node_response["id"]

        properties_response = self.graph_api_service.create_properties(modality_id, modality)
        if properties_response["errors"] is not None:
            return ModalityOut(modality=modality.modality, errors=properties_response["errors"])

        return ModalityOut(modality=modality.modality, id=modality_id)

    def get_modalities(self):
        """
        Send request to graph api to get all modalities

        Returns:
            Result of request as list of modality objects
        """
        get_response = self.graph_api_service.get_nodes("Modality")
        modalities = [BasicModalityOut(id=modality["id"], modality=modality["properties"][0]["value"])
                      for modality in get_response["nodes"]]

        return ModalitiesOut(modalities=modalities)

    def get_modality(self, modality_id: int):
        """
        Send request to graph api to get given modality

        Args:
        modality_id (int): Id of modality

        Returns:
            Result of request as modality object
        """
        get_response = self.graph_api_service.get_node(modality_id)

        if get_response["errors"] is not None:
            return NotFoundByIdModel(id=modality_id, errors=get_response["errors"])
        if get_response["labels"][0] != "Modality":
            return NotFoundByIdModel(id=modality_id, errors="Node not found.")

        modality = {'id': get_response['id'], 'relations': [], 'reversed_relations': []}
        for property in get_response["properties"]:
            modality[property["key"]] = property["value"]

        relations_response = self.graph_api_service.get_node_relationships(modality_id)

        for relation in relations_response["relationships"]:
            if relation["start_node"] == modality_id:
                modality['relations'].append(RelationInformation(second_node_id=relation["end_node"],
                                                                 name=relation["name"], relation_id=relation["id"]))
            else:
                modality['reversed_relations'].append(RelationInformation(second_node_id=relation["start_node"],
                                                                          name=relation["name"],
                                                                          relation_id=relation["id"]))

        return ModalityOut(**modality)
Esempio n. 16
0
class AppearanceService:
    """
    Object to handle logic of appearance requests

    Attributes:
        graph_api_service (GraphApiService): Service used to communicate with Graph API
    """
    graph_api_service = GraphApiService()

    def save_appearance_occlusion(self, appearance: AppearanceOcclusionIn):
        """
        Send request to graph api to create new appearance occlusion model

        Args:
            appearance (AppearanceIn): Appearance to be added

        Returns:
            Result of request as appearance state object
        """
        node_response = self.graph_api_service.create_node("Appearance")

        if node_response["errors"] is not None:
            return AppearanceOcclusionOut(glasses=appearance.glasses,
                                          beard=appearance.beard,
                                          moustache=appearance.moustache,
                                          errors=node_response["errors"])

        appearance_id = node_response["id"]

        properties_response = self.graph_api_service.create_properties(
            appearance_id, appearance)
        if properties_response["errors"] is not None:
            return AppearanceOcclusionOut(glasses=appearance.glasses,
                                          beard=appearance.beard,
                                          moustache=appearance.moustache,
                                          errors=properties_response["errors"])

        return AppearanceOcclusionOut(glasses=appearance.glasses,
                                      beard=appearance.beard,
                                      moustache=appearance.moustache,
                                      id=appearance_id)

    def save_appearance_somatotype(self, appearance: AppearanceSomatotypeIn):
        """
        Send request to graph api to create new appearance somatotype model

        Args:
            appearance (AppearanceIn): Appearance to be added

        Returns:
            Result of request as appearance state object
        """

        if not 1 <= appearance.ectomorph <= 7 or not 1 <= appearance.endomorph <= 7 \
                or not 1 <= appearance.mesomorph <= 7:
            return AppearanceSomatotypeOut(
                ectomorph=appearance.ectomorph,
                endomorph=appearance.endomorph,
                mesomorph=appearance.mesomorph,
                errors="Scale range not between 1 and 7")

        node_response = self.graph_api_service.create_node("Appearance")

        if node_response["errors"] is not None:
            return AppearanceSomatotypeOut(ectomorph=appearance.ectomorph,
                                           endomorph=appearance.endomorph,
                                           mesomorph=appearance.mesomorph,
                                           errors=node_response["errors"])

        appearance_id = node_response["id"]

        properties_response = self.graph_api_service.create_properties(
            appearance_id, appearance)
        if properties_response["errors"] is not None:
            return AppearanceSomatotypeOut(
                ectomorph=appearance.ectomorph,
                endomorph=appearance.endomorph,
                mesomorph=appearance.mesomorph,
                errors=properties_response["errors"])

        return AppearanceSomatotypeOut(ectomorph=appearance.ectomorph,
                                       endomorph=appearance.endomorph,
                                       mesomorph=appearance.mesomorph,
                                       id=appearance_id)

    def get_appearance(self, appearance_id: int):
        """
        Send request to graph api to get given appearance

        Args:
            appearance_id (int): Id of appearance

        Returns:
            Result of request as appearance object
        """
        get_response = self.graph_api_service.get_node(appearance_id)

        if get_response["errors"] is not None:
            return NotFoundByIdModel(id=appearance_id,
                                     errors=get_response["errors"])
        if get_response["labels"][0] != "Appearance":
            return NotFoundByIdModel(id=appearance_id,
                                     errors="Node not found.")

        appearance = {
            'id': appearance_id,
            'relations': [],
            'reversed_relations': []
        }
        appearance.update({
            property["key"]: property["value"]
            for property in get_response["properties"]
        })

        relations_response = self.graph_api_service.get_node_relationships(
            appearance_id)

        for relation in relations_response["relationships"]:
            if relation["start_node"] == appearance_id:
                appearance["relations"].append(
                    RelationInformation(second_node_id=relation["end_node"],
                                        name=relation["name"],
                                        relation_id=relation["id"]))
            else:
                appearance["reversed_relations"].append(
                    RelationInformation(second_node_id=relation["start_node"],
                                        name=relation["name"],
                                        relation_id=relation["id"]))

        return AppearanceOcclusionOut(**appearance) if "glasses" in appearance.keys() \
            else AppearanceSomatotypeOut(**appearance)

    def get_appearances(self):
        """
        Send request to graph api to get appearances

        Returns:
            Result of request as list of appearances objects
        """
        get_response = self.graph_api_service.get_nodes("Appearance")

        appearances = []

        for appearance_node in get_response["nodes"]:
            properties = {
                property["key"]: property["value"]
                for property in appearance_node["properties"]
            }
            properties["id"] = appearance_node["id"]
            appearance = BasicAppearanceOcclusionOut(**properties) if "glasses" in properties.keys() \
                else BasicAppearanceSomatotypeOut(**properties)
            appearances.append(appearance)

        return AppearancesOut(appearances=appearances)

    def delete_appearance(self, appearance_id: int):
        """
        Send request to graph api to delete given appearance

        Args:
            appearance_id (int): Id of appearance

        Returns:
            Result of request as appearance object
        """
        get_response = self.get_appearance(appearance_id)

        if type(get_response) is NotFoundByIdModel:
            return get_response
        self.graph_api_service.delete_node(appearance_id)
        return get_response

    def update_appearance_occlusion(self, appearance_id: int,
                                    appearance: AppearanceOcclusionIn):
        """
        Send request to graph api to update given appearance occlusion model

        Args:
            appearance_id (int): Id of appearance
            appearance (AppearanceOcclusionIn): Properties to update

        Returns:
            Result of request as appearance object
        """
        get_response = self.get_appearance(appearance_id)

        if type(get_response) is NotFoundByIdModel:
            return get_response
        if type(get_response) is AppearanceSomatotypeOut:
            return NotFoundByIdModel(id=appearance_id,
                                     errors="Node not found.")

        self.graph_api_service.create_properties(appearance_id, appearance)

        appearance_response = get_response.dict()
        appearance_response.update(appearance)
        return AppearanceOcclusionOut(**appearance_response)

    def update_appearance_somatotype(self, appearance_id: int,
                                     appearance: AppearanceSomatotypeIn):
        """
        Send request to graph api to update given appearance somatotype model

        Args:
            appearance_id (int): Id of appearance
            appearance (AppearanceSomatotypeIn): Properties to update

        Returns:
            Result of request as appearance object
        """
        if not 1 <= appearance.ectomorph <= 7 or not 1 <= appearance.endomorph <= 7 \
                or not 1 <= appearance.mesomorph <= 7:

            return AppearanceSomatotypeOut(
                **appearance.dict(), errors="Scale range not between 1 and 7")

        get_response = self.get_appearance(appearance_id)
        if type(get_response) is NotFoundByIdModel:
            return get_response
        if type(get_response) is AppearanceOcclusionOut:
            return NotFoundByIdModel(id=appearance_id,
                                     errors="Node not found.")

        self.graph_api_service.create_properties(appearance_id, appearance)

        appearance_response = get_response.dict()
        appearance_response.update(appearance)
        return AppearanceSomatotypeOut(**appearance_response)
Esempio n. 17
0
class ObservableInformationService:
    """
    Object to handle logic of observable information requests

    Attributes:
    graph_api_service (GraphApiService): Service used to communicate with Graph API
    modality_service (ModalityService): Service used to communicate with Modality
    life_activity_service (LifeActivityService): Service used to communicate with Life Activity
    recording_service (RecordingService): Service used to communicate with Recording
    """
    graph_api_service = GraphApiService()
    modality_service = ModalityService()
    life_activity_service = LifeActivityService()
    recording_service = RecordingService()

    def save_observable_information(
            self, observable_information: ObservableInformationIn):
        """
        Send request to graph api to create new observable information

        Args:
            observable_information (ObservableInformationIn): Observable information to be added

        Returns:
            Result of request as observable information object
        """
        node_response = self.graph_api_service.create_node(
            "`Observable Information`")

        if node_response["errors"] is not None:
            return ObservableInformationOut(errors=node_response["errors"])

        observable_information_id = node_response["id"]

        if observable_information.modality_id is not None and \
                type(self.modality_service.get_modality(observable_information.modality_id)) is not NotFoundByIdModel:
            self.graph_api_service.create_relationships(
                start_node=observable_information_id,
                end_node=observable_information.modality_id,
                name="hasModality")

        if observable_information.life_activity_id is not None and \
                type(self.life_activity_service.get_life_activity(
                    observable_information.life_activity_id)) is not NotFoundByIdModel:
            self.graph_api_service.create_relationships(
                start_node=observable_information_id,
                end_node=observable_information.life_activity_id,
                name="hasLifeActivity")

        if observable_information.recording_id is not None and \
                type(
                    self.recording_service.get_recording(observable_information.recording_id)) is not NotFoundByIdModel:
            self.graph_api_service.create_relationships(
                start_node=observable_information_id,
                end_node=observable_information.recording_id,
                name="hasRecording")

        return self.get_observable_information(observable_information_id)

    def get_observable_informations(self):
        """
        Send request to graph api to get observable information
        Returns:
            Result of request as list of observable information objects
        """
        get_response = self.graph_api_service.get_nodes(
            "`Observable Information`")

        observable_informations = []

        for observable_information_node in get_response["nodes"]:
            properties = {'id': observable_information_node['id']}
            observable_information = BasicObservableInformationOut(
                **properties)
            observable_informations.append(observable_information)

        return ObservableInformationsOut(
            observable_informations=observable_informations)

    def get_observable_information(self, observable_information_id: int):
        """
        Send request to graph api to get given observable information
        Args:
            observable_information_id (int): Id of observable information
        Returns:
            Result of request as observable information object
        """
        get_response = self.graph_api_service.get_node(
            observable_information_id)

        if get_response["errors"] is not None:
            return NotFoundByIdModel(id=observable_information_id,
                                     errors=get_response["errors"])
        if get_response["labels"][0] != "Observable Information":
            return NotFoundByIdModel(id=observable_information_id,
                                     errors="Node not found.")

        observable_information = {
            'id': get_response['id'],
            'relations': [],
            'reversed_relations': []
        }

        relations_response = self.graph_api_service.get_node_relationships(
            observable_information_id)

        for relation in relations_response["relationships"]:
            if relation["start_node"] == observable_information_id:
                observable_information['relations'].append(
                    RelationInformation(second_node_id=relation["end_node"],
                                        name=relation["name"],
                                        relation_id=relation["id"]))
            else:
                observable_information['reversed_relations'].append(
                    RelationInformation(second_node_id=relation["start_node"],
                                        name=relation["name"],
                                        relation_id=relation["id"]))

        return ObservableInformationOut(**observable_information)

    def delete_observable_information(self, observable_information_id: int):
        """
        Send request to graph api to delete given observable information
        Args:
            observable_information_id (int): Id of observable information
        Returns:
            Result of request as observable information object
        """
        get_response = self.get_observable_information(
            observable_information_id)

        if type(get_response) is NotFoundByIdModel:
            return get_response

        self.graph_api_service.delete_node(observable_information_id)
        return get_response

    def update_observable_information_relationships(
            self, observable_information_id: int,
            observable_information: ObservableInformationIn):
        """
        Send request to graph api to update given observable information
        Args:
            observable_information_id (int): Id of observable information
            observable_information (ObservableInformationIn): Relationships to update
        Returns:
            Result of request as observable information object
        """
        get_response = self.get_observable_information(
            observable_information_id)

        if type(get_response) is NotFoundByIdModel:
            return get_response

        if observable_information.modality_id is not None and \
                type(self.modality_service.get_modality(observable_information.modality_id)) is not NotFoundByIdModel:
            self.graph_api_service.create_relationships(
                start_node=observable_information_id,
                end_node=observable_information.modality_id,
                name="hasModality")

        if observable_information.life_activity_id is not None and \
                type(self.life_activity_service.get_life_activity(
                    observable_information.life_activity_id)) is not NotFoundByIdModel:
            self.graph_api_service.create_relationships(
                start_node=observable_information_id,
                end_node=observable_information.life_activity_id,
                name="hasLifeActivity")

        if observable_information.recording_id is not None and \
                type(
                    self.recording_service.get_recording(observable_information.recording_id)) is not NotFoundByIdModel:
            self.graph_api_service.create_relationships(
                start_node=observable_information_id,
                end_node=observable_information.recording_id,
                name="hasRecording")

        return self.get_observable_information(observable_information_id)
Esempio n. 18
0
class ParticipationService:
    """
    Object to handle logic of participation requests

    Attributes:
    graph_api_service (GraphApiService): Service used to communicate with Graph API
    activity_execution_service (ActivityExecutionService): Service to send activity execution requests
    participant_state_service (ParticipantStateService): Service to send participant state requests
    """
    graph_api_service = GraphApiService()
    activity_execution_service = ActivityExecutionService()
    participant_state_service = ParticipantStateService()

    def save_participation(self, participation: ParticipationIn):
        """
        Send request to graph api to create new participation

        Args:
            participation (ParticipationIn): Participation to be added

        Returns:
            Result of request as participation object
        """
        node_response = self.graph_api_service.create_node("Participation")

        if node_response["errors"] is not None:
            return ParticipationOut(errors=node_response["errors"])

        participation_id = node_response["id"]

        if participation.activity_execution_id is not None and \
                type(self.activity_execution_service.get_activity_execution(participation.activity_execution_id)) \
                is not NotFoundByIdModel:
            self.graph_api_service.create_relationships(
                participation_id, participation.activity_execution_id,
                "hasActivityExecution")

        if participation.participant_state_id is not None and \
                type(self.participant_state_service.get_participant_state(participation.participant_state_id)) \
                is not NotFoundByIdModel:
            self.graph_api_service.create_relationships(
                participation_id, participation.participant_state_id,
                "hasParticipantState")

        return self.get_participation(participation_id)

    def get_participations(self):
        """
        Send request to graph api to get participations
        Returns:
            Result of request as list of participation objects
        """
        get_response = self.graph_api_service.get_nodes("Participation")

        participations = []

        for participation_node in get_response["nodes"]:
            properties = {'id': participation_node['id']}
            participation = BasicParticipationOut(**properties)
            participations.append(participation)

        return ParticipationsOut(participations=participations)

    def get_participation(self, participation_id: int):
        """
        Send request to graph api to get given participation
        Args:
            participation_id (int): Id of participation
        Returns:
            Result of request as participation object
        """
        get_response = self.graph_api_service.get_node(participation_id)

        if get_response["errors"] is not None:
            return NotFoundByIdModel(id=participation_id,
                                     errors=get_response["errors"])
        if get_response["labels"][0] != "Participation":
            return NotFoundByIdModel(id=participation_id,
                                     errors="Node not found.")

        participation = {
            'id': get_response['id'],
            'relations': [],
            'reversed_relations': []
        }

        relations_response = self.graph_api_service.get_node_relationships(
            participation_id)

        for relation in relations_response["relationships"]:
            if relation["start_node"] == participation_id:
                participation['relations'].append(
                    RelationInformation(second_node_id=relation["end_node"],
                                        name=relation["name"],
                                        relation_id=relation["id"]))
            else:
                participation['reversed_relations'].append(
                    RelationInformation(second_node_id=relation["start_node"],
                                        name=relation["name"],
                                        relation_id=relation["id"]))

        return ParticipationOut(**participation)

    def delete_participation(self, participation_id: int):
        """
        Send request to graph api to delete given participation
        Args:
            participation_id (int): Id of participation
        Returns:
            Result of request as participation object
        """
        get_response = self.get_participation(participation_id)

        if type(get_response) is NotFoundByIdModel:
            return get_response

        self.graph_api_service.delete_node(participation_id)
        return get_response

    def update_participation_relationships(self, participation_id: int,
                                           participation: ParticipationIn):
        """
        Send request to graph api to update given participation relationships
        Args:
            participation_id (int): Id of participation
            participation (ParticipationIn): Relationships to update
        Returns:
            Result of request as participation object
        """
        get_response = self.get_participation(participation_id)

        if type(get_response) is NotFoundByIdModel:
            return get_response

        if participation.activity_execution_id is not None and \
                type(self.activity_execution_service.get_activity_execution(participation.activity_execution_id)) \
                is not NotFoundByIdModel:
            self.graph_api_service.create_relationships(
                participation_id, participation.activity_execution_id,
                "hasActivityExecution")

        if participation.participant_state_id is not None and \
                type(self.participant_state_service.get_participant_state(participation.participant_state_id)) \
                is not NotFoundByIdModel:
            self.graph_api_service.create_relationships(
                participation_id, participation.participant_state_id,
                "hasParticipantState")

        return self.get_participation(participation_id)
 def setUp(self):
     self.graph_api_service = GraphApiService()
     self.response_content = {'id': 1, 'errors': [], 'links': {}}
     self.response = Response()
     self.response._content = json.dumps(self.response_content).encode('utf-8')