From d50923553dcab7be7e5e202cd8532fdf6ef284bc Mon Sep 17 00:00:00 2001 From: Lars Kruse Date: Sun, 22 May 2016 21:25:24 +0200 Subject: [PATCH] web: add API functions for retrieving unique values of specific keys the following API paths are added: * /item/values/FIELD * /album/values/FIELD Both paths will deliver a json dictionary with the key 'values' containing a list of unique values belonging to the requested table and field. Sorting is possible by supplying the query argument "sort_key". This feature is useful for remote clients, e.g. Mopidy-Beets: * track genres: /item/unique/genre * track languages: /album/unique/language * album artists: /album/unique/albumartist?sort_key=albumartist_sort * album years: /album/unique/year --- beetsplug/web/__init__.py | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/beetsplug/web/__init__.py b/beetsplug/web/__init__.py index ede4658a2..582eb1606 100644 --- a/beetsplug/web/__init__.py +++ b/beetsplug/web/__init__.py @@ -124,6 +124,16 @@ def resource_list(name): return make_responder +def _get_unique_table_field_values(model, field, sort_field): + """ retrieve all unique values belonging to a key from a model """ + if field not in model.all_keys() or sort_field not in model.all_keys(): + raise KeyError + with g.lib.transaction() as tx: + rows = tx.query('SELECT DISTINCT "{0}" FROM "{1}" ORDER BY "{2}"' + .format(field, model._table, sort_field)) + return [row[0] for row in rows] + + class IdListConverter(BaseConverter): """Converts comma separated lists of ids in urls to integer lists. """ @@ -194,6 +204,17 @@ def item_query(queries): return g.lib.items(queries) +@app.route('/item/values/') +def item_unique_field_values(key): + sort_key = flask.request.args.get('sort_key', key) + try: + values = _get_unique_table_field_values(beets.library.Item, key, + sort_key) + except KeyError: + return flask.abort(404) + return flask.jsonify(values=values) + + # Albums. @app.route('/album/') @@ -221,6 +242,17 @@ def album_art(album_id): return flask.send_file(album.artpath) +@app.route('/album/values/') +def album_unique_field_values(key): + sort_key = flask.request.args.get('sort_key', key) + try: + values = _get_unique_table_field_values(beets.library.Album, key, + sort_key) + except KeyError: + return flask.abort(404) + return flask.jsonify(values=values) + + # Artists. @app.route('/artist/')