server/services/music_brainz.js
2022-02-02 21:08:46 +01:00

216 lines
6.0 KiB
JavaScript

var request = require("request");
var notifier = require("./notifier");
var album_cover_queue = [];
var album_cover_requst_is_running = false;
var artist_cover_queue = [];
var artist_cover_queue_is_running = false;
let options = {
headers: {
"User-Agent":
"WebPlay/0.1.0 (https://gitea.com/WebPlay)"
}
};
exports.find_album_cover = function(album) {
album_cover_queue.push(album);
console.log("MB Album: " + album.title + " by " + album.artist_name);
run_album_cover_request();
};
exports.find_artist_cover = function(artist) {
artist_cover_queue.push(artist);
console.log("MB Artist: " + artist.name);
run_artist_cover_request();
};
// ARTIST COVER
async function run_artist_cover_request() {
console.log("started request for artist covers");
if (artist_cover_queue_is_running) {
return;
}
artist_cover_queue_is_running = true;
while (artist_cover_queue && artist_cover_queue.length > 0) {
await sleep(1500);
let artist = artist_cover_queue.shift();
console.log("SHIFT Artist: " + artist.name);
for (let i = 0; i < artist.albums.length; i++) {
await sleep(1500);
if (artist.image_downloaded) {
break;
}
let album = artist.albums[i];
let album_title = album.title.replace("&", "%26").replace("/", "_");
let artist_name = artist.name.replace("&", "%26").replace("/", "_");
let url = `https://musicbrainz.org/ws/2/release/?query=release:${album_title} AND artist:${artist_name}&fmt=json`;
options.url = url;
request(options, (err, res, body) => {
if (err) {
console.log(err);
return;
}
let json = json_parser(body, url);
if (!json) {
return;
}
if (json.releases && json.releases.length > 0) {
let release = json.releases[0];
if (release["artist-credit"] && release["artist-credit"].length > 0) {
let artist_id = release["artist-credit"][0].artist.id;
console.log(artist_id);
get_image_by_artist_id(artist, artist_id);
}
}
});
}
}
artist_cover_queue_is_running = false;
}
async function get_image_by_artist_id(artist, artist_id) {
let url = `https://musicbrainz.org/ws/2/artist/${artist_id}?inc=url-rels&fmt=json`;
console.log(url);
options.url = url;
request(options, (err, res, body) => {
let json = json_parser(body, url);
if (!json) {
return;
}
if (!json.relations) {
return;
}
json.relations.forEach(relation => {
if (relation.type == "image" && relation.url && relation.url.resource) {
let resource = relation.url.resource;
if (resource.includes("commons.wikimedia.org")) {
get_image_by_wikimedia(artist, resource);
} else {
artist.image_downloaded = true;
notifier.emit("found_music_brainz_artist_cover", {
artist: artist,
mb: resource
});
}
}
});
});
}
function get_image_by_wikimedia(artist, url) {
let regex = RegExp("(?<=File:)[^<]*", "g");
let result = regex.exec(url);
if (result) {
console.log(result[0]);
let file = result[0];
let url = `https://en.wikipedia.org/w/api.php?action=query&titles=File:${file}&prop=imageinfo&iiprop=url&iiurlwidth=600&iiurlheight=600&format=json`;
console.log(url);
options.url = url;
request(options, (err, res, body) => {
let json = json_parser(body, url);
if (!json) {
return;
}
if (json.query.pages["-1"].imageinfo[0].thumburl) {
console.log(json.query.pages["-1"].imageinfo[0].thumburl);
artist.image_downloaded = true;
notifier.emit("found_music_brainz_artist_cover", {
artist: artist,
mb: json.query.pages["-1"].imageinfo[0].thumburl
});
}
});
}
}
// ALBUM COVER
async function run_album_cover_request() {
console.log("started request for album covers");
if (album_cover_requst_is_running) {
return;
}
album_cover_requst_is_running = true;
while (album_cover_queue && album_cover_queue.length > 0) {
await sleep(1500);
let album = album_cover_queue.shift();
console.log("SHIFT Album: " + album.title);
let album_title = album.title.replace("&", "%26").replace("/", "_");
let artist_name = album.artist_name.replace("&", "%26").replace("/", "_");
let url = `https://musicbrainz.org/ws/2/release/?query=release:${album_title} AND artist:${artist_name}&fmt=json`;
console.log(url);
options.url = url;
request(options, (err, res, body) => {
let json;
try {
json = JSON.parse(body);
} catch (err) {
console.log(err);
return;
}
if (json.releases && json.releases.length > 0) {
let release_id = json.releases[0].id;
let title = json.releases[0].title;
console.log(release_id + ": " + title);
get_album_cover_url(album, release_id);
}
});
}
album_cover_requst_is_running = false;
}
function get_album_cover_url(album, id) {
let url = "https://coverartarchive.org/release/" + id;
options.url = url;
request(options, (err, res, body) => {
if (err) {
console.log(err);
return;
}
if (res.statusCode != 200) {
return;
}
let json = JSON.parse(body);
if (json.images && json.images.length > 0) {
if (json.images[0].thumbnails.large) {
notifier.emit("found_music_brainz_album_cover", {
album: album,
mb: json.images[0].thumbnails.large
});
} else if (json.images[0].image) {
notifier.emit("found_music_brainz_album_cover", {
album: album,
mb: json.images[0].image
});
}
}
});
}
function sleep(milliseconds) {
return new Promise(resolve => setTimeout(resolve, milliseconds));
}
function json_parser(body, url) {
let json;
try {
json = JSON.parse(body);
} catch (err) {
console.log(err);
console.log(url);
console.log("BODY============BEGIN");
console.log(body);
console.log("BODY============END");
}
return json;
}