2016-03-14 07:52:18 +00:00
// ==UserScript==
// @name Import Takealot releases to MusicBrainz
2019-01-04 12:29:38 +00:00
// @description Add a button to import https://www.takealot.com/ releases to MusicBrainz via API
2019-01-05 09:58:20 +00:00
// @version 2019.1.5.1
2016-03-15 16:59:40 +00:00
// @namespace https://github.com/murdos/musicbrainz-userscripts
2019-01-04 13:24:35 +00:00
// @downloadURL https://raw.github.com/murdos/musicbrainz-userscripts/master/takealot_importer.user.js
// @updateURL https://raw.github.com/murdos/musicbrainz-userscripts/master/takealot_importer.user.js
2016-03-14 07:52:18 +00:00
// @include http*://www.takealot.com/*
// @require https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js
2016-03-15 19:41:14 +00:00
// @require lib/mbimport.js
// @require lib/logger.js
// @require lib/mblinks.js
// @require lib/mbimportstyle.js
2016-03-14 07:52:18 +00:00
// @icon https://raw.githubusercontent.com/murdos/musicbrainz-userscripts/master/assets/images/Musicbrainz_import_logo.png
// ==/UserScript==
2019-01-04 12:29:38 +00:00
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/ *
* Test cases :
* - https : //www.takealot.com/theuns-jordaan-roeper-cd/PLID17284867 - working (Single artist release) [v1_type2]
* - https : //www.takealot.com/now-71-various-artists-cd/PLID40688034 - [v1_type1]
* - https : //www.takealot.com/du-plessis-juanita-vlieg-hoog-gospel-album-vol-2-cd/PLID15072701 [v2_type1]
* /
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2016-03-14 07:52:18 +00:00
// prevent JQuery conflicts, see http://wiki.greasespot.net/@grant
this . $ = this . jQuery = jQuery . noConflict ( true ) ;
2019-01-04 13:24:35 +00:00
var DEBUG = false ; // true | false
2019-01-04 12:29:38 +00:00
2016-03-14 07:52:18 +00:00
if ( DEBUG ) {
2018-11-20 22:18:49 +00:00
LOGGER . setLevel ( 'debug' ) ;
2016-03-14 07:52:18 +00:00
}
2019-01-04 12:29:38 +00:00
// promise to ensure all api calls are done before we parse the release
var tracks _deferred = $ . Deferred ( ) ;
var retrieve _tracks _promise = tracks _deferred . promise ( ) ;
// object to store all global attributes collected for the release
var release _attributes = { } ; // albumid, total_pages, artist_name, label
// arrays to store the data retrieved from API to parse for MB release
var album _api _array = [ ] ; // album information [0]
var tracks _api _array = [ ] ; // track information [0,1,2,..] one element for each pagination in FMA tracks API
2016-03-14 07:52:18 +00:00
$ ( document ) . ready ( function ( ) {
2019-01-04 12:29:38 +00:00
LOGGER . info ( 'Document Ready & Takealot Userscript Executing' ) ;
let fmaPage = parseFMApage ( ) ;
let mblinks = new MBLinks ( 'FMA_CACHE' , 7 * 24 * 60 ) ;
if ( DEBUG ) {
insertAPISection ( ) ;
updateAPISection . AlbumId ( release _attributes . albumid ) ;
}
2019-01-04 14:34:25 +00:00
if ( $ ( 'span.crumb:nth-child(1)' ) . text ( ) == 'Music' ) {
2019-01-04 12:29:38 +00:00
// To make sure API and release only build on Album page.
// Album detail
let retrieve _album _detail = new album _api ( ) ;
$ . when ( retrieve _album _detail ) . done ( function ( ) {
LOGGER . info ( 'All the AJAX API calls are done continue to build the release object ...' ) ;
2019-01-04 14:34:25 +00:00
LOGGER . debug ( ` ALBUM Object > ${ album _api _array [ 0 ] } ` ) ;
2019-01-04 12:29:38 +00:00
// LOGGER.debug("TRACK Object > " + tracks_api_array);
let FreeMusicArchiveRelease = new Parsefmarelease ( album _api _array [ 0 ] , tracks _api _array ) ;
insertMBSection ( FreeMusicArchiveRelease ) ;
let album _link = window . location . href ;
mblinks . searchAndDisplayMbLink ( album _link , 'release' , function ( link ) {
2019-01-04 17:28:50 +00:00
$ ( 'div.product-title' ) . after ( link ) ;
2019-01-04 12:29:38 +00:00
} ) ;
} ) ;
}
} ) ;
// Determine the location on page to add MusicBrainz Section
2016-03-14 07:52:18 +00:00
function insertMbUI ( mbUI ) {
2018-11-20 22:18:49 +00:00
let e ;
2019-01-04 12:29:38 +00:00
if ( ( e = $ ( '.search-nav-wrap' ) ) && e . length ) {
e . after ( mbUI ) ;
} else if ( ( e = $ ( 'div.panel.pdp-main-panel' ) ) && e . length ) {
2018-11-20 22:18:49 +00:00
e . after ( mbUI ) ;
2019-01-04 12:29:38 +00:00
} else if ( ( e = $ ( '.breadcrumbs ' ) ) && e . length ) {
e . append ( mbUI ) ;
2018-11-20 22:18:49 +00:00
}
2016-03-14 07:52:18 +00:00
}
2016-04-11 10:33:37 +00:00
// Insert links to high res image in Takealot page
function insertIMGlinks ( ) {
2019-01-04 12:29:38 +00:00
let imghref = $ ( 'div.image-box.main-gallery-photo img.image-loaded' ) . attr ( 'src' ) ;
//LOGGER.debug('insertIMGlinks 1:: ', imghref);
2019-01-04 14:34:25 +00:00
let imgnewhref = imghref . substring ( 0 , imghref . lastIndexOf ( '-' ) ) ;
2019-01-04 12:29:38 +00:00
//LOGGER.debug('insertIMGlinks 2:: ', imgnewhref);
2019-01-04 14:34:25 +00:00
let imgnewtype = imghref . substring ( imghref . lastIndexOf ( '.' ) ) ;
2019-01-04 12:29:38 +00:00
//LOGGER.debug('insertIMGlinks 3:: ', imgnewtype);
2019-01-04 14:34:25 +00:00
imgnewhref = ` ${ imgnewhref } -full ${ imgnewtype } ` ;
2019-01-04 12:29:38 +00:00
//LOGGER.debug('insertIMGlinks 4:: ', imgnewhref);
2019-01-04 14:34:25 +00:00
$ ( 'div.panel.pdp-main-panel' ) . append (
` <p><img src="http://musicbrainz.org/favicon.ico" /><a href=" ${ imgnewhref } ">MB High Res Image</a></p> `
) ;
2019-01-04 12:29:38 +00:00
}
// Insert FreeMusicArchive API Status section on FMA page
function insertAPISection ( ) {
2019-01-04 14:34:25 +00:00
LOGGER . debug ( 'FMA insertAPISection Function Executing' ) ;
2019-01-04 12:29:38 +00:00
let fmaUI = $ ( '<div id="fmaapistatus" class="sbar-stat"><h4 class="wlinepad"><span class="hd">Takealot API</span></h4></div>' ) . hide ( ) ;
if ( DEBUG )
fmaUI . css ( {
border : '1px dotted red'
} ) ;
let fmaStatusBlock = $ (
'<a class="lbut-lt" id="lbut-lt-fma-api-album-id">»</a> <a class="lbut-lt" id="lbut-lt-fma-api-key-id">»</a> <a id="lbut-lt-fma-api-album" class="lbut-lt">Album info retrieved</a>'
) ;
fmaUI . append ( fmaStatusBlock ) ;
insertMbUI ( fmaUI ) ; // Insert the FMA API Status UI
$ ( '#fmaapistatus' ) . css ( {
display : 'inline-block' ,
float : 'left' ,
height : '120px' ,
width : '49%'
} ) ;
fmaUI . slideDown ( ) ;
2016-04-11 10:33:37 +00:00
}
2016-03-14 07:52:18 +00:00
2019-01-04 12:29:38 +00:00
// Update FreeMusicArchive API Status section on FMA page
var updateAPISection = {
AlbumId : function ( albumid ) {
this . albumid = albumid ;
$ ( '#lbut-lt-fma-api-album-id' ) . text ( this . albumid ) ;
return 'complete' ;
} ,
ApiKey : function ( apikey ) {
this . apikey = apikey ;
$ ( '#lbut-lt-fma-api-key-id' ) . text ( FMA _API ) ;
return 'complete' ;
} ,
AlbumAjaxStatus : function ( ajaxstatus ) {
if ( ajaxstatus === null ) {
this . ajaxstatus = 'notcalled' ;
} else {
this . ajaxstatus = ajaxstatus ;
2018-11-20 22:18:49 +00:00
}
2019-01-04 12:29:38 +00:00
switch ( this . ajaxstatus ) {
case 'completed' : // Definition is that api call was successfull hence busy retrieving data
//test chaging status of album api to error retrieving data after 2 seconds
$ ( '#lbut-lt-fma-api-album' ) . css ( {
'background-color' : 'green'
} ) ;
break ;
case 'busy' : // Definition is that api call was successfull hence busy retrieving data
//test chaging status of album api to error retrieving data after 2 seconds
$ ( '#lbut-lt-fma-api-album' ) . css ( {
'background-color' : 'orange'
} ) ;
break ;
case 'fail' : // Definition is that api call was successfull hence busy retrieving data
//test chaging status of album api to error retrieving data after 2 seconds
$ ( '#lbut-lt-fma-api-album' ) . css ( {
'background-color' : 'red'
} ) ;
break ;
}
2018-11-20 22:18:49 +00:00
}
2019-01-04 12:29:38 +00:00
} ;
2016-04-11 10:58:30 +00:00
2019-01-04 16:29:07 +00:00
// function to determine if JSON or sub objects exist
// hasProp(albumobject, 'meta.Artists'); return true | false
function hasProp ( obj , propPath , i ) {
if ( typeof i === 'undefined' && ! ( i = 0 ) ) {
propPath = propPath . split ( '.' ) ;
}
2019-01-05 09:58:20 +00:00
if ( typeof obj [ propPath [ i ] ] !== 'undefined' && obj [ propPath [ i ] ] != null ) {
//added null check as some JSON set to null
2019-01-04 16:29:07 +00:00
return ++ i && i !== propPath . length ? hasProp ( obj [ propPath [ i - 1 ] ] , propPath , i ) : true ;
}
return false ;
}
2019-01-04 12:29:38 +00:00
// Insert MusicBrainz section on FMA page
2016-03-14 07:52:18 +00:00
function insertMBSection ( release ) {
2019-01-04 12:29:38 +00:00
//LOGGER.debug(release);
2018-11-20 22:18:49 +00:00
2019-01-04 12:29:38 +00:00
let mbUI = $ (
'<div class="search-nav-wrap-2"></div>'
//'<div id="musicbrainz" class="section musicbrainz"><h4 class="wlinepad"><span class="hd">MusicBrainz</span></h4></div>'
) . hide ( ) ;
2018-11-20 22:18:49 +00:00
if ( DEBUG )
mbUI . css ( {
2019-01-04 12:29:38 +00:00
border : '1px dotted red'
2018-11-20 22:18:49 +00:00
} ) ;
2019-01-04 14:34:25 +00:00
let mbContentBlock = $ (
'<div class="trim"><div class="cat-navigation left"><a href="https://www.musicbrainz.com">MusicBrainz</a></div></div>'
) ;
2018-11-20 22:18:49 +00:00
mbUI . append ( mbContentBlock ) ;
if ( release . maybe _buggy ) {
let warning _buggy = $ ( '<p><small><b>Warning</b>: this release is buggy, please check twice the data you import.</small><p' ) . css ( {
color : 'red' ,
2019-01-04 12:29:38 +00:00
float : 'left' ,
2018-11-20 22:18:49 +00:00
'margin-top' : '4px' ,
'margin-bottom' : '4px'
} ) ;
mbContentBlock . prepend ( warning _buggy ) ;
}
// Form parameters
2019-01-04 17:28:50 +00:00
let edit _note = ` Takealot_Album_Id: ${ release _attributes . albumid } ` ; // temp add album id here untill we can add easy way to schema
2019-01-04 12:29:38 +00:00
edit _note = edit _note + MBImport . makeEditNote ( window . location . href , 'Takealot' ) ;
2018-11-20 22:18:49 +00:00
let parameters = MBImport . buildFormParameters ( release , edit _note ) ;
2019-01-04 12:29:38 +00:00
2018-11-20 22:18:49 +00:00
// Build form + search button
2019-01-04 12:29:38 +00:00
//let innerHTML = `<div id="mb_buttons">${MBImport.buildFormHTML(parameters)}${MBImport.buildSearchButton(release)}</div>`;
//<button class="button add-to-mb-button async-button"><i class="plus-icon"></i><i class="add-to-mb-icon"></i></button>
2019-01-04 17:28:50 +00:00
let innerHTML = ` <div class="search-wrap right"> ${ MBImport . buildFormHTML ( parameters ) } ${ MBImport . buildSearchButton ( release ) } </div> ` ;
2018-11-20 22:18:49 +00:00
mbContentBlock . append ( innerHTML ) ;
2019-01-04 12:29:38 +00:00
insertMbUI ( mbUI ) ; // Insert the MusicBrainzUI
insertIMGlinks ( ) ; // Insert the link to high res image
2018-11-20 22:18:49 +00:00
2019-01-04 12:29:38 +00:00
$ ( '.search-nav-wrap-2' ) . css ( {
'background-color' : '#eb743b' ,
2019-01-04 14:34:25 +00:00
position : 'absolute' ,
top : '150px' ,
width : '100%'
2018-11-20 22:18:49 +00:00
} ) ;
2019-01-04 12:29:38 +00:00
2018-11-20 22:18:49 +00:00
$ ( 'form.musicbrainz_import' ) . css ( {
2019-01-04 14:34:25 +00:00
display : 'inline-block' ,
2019-01-04 12:29:38 +00:00
'vertical-align' : 'middle' ,
2019-01-04 14:34:25 +00:00
margin : '0 0 1rem 0' ,
2019-01-04 12:29:38 +00:00
'margin-bottom' : '1rem' ,
'font-family' : 'inherit' ,
2019-01-04 14:34:25 +00:00
padding : '0.85em 1em' ,
2019-01-04 12:29:38 +00:00
'-webkit-appearance' : 'none' ,
2019-01-04 14:34:25 +00:00
border : '1px solid transparent' ,
2019-01-04 12:29:38 +00:00
'border-radius' : '0' ,
'-webkit-transition' : 'background-color 0.25s ease-out, color 0.25s ease-out' ,
'-o-transition' : 'background-color 0.25s ease-out, color 0.25s ease-out' ,
2019-01-04 14:34:25 +00:00
transition : 'background-color 0.25s ease-out, color 0.25s ease-out' ,
2019-01-04 12:29:38 +00:00
'font-size' : '0.9rem' ,
'line-height' : '1' ,
'text-align' : 'center' ,
2019-01-04 14:34:25 +00:00
cursor : 'pointer' ,
2019-01-04 12:29:38 +00:00
'background-color' : '#0b79bf' ,
2019-01-04 14:34:25 +00:00
color : '#fefefe'
2018-11-20 22:18:49 +00:00
} ) ;
2019-01-04 12:29:38 +00:00
2019-01-04 17:28:50 +00:00
$ ( 'form.musicbrainz_import_search' ) . css ( {
display : 'inline-block' ,
'vertical-align' : 'middle' ,
margin : '0 0 1rem 0' ,
'margin-bottom' : '1rem' ,
'font-family' : 'inherit' ,
padding : '0.85em 1em' ,
'-webkit-appearance' : 'none' ,
border : '1px solid transparent' ,
'border-radius' : '0' ,
'-webkit-transition' : 'background-color 0.25s ease-out, color 0.25s ease-out' ,
'-o-transition' : 'background-color 0.25s ease-out, color 0.25s ease-out' ,
transition : 'background-color 0.25s ease-out, color 0.25s ease-out' ,
'font-size' : '0.9rem' ,
'line-height' : '1' ,
'text-align' : 'center' ,
cursor : 'pointer' ,
'background-color' : '#0b79bf' ,
color : '#fefefe'
} ) ;
2019-01-04 12:29:38 +00:00
/ * $ ( ' # m b _ b u t t o n s ' ) . c s s ( {
display : 'inline-block' ,
float : 'right' ,
height : '80px'
} ) ;
$ ( 'form.musicbrainz_import' ) . css ( {
width : '49%' ,
display : 'inline-block'
} ) ;
$ ( 'form.musicbrainz_import_search' ) . css ( {
float : 'right'
} ) ;
$ ( 'form.musicbrainz_import > button' ) . css ( {
width : '63px' ,
height : '80px' ,
'box-sizing' : 'border-box'
} ) ; * /
mbUI . slideDown ( ) ;
}
// Insert MusicBrainz API section on FMA page to enter API Key
function insertAPIKEYSection ( ) {
LOGGER . debug ( 'FMA insertAPIKEYSection Function Executing' ) ;
let mbUI = $ (
'<div id="musicbrainz_apikey" class="section musicbrainz"><h4 class="wlinepad"><span class="hd">Import FMA API KEY for MusicBrainz</span></h4></div>'
) . hide ( ) ;
if ( DEBUG )
mbUI . css ( {
border : '1px dotted red'
} ) ;
let mbContentBlock = $ ( '<div class="section_content"></div>' ) ;
mbUI . append ( mbContentBlock ) ;
// Build section
let innerHTML =
'<span class="mhd-nosep">Please enter API Key found <a class="donate" href="https://freemusicarchive.org/member/api_key" target="_blank">here</a></span>' ;
innerHTML = ` ${ innerHTML } <div id="mb_buttons"><input id="apikey_input" type="text" name="apikey_input" value=""><br><input id="api_key_submit" type="submit" value="Import API KEY"></div> ` ;
mbContentBlock . append ( innerHTML ) ;
insertMbUI ( mbUI ) ; // Insert the MusicBrainzUI
$ ( '#musicbrainz_apikey' ) . css ( {
display : 'block' ,
float : 'right' ,
height : '120px' ,
width : '49%'
2018-11-20 22:18:49 +00:00
} ) ;
2019-01-04 12:29:38 +00:00
$ ( '#mb_buttons' ) . css ( {
display : 'inline-block' ,
float : 'right' ,
height : '80px'
2018-11-20 22:18:49 +00:00
} ) ;
mbUI . slideDown ( ) ;
2016-03-14 07:52:18 +00:00
}
2019-01-04 12:29:38 +00:00
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Retrieve data from TAL API //
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2016-05-10 18:08:40 +00:00
2019-01-04 12:29:38 +00:00
// Retrieve Album JSON from API and push into array
function album _api ( ) {
let fmaWsUrl = ` https://api.takealot.com/rest/v-1-6-0/productlines/lookup?idProduct= ${ release _attributes . albumid } ` ;
var promise _variable = $ . getJSON ( fmaWsUrl , function ( ) {
updateAPISection . AlbumAjaxStatus ( 'busy' ) ;
LOGGER . debug ( ` promise_variable [state] in [getJSON] ${ promise _variable . state ( ) } ` ) ;
} ) . done ( function ( albumjson ) {
LOGGER . debug ( ' >> Album > DONE' ) ;
updateAPISection . AlbumAjaxStatus ( 'completed' ) ;
//LOGGER.debug('Takealot RAW album JSON: ',albumjson);
2019-01-04 16:29:07 +00:00
// test for meta.Artists key
if ( hasProp ( albumjson , 'response.meta.Artists' ) ) {
LOGGER . debug ( 'response.meta.Artists > exist in JSON' ) ;
release _attributes . artist _name = albumjson . response . meta . Artists [ 0 ] ;
}
2019-01-04 12:29:38 +00:00
album _api _array . push ( albumjson . response ) ;
2018-11-20 22:18:49 +00:00
} ) ;
2019-01-04 12:29:38 +00:00
return promise _variable . promise ( ) ;
2016-05-10 18:08:40 +00:00
}
2018-11-20 22:18:49 +00:00
2019-01-04 12:29:38 +00:00
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Parse information from FMA Page //
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function parseFMApage ( ) {
// Check to see if it is an album class is minitag-album div#content div.bcrumb h1 span.minitag-album
let FMAtype = 'album' ; //manually set this on Takealot as I cant se where on page yet to define its a album
// class inp-embed-code contain the album id
if ( $ ( '.minitag-album' ) . length ) {
FMAtype = 'album' ;
} else if ( $ ( '.minitag-song' ) . length ) {
FMAtype = 'track' ;
} else if ( $ ( '.minitag-artist' ) . length ) {
FMAtype = 'artist' ;
}
if ( FMAtype == 'album' ) {
//LOGGER.debug("FMA parseFMApage Function Executing on ", FMAtype);
// <input type="hidden" id="idProduct" value="53513920">
2019-01-04 14:34:25 +00:00
if ( typeof $ ( '#idProduct' ) . attr ( 'value' ) === 'undefined' && $ ( 'div.cell:nth-child(3) > a:nth-child(1)' ) . length ) {
2019-01-04 12:29:38 +00:00
LOGGER . debug ( 'Uhm I think the idProduct is missing folks and comments left ...' ) ;
let FMAEmbedCode = $ ( 'div.cell:nth-child(3) > a:nth-child(1)' ) . attr ( 'href' ) ;
LOGGER . debug ( 'The album id for API: ' , FMAEmbedCode ) ;
FMAEmbedCodeRegex = /product_id\=(\d*)/ ;
let FMAAlbumIdMatch = FMAEmbedCode . match ( FMAEmbedCodeRegex ) ; // match the Id
release _attributes . albumid = FMAAlbumIdMatch [ 1 ] ; // assign the ID to a variable
2019-01-04 14:34:25 +00:00
} else if ( typeof $ ( '#idProduct' ) . attr ( 'value' ) === 'undefined' && $ ( '.reviews > a:nth-child(1)' ) . length ) {
2019-01-04 12:29:38 +00:00
LOGGER . debug ( 'Uhm I think the idProduct is missing folks ...' ) ;
let FMAEmbedCode = $ ( '.reviews > a:nth-child(1)' ) . attr ( 'href' ) ;
LOGGER . debug ( 'The album id for API: ' , FMAEmbedCode ) ;
FMAEmbedCodeRegex = /product_id\=(\d*)/ ;
let FMAAlbumIdMatch = FMAEmbedCode . match ( FMAEmbedCodeRegex ) ; // match the Id
release _attributes . albumid = FMAAlbumIdMatch [ 1 ] ; // assign the ID to a variable
} else {
LOGGER . debug ( 'Aha got that idProduct value, Jipeeeee ...' ) ;
let FMAEmbedCode = $ ( '#idProduct' ) . attr ( 'value' ) ;
FMAEmbedCodeRegex = /\d{8}/ ; // regex to match the value from the idProduct object
let FMAAlbumIdMatch = FMAEmbedCode . match ( FMAEmbedCodeRegex ) ; // match the Id
release _attributes . albumid = FMAAlbumIdMatch [ 0 ] ; // assign the ID to a variable
2018-11-20 22:18:49 +00:00
}
2019-01-04 12:29:38 +00:00
LOGGER . info ( 'Takealot Album identified as: ' , release _attributes . albumid ) ;
} else {
LOGGER . error ( 'No unique album identified on page' , window . location . href ) ;
release _attributes . albumid = '' ;
2018-11-20 22:18:49 +00:00
}
2019-01-04 12:29:38 +00:00
// Label parsed from webpage as it is not in API
/ * $ ( ' d i v . s b a r - s t a t s p a n . l f 1 0 5 . s t a t h d ' ) . e a c h ( f u n c t i o n ( ) {
//var tester = $(this).eq(0).text().trim().toLowerCase(); // working
let taglist = $ ( this )
. eq ( 0 )
. text ( )
. trim ( )
. toLowerCase ( ) ;
if ( taglist == 'label:' ) {
release _attributes . label = $ ( this )
. next ( )
. text ( ) ;
// fmarelease.labels.push({
// name: FMAAlbumLabel
// });
2018-11-20 22:18:49 +00:00
} else {
2019-01-04 12:29:38 +00:00
release _attributes . label = '' ;
2018-11-20 22:18:49 +00:00
}
2019-01-04 12:29:38 +00:00
} ) ; * /
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Analyze FMA data and return a release object //
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Parse the date string and set object properties day, month, year
function parse _MM _DD _YYYY ( date , obj ) {
if ( ! date ) return ;
let m = date . split ( /\D+/ , 3 ) . map ( function ( e ) {
return parseInt ( e , 10 ) ;
} ) ;
if ( m [ 0 ] !== undefined ) {
obj . month = m [ 0 ] ;
if ( m [ 1 ] !== undefined ) {
obj . day = m [ 1 ] ;
if ( m [ 2 ] !== undefined ) {
obj . year = m [ 2 ] ;
2018-11-20 22:18:49 +00:00
}
}
2019-01-04 12:29:38 +00:00
}
}
2018-11-20 22:18:49 +00:00
2019-01-04 12:29:38 +00:00
function parse _YYYY _MM _DD ( date , obj ) {
if ( ! date ) return ;
let m = date . split ( /\D+/ , 3 ) . map ( function ( e ) {
return parseInt ( e , 10 ) ;
} ) ;
if ( m [ 0 ] !== undefined ) {
obj . month = m [ 1 ] ;
if ( m [ 1 ] !== undefined ) {
obj . day = m [ 2 ] ;
if ( m [ 2 ] !== undefined ) {
obj . year = m [ 0 ] ;
}
}
2018-11-20 22:18:49 +00:00
}
2019-01-04 12:29:38 +00:00
}
2018-11-20 22:18:49 +00:00
2019-01-04 12:29:38 +00:00
// parse the release from the album and track objects
function Parsefmarelease ( albumobject , trackobject ) {
if ( albumobject === undefined ) {
albumobject = [ ] ;
} else {
albumobject = albumobject ;
}
2018-11-20 22:18:49 +00:00
2019-01-04 12:29:38 +00:00
let fmarelease = { } ;
// Create an empty object required for MBImport
fmarelease . title = '' ;
fmarelease . artist _credit = [ ] ;
fmarelease . type = '' ;
fmarelease . status = '' ;
fmarelease . language = '' ;
fmarelease . script = '' ;
fmarelease . packaging = '' ;
fmarelease . country = '' ;
fmarelease . year = '' ;
fmarelease . month = '' ;
fmarelease . day = '' ;
fmarelease . labels = [ ] ;
fmarelease . barcode = '' ;
fmarelease . urls = [ ] ;
fmarelease . discs = [ ] ;
2019-01-05 09:58:20 +00:00
fmarelease . disc _format = '' ;
2019-01-04 12:29:38 +00:00
2019-01-04 14:34:25 +00:00
LOGGER . debug ( 'Album object for parsing' , albumobject ) ;
2019-01-04 12:29:38 +00:00
// Title
fmarelease . title = albumobject . title ;
LOGGER . debug ( 'Title: ' , fmarelease . title ) ;
// Artist Credit
let VariousArtistsRegex = /(Various Artists)/ ; //found "Various Artists || Various Artists [album name]"
2019-01-04 16:29:07 +00:00
// added a check to see if JSON proerty exist
if ( hasProp ( albumobject , 'meta.Artists' ) ) {
2019-01-05 09:58:20 +00:00
//LOGGER.debug('Testing > hasOwnProperty > albumobject.meta.Artists = success');
2019-01-04 16:29:07 +00:00
let various _artists = VariousArtistsRegex . test ( albumobject . meta . Artists [ 0 ] ) ;
if ( various _artists ) {
2019-01-05 09:58:20 +00:00
//LOGGER.debug('Testing > hasOwnProperty > value > Various Artists = success');
2019-01-04 16:29:07 +00:00
fmarelease . artist _credit = [ MBImport . specialArtist ( 'various_artists' ) ] ;
} else {
2019-01-05 09:58:20 +00:00
//LOGGER.debug('Testing > hasOwnProperty > value > Various Artists = false');
2019-01-04 16:29:07 +00:00
fmarelease . artist _credit = MBImport . makeArtistCredits ( [ albumobject . meta . Artists [ 0 ] ] ) ;
2019-01-05 09:58:20 +00:00
//LOGGER.debug('Testing > hasOwnProperty > value > Various Artists = false : ', fmarelease.artist_credit);
2019-01-04 16:29:07 +00:00
}
2019-01-04 12:29:38 +00:00
}
2018-11-20 22:18:49 +00:00
2019-01-04 12:29:38 +00:00
// Type
// TODO: match all FMA types to MB types
2019-01-04 17:28:50 +00:00
// currently if exist and music then its set to album
if ( hasProp ( albumobject , 'type.slug' ) ) {
LOGGER . debug ( 'Album type from albumobject: ' , albumobject . type . slug ) ;
if ( albumobject . type . slug == 'music' ) {
fmarelease . type = 'album' ;
}
2019-01-04 12:29:38 +00:00
} else {
2019-01-04 17:28:50 +00:00
// no type could be found, made it album as default
2019-01-04 12:29:38 +00:00
fmarelease . type = 'album' ;
}
2018-11-20 22:18:49 +00:00
2019-01-04 12:29:38 +00:00
// Default status is official
fmarelease . status = 'official' ;
2018-11-20 22:18:49 +00:00
2019-01-04 12:29:38 +00:00
// Script
fmarelease . script = 'Latn' ;
2018-11-20 22:18:49 +00:00
2019-01-04 12:29:38 +00:00
// Barcode
if ( albumobject . meta . Barcode ) {
fmarelease . barcode = albumobject . meta . Barcode ;
} else {
fmarelease . barcode = albumobject . meta . BarCode ;
}
2018-11-20 22:18:49 +00:00
2019-01-04 12:29:38 +00:00
// Country
fmarelease . country = Countries [ albumobject . meta . Country ] ;
// Check to see if field is not empty
if ( albumobject . meta . Format ) {
//fmarelease.packaging = albumobject.meta.Format; // set Format to the JSON received
// Release URL
fmarelease . urls . push ( {
url : albumobject . uri ,
link _type : MBImport . URL _TYPES . purchase _for _mail _order
} ) ;
} else {
// Release URL
fmarelease . urls . push ( {
url : albumobject . uri ,
link _type : MBImport . URL _TYPES . purchase _for _mail _order
} ) ;
}
// Release date
if ( albumobject . date _released ) {
//parse_YYYY_MM_DD(albumobject.date_released, fmarelease);
2019-01-04 14:34:25 +00:00
parse _YYYY _MM _DD ( albumobject . meta [ 'Date Released' ] , fmarelease ) ;
2019-01-04 12:29:38 +00:00
}
2019-01-05 09:58:20 +00:00
// @TODO: need to figure out to get packaging styles from page
if ( hasProp ( albumobject , 'meta.Media' ) ) {
fmarelease . packaging = PackagingFormats [ albumobject . meta . Media ] ;
}
if ( hasProp ( albumobject , 'meta.Format' ) ) {
fmarelease . disc _format = albumobject . meta . Format ;
}
//labels
if ( hasProp ( albumobject , 'meta.Label' ) ) {
fmarelease . labels . push ( {
name : albumobject . meta . Label
} ) ;
}
// Language
if ( hasProp ( albumobject , 'meta.Languages' ) ) {
2019-01-05 10:03:35 +00:00
fmarelease . language = Languages [ albumobject . meta . Languages ] ;
2019-01-05 09:58:20 +00:00
}
2019-01-04 12:29:38 +00:00
let alltracklist = [ ] ;
2019-01-04 14:34:25 +00:00
let lastdiscnumber = 0 ;
2019-01-04 12:29:38 +00:00
// copied logic from original TAL page as first try
//var tracklistarray = []; // create the tracklist array to use later
// Discs
2019-01-04 14:34:25 +00:00
let disclistarray = [ ] ; // create the tracklist array to use later
2019-01-04 12:29:38 +00:00
LOGGER . debug ( 'Report on meta track type:' , typeof albumobject . meta . Tracks ) ;
// to catch the first format type (1) - start of type 1 array tracks
if ( typeof albumobject . meta . Tracks === 'object' ) {
alltracklist = albumobject . meta . Tracks ;
LOGGER . debug ( 'The track array to work with: ' , alltracklist ) ;
//release artist
LOGGER . debug ( 'alltracklist length' , alltracklist . length ) ;
// Last track to find last disc number
2019-01-04 14:34:25 +00:00
let lasttrack = alltracklist [ alltracklist . length - 1 ] ;
2019-01-04 12:29:38 +00:00
LOGGER . debug ( ` The last track: ${ lasttrack } ` ) ;
// Define all te formats here
takealot _format _1 _1 _regex = /\[ Disc (\d{2}) Track.(\b\d{2}) \] (.*) - (.*)/ ;
takealot _format _1 _2 _regex = /\[ Disc (\d{2}) Track.(\b\d{2}) \] (.*)/ ;
let takealot _format _1 _1 _test = takealot _format _1 _1 _regex . test ( lasttrack ) ;
let takealot _format _1 _2 _test = takealot _format _1 _2 _regex . test ( lasttrack ) ;
var takealot _format = '' ;
if ( takealot _format _1 _1 _test ) {
// set the disctracktitleregex to format 1.1
takealot _format = 'v1_type1' ;
LOGGER . info ( 'Formatting: v1_type1' ) ;
disctracktitleregex = takealot _format _1 _1 _regex ;
} else if ( takealot _format _1 _2 _test ) {
// set the disctracktitleregex to format 1.2
takealot _format = 'v1_type2' ;
LOGGER . info ( 'Formatting: v1_type2' ) ;
disctracktitleregex = takealot _format _1 _2 _regex ;
2018-11-20 22:18:49 +00:00
} else {
2019-01-04 12:29:38 +00:00
LOGGER . error ( 'No REGEX matched the v1 pages' ) ;
takealot _format = 'unmatched' ;
2018-11-20 22:18:49 +00:00
}
2019-01-04 12:29:38 +00:00
lastdiscnumberregex = /\[ Disc (.*) Track./ ; // regex to match disc number from last track
2019-01-04 14:34:25 +00:00
let lastdiscnumbermatch = lasttrack . match ( lastdiscnumberregex ) ;
2019-01-04 12:29:38 +00:00
lastdiscnumber = parseInt ( lastdiscnumbermatch [ 1 ] ) ;
LOGGER . debug ( 'Last Disc Number: ' , lastdiscnumber ) ;
2019-01-04 14:34:25 +00:00
for ( let k = 1 ; k < lastdiscnumber + 1 ; k ++ ) {
2019-01-04 12:29:38 +00:00
// start at 1 to keep array in sync with disc numbers
LOGGER . debug ( 'Disc iterate: ' , k ) ;
// Tracks
var tracklistarray = new Array ( ) ; // create the track list array
for ( let j = 0 ; j < alltracklist . length ; j ++ ) {
// changed j to 0 and length-1 as Artist is at end
// do regex here and if current disc listed in track = k then push the track into the array for that disc
let trackdetails = alltracklist [ j ] ;
// sample: [ Disc 01 Track 01 ] What Do You Mean? - Justin Bieber
// do this up in regex tester now...
//disctracktitleregex = /\[ Disc (\d{2}) Track.(\b\d{2}) \] (.*) - (.*)/;
let disctracktitle = trackdetails . match ( disctracktitleregex ) ;
let currentdiscnumber = parseInt ( disctracktitle [ 1 ] ) ;
if ( currentdiscnumber == k ) {
var track = { } ;
let track _artist _credit = [ ] ;
track . number = parseInt ( disctracktitle [ 2 ] ) ;
track . title = disctracktitle [ 3 ] ;
//LOGGER.debug('TAL FORMAT *** ', takealot_format);
if ( takealot _format === 'v1_type1' ) {
track . artist _credit = MBImport . makeArtistCredits ( [ disctracktitle [ 4 ] ] ) ;
} else if ( takealot _format === 'v1_type2' ) {
track . artist _credit = MBImport . makeArtistCredits ( [ albumobject . meta . Artists [ 0 ] ] ) ;
} else {
fmarelease . maybe _buggy = true ;
2019-01-04 14:34:25 +00:00
track . artist _credit = MBImport . makeArtistCredits ( [ '' ] ) ;
2019-01-04 12:29:38 +00:00
}
LOGGER . debug ( 'The track object: ' , ` ${ currentdiscnumber } - ${ track . number } - ${ track . title } ` ) ;
2018-11-20 22:18:49 +00:00
tracklistarray . push ( track ) ;
}
}
disclistarray . push ( tracklistarray ) ;
}
2019-01-04 12:29:38 +00:00
LOGGER . debug ( '** Disclist Array *** ' , disclistarray ) ;
} // end of type 1 array tracks
2018-11-20 22:18:49 +00:00
2019-01-04 12:29:38 +00:00
// to catch the first format type (2) - start of type 2 array tracks
if ( typeof albumobject . meta . Tracks === 'string' ) {
LOGGER . debug ( 'Version 2 parsing starting ...' ) ;
alltracklist = albumobject . meta . Tracks ;
LOGGER . debug ( 'The track array to work with: ' , alltracklist ) ;
2018-11-20 22:18:49 +00:00
2019-01-04 12:29:38 +00:00
//var lines = alltracklist.value.split("\n");
//var lines = alltracklist.val().split('\n');
2019-01-04 14:34:25 +00:00
let lines = alltracklist . split ( /\r?\n/ ) ;
2018-11-20 22:18:49 +00:00
2019-01-04 12:29:38 +00:00
takealot _format = 'v2_type1' ;
2018-11-20 22:18:49 +00:00
2019-01-04 12:29:38 +00:00
// Tracks
var tracklistarray = new Array ( ) ; // create the track list array
2018-11-20 22:18:49 +00:00
2019-01-04 14:34:25 +00:00
for ( let j = 0 ; j < lines . length ; j ++ ) {
2019-01-04 12:29:38 +00:00
//code here using lines[i] which will give you each line
LOGGER . debug ( 'Line: ' , j , ' - ' , lines [ j ] ) ;
2018-11-20 22:18:49 +00:00
2019-01-04 12:29:38 +00:00
// changed j to 0 and length-1 as Artist is at end
// do regex here and if current disc listed in track = k then push the track into the array for that disc
//let trackdetails = lines[j];
// sample: [ Disc 01 Track 01 ] What Do You Mean? - Justin Bieber
// do this up in regex tester now...
//disctracktitleregex = /\[ Disc (\d{2}) Track.(\b\d{2}) \] (.*) - (.*)/;
//let disctracktitle = trackdetails.match(disctracktitleregex);
2018-11-20 22:18:49 +00:00
2019-01-04 12:29:38 +00:00
let currentdiscnumber = 1 ;
lastdiscnumber = 1 ;
2018-11-20 22:18:49 +00:00
2019-01-04 12:29:38 +00:00
if ( currentdiscnumber == 1 ) {
var track = { } ;
let track _artist _credit = [ ] ;
2018-11-20 22:18:49 +00:00
2019-01-04 12:29:38 +00:00
track . number = j + 1 ;
track . title = lines [ j ] ;
2018-11-20 22:18:49 +00:00
2019-01-04 12:29:38 +00:00
//LOGGER.debug('TAL FORMAT *** ', takealot_format);
if ( takealot _format === 'v2_type2' ) {
track . artist _credit = MBImport . makeArtistCredits ( [ disctracktitle [ 4 ] ] ) ;
} else if ( takealot _format === 'v2_type1' ) {
track . artist _credit = MBImport . makeArtistCredits ( [ albumobject . meta . Artists [ 0 ] . trim ( ) ] ) ;
} else {
fmarelease . maybe _buggy = true ;
2019-01-04 14:34:25 +00:00
track . artist _credit = MBImport . makeArtistCredits ( [ '' ] ) ;
2018-11-20 22:18:49 +00:00
}
2019-01-04 12:29:38 +00:00
LOGGER . debug ( 'The track object: ' , ` ${ currentdiscnumber } - ${ track . number } - ${ track . title } ` ) ;
tracklistarray . push ( track ) ;
2018-11-20 22:18:49 +00:00
}
}
2019-01-04 12:29:38 +00:00
disclistarray . push ( tracklistarray ) ;
LOGGER . debug ( '** Disclist Array *** ' , disclistarray ) ;
} // end of type 2 array tracks
fmarelease . discs = [ ] ;
for ( let l = 0 ; l < lastdiscnumber ; l ++ ) {
2019-01-04 14:34:25 +00:00
LOGGER . debug ( 'Disc position:' , l + 1 ) ;
LOGGER . debug ( 'Tracklist for the selected disc: ' , disclistarray [ l ] ) ;
2019-01-04 12:29:38 +00:00
let disc = {
position : l + 1 ,
2019-01-05 09:58:20 +00:00
format : DiscFormats [ fmarelease . disc _format ] ,
2019-01-04 12:29:38 +00:00
tracks : disclistarray [ l ]
} ;
fmarelease . discs . push ( disc ) ;
2018-11-20 22:18:49 +00:00
}
2019-01-04 12:29:38 +00:00
LOGGER . info ( 'Release:' , fmarelease ) ;
return fmarelease ;
2016-03-14 12:17:50 +00:00
}
2016-03-14 07:52:18 +00:00
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Takealot -> MusicBrainz mapping //
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2019-01-04 12:29:38 +00:00
var DiscFormats = [ ] ;
2018-11-20 22:18:49 +00:00
DiscFormats [ 'CD' ] = 'CD' ;
DiscFormats [ 'DVD' ] = 'DVD' ;
DiscFormats [ 'Audio CD' ] = 'CD' ;
2016-05-10 16:36:45 +00:00
2019-01-04 12:29:38 +00:00
var Languages = [ ] ;
2018-11-20 22:18:49 +00:00
Languages [ 'Afrikaans' ] = 'afr' ;
2019-01-05 10:03:35 +00:00
Languages [ 'afrikaans' ] = 'afr' ;
2016-03-14 07:52:18 +00:00
2019-01-04 12:29:38 +00:00
var Countries = [ ] ;
2018-11-20 22:18:49 +00:00
Countries [ 'South Africa' ] = 'ZA' ;
2019-01-04 14:34:25 +00:00
Countries [ 'SA' ] = 'ZA' ;
2019-01-05 09:58:20 +00:00
var PackagingFormats = [ ] ;
PackagingFormats [ 'CD' ] = 'jewel case' ;