diff --git a/beetsplug/web/__init__.py b/beetsplug/web/__init__.py index 91b1b3a28..baf83f7ca 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. @@ -55,11 +55,13 @@ 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 :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 @@ -69,10 +71,16 @@ 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(): + """Returns whether the current request is for an expanded response.""" + + return flask.request.args.get('expand') is not None + + def resource(name): """Decorates a function to handle RESTful HTTP requests for a resource. """ @@ -82,7 +90,7 @@ def resource(name): 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())) elif entities: return app.response_class( json_generator(entities, root=name), @@ -101,7 +109,10 @@ 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() + ), mimetype='application/json' ) responder.__name__ = 'query_{0}'.format(name) @@ -116,7 +127,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()), mimetype='application/json' ) responder.__name__ = 'all_{0}'.format(name) @@ -310,6 +321,9 @@ class WebPlugin(BeetsPlugin): 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}', diff --git a/docs/changelog.rst b/docs/changelog.rst index 85ac0dfcc..f7ea2c0b3 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) ---------------------- diff --git a/docs/plugins/web.rst b/docs/plugins/web.rst index 7b2bfedef..b267af9d2 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``