Adapt bc changes; add 'label' + 'publisher' props

This commit is contained in:
patrickkfkan 2021-10-20 00:55:46 +08:00
parent 12255e18de
commit fd2e18c696
2 changed files with 108 additions and 46 deletions

View File

@ -174,12 +174,16 @@ async function getArtistOrLabelInfo(artistOrLabelUrl, options = {}) {
artistOrLabelUrl,
imageFormat: await _parseImageFormatArg(options.imageFormat)
};
let url = utils.getUrl('music', artistOrLabelUrl);
if (options.labelId) {
url += '/?label=' + encodeURIComponent(options.labelId);
}
// The landing page of some artists and labels don't actually
// contain the 'bio' column, so we fetch from the
// 'music' page instead. For artists, if the 'music' page does not
// have the artist info, we shall try with an album or track page
// (this is inefficient...perhaps there is a better way?).
return _fetchPage(utils.getUrl('music', artistOrLabelUrl))
return _fetchPage(url)
.then( html => parser.parseArtistOrLabelInfo(html, opts) )
.then( info => {
if (info.type === 'label' || info.name !== '') {

View File

@ -145,44 +145,59 @@ function parseAlbumInfo(html, opts) {
numTracks: basic.numTracks,
imageUrl: utils.reformatImageUrl(basic.image, opts.albumImageFormat),
keywords: basic.keywords,
description: basic.description,
description: basic.description || '',
releaseDate: extra.album_release_date,
artist: {
name: basic.byArtist.name,
url: basic.byArtist['@id'],
description: basic.byArtist.description,
imageUrl: utils.reformatImageUrl(basic.byArtist.image, opts.artistImageFormat)
url: basic.byArtist['@id'] || null,
description: null,
imageUrl: null,
},
publisher: null,
label: _parseBackToLabelLink($),
releases: [],
tracks: []
};
_setPublisher(album, basic, opts.artistImageFormat);
if (Array.isArray(basic.albumRelease)) {
basic.albumRelease.forEach( release => {
basic.albumRelease.filter( release => release.musicReleaseFormat ).forEach( release => {
const releaseItem = {
name: release.name,
url: null,
format: release.musicReleaseFormat,
description: release.description || '',
imageUrl: utils.reformatImageUrl(release.image, opts.albumImageFormat)
imageUrl: null
}
if (release.url) {
releaseItem.url = !utils.isAbsoluteUrl(release.url) ? utils.getUrl(release.url, album.url) : release.url;
if (release['@id']) {
releaseItem.url = !utils.isAbsoluteUrl(release['@id']) ? utils.getUrl(release['@id'], album.url) : release['@id'];
}
if (release.image) {
if (Array.isArray(release.image) && release.image[0]) {
releaseItem.imageUrl = release.image[0];
}
}
else {
let releaseImageArtId = getAdditionalPropertyValue(release, 'art_id');
if (releaseImageArtId) {
opts.imageBaseUrl + '/img/a' + releaseImageArtId + '_' + opts.albumImageFormat.id + '.jpg'
}
}
album.releases.push(releaseItem);
});
}
if (Array.isArray(basic.track.itemListElement)) {
basic.track.itemListElement.forEach( track => {
let trackUrl = track.item['@id'];
if (Array.isArray(extra.trackinfo)) {
extra.trackinfo.forEach( track => {
let trackUrl = track.title_link;
if (!utils.isAbsoluteUrl(trackUrl)) {
trackUrl = utils.getUrl(trackUrl, album.url);
}
album.tracks.push({
position: track.position,
name: track.item.name,
position: track.track_num,
name: track.title,
url: trackUrl,
duration: getAdditionalPropertyValue(track.item, 'duration_secs'),
streamUrl: getAdditionalPropertyValue(track.item, 'file_mp3-128') || null
duration: track.duration,
streamUrl: (track.file && track.file['mp3-128']) || null
});
});
}
@ -227,15 +242,27 @@ function parseTrackInfo(html, opts) {
releaseDate: extra.current.release_date,
duration: getAdditionalPropertyValue(basic, 'duration_secs'),
streamUrl: extra.trackinfo && extra.trackinfo[0] && extra.trackinfo[0].file && extra.trackinfo[0].file['mp3-128'] ? extra.trackinfo[0].file['mp3-128'] : null,
artist: {
name: basic.byArtist.name,
url: basic.byArtist['@id'],
description: basic.byArtist.description,
imageUrl: utils.reformatImageUrl(basic.byArtist.image, opts.artistImageFormat)
},
artist: null,
publisher: null,
label: _parseBackToLabelLink($),
album: null
}
if (basic.inAlbum) {
let byArtist;
if (basic.inAlbum && basic.inAlbum.byArtist) {
byArtist = basic.inAlbum.byArtist;
}
else {
byArtist = basic.byArtist;
}
track.artist = {
name: byArtist.name,
url: byArtist['@id'] || null,
description: null,
imageUrl: null
}
_setPublisher(track, basic, opts.artistImageFormat);
if (basic.inAlbum && basic.inAlbum['@id']) {
track.album = {
name: basic.inAlbum.name,
url: basic.inAlbum['@id'],
@ -266,12 +293,9 @@ function parseTrackInfoFromAlbum(html, opts, trackPosition) {
releaseDate: album.releaseDate,
duration: trackData.duration,
streamUrl: trackData.streamUrl,
artist: {
name: album.artist.name,
url: album.artist.url,
description: album.artist.description,
imageUrl: album.artist.imageUrl
},
artist: album.artist,
publisher: album.publisher,
label: album.label,
album: {
name: album.name,
url: album.url,
@ -407,6 +431,7 @@ function parseDiscography(html, opts) {
function parseArtistOrLabelInfo(html, opts) {
const $ = cheerio.load(html);
const bandData = JSON.parse(decode($('script[data-band]').attr('data-band')));
let bioText = $('#bio-text');
let description;
@ -429,30 +454,22 @@ function parseArtistOrLabelInfo(html, opts) {
description = '';
}
let isLabel = $('a[href="/artists"]').length;
let label = null;
if (!isLabel) {
let labelLink = $('a.back-to-label-link');
if (labelLink.length) {
let linkText = labelLink.find('.back-link-text').html();
label = {
name: utils.substrAfter(linkText, '<br>') || utils.substrBefore(linkText, ' に戻る') || utils.substrBefore(linkText, ' のアイテムをもっと聴く'),
url: utils.splitUrl(labelLink.attr('href')).base
};
}
}
let isLabel = bandData.is_label;
const result = {
type: isLabel ? 'label' : 'artist',
name: $('#band-name-location').find('.title').text(),
url: opts.artistOrLabelUrl,
name: bandData.name,
url: bandData.url,
description: description,
location: $('#band-name-location').find('.location').text(),
imageUrl: utils.reformatImageUrl($('img.band-photo').attr('src'), opts.imageFormat)
};
if (!isLabel) {
result.label = label;
result.label = _parseBackToLabelLink($);
}
else {
result.labelId = bandData.id;
}
return result;
}
@ -1047,7 +1064,7 @@ function parseHubJSPath(html) {
function parseHubJSFilterValueNames(js) {
const filterValueNames = {};
const tObj = /"hubs\/digdeeper\/filter_value":(.+?)}\);/gs.exec(js);
const tObj = /"hubs\/digdeeper\/filter_value":(.+?)}\),/gs.exec(js);
if (tObj[1]) {
const t = safeEval(tObj[1]);
if (t && t[0] && Array.isArray(t[0].blocks)) {
@ -1237,6 +1254,47 @@ function parseSearchLocationResults(json) {
}
}
function _parseBackToLabelLink($) {
let labelLink = $('.back-to-label-link');
if (labelLink.length) {
let linkText = labelLink.find('.back-link-text').html();
label = {
name: utils.substrAfter(linkText, '<br/>') ||
utils.substrAfter(linkText, '<br>') ||
utils.substrBefore(linkText, ' に戻る') ||
utils.substrBefore(linkText, ' のアイテムをもっと聴く'),
url: utils.splitUrl(labelLink.attr('href')).base
};
return label;
}
return null;
}
function _setPublisher(target, json, imageFormat) {
if (json.publisher) {
let publisher = {
name: json.publisher.name,
url: json.publisher['@id'],
description: json.publisher.description,
imageUrl: utils.reformatImageUrl(json.publisher.image, imageFormat)
}
target.publisher = publisher;
// For backward compatibility
if (target.artist) {
if (target.artist.url === null) {
target.artist.url = target.publisher.url;
}
target.artist.description = target.publisher.description;
target.artist.imageUrl = target.publisher.imageUrl;
}
}
else {
target.publisher = null;
}
}
module.exports = {
parseDiscoverResults,
parseDiscoverOptions,