123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289 |
- import mongoose from "mongoose";
- import async from "async";
- import config from "config";
- import * as rax from "retry-axios";
- import axios from "axios";
- import CoreClass from "../core";
- let SoundCloudModule;
- let CacheModule;
- let DBModule;
- let MediaModule;
- let SongsModule;
- let StationsModule;
- let PlaylistsModule;
- let WSModule;
- class RateLimitter {
-
- constructor(timeBetween) {
- this.dateStarted = Date.now();
- this.timeBetween = timeBetween;
- }
-
- continue() {
- return new Promise(resolve => {
- if (Date.now() - this.dateStarted >= this.timeBetween) resolve();
- else setTimeout(resolve, this.dateStarted + this.timeBetween - Date.now());
- });
- }
-
- restart() {
- this.dateStarted = Date.now();
- }
- }
- class _SoundCloudModule extends CoreClass {
-
- constructor() {
- super("soundcloud");
- SoundCloudModule = this;
- }
-
- async initialize() {
- CacheModule = this.moduleManager.modules.cache;
- DBModule = this.moduleManager.modules.db;
- MediaModule = this.moduleManager.modules.media;
- SongsModule = this.moduleManager.modules.songs;
- StationsModule = this.moduleManager.modules.stations;
- PlaylistsModule = this.moduleManager.modules.playlists;
- WSModule = this.moduleManager.modules.ws;
-
-
-
- this.soundcloudTrackModel = this.SoundCloudTrackModel = await DBModule.runJob("GET_MODEL", {
- modelName: "soundcloudTrack"
- });
- return new Promise(resolve => {
- this.rateLimiter = new RateLimitter(config.get("apis.soundcloud.rateLimit"));
- this.requestTimeout = config.get("apis.soundcloud.requestTimeout");
- this.axios = axios.create();
- this.axios.defaults.raxConfig = {
- instance: this.axios,
- retry: config.get("apis.soundcloud.retryAmount"),
- noResponseRetries: config.get("apis.soundcloud.retryAmount")
- };
- rax.attach(this.axios);
- SoundCloudModule.runJob("GET_TRACK", { identifier: 469902882, createMissing: false })
- .then(res => {
- console.log(57567, res);
- })
- .catch(err => {
- console.log(78768, err);
- });
- resolve();
- });
- }
-
- API_GET_TRACK(payload) {
- return new Promise((resolve, reject) => {
- const { trackId } = payload;
- SoundCloudModule.runJob(
- "API_CALL",
- {
- url: `https://api-v2.soundcloud.com/tracks/${trackId}`
- },
- this
- )
- .then(response => {
- resolve(response);
- })
- .catch(err => {
- reject(err);
- });
- });
- }
-
- API_CALL(payload) {
- return new Promise((resolve, reject) => {
-
- const { url } = payload;
- const params = {
- client_id: config.get("apis.soundcloud.key")
- };
- SoundCloudModule.axios
- .get(url, {
- params,
- timeout: SoundCloudModule.requestTimeout
- })
- .then(response => {
- if (response.data.error) {
- reject(new Error(response.data.error));
- } else {
- resolve({ response });
- }
- })
- .catch(err => {
- reject(err);
- });
-
- });
- }
-
- CREATE_TRACK(payload) {
- return new Promise((resolve, reject) => {
- async.waterfall(
- [
- next => {
- const { soundcloudTrack } = payload;
- if (typeof soundcloudTrack !== "object") next("Invalid soundcloudTrack type");
- else {
- SoundCloudModule.soundcloudTrackModel.insertMany(soundcloudTrack, next);
- }
- },
- (soundcloudTrack, next) => {
- const mediaSource = `soundcloud:${soundcloudTrack.trackId}`;
- MediaModule.runJob("RECALCULATE_RATINGS", { mediaSource }, this)
- .then(() => next(null, soundcloudTrack))
- .catch(next);
- }
- ],
- (err, soundcloudTrack) => {
- if (err) reject(new Error(err));
- else resolve({ soundcloudTrack });
- }
- );
- });
- }
-
- GET_TRACK(payload) {
- return new Promise((resolve, reject) => {
- async.waterfall(
- [
- next => {
- const query = mongoose.isObjectIdOrHexString(payload.identifier)
- ? { _id: payload.identifier }
- : { trackId: payload.identifier };
- return SoundCloudModule.soundcloudTrackModel.findOne(query, next);
- },
- (track, next) => {
- if (track) return next(null, track, false);
- if (mongoose.isObjectIdOrHexString(payload.identifier) || !payload.createMissing)
- return next("SoundCloud track not found.");
- return SoundCloudModule.runJob("API_GET_TRACK", { trackId: payload.identifier }, this)
- .then(({ response }) => {
- const { data } = response;
- if (!data || !data.id)
- return next("The specified track does not exist or cannot be publicly accessed.");
- const {
- id,
- title,
- artwork_url: artworkUrl,
- created_at: createdAt,
- duration,
- genre,
- kind,
- license,
- likes_count: likesCount,
- playback_count: playbackCount,
- public: _public,
- tag_list: tagList,
- user_id: userId,
- user
- } = data;
- const soundcloudTrack = {
- trackId: id,
- title,
- artworkUrl,
- soundcloudCreatedAt: new Date(createdAt),
- duration: duration / 1000,
- genre,
- kind,
- license,
- likesCount,
- playbackCount,
- public: _public,
- tagList,
- userId,
- username: user.username
- };
- return next(null, false, soundcloudTrack);
- })
- .catch(next);
- },
- (track, soundcloudTrack, next) => {
- if (track) return next(null, track, true);
- return SoundCloudModule.runJob("CREATE_TRACK", { soundcloudTrack }, this)
- .then(res => {
- if (res.soundcloudTrack.length === 1) next(null, res.soundcloudTrack, false);
- else next("SoundCloud track not found.");
- })
- .catch(next);
- }
- ],
- (err, track, existing) => {
- if (err) reject(new Error(err));
- else resolve({ track, existing });
- }
- );
- });
- }
- }
- export default new _SoundCloudModule();
|