Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support the track/list_by_mbid API route #57

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 56 additions & 0 deletions acoustid.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,11 @@ def _get_submission_status_url():
return API_BASE_URL + 'submission_status'


def _get_track_by_mbid_url():
"""Get the URL of the track-by-MBID API endpoint."""
return API_BASE_URL + 'track/list_by_mbid'


# Compressed HTTP request bodies.

def _compress(data):
Expand Down Expand Up @@ -412,3 +417,54 @@ def get_submission_status(apikey, submission_id, timeout=None):
'id': submission_id,
}
return _api_request(_get_submission_status_url(), params, timeout)


def track_by_mbid(release_ids, disabled=False, timeout=None):
"""Get AcoustID track id(s) corresponding to the given MusicBrainz
release id(s).
If ``release_ids`` is a str, a list of strs (possibly empty) is returned.
If ``release_ids`` is a list of strs, a dict mapping each str in that list
to a (possibly empty) list of strs is returned.
If ``disabled`` is True, those lists of str are instead pairs of lists of
strs, the first containing the enabled AcoustID track ids and the second the
disabled track ids."""

# Avoid isinstance(release_ids, list) in case the caller wants to pass some
# other sequence. We let requests convert the sequence to a repeated param.
batch = not isinstance(release_ids, str)
params = {
'format': 'json',
'mbid': release_ids,
'disabled': '1' if disabled else '0',
'batch': '1' if batch else '0',
# this route doesn't require an API key
}

response = _api_request(_get_track_by_mbid_url(), params, timeout)
# Copied from submit, above.
if response.get('status') != 'ok':
try:
code = response['error']['code']
message = response['error']['message']
except KeyError:
raise WebServiceError("response: {0}".format(response))
raise WebServiceError("error {0}: {1}".format(code, message))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed, as you mentioned, maybe this can be factored out into a function to avoid duplication. The two options are for it to go into _api_request or into a new, separate function. The former would be more appropriate if we only ever use _api_request this way; the latter might be better if some calls to _api_request need to process stuff differently.


# When disabled is true, we defensively check for disabled: false even
# though AcoustID currently omits that attribute for enabled MBIDs.
if batch:
mbids = response['mbids']
if disabled:
return {m['mbid']:
([x['id'] for x in m['tracks'] if 'disabled' not in x or not x['disabled']],
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This bit:

'disabled' not in x or not x['disabled']

is equivalent to this slightly shorter expression:

not x.get('disabled')

[x['id'] for x in m['tracks'] if 'disabled' in x and x['disabled']])
for m in mbids}
else:
return {m['mbid']: [x['id'] for x in m['tracks']] for m in mbids}
else:
tracks = response['tracks']
if disabled:
return ([x['id'] for x in tracks if 'disabled' not in x or not x['disabled']],
[x['id'] for x in tracks if 'disabled' in x and x['disabled']])
else:
return [x['id'] for x in tracks]