From 5831b99b9f1635580e8fc2d45c15ef04a64bccbd Mon Sep 17 00:00:00 2001 From: Max Ammann Date: Mon, 13 Jun 2016 14:05:30 +0200 Subject: [PATCH 1/7] Adding 'expand' flag for json requests This allows you to query the individual items of an album --- beetsplug/web/__init__.py | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/beetsplug/web/__init__.py b/beetsplug/web/__init__.py index 91b1b3a282..fefa4ce5f9 100644 --- a/beetsplug/web/__init__.py +++ b/beetsplug/web/__init__.py @@ -55,7 +55,7 @@ def _rep(obj, expand=False): return out -def json_generator(items, root): +def json_generator(items, root, expand=False): """Generator that dumps list of beets Items or Albums as JSON :param root: root key for JSON @@ -69,10 +69,14 @@ def json_generator(items, root): first = False else: yield ',' - yield json.dumps(_rep(item)) + yield json.dumps(_rep(item, expand=expand)) yield ']}' +def is_expand(args): + return "expand" in args + + def resource(name): """Decorates a function to handle RESTful HTTP requests for a resource. """ @@ -82,7 +86,7 @@ def responder(ids): entities = [entity for entity in entities if entity] if len(entities) == 1: - return flask.jsonify(_rep(entities[0])) + return flask.jsonify(_rep(entities[0], expand=is_expand(flask.request.args))) elif entities: return app.response_class( json_generator(entities, root=name), @@ -101,7 +105,7 @@ def resource_query(name): def make_responder(query_func): def responder(queries): return app.response_class( - json_generator(query_func(queries), root='results'), + json_generator(query_func(queries), root='results', expand=is_expand(flask.request.args)), mimetype='application/json' ) responder.__name__ = 'query_{0}'.format(name) @@ -116,7 +120,7 @@ def resource_list(name): def make_responder(list_all): def responder(): return app.response_class( - json_generator(list_all(), root=name), + json_generator(list_all(), root=name, expand=is_expand(flask.request.args)), mimetype='application/json' ) responder.__name__ = 'all_{0}'.format(name) @@ -310,6 +314,9 @@ def func(lib, opts, args): self.config['port'] = int(args.pop(0)) app.config['lib'] = lib + # Normalizes json output + app.config['JSONIFY_PRETTYPRINT_REGULAR'] = False + # Enable CORS if required. if self.config['cors']: self._log.info(u'Enabling CORS with origin: {0}', From 4be45eacc6867ee7f3184ada2d06f2f6da5485df Mon Sep 17 00:00:00 2001 From: Max Ammann Date: Mon, 13 Jun 2016 14:08:01 +0200 Subject: [PATCH 2/7] Added documentation for the new 'expand' flag --- docs/plugins/web.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/plugins/web.rst b/docs/plugins/web.rst index 7b2bfedefd..b267af9d2c 100644 --- a/docs/plugins/web.rst +++ b/docs/plugins/web.rst @@ -197,6 +197,7 @@ The interface and response format is similar to the item API, except replacing the encapsulation key ``"items"`` with ``"albums"`` when requesting ``/album/`` or ``/album/5,7``. In addition we can request the cover art of an album with ``GET /album/5/art``. +You can also add the '?expand' flag to get the individual items of an album. ``GET /stats`` From 041adf47acc21eb36a3507dc2eb19f77cfc08b56 Mon Sep 17 00:00:00 2001 From: Max Ammann Date: Mon, 13 Jun 2016 14:35:24 +0200 Subject: [PATCH 3/7] Fixed lines which are mor than 79 characters --- beetsplug/web/__init__.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/beetsplug/web/__init__.py b/beetsplug/web/__init__.py index fefa4ce5f9..e485bc84df 100644 --- a/beetsplug/web/__init__.py +++ b/beetsplug/web/__init__.py @@ -86,7 +86,9 @@ def responder(ids): entities = [entity for entity in entities if entity] if len(entities) == 1: - return flask.jsonify(_rep(entities[0], expand=is_expand(flask.request.args))) + return flask.jsonify( + _rep(entities[0], expand=is_expand(flask.request.args)) + ) elif entities: return app.response_class( json_generator(entities, root=name), @@ -105,7 +107,10 @@ def resource_query(name): def make_responder(query_func): def responder(queries): return app.response_class( - json_generator(query_func(queries), root='results', expand=is_expand(flask.request.args)), + json_generator( + query_func(queries), + root='results', expand=is_expand(flask.request.args) + ), mimetype='application/json' ) responder.__name__ = 'query_{0}'.format(name) @@ -120,7 +125,8 @@ def resource_list(name): def make_responder(list_all): def responder(): return app.response_class( - json_generator(list_all(), root=name, expand=is_expand(flask.request.args)), + json_generator(list_all(), root=name, + expand=is_expand(flask.request.args)), mimetype='application/json' ) responder.__name__ = 'all_{0}'.format(name) From 619344c8134f553e00563d9bb19f736cc6e92457 Mon Sep 17 00:00:00 2001 From: Max Ammann Date: Mon, 13 Jun 2016 14:38:51 +0200 Subject: [PATCH 4/7] Added documentation for the expand parameter --- beetsplug/web/__init__.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/beetsplug/web/__init__.py b/beetsplug/web/__init__.py index e485bc84df..65c1dcad88 100644 --- a/beetsplug/web/__init__.py +++ b/beetsplug/web/__init__.py @@ -60,6 +60,8 @@ def json_generator(items, root, expand=False): :param root: root key for JSON :param items: list of :class:`Item` or :class:`Album` to dump + :param expand: If true every :class:`Album` contains its items in the json + representation :returns: generator that yields strings """ yield '{"%s":[' % root From 2ae26548fcc5ed66cd5a4d99bdff32610b5979ad Mon Sep 17 00:00:00 2001 From: Max Ammann Date: Mon, 13 Jun 2016 15:08:47 +0200 Subject: [PATCH 5/7] Modified and simplified is_expand(...) method --- beetsplug/web/__init__.py | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/beetsplug/web/__init__.py b/beetsplug/web/__init__.py index 65c1dcad88..59fa6b42ac 100644 --- a/beetsplug/web/__init__.py +++ b/beetsplug/web/__init__.py @@ -75,8 +75,10 @@ def json_generator(items, root, expand=False): yield ']}' -def is_expand(args): - return "expand" in args +def is_expand(): + """Returns whether the current request is for an expanded response.""" + + return flask.request.args.get('expand') is not None def resource(name): @@ -88,9 +90,7 @@ def responder(ids): entities = [entity for entity in entities if entity] if len(entities) == 1: - return flask.jsonify( - _rep(entities[0], expand=is_expand(flask.request.args)) - ) + return flask.jsonify(_rep(entities[0], expand=is_expand())) elif entities: return app.response_class( json_generator(entities, root=name), @@ -111,7 +111,7 @@ def responder(queries): return app.response_class( json_generator( query_func(queries), - root='results', expand=is_expand(flask.request.args) + root='results', expand=is_expand() ), mimetype='application/json' ) @@ -127,8 +127,7 @@ def resource_list(name): def make_responder(list_all): def responder(): return app.response_class( - json_generator(list_all(), root=name, - expand=is_expand(flask.request.args)), + json_generator(list_all(), root=name, expand=is_expand()), mimetype='application/json' ) responder.__name__ = 'all_{0}'.format(name) From 5e8ac9e4a5d06de791fe051a419ba070bbdd5bec Mon Sep 17 00:00:00 2001 From: Max Ammann Date: Tue, 14 Jun 2016 21:14:21 +0200 Subject: [PATCH 6/7] Expose the relative path to the library instead of omitting the 'path' variable --- beetsplug/web/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/beetsplug/web/__init__.py b/beetsplug/web/__init__.py index 59fa6b42ac..baf83f7ca7 100644 --- a/beetsplug/web/__init__.py +++ b/beetsplug/web/__init__.py @@ -37,7 +37,7 @@ def _rep(obj, expand=False): out = dict(obj) if isinstance(obj, beets.library.Item): - del out['path'] + out['path'] = obj.destination(fragment=True) # Get the size (in bytes) of the backing file. This is useful # for the Tomahawk resolver API. From cfd70c2685d0da3c06b93043522f585fb58b87bd Mon Sep 17 00:00:00 2001 From: Max Ammann Date: Sun, 26 Jun 2016 20:01:48 +0200 Subject: [PATCH 7/7] Added changelog for beetbox/beets#2050 --- docs/changelog.rst | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/docs/changelog.rst b/docs/changelog.rst index 85ac0dfcc7..f7ea2c0b37 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -4,8 +4,15 @@ Changelog 1.3.20 (in development) ----------------------- -Changelog goes here! +New features: + +* :doc:`/plugins/web`: Added an option to show the items of an album and a + 'path' tag to the json outpu of a file which shows the relative path to the + file. :bug:`2050` + +Other fixes: +* :doc:`/plugins/web`: Normalized the json output 1.3.19 (June 25, 2016) ----------------------