5.7 KiB
Genre tags
The issue
Funkwhale offers users a facility to assign genre tags to items such as tracks, albums, and artists. The tags_tag
table is populated automatically when new tags are found in uploaded content, and users can also enter custom tags. By default, the table is empty. This means that a user on a new pod won't see any results when attempting to tag items in the frontend.
The solution
To provide the best experience for new Funkwhale users, we should prepopulate this table with genre tags from Musicbrainz. Doing this enables users to easily search for and select the tags they want to assign to their content without needing to create custom tags or upload tagged content.
Having these tags easily available also facilitates better tagging within Funkwhale in future, reducing the reliance on external tools such as Picard.
Feature behavior
Backend behavior
The tags_tag
table contains the following fields:
Field | Data type | Description | Relations | Constraints |
---|---|---|---|---|
id |
Integer | The randomly generated table ID | tags_taggeditem.tag_id foreign key |
None |
musicbrainz_id |
UUID | The Musicbrainz genre tag id . Used to identify the tag in Musicbrainz fetches |
None | None |
name |
String | The name of the tag. Assigned by Funkwhale during creation for use in URLs. Uses Pascal casing for consistency | None | Must be unique |
display_name |
String | The name of the tag as the user entered it or as it was originally written by Musicbrainz. Lowercase, normalizes spaces | None | None |
creation_date |
Timestamp with time zone | The date on which the tag was created | None | None |
Musicbrainz fetch task
To keep Funkwhale's database up-to-date with Musicbrainz's genre tags, we must fetch information from Musicbrainz periodically. We can use the following endpoint to fetch the information:
https://musicbrainz.org/ws/2/genre/all
This endpoint accepts the application/json
header for a JSON response. See the Musicbrainz API documentation for more information.
The fetch task should run initially upon first startup and then monthly thereafter. The pod admin must be able to disable this job or run it manually at their discretion.
The task should use the following logic:
- Call the Musicbrainz API to fetch new data
- Verify the listed entries against the Funkwhale tag table. The
id
field in the response should be checked against themusicbrainz_id
field - Any entries that do not currently exist in Funkwhale should be added with the following mapping:
Musicbrainz response field | Tags table column | Notes |
---|---|---|
id |
musicbrainz_id |
|
name |
display_name |
Funkwhale should automatically generate a Pascal cased name based on this entry |
- If the
display_name
of a tag exactly matches aname
in the Musicbrainz response but the tag has nomusicbrainz_id
, themusicbrainz_id
should be populated
Frontend behavior
Tagged uploads
When a user uploads new content with genre tags, the tagged item should be linked to any existing tags and new ones should be created if they're not found.
In-app tagging
When a user uploads new content with no genre tags, they should be able to select tags from a dropdown menu. This menu is populated with the tags from the database with the display_name
shown in the list. When a tag is selected, the item is linked to the associated tag.
If a user inserts a new tag, Funkwhale should:
- Store the entered string as the tag's
display_name
- Generate a Pascal cased
name
for the tag - Associate the targeted object with the new tag
Search results
Users should be able to search for tags using Funkwhale's in-app search. In search autocomplete and search results page, the display_name
should be used. The name
of the tag should be used to populate the search URL.
Cards
The display_name
of the tag should be shown in pills against cards.
Availability
- Admin panel
- App frontend
- CLI
Responsible parties
- Backend group:
- Update the tracks table to support the new information
- Update the API to support the new information, or create a new v2 endpoint
- Create the new fetch task
- Add admin controls for the new task
- Frontend group:
- Update views to use
display_name
instead ofname
for tag results - Update API calls to use the new API structure created by the backend group
- Update views to use
- Documentation group:
- Document the new task and settings for admins