Integrate Wikidata card for music
authorDan Scott <dscott@laurentian.ca>
Tue, 23 May 2017 03:26:28 +0000 (23:26 -0400)
committerDan Scott <dscott@laurentian.ca>
Mon, 17 Jul 2017 16:08:55 +0000 (12:08 -0400)
A very rough implementation! But the start of something beautiful?

Signed-off-by: Dan Scott <dscott@laurentian.ca>
Open-ILS/src/templates/opac/parts/js.tt2
Open-ILS/web/js/ui/default/opac/wikidata_music_card.js [new file with mode: 0644]

index 4d5b400..fe67504 100644 (file)
 
 [% INCLUDE "opac/parts/acjs.tt2" IF ctx.page == 'record' %]
 [% INCLUDE "opac/parts/ac_google_books.tt2" IF ctx.page == 'record' AND ctx.google_books_preview %]
+[% IF ctx.page == 'record' %]
+<script type="text/javascript" src="[% ctx.media_prefix %]/js/ui/default/opac/wikidata_music_card.js"></script>
+[% END %]
 [% IF ctx.page == 'advanced' %]
 <script type="text/javascript" 
     src="[% ctx.media_prefix %]/js/ui/default/opac/copyloc.js"></script>
diff --git a/Open-ILS/web/js/ui/default/opac/wikidata_music_card.js b/Open-ILS/web/js/ui/default/opac/wikidata_music_card.js
new file mode 100644 (file)
index 0000000..8174871
--- /dev/null
@@ -0,0 +1,159 @@
+;(function () {
+  var performer;
+  var entity_name;
+  var note;
+  var wd;
+
+  if (document.getElementById('canvas_main').getAttribute('typeof').indexOf('MusicAlbum') > -1) {
+    performer = document.querySelector('span[resource="#schemacontrib1"] span[property="name"]');
+    entity_name = performer.textContent.trim();
+    var lastchar = entity_name[entity_name.length - 1];
+    if (lastchar === '.' || lastchar === ',') {
+      entity_name = entity_name.slice(0, -1);
+    }
+    var inverse = entity_name.split(',');
+    if (inverse.length === 2) {
+      entity_name = inverse[1].trim() + " " + inverse[0].trim();
+    }
+    note = document.createElement('span');
+    note.innerText = '♪';
+    note.addEventListener('click', perform, { once: true });
+    performer.appendChild(note);
+  }
+
+  function perform(e) {
+    findPerformer(performer, entity_name);
+    e.preventDefault();
+    e.stopPropagation();
+  }
+
+  function toggleMode(el) {
+    wd = document.getElementById('magic_musician');
+    wd.style.display = 'inherit';
+    el.addEventListener('click', toggle);
+  }
+
+  function toggle(e) {
+    wd = document.getElementById('magic_musician');
+    
+    if (wd.style.display === 'inherit') {
+      wd.style.display = 'none';
+    } else {
+      wd.style.display = 'inherit';
+    }
+    e.preventDefault();
+    e.stopPropagation();
+  }
+
+  function findPerformer(performer, entity_name) {
+    var url = 'https://query.wikidata.org/sparql';
+    var query = 'SELECT DISTINCT ?item ?itemLabel ?itemDescription ?image ?website ?songKick WHERE {' +
+        '?item rdfs:label "' + entity_name + '"@en . ' +
+        '{ ?item wdt:P31 wd:Q215380 . } ' + // band
+        'UNION ' +
+        '{ ?item wdt:P31 wd:Q5741069 . } ' + // rock band
+        'UNION ' +
+        '{ ?item wdt:P106/wdt:P279* wd:Q639669 . } ' +
+        'OPTIONAL { ?item wdt:P3478 ?songKick . ' +
+        '  ?item wdt:P856 ?website . ' +
+        '  ?item wdt:P18 ?image } . ' +
+        'SERVICE wikibase:label { bd:serviceParam wikibase:language "en". } ' +
+    '} ' +
+    'LIMIT 10';
+    var q = '?query=' + encodeURIComponent(query);
+
+    var req = new window.XMLHttpRequest();
+    req.open('GET', url + q);
+    req.setRequestHeader('Accept', 'application/sparql-results+json');
+    if (req.responseType && (req.responseType = 'json')) {
+      req.onload = function (evt) {
+        var r = req.response.results.bindings[0];
+        if (r !== undefined) {
+          generateCard(performer, r);
+          toggleMode(note);
+          // console.log(r);
+        }
+      }
+    } else {
+      // IE 10/11
+      req.onload = function (evt) {
+        var r = JSON.parse(req.responseText).results.bindings[0];
+        if (r !== undefined) {
+          generateCard(performer, r);
+          toggleMode(note);
+          // console.log(r);
+        }
+      }
+    }
+    req.send();
+  }
+
+  function generateCard(performer, r) {
+    var auth_div = document.querySelector('div[class="rdetail_authors_div"]');
+    var musician = document.createElement('div');
+    musician.id = 'magic_musician';
+    musician.style.padding = '0.5em 1em 1em 1em';
+    musician.style.border = 'thin blue solid';
+    musician.style.overflow = 'hidden';
+
+    if (r.hasOwnProperty('image')) {
+      var img = document.createElement('img');
+      img.src = r.image.value.replace('http:', 'https:');
+      img.style.float = 'left';
+      img.style.width = '150px';
+      img.style['margin-right'] = '1em';
+      musician.appendChild(img);
+    }
+
+    if (r.hasOwnProperty('itemDescription')) {
+      var description = r.itemDescription.value;
+      var wdd = document.createElement('div');
+      var wddl = document.createElement('label');
+      wddl.innerText = description;
+      wdd.appendChild(wddl);
+      musician.appendChild(wdd);
+    }
+
+    var uri = r.item.value;
+    var wd = document.createElement('div');
+    var wdl = document.createElement('label');
+    wdl.innerText = 'Wikidata ID: ';
+    var wdv = document.createElement('a');
+    wdv.href = uri;
+    wdv.innerText = uri.substr(uri.lastIndexOf('/') + 1);
+    wd.appendChild(wdl);
+    wd.appendChild(wdv);
+    musician.appendChild(wd);
+
+    var website = '';
+    if (r.hasOwnProperty('website')) {
+      website = r.website.value;
+      var ws = document.createElement('div');
+      var wsl = document.createElement('label');
+      wsl.innerText = 'Web site: ';
+      var wsv = document.createElement('a');
+      wsv.href = website;
+      wsv.innerText = website;
+      ws.appendChild(wsl);
+      ws.appendChild(wsv);
+      musician.appendChild(ws);
+    }
+
+    var songkick = '';
+    if (r.hasOwnProperty('songKick')) {
+      songkick = 'http://www.songkick.com/artists/' + r.songKick.value;
+      var sk = document.createElement('div');
+      var skl = document.createElement('label');
+      skl.innerText = 'Songkick ID: ';
+      var skv = document.createElement('a');
+      skv.href = songkick;
+      skv.innerText = songkick.substr(songkick.lastIndexOf('/') +1);
+      sk.appendChild(skl);
+      sk.appendChild(skv);
+      musician.appendChild(sk);
+    }
+
+    auth_div.appendChild(musician);
+    document.getElementById('rdetail_image_div').style.clear = 'both';
+  }
+})()