More Musicbrainz…
What I posted about yesterday was obviously too ridiculously difficult to actually be a real solution to the problem. So, I set about making something that works at least a little bit better.
It’s possible to generate “TRM”s for songs you have. These TRMs are basically accoustic identifiers for the track: they let you identify the song based on the way it sounds. This is how Musicbrainz does its identification. Yesterday, I installed a bunch of musicbrainz stuff in an effort to get this working, and did end up finding something that will generate TRM files. My current song, Chumbawumba’s Tubthumping, has a TRM of 776643d0-9b47-4eb9-8d29-608fa9ccedcd.
So, I can generate TRMs: but that doesn’t get me very far. Now, I need to figure out the actual track associated. Since I’m doing this mostly non-interactively, I’m just going to use the most popular track with that TRM. (This doesn’t always work: for me so far this evening, it’s given me a ~80% accuracy rate). So, I fetch the RDF version of the TRM file: this can be retrieved from http://musicbrainz.org/trmid/776643d0-9b47-4eb9-8d29-608fa9ccedcd for the song I mentioned earlier.
The first song in the “tracklist” RDF bag is the one that is the best match, so I’ll grab that Track. I can then add that URI, and fetch the creator ID from that file. All these files can be tossed into the general RDF model I keep lying around, along with the turtle that I mentioned in the earlier entry: [a foaf:Person; foaf:nick “crschmidt”; menow:hasStatus [a menow:Status; dc:date “timestamp”; menow:listeningTo <trackuri>]].
Then, I can issue a query against the model: since I know the time, I only return the most recent result:
select ?t, ?n, ?d where (?p foaf:nick “crschmidt”) (?p menow:hasStatus ?s) (?s dc:date ?d) (?s menow:listeningTo ?o) (?o dc:title ?t) (?o dc:creator ?a) (?a dc:title ?n) AND ?d =~ /timestamp/
The end result? A couple hundred extra triples loaded into the global model, and I can see:
23:23:56 <crschmidt> ^listeningTo 776643d0-9b47-4eb9-8d29-608fa9ccedcd
23:24:02 <julie> 2005-03-30T04:24:01Z Tubthumping Chumbawamba
Some of the tracks I’ve been listening to tonight can be shown via:^q select ?t, ?n, ?d where (?p foaf:nick “crschmidt”) (?p menow:hasStatus ?s) (?s dc:date ?d) (?s menow:listeningTo ?o) (?o dc:title ?t) (?o dc:creator ?a) (?a dc:title ?n) AND ?d =~ /2005-03-30/. Feel free to stop by #julie on irc.freenode.net and try it!
Code for the above function in Julie:
mm = RDF.NS("http://musicbrainz.org/mm/mm-2.0#") rdf = RDF.NS("http://www.w3.org/1999/02/22-rdf-syntax-ns#") dc = RDF.NS("http://purl.org/dc/elements/1.1/") model = RDF.Model(get_storage(self.db_password)) trm = m.group(1) m = RDF.Model() p = RDF.Parser() p.parse_into_model(m, "http://musicbrainz.org/trmid/%s"%trm) p.parse_into_model(model, "http://musicbrainz.org/trmid/%s"%trm) tl = m.find_statements(RDF.Statement(None, mm.trackList, None)) tracklistBag = tl.current().object t1 = m.find_statements(RDF.Statement(tracklistBag, rdf['_1'], None)) trackId = t1.current().object.uri p.parse_into_model(m, trackId) p.parse_into_model(model, trackId) c = m.find_statements(RDF.Statement(trackId, dc.creator, None)) creator = c.current().object.uri p.parse_into_model(model, creator) tp = RDF.TurtleParser() timestamp = time.strftime('%Y-%m-%dT%H:%M:%SZ', time.gmtime()) turtle = """[a foaf:Person; foaf:nick "%s"; menow:hasStatus [a menow:Status; dc:date "%s"; menow:listeningTo < %s>]].""" % (split_origin(origin)[0], timestamp, trackId) turtlestr = turtle for key, value in common_namespaces().items() : turtlestr = "@prefix %s: < %s> .\n%s" % (key, value, turtlestr) tp.parse_string_into_model(model, turtlestr,RDF.Uri("http://crschmidt.net/julie/data/")) self.query_thread("""select ?t, ?n, ?d where (?p foaf:nick "%s") (?p menow:hasStatus ?s) (?s dc:date ?d) (?s menow:listeningTo ?o) (?o dc:title ?t) (?o dc:creator ?a) (?a dc:title ?n) AND ?d =~ /%s/""" % (split_origin(origin)[0], timestamp) ,origin,args,model)
March 30th, 2005 at 12:48 am
I assume the line ending in lots of spaces plus “c = m.find_statements(RDF.Statement(trackId, dc.creator, None))” is intended to be two lines… could you please change that?
It’s breaking my friends page on LiveJournal, and when I go directly to your blog, the end of the line doesn’t appear, so it seems as if c is never assigned to before being used.
March 30th, 2005 at 7:25 am
Philip: Changed. sorry about that.