Cover art archive & release group timeline

In [1]:
%run startup.ipy
Last notebook update: 2018-06-06
Git repo: git@bitbucket.org:loujine/musicbrainz-dataviz.git
Importing libs
Defining database parameters

Defining *sql* helper function
Last database update: 2018-06-02

Python packages versions:
numpy       1.14.3
pandas      0.23.0
sqlalchemy  1.2.8
CPython 3.7.0b5
IPython 6.4.0
In [2]:
performer_name = 'Dino Ciani'
In [3]:
def data(performer_name):
    df = sql("""
SELECT r.name AS album,
       ac.name AS artists,
       to_date(to_char(ev.date_year, '9999') ||
               to_char(COALESCE(ev.date_month, 1), '99') ||
               to_char(COALESCE(ev.date_day, 1), '99'), 'YYYY MM DD') AS date,
       rg.gid AS mbid
  FROM artist             AS a
  JOIN artist_credit_name AS acn ON a.id = acn.artist
  JOIN artist_credit      AS ac  ON ac.id = acn.artist_credit
  JOIN release_group      AS rg  ON rg.artist_credit = ac.id
  JOIN release            AS r   ON r.release_group = rg.id
  JOIN release_event      AS ev  ON ev.release = r.id
 WHERE a.name = %(performer_name)s
   ;""", performer_name=performer_name)
    return df

covers = data(performer_name)
covers
Out[3]:
album artists date mbid
0 Préludes / Suite bergamasque / Pour le piano Debussy; Dino Ciani, Tamás Vásáry 1997-01-01 b02fc3e7-aee9-4b90-bbb3-00f0109742d4
1 Suite bergamasque / 12 Préludes Claude Debussy; Tamás Vásáry, Dino Ciani 1994-07-05 039ff6a3-88dc-4c7f-ae68-54374b032121
In [4]:
cover_url_template = 'https://coverartarchive.org/release-group/%s/front-250.jpg'
rg_url_template = 'https://musicbrainz.org/release-group/%s'

# Transform into JSON
data = [{'start': line.date.isoformat(),
         'album': line.album,
         'artists': line.artists,
         'cover_url': cover_url_template % line.mbid,
         'rg_url': rg_url_template % line.mbid,         
        } for _, line in covers.iterrows()]

# Send to Javascript
import json
from IPython.display import Javascript
Javascript("""window.albumData={};""".format(json.dumps(data)))
Out[4]:
In [5]:
%%javascript
element.append('<div id="timeline" style="width: 100%; height: 100%;"></div>');

requirejs.config({
    paths: {
        vis: '//cdnjs.cloudflare.com/ajax/libs/vis/4.20.1/vis',
        handlebar: '//cdnjs.cloudflare.com/ajax/libs/handlebars.js/4.0.5/handlebars'
    }
});

require(['handlebar', 'vis'], function (handlebar, vis) {
    var template = handlebar.compile(`
      <div>
      <a href="{{rg_url}}">{{album}}</a>
      <br />
      {{artists}}
      <img src="{{cover_url}}" width="150" height="150">    
      </div>
    `);

    var timeline = new vis.Timeline(
        document.getElementById('timeline'), // container, 
        new vis.DataSet(window.albumData), // data
        {
            template: template,
            editable: false
        } // options
    );
})
In [6]:
%%html
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/vis/4.20.1/vis-timeline-graph2d.min.css" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/handlebars.js/4.0.5/handlebars.min.js"></script>