diff --git a/docs/usage/tracks.md b/docs/usage/tracks.md index 3239e4b..31fd321 100644 --- a/docs/usage/tracks.md +++ b/docs/usage/tracks.md @@ -295,6 +295,10 @@ Tracks in nendo have metadata attached to them, in the form of the `NendoTrack.m ### Working with plugin data +??? info "Plugin data version" + + Plugin data in Nendo Core is _versioned_, in accordance with the version of the plugin that was used to produce it. That means, that if a specific plugin is used to process a given track twice, it will only overwrite the previous data if the version of the plugin has not changed since the last run. This is to ensure proper traceability of results and to make the nendo library compatible with plugin upgrades. + The `NendoTrack` object provides various functions for processing it with a `NendoPlugin` and for accessing the resulting `NendoPluginData`: === "Running a plugin" @@ -334,23 +338,18 @@ The `NendoTrack` object provides various functions for processing it with a `Nen # ... ``` - You can also provide the specific `key` you are interested in to further filter the `plugin_data` entries. In the example, only a single entry was found for the given combination of `plugin_name` and `key` and thus, the `value` of the `plugin_data` is returned directly. + If you are sure that for a specific key, only a single `plugin_data` entry exists, you can also use the `get_plugin_value()` method that will directly return the value for a given key. If the track has multiple `plugin_data` entries for the given key, the _first_ one is returned (and actually, in most cases, it would make sense to use the `get_plugin_data()` method instead to make sure you really retrieve the value what you want). !!! example ```pycon - >>> plugin_data = track.get_plugin_data( - ... plugin_name="nendo_plugin_classify_core", + >>> plugin_data = track.get_plugin_value( ... key = "duration", ... ) >>> print(plugin_data) 121.1 ``` - ??? info "Plugin data version" - - Plugin data in Nendo Core is _versioned_, in accordance with the version of the plugin that was used to produce it. That means, that if a specific plugin is used to process a given track twice, it will only overwrite the previous data if the version of the plugin has not changed since the last run. This is to ensure proper traceability of results and to make the nendo library compatible with plugin upgrades. - ### Working with collections Aside from having relationships to other tracks, a `NendoTrack` can also have relationships to one or more [collections](#nendocollection). You can use the following functions to add or remove such assignments directly from the `NendoTrack` object: diff --git a/src/nendo/schema/core.py b/src/nendo/schema/core.py index 0ee6cac..39fc706 100644 --- a/src/nendo/schema/core.py +++ b/src/nendo/schema/core.py @@ -553,7 +553,7 @@ def get_plugin_data( self, plugin_name: str = "", key: str = "", - ) -> Union[List[NendoPluginData], str, NendoBlob]: + ) -> List[NendoPluginData]: """Get all plugin data related to the given plugin name and the given key. Note: Function behavior @@ -563,8 +563,6 @@ def get_plugin_data( plugin_name is returned. - If neither key, nor plugin_name is specified, all plugin data is returned. - - If the return value is a single item, it's `value` will be returned - directly, otherwise a list of `NendoPluginData` will be returned. - Certain kinds of plugin data are actually stored as blobs and the corresponding blob id is stored in the plugin data's value field. Those will be automatically loaded from the blob into memory @@ -591,17 +589,34 @@ def get_plugin_data( ): # if we have a UUID, load the corresponding blob if uuid_pattern.match(pd.value): - pd_loaded = self.nendo_instance.library.load_blob( + loaded_blob = self.nendo_instance.library.load_blob( blob_id=uuid.UUID(pd.value), ) - plugin_data.append(pd_loaded) - # otherwise it's "normal" (non-blobified) data, load directly - else: - plugin_data.append(pd) - if len(plugin_data) == 1: - return plugin_data[0].value + pd.value = loaded_blob + plugin_data.append(pd) return plugin_data + def get_plugin_value( + self, + key: str, + ) -> str: + """Return the value for a specific plugin_data key. + + Args: + key (str): The key for which the plugin data value should + be returned. + + Returns: + str: The plugin data value belonging to the given key. + If multiple plugin_data entries exist for the given key, + the first one is returned. If none exist, None is returned. + """ + pd = self.get_plugin_data(key = key) + print(pd) + if len(pd) == 0: + return None + return pd[0].value + def add_related_track( self, file_path: FilePath, diff --git a/tests/test_plugin_data.py b/tests/test_plugin_data.py index be771ad..63e4256 100644 --- a/tests/test_plugin_data.py +++ b/tests/test_plugin_data.py @@ -61,8 +61,23 @@ def test_get_plugin_data(self): self.assertEqual(len(plugin_data), 2) self.assertEqual(type(plugin_data[0]), NendoPluginData) plugin_data_2 = track.get_plugin_data(plugin_name="test_plugin", key="test2") - self.assertEqual(type(plugin_data_2), str) - self.assertEqual(plugin_data_2, "value2") + self.assertEqual(type(plugin_data_2), list) + self.assertEqual(plugin_data_2[0].value, "value2") + + def test_get_plugin_value(self): + nd.library.reset(force=True) + track = nd.library.add_track(file_path="tests/assets/test.mp3") + _ = nd.library.add_plugin_data( + track_id=track.id, + plugin_name="test_plugin", + plugin_version="1.0", + key="test", + value="value", + ) + track = nd.library.get_track(track_id=track.id) + plugin_value = track.get_plugin_value("test") + self.assertEqual(type(plugin_value), str) + self.assertEqual(plugin_value, "value") def test_filter_random_track(self): """Test the retrieval of a random `NendoTrack` from the library.""" @@ -80,8 +95,8 @@ def test_filter_random_track(self): order_by="random", plugin_names=["test_plugin"], )[0].get_plugin_data(plugin_name="test_plugin") - self.assertEqual(type(example_data), str) - self.assertEqual(example_data, pd.value) + self.assertEqual(type(example_data), list) + self.assertEqual(example_data[0].value, pd.value) def test_filter_by_plugin_data_and_filename(self): """Test filtering by plugin data and track file name.""" @@ -100,8 +115,8 @@ def test_filter_by_plugin_data_and_filename(self): order_by="random", plugin_names=["test_plugin"], )[0].get_plugin_data(plugin_name="test_plugin") - self.assertEqual(type(example_data), str) - self.assertEqual(example_data, pd.value) + self.assertEqual(type(example_data), list) + self.assertEqual(example_data[0].value, pd.value) def test_filter_tracks_by_plugin_data(self): """Test the filtering of `NendoTrack`s by plugin data.""" @@ -119,14 +134,14 @@ def test_filter_tracks_by_plugin_data(self): filters={"foo": "bar"}, plugin_names=["test_plugin"], )[0].get_plugin_data(plugin_name="test_plugin") - self.assertEqual(type(example_data), str) - self.assertEqual(example_data, track.plugin_data[0].value) + self.assertEqual(type(example_data), list) + self.assertEqual(example_data[0].value, track.plugin_data[0].value) example_data = nd.library.filter_tracks( filters={"foo": ["bar", "baz"]}, plugin_names=["test_plugin"], )[0].get_plugin_data(plugin_name="test_plugin") - self.assertEqual(type(example_data), str) - self.assertEqual(example_data, pd.value) + self.assertEqual(type(example_data), list) + self.assertEqual(example_data[0].value, pd.value) example_data = nd.library.filter_tracks( filters={"foo": ["bat", "baz"]}, plugin_names=["test_plugin"], @@ -144,14 +159,14 @@ def test_filter_tracks_by_plugin_data(self): filters={"number": (10.0, 20.0)}, plugin_names=["test_plugin"], )[0].get_plugin_data(plugin_name="test_plugin", key="number") - self.assertEqual(type(example_data), str) - self.assertEqual(example_data, pd2.value) + self.assertEqual(type(example_data), list) + self.assertEqual(example_data[0].value, pd2.value) example_data = nd.library.filter_tracks( filters={"number": (10, 20)}, plugin_names=["test_plugin"], )[0].get_plugin_data(plugin_name="test_plugin", key="number") - self.assertEqual(type(example_data), str) - self.assertEqual(example_data, pd2.value) + self.assertEqual(type(example_data), list) + self.assertEqual(example_data[0].value, pd2.value) example_data = nd.library.filter_tracks( filters={"number": (20.0, 30.0)}, plugin_names=["test_plugin"],