const { Manager } = require('./manager') const { GuildAction } = require('./guild_action') const { Track } = require('./track') const { youtube_instance } = require("./youtube") /** * The {@link Manager} that manage resources. Its main goal is to search resources and get their metadata.
* Note that it only works for YouTube videos for now. * @extends Manager */ class ResourceManager extends Manager { #awaiting_answers constructor() { super(...arguments) this.#awaiting_answers = [] } /** * Performs a research, depending on the search terms it's been asked for * @param {string|string[]} query The search terms * @returns {Track[]} An array of objects representing the search results. */ async get_search_results(query) { if (query instanceof Array) query = query.join(' ') return await youtube_instance.search_track(query) } /** * Do a research and send the search results back to the Discord channel it's been asked for * @param {GuildAction} */ async search({ message, params }) { const tracks = await this.get_search_results(params) if (tracks.length === 0) { message.channel.send(':warning: Something went wrong. Please try again') } else { const text_res = tracks .slice(0, 10) .map((track, i) => (i + 1) + ' ' + track) .join('\n') const input_manager = this.get_manager('input') // TODO: 2000 chars limit // TODO: find a better syntaxic coloration than js const own_message = await message.channel.send('```js\n' + text_res + '```') const trigger = { pattern: /^\d+/, target: 'resource', action: 'search_confirm', ttl: 300, user_shared: false, repeat: 1, on_expire: function() { own_message.react('🛑') } } this.#awaiting_answers.push({ trigger: trigger, search_results: tracks, from: message.member.id }) input_manager.add_trigger(trigger) } } /** * Choose a track given its id in a search result. Note that this only works right after a call to the {@link ResourceManager#search} action. * @param {GuildAction} */ async search_confirm({ message, params }) { // TODO: update this so that it can be more relient on the Trigger received const id = parseInt(message.content) const answer = this.#awaiting_answers .filter(a => a.from === message.member.id) .slice(-1)[0] if (answer === undefined) { message.channel.send(':warning: Something went wrong. That\'s not supposed to happen...') } else if (answer.search_results[id - 1] === undefined) { message.channel.send(':warning: Please choose a number between 1 and ' + answer.search_results.length) } else { // TODO: calling the add method is a bit ugly, we can probably do better... const action = new GuildAction({ message, params: [answer.search_results[id - 1].get_url()] }) this.get_manager('player').add(action) message.react('👌') } } /** * Given the url of a song, get its metadata. * @param {string} url * @returns {Track} */ async get_metadata(url) { return youtube_instance.get_metadata(url) } } module.exports = { ResourceManager }