Skip to content

Commit

Permalink
fix: change get_plugin_data; add get_plugin_value
Browse files Browse the repository at this point in the history
  • Loading branch information
faradox committed Nov 30, 2023
1 parent c7b05d3 commit e788e82
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 31 deletions.
13 changes: 6 additions & 7 deletions docs/usage/tracks.md
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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:
Expand Down
35 changes: 25 additions & 10 deletions src/nendo/schema/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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,
Expand Down
43 changes: 29 additions & 14 deletions tests/test_plugin_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -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."""
Expand All @@ -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."""
Expand All @@ -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."""
Expand All @@ -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"],
Expand All @@ -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"],
Expand Down

0 comments on commit e788e82

Please sign in to comment.