Did you know ... Search Documentation:
Pack musicbrainz -- README

This package provides access to the Musicbrainz XML web service. See musicbrainz.pl for details. It also provides a language for building Lucene queries, which Musicbrainz uses for doing complex searches. See lucene.pl.

Quick start

Install this pack. Then load the modules:

?- use_module(library(musicbrainz)).

Then, simple search returning a 'goodness of match' in Score and an XML element in E, then extracting info from E with mb_facet/2:

?- mb_search(artist,'John Coltrane',Score,E), forall(mb_facet(E,F),(print(F),nl)).

Lucene search for releases with 'trane' in the title but not by anyone with 'coltrane' in the name, using general purpose mb_query/5 to get progress info:

?- mb_query(release,search([trane, -artist:coltrane]),[],Prog,E).

Search for artist then browse releases:

?- mb_search(artist,'John Coltrane',_,Artist),
   mb_browse(release,Artist,E),
        forall(mb_facet(E,F),(print(F),nl)).

Lucene search for male artist then direct lookup all releases:

?- mb_search(artist,[coltrane, gender:male],_,Artist),
   mb_lookup(Artist,[inc([releases])],Item),
        forall(mb_facet(Item,F),(print(F),nl)).

Prerequisites

You need the SWI Prolog SGML and HTTP libraries. They are both installed by default when you install SWI Prolog.

Planned enhancements

  • Switch to JSON return format for an easier life.

Changes in v0.7.0

  • ADDED sandbox awareness: lucence predicates are safe, mb_facet/2 is safe, Library users must declare mb_query/4 predicate safe if they wish to allow network access. Higher level predicates should become safe automatically.
  • FIXED inc option parameter checking.
  • CHANGED mb_facet/2 handles more relations and returns them as a term relation/3, where the 3rd argument includes begin/1, end/1, and attribute/1 terms.
  • FIXED mb_facet/2 handling of forward/backward relations.
  • ADDED mb_facet/2 now reports unrecognised relations
  • lookup and browse now accept URIs as well as XML elements or Class-ID pairs.
  • FIXED removed unwanted non-determinism in doc_item/4
  • ADDED new mb_relation/5 as an alternative to mb_facet for getting relations
    • ADDED new facets for birth place, death place, and whether or not an artist is dead.

Changes in v0.6

  • CHANGED mb_browse/3 and mb_query(_,browse(...),...) In line with the changes to mb_lookup/3 in v0.5, browse queries now accept the linked-to entity either as a pair Class-Id or an element returned by a previous query.
  • CHANGED mb_search/5 to mb_search/4. Thanks to changes in mb_browse and mb_lookup, there is not so much need to deal with Musicbrainz IDs directly, so this has been removed from mb_search.
  • ADDED beginnings of JSON and dict support for planned switch away from XML.

Changes in v0.5

Quite a few changes in this version.

  • ADDED mb_class/2 This extracts the MB class name of an XML entity.
  • CHANGED mb_lookup/3 now accepts options as the second parameter, and instead of accepting the class and ID of an entity as the first two parameters, these are now expected as a pair (Class-ID). Alternatively an XML element returned by a previous query can be used, in which case the class and ID will be extracted.
  • CHANGED inc parameter handling. Instead of accepting a single inc option string as expected by the MBZ server, inclusions are now specified in a more structured way, with validation.

    Ordinary includes are specified using the inc(Includes:list(atom)) option, where Includes is a list of atoms chosen from [recordings,releases,artists, ...], ie the standard MBZ API names. These are validated with respect to the kind of entity being retrieved.

    Relations to include are specified using the rels(Rels:list(mb_class)) option, which accepts a list of MBZ class names. The are checked and translated by having "-rels" appended.

    The "work-level-rels" and "recording-level-rels" includes are specified using the lrels(LRs:list(oneof([recording,work]))) option, and can only be used when querying releases.

  • ADDED lots of facets More facets are understood, but the code is starting to get messy. I plan to switch to receiving JSON enceded results from the server, and also change to a more compositional facet definition scheme so that derived facets can be defined in terms of lower-level facets.