| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297 | 
							- import axios from "axios";
 
- import CoreClass from "../core";
 
- class RateLimitter {
 
- 	/**
 
- 	 * Constructor
 
- 	 *
 
- 	 * @param {number} timeBetween - The time between each allowed WikiData request
 
- 	 */
 
- 	constructor(timeBetween) {
 
- 		this.dateStarted = Date.now();
 
- 		this.timeBetween = timeBetween;
 
- 	}
 
- 	/**
 
- 	 * Returns a promise that resolves whenever the ratelimit of a WikiData request is done
 
- 	 *
 
- 	 * @returns {Promise} - promise that gets resolved when the rate limit allows it
 
- 	 */
 
- 	continue() {
 
- 		return new Promise(resolve => {
 
- 			if (Date.now() - this.dateStarted >= this.timeBetween) resolve();
 
- 			else setTimeout(resolve, this.dateStarted + this.timeBetween - Date.now());
 
- 		});
 
- 	}
 
- 	/**
 
- 	 * Restart the rate limit timer
 
- 	 */
 
- 	restart() {
 
- 		this.dateStarted = Date.now();
 
- 	}
 
- }
 
- let WikiDataModule;
 
- let DBModule;
 
- class _WikiDataModule extends CoreClass {
 
- 	// eslint-disable-next-line require-jsdoc
 
- 	constructor() {
 
- 		super("wikidata", {
 
- 			concurrency: 10
 
- 		});
 
- 		WikiDataModule = this;
 
- 	}
 
- 	/**
 
- 	 * Initialises the activities module
 
- 	 *
 
- 	 * @returns {Promise} - returns promise (reject, resolve)
 
- 	 */
 
- 	async initialize() {
 
- 		DBModule = this.moduleManager.modules.db;
 
- 		this.genericApiRequestModel = this.GenericApiRequestModel = await DBModule.runJob("GET_MODEL", {
 
- 			modelName: "genericApiRequest"
 
- 		});
 
- 		this.rateLimiter = new RateLimitter(1100);
 
- 		this.requestTimeout = 5000;
 
- 		this.axios = axios.create();
 
- 	}
 
- 	/**
 
- 	 * Get WikiData data from entity url
 
- 	 *
 
- 	 * @param {object} payload - object that contains the payload
 
- 	 * @param {string} payload.entityUrl - entity url
 
- 	 * @returns {Promise} - returns promise (reject, resolve)
 
- 	 */
 
- 	async API_GET_DATA_FROM_ENTITY_URL(payload) {
 
- 		const { entityUrl } = payload;
 
- 		const sparqlQuery = `PREFIX entity_url: <${entityUrl}>
 
- 							SELECT DISTINCT ?YouTube_video_ID ?SoundCloud_track_ID WHERE {
 
- 								OPTIONAL { entity_url: wdt:P1651 ?YouTube_video_ID. }
 
- 								OPTIONAL { entity_url: wdt:P3040 ?SoundCloud_track_ID. }
 
- 							}`
 
- 			.replaceAll("\n", "")
 
- 			.replaceAll("\t", "");
 
- 		return WikiDataModule.runJob(
 
- 			"API_CALL",
 
- 			{
 
- 				url: "https://query.wikidata.org/sparql",
 
- 				params: {
 
- 					query: sparqlQuery
 
- 				}
 
- 			},
 
- 			this
 
- 		);
 
- 	}
 
- 	/**
 
- 	 * Get WikiData data from work id
 
- 	 *
 
- 	 * @param {object} payload - object that contains the payload
 
- 	 * @param {string} payload.workId - work id
 
- 	 * @returns {Promise} - returns promise (reject, resolve)
 
- 	 */
 
- 	async API_GET_DATA_FROM_MUSICBRAINZ_WORK(payload) {
 
- 		const { workId } = payload;
 
- 		const sparqlQuery =
 
- 			`SELECT DISTINCT ?item ?itemLabel ?YouTube_video_ID ?SoundCloud_ID ?Music_video_entity_URL WHERE {
 
- 				SERVICE wikibase:label { bd:serviceParam wikibase:language "[AUTO_LANGUAGE]". }
 
- 				{
 
- 					SELECT DISTINCT ?item WHERE {
 
- 						?item p:P435 ?statement0.
 
- 						?statement0 ps:P435 "${workId}".
 
- 					}
 
- 					LIMIT 100
 
- 				}
 
- 				OPTIONAL { ?item wdt:P1651 ?YouTube_video_ID. }
 
- 				OPTIONAL { ?item wdt:P3040 ?SoundCloud_ID. }
 
- 				OPTIONAL { ?item wdt:P6718 ?Music_video_entity_URL. }
 
- 			}`
 
- 				.replaceAll("\n", "")
 
- 				.replaceAll("\t", "");
 
- 		return WikiDataModule.runJob(
 
- 			"API_CALL",
 
- 			{
 
- 				url: "https://query.wikidata.org/sparql",
 
- 				params: {
 
- 					query: sparqlQuery
 
- 				}
 
- 			},
 
- 			this
 
- 		);
 
- 	}
 
- 	/**
 
- 	 * Get WikiData data from release group id
 
- 	 *
 
- 	 * @param {object} payload - object that contains the payload
 
- 	 * @param {string} payload.releaseGroupId - release group id
 
- 	 * @returns {Promise} - returns promise (reject, resolve)
 
- 	 */
 
- 	async API_GET_DATA_FROM_MUSICBRAINZ_RELEASE_GROUP(payload) {
 
- 		const { releaseGroupId } = payload;
 
- 		const sparqlQuery =
 
- 			`SELECT DISTINCT ?item ?itemLabel ?YouTube_video_ID ?SoundCloud_ID ?Music_video_entity_URL WHERE {
 
- 				SERVICE wikibase:label { bd:serviceParam wikibase:language "[AUTO_LANGUAGE]". }
 
- 				{
 
- 					SELECT DISTINCT ?item WHERE {
 
- 						?item p:P436 ?statement0.
 
- 						?statement0 ps:P436 "${releaseGroupId}".
 
- 					}
 
- 					LIMIT 100
 
- 				}
 
- 				OPTIONAL { ?item wdt:P1651 ?YouTube_video_ID. }
 
- 				OPTIONAL { ?item wdt:P3040 ?SoundCloud_ID. }
 
- 				OPTIONAL { ?item wdt:P6718 ?Music_video_entity_URL. }
 
- 			}`
 
- 				.replaceAll("\n", "")
 
- 				.replaceAll("\t", "");
 
- 		return WikiDataModule.runJob(
 
- 			"API_CALL",
 
- 			{
 
- 				url: "https://query.wikidata.org/sparql",
 
- 				params: {
 
- 					query: sparqlQuery
 
- 				}
 
- 			},
 
- 			this
 
- 		);
 
- 	}
 
- 	/**
 
- 	 * Get WikiData data from Spotify album id
 
- 	 *
 
- 	 * @param {object} payload - object that contains the payload
 
- 	 * @param {string} payload.spotifyAlbumId - Spotify album id
 
- 	 * @returns {Promise} - returns promise (reject, resolve)
 
- 	 */
 
- 	async API_GET_DATA_FROM_SPOTIFY_ALBUM(payload) {
 
- 		const { spotifyAlbumId } = payload;
 
- 		if (!spotifyAlbumId) throw new Error("Invalid Spotify album ID provided.");
 
- 		const sparqlQuery = `SELECT DISTINCT ?item ?itemLabel ?YouTube_playlist_ID ?SoundCloud_ID WHERE {
 
- 				SERVICE wikibase:label { bd:serviceParam wikibase:language "[AUTO_LANGUAGE]". }
 
- 				{
 
- 					SELECT DISTINCT ?item WHERE {
 
- 						?item p:P2205 ?statement0.
 
- 						?statement0 ps:P2205 "${spotifyAlbumId}".
 
- 					}
 
- 					LIMIT 100
 
- 				}
 
- 				OPTIONAL { ?item wdt:P4300 ?YouTube_playlist_ID. }
 
- 				OPTIONAL { ?item wdt:P3040 ?SoundCloud_ID. }
 
- 			}`
 
- 			.replaceAll("\n", "")
 
- 			.replaceAll("\t", "");
 
- 		return WikiDataModule.runJob(
 
- 			"API_CALL",
 
- 			{
 
- 				url: "https://query.wikidata.org/sparql",
 
- 				params: {
 
- 					query: sparqlQuery
 
- 				}
 
- 			},
 
- 			this
 
- 		);
 
- 	}
 
- 	/**
 
- 	 * Get WikiData data from Spotify artist id
 
- 	 *
 
- 	 * @param {object} payload - object that contains the payload
 
- 	 * @param {string} payload.spotifyArtistId - Spotify artist id
 
- 	 * @returns {Promise} - returns promise (reject, resolve)
 
- 	 */
 
- 	async API_GET_DATA_FROM_SPOTIFY_ARTIST(payload) {
 
- 		const { spotifyArtistId } = payload;
 
- 		if (!spotifyArtistId) throw new Error("Invalid Spotify artist ID provided.");
 
- 		const sparqlQuery =
 
- 			`SELECT DISTINCT ?item ?itemLabel ?YouTube_channel_ID ?SoundCloud_ID ?MusicBrainz_artist_ID WHERE {
 
- 				SERVICE wikibase:label { bd:serviceParam wikibase:language "[AUTO_LANGUAGE]". }
 
- 				{
 
- 					SELECT DISTINCT ?item WHERE {
 
- 						?item p:P1902 ?statement0.
 
- 						?statement0 ps:P1902 "${spotifyArtistId}".
 
- 					}
 
- 					LIMIT 100
 
- 				}
 
- 				OPTIONAL { ?item wdt:P2397 ?YouTube_channel_ID. }
 
- 				OPTIONAL { ?item wdt:P3040 ?SoundCloud_ID. }
 
- 				OPTIONAL { ?item wdt:P434 ?MusicBrainz_artist_ID. }
 
- 			}`
 
- 				.replaceAll("\n", "")
 
- 				.replaceAll("\t", "");
 
- 		return WikiDataModule.runJob(
 
- 			"API_CALL",
 
- 			{
 
- 				url: "https://query.wikidata.org/sparql",
 
- 				params: {
 
- 					query: sparqlQuery
 
- 				}
 
- 			},
 
- 			this
 
- 		);
 
- 	}
 
- 	/**
 
- 	 * Perform WikiData API call
 
- 	 *
 
- 	 * @param {object} payload - object that contains the payload
 
- 	 * @param {string} payload.url - request url
 
- 	 * @param {object} payload.params - request parameters
 
- 	 * @returns {Promise} - returns promise (reject, resolve)
 
- 	 */
 
- 	async API_CALL(payload) {
 
- 		const { url, params } = payload;
 
- 		let genericApiRequest = await WikiDataModule.GenericApiRequestModel.findOne({
 
- 			url,
 
- 			params
 
- 		});
 
- 		if (genericApiRequest) return genericApiRequest._doc.responseData;
 
- 		await WikiDataModule.rateLimiter.continue();
 
- 		WikiDataModule.rateLimiter.restart();
 
- 		const { data: responseData } = await WikiDataModule.axios.get(url, {
 
- 			params,
 
- 			headers: {
 
- 				Accept: "application/sparql-results+json"
 
- 			},
 
- 			timeout: WikiDataModule.requestTimeout
 
- 		});
 
- 		if (responseData.error) throw new Error(responseData.error);
 
- 		genericApiRequest = new WikiDataModule.GenericApiRequestModel({
 
- 			url,
 
- 			params,
 
- 			responseData,
 
- 			date: Date.now()
 
- 		});
 
- 		genericApiRequest.save();
 
- 		return responseData;
 
- 	}
 
- }
 
- export default new _WikiDataModule();
 
 
  |