forked from murdos/musicbrainz-userscripts
-
Notifications
You must be signed in to change notification settings - Fork 0
/
boomkat_importer.user.js
167 lines (143 loc) · 5.7 KB
/
boomkat_importer.user.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
// ==UserScript==
// @name Import Boomkat releases to Musicbrainz
// @description Add a button on Boomkat release pages to open MusicBrainz release editor with pre-filled data for the selected release
// @version 2024.09.10.1
// @license X11
// @downloadURL https://raw.githubusercontent.com/murdos/musicbrainz-userscripts/master/boomkat_importer.user.js
// @updateURL https://raw.githubusercontent.com/murdos/musicbrainz-userscripts/master/boomkat_importer.user.js
// @namespace https://github.com/murdos/musicbrainz-userscripts
// @include https://boomkat.com/products/*
// @require lib/mbimport.js
// @require lib/logger.js
// @require lib/mbimportstyle.js
// ==/UserScript==
async function onLoad() {
MBImportStyle();
const release_url = window.location.href.replace('/?.*$/', '').replace(/#.*$/, '');
await fetchTracksAndInsertLink(release_url);
// Update the release info when a different tab/format is
// selected. We pass the event target down to fetchTracksAndInsertLink
// so we can easily fetch the format type from the clicked link.
// Without this, we'd need to resort to delays which are... inconsistent
// on Boomkat.
document.querySelectorAll('ul.tabs li.tab-title a').forEach(function (elem) {
elem.addEventListener('click', async function (event) {
await fetchTracksAndInsertLink(release_url, event.target);
});
});
}
function getFormat(format) {
if (format.match(/MP3|WAV|FLAC/i)) {
return 'Digital Media';
}
if (format.match(/CD/i)) {
return 'CD';
}
if (format.match(/LP|12"/i)) {
return 'Vinyl';
}
if (format.match(/CASSETTE/i)) {
return 'Cassette';
}
return '';
}
function getLinkType(media) {
if (media == 'Digital Media') {
return MBImport.URL_TYPES.purchase_for_download;
}
return MBImport.URL_TYPES.purchase_for_mail_order;
}
async function fetchTracksAndInsertLink(release_url, formatElement) {
const release = await retrieveReleaseInfo(release_url, formatElement);
insertLink(release, release_url);
}
async function retrieveReleaseInfo(release_url, formatElement) {
const releaseDateStr = document.querySelector('span.release-date-placeholder').textContent.replace('Release date: ', '');
const releaseDate = new Date(releaseDateStr);
const artist = document.querySelector('h1.detail--artists').textContent.trim();
const release = {
artist_credit: MBImport.makeArtistCredits([artist]),
title: document.querySelector('h2.detail_album').textContent.trim(),
year: releaseDate.getUTCFullYear(),
month: releaseDate.getUTCMonth() + 1,
day: releaseDate.getUTCDate(),
country: 'XW',
status: 'official',
language: 'eng',
script: 'Latn',
type: '',
urls: [],
labels: [],
discs: [],
};
// Labels
release.labels.push({
name: document.querySelector('span.label-placeholder a').textContent,
catno: document.querySelector('span.catalogue-number-placeholder').textContent.replace(/Cat No:/, ''),
});
// Format/packaging
let format;
if (formatElement != null) {
format = formatElement.textContent.trim();
} else {
format = document.querySelector('ul.tabs .tab-title.active a').textContent.trim();
}
release.format = getFormat(format);
release.packaging = release.format == 'Digital Media' ? 'None' : '';
// URLs
release.urls.push({
url: release_url,
link_type: getLinkType(release.format),
});
// Tracks
// Boomkat loads the tracklist dynamically. Using setTimeout()
// here is not consistent for reasons I have not yet figured out.
// For now, just fetch the tracks the same way Boomkat does.
const releaseID = document.querySelector('a.play-all').dataset.audioPlayerRelease;
const tracklistURL = `https://boomkat.com/tracklist/${releaseID}`;
const tracks = [];
const response = await fetch(tracklistURL);
const body = await response.text();
const doc = document.implementation.createHTMLDocument('');
doc.body.innerHTML = body;
doc.querySelectorAll('div.table-row.track.mp3.clearfix a').forEach(function (link) {
tracks.push({
artist_credit: MBImport.makeArtistCredits([link.dataset.artist]),
title: link.dataset.name,
duration: link.dataset.duration,
});
});
release.discs.push({
tracks: tracks,
format: release.format,
});
LOGGER.info('Parsed release: ', release);
return release;
}
// Insert button into page
function insertLink(release, release_url) {
// Remove any existing buttons
document.querySelectorAll('.musicbrainz-import').forEach(function (elem) {
elem.remove();
});
const edit_note = MBImport.makeEditNote(release_url, 'Boomkat');
const div = document.createElement('div');
div.className = 'product-note';
const formButton = document.createElement('span');
formButton.className = 'tab-title musicbrainz-import';
formButton.innerHTML = MBImport.buildFormHTML(MBImport.buildFormParameters(release, edit_note));
formButton.style.display = 'inline-block';
const searchButton = document.createElement('span');
searchButton.className = 'tab-title musicbrainz-import';
searchButton.innerHTML = MBImport.buildSearchButton(release);
searchButton.style.display = 'inline-block';
div.appendChild(formButton);
div.appendChild(searchButton);
const albumHeader = document.querySelector('h2.detail_album');
albumHeader.after(div);
}
if (document.readyState !== 'loading') {
onLoad();
} else {
document.addEventListener('DOMContentLoaded', onLoad);
}