Plugins/web: fix endpoints /…/values/… (#6158)

Following #4709 and #5447, the web plugin used single-quotes (ie. string
litteral) in the SQL query for table columns.

Thus, for instance, the query `GET /item/values/albumartist` would
return the litteral "albumartist" instead of a list of unique album
artists.

This prevents the Mopidy beets integration from working, returning the
single artist "albumartist".
This commit is contained in:
Sebastian Mohr 2025-11-17 10:21:31 +01:00 committed by GitHub
commit 88ca0ce1fb
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 25 additions and 2 deletions

View file

@ -17,9 +17,10 @@
import base64 import base64
import json import json
import os import os
import typing as t
import flask import flask
from flask import g, jsonify from flask import jsonify
from unidecode import unidecode from unidecode import unidecode
from werkzeug.routing import BaseConverter, PathConverter from werkzeug.routing import BaseConverter, PathConverter
@ -28,6 +29,17 @@ from beets import ui, util
from beets.dbcore.query import PathQuery from beets.dbcore.query import PathQuery
from beets.plugins import BeetsPlugin from beets.plugins import BeetsPlugin
# Type checking hacks
if t.TYPE_CHECKING:
class LibraryCtx(flask.ctx._AppCtxGlobals):
lib: beets.library.Library
g = LibraryCtx()
else:
from flask import g
# Utilities. # Utilities.
@ -232,7 +244,7 @@ def _get_unique_table_field_values(model, field, sort_field):
raise KeyError raise KeyError
with g.lib.transaction() as tx: with g.lib.transaction() as tx:
rows = tx.query( rows = tx.query(
f"SELECT DISTINCT '{field}' FROM '{model._table}' ORDER BY '{sort_field}'" f"SELECT DISTINCT {field} FROM {model._table} ORDER BY {sort_field}"
) )
return [row[0] for row in rows] return [row[0] for row in rows]

View file

@ -43,6 +43,10 @@ Bug fixes:
accepted a list of strings). :bug:`5962` accepted a list of strings). :bug:`5962`
- Fix a bug introduced in release 2.4.0 where import from any valid - Fix a bug introduced in release 2.4.0 where import from any valid
import-log-file always threw a "none of the paths are importable" error. import-log-file always threw a "none of the paths are importable" error.
- :doc:`/plugins/web`: repair broken `/item/values/…` and `/albums/values/…`
endpoints. Previously, due to single-quotes (ie. string literal) in the SQL
query, the query eg. `GET /item/values/albumartist` would return the literal
"albumartist" instead of a list of unique album artists.
For plugin developers: For plugin developers:

View file

@ -118,6 +118,13 @@ class WebPluginTest(ItemInDBTestCase):
assert response.status_code == 200 assert response.status_code == 200
assert len(res_json["items"]) == 3 assert len(res_json["items"]) == 3
def test_get_unique_item_artist(self):
response = self.client.get("/item/values/artist")
res_json = json.loads(response.data.decode("utf-8"))
assert response.status_code == 200
assert res_json["values"] == ["", "AAA Singers"]
def test_get_single_item_by_id(self): def test_get_single_item_by_id(self):
response = self.client.get("/item/1") response = self.client.get("/item/1")
res_json = json.loads(response.data.decode("utf-8")) res_json = json.loads(response.data.decode("utf-8"))