diff --git a/commands/utility/download.js b/commands/utility/download.js index 8fed2012..e7b6a929 100644 --- a/commands/utility/download.js +++ b/commands/utility/download.js @@ -1,6 +1,7 @@ const { Command } = require('discord-akairo'); const downloader = require('../../utils/download'); const compress = require('../../utils/compress'); +const checkHapi = require('../../utils/checkHapi'); const { proxy, Hapi } = require('../../config.json'); const os = require('os'); const fs = require('fs'); @@ -52,108 +53,7 @@ class DownloadCommand extends Command { } async exec(message, args) { - let Embed = this.client.util.embed() - .setColor(message.member ? message.member.displayHexColor : 'NAVY') - .setAuthor(`Downloaded by ${message.author.username}`, message.author.displayAvatarURL(), args.link) - .setDescription(args.caption ? args.caption : '') - .setFooter(`You can get the original video by clicking on the "downloaded by ${message.author.username}" message!`); - - let compressEmbed = this.client.util.embed() - .setColor(message.member ? message.member.displayHexColor : 'NAVY') - .setTitle('This one will need compression!') - .setDescription('Starting compression now!') - .setFooter('Want it to go faster? Donate to the dev with the donate command, so i can get a better server and do it faster!'); - - let loadingmsg = await message.channel.send('Downloading '); - - - if (Hapi) { - let error = false; - - const params = new URLSearchParams(); - params.append('url', args.link.href); - fetch(`${Hapi}/download`, {method: 'POST', body: params}) - .then(async res => { - Embed.setFooter(`Using Hapi | ${Embed.footer.text}`); - compressEmbed.setFooter(`Using Hapi | ${compressEmbed.footer.text}`); - - if (res.headers.get('content-type') == 'application/json; charset=utf-8') { - let json = await res.json(); - let compressmsg = await message.channel.send(compressEmbed); - - console.log(json); - - let editmsg = setInterval(() => { - console.log('a'); - fetch(json.status) - .then(res => res.json()) - .then(json => { - console.log(json); - compressEmbed.setDescription(`Ready in ${json.eta === '' ? 'soon enough' : json.eta}. ${json.percent}% complete.`); - compressmsg.edit(compressEmbed); - }) - .catch (e=> { - console.error(e); - clearInterval(editmsg); - return message.channel.send('Hapi server returned an error.'); - }); - }, 5000); - - - let retry = 0; - let interval = setInterval(() => { - fetch(`${json.final}`) - .then(res => { - if (res.status == 200) { - clearInterval(editmsg); - clearInterval(interval); - const dest = fs.createWriteStream(`${os.tmpdir()}/${message.id}compressed.mp4`); - res.body.pipe(dest); - dest.on('finish', () => { - compressmsg.delete(); - message.channel.send({ - embed: Embed, - files: [`${os.tmpdir()}/${message.id}compressed.mp4`] - }) - .catch(err => { - console.error(err); - return message.channel.send(`${err.name}: ${err.message} ${err.message === 'Request entity too large' ? 'The file size is too big' : ''}`); - }); - }); - } else { - retry++; - if (retry >= 5) - return; - } - console.log(`try #${retry} status ${res.status}`); - }) - .catch (e=> { - console.error(e); - clearInterval(interval); - return message.channel.send('Hapi server returned an error.'); - }); - }, 5000); - } else { - const dest = fs.createWriteStream(`${os.tmpdir()}/${message.id}.mp4`); - res.body.pipe(dest); - dest.on('finish', () => { - message.channel.send({embed: Embed, files: [`${os.tmpdir()}/${message.id}.mp4`]}); - }); - } - - message.delete(); - loadingmsg.delete(); - return; - }) - .catch(e => { - console.error(e); - error = true; - message.channel.send('Hapi server returned an error or is unreachable. Trying standalone download.'); - }); - - if (!error) - return; - } + if (!args.link) return message.channel.send('Please try again with a valid URL.'); if (args.listproxy) { let proxys = []; @@ -173,105 +73,215 @@ class DownloadCommand extends Command { return message.channel.send(Embed); } - if (!args.link) return message.channel.send('Please try again with a valid URL.'); - let filename = `${message.id}_video`; - if (args.proxy && !args.proxyAuto) { // args.proxyAuto is only provided when the command is run after a error 429 - args.proxy = args.proxy - 1; - if (!proxy[args.proxy]) args.proxy = 0; - } + let Embed = this.client.util.embed() + .setColor(message.member ? message.member.displayHexColor : 'NAVY') + .setAuthor(`Downloaded by ${message.author.username}`, message.author.displayAvatarURL(), args.link) + .setDescription(args.caption ? args.caption : '') + .setFooter(`You can get the original video by clicking on the "downloaded by ${message.author.username}" message!`); - if (args.spoiler) { - filename = `SPOILER_${message.id}_video`; - } + let compressEmbed = this.client.util.embed() + .setColor(message.member ? message.member.displayHexColor : 'NAVY') + .setTitle('This one will need compression!') + .setDescription('Starting compression now!') + .setFooter('Want it to go faster? Donate to the dev with the donate command, so i can get a better server and do it faster!'); - downloader(args.link.href, args.proxy != null ? ['--proxy', proxy[args.proxy].ip] : null, `${os.tmpdir()}/${filename}.mp4`) - .on('error', async err => { - if (err.includes('HTTP Error 429: Too Many Requests')) { - if (args.proxy != null) { - args.proxy = args.proxy + 1; - } else { - args.proxy = 0; - args.proxyAuto = true; + let loadingmsg = await message.channel.send('Downloading '); + + + const spoiler = args.spoiler; + let filePath = `${os.tmpdir()}/${message.id}.mp4`; + + if (spoiler) + filePath = `SPOILER_${filePath}`; + + const isHapiOnline = await checkHapi(); + + if (isHapiOnline) { // I should move that into the download utility file + console.log(`[Download] Hapi server is online at: ${Hapi}`); + Embed.setFooter(`Using Hapi | ${Embed.footer.text}`); + compressEmbed.setFooter(`Using Hapi | ${compressEmbed.footer.text}`); + + const params = new URLSearchParams(); + params.append('url', args.link.href); + + fetch(`${Hapi}/download`, {method: 'POST', body: params}) + .then(async res => { + console.log(`status is ${res.status}`); + if (res.status !== 200) { + console.log('Status is not 200. Abort'); + return message.channel.send('An error has occurred.'); } - if (!proxy[args.proxy]) return message.channel.send('`HTTP Error 429: Too Many Requests.`\nThe website you tried to download from probably has the bot blocked along with its proxy'); + if (res.headers.get('content-type') === 'application/json; charset=utf-8') { // If we receive JSON it mean it started compressing the video + console.log('Compressing'); + let json = await res.json(); + let compressmsg = await message.channel.send(compressEmbed); - loadingmsg.delete(); - return this.client.commandHandler.runCommand(message, this.client.commandHandler.findCommand('download'), args); - } + console.log(`Got json!\n${json}`); - if (err.includes('Error: status code 403')) return message.channel.send('`HTTP Error 403: Forbidden.`\nThe video you tried to download is not publicly available therefor the bot can\'t download it.'); + // Edit compression embed progress + let editmsg = setInterval(() => { + fetch(json.status) + .then(res => res.json()) + .then(json => { + compressEmbed.setDescription(`Ready in ${json.eta === '' ? 'soon enough' : json.eta}. ${json.percent}% complete.`); + compressmsg.edit(compressEmbed); + }) + .catch (e=> { + console.error(e); + clearInterval(editmsg); + return message.channel.send('Hapi server returned an error.'); + }); + }, 5000); - return message.channel.send(err, { code: true }); - }) - .on('end', async output => { - let file = fs.statSync(output); - let fileSize = file.size / 1000000.0; + // Check if the file is at the final location ( end result once it get compressed ) give up after 100 try + let retry = 0; + let interval = setInterval(() => { + fetch(`${json.final}`) + .then(res => { + if (res.status !== 200) { + console.log(`try #${retry} status ${res.status}`); + retry++; + if (retry >= 100) { + clearInterval(editmsg); + clearInterval(interval); + return message.channel.send('Timed out, your video was probably too big to get compressed.'); + } + } else { + clearInterval(editmsg); + clearInterval(interval); - if (fileSize > 8) { - loadingmsg.delete(); + const dest = fs.createWriteStream(filePath); + res.body.pipe(dest); - let compressmsg = await message.channel.send(compressEmbed); + dest.on('finish', () => { + compressmsg.delete(); + loadingmsg.delete(); + message.delete(); + message.channel.send({ + embed: Embed, + files: [filePath] + }) + .catch(err => { + console.error(err); + return message.channel.send(`${err.name}: ${err.message} ${err.message === 'Request entity too large' ? 'The file size is too big' : ''}`); + }); + }); + } + }) + .catch (e=> { + console.error(e); + clearInterval(interval); + return message.channel.send('Hapi server returned an error.'); + }); + }, 5000); - let handbrake = compress(output, `${os.tmpdir()}/${filename}compressed.mp4`); + } else { + console.log('finished download'); + const dest = fs.createWriteStream(filePath); + res.body.pipe(dest); + dest.on('finish', () => { + message.channel.send({embed: Embed, files: [filePath]}); + }); + } + }); + } else { // No Hapi server, let the bot download it + if (args.proxy && !args.proxyAuto) { // args.proxyAuto is only provided when the command is run after a error 429 + args.proxy = args.proxy - 1; + if (!proxy[args.proxy]) args.proxy = 0; + } - let percentComplete; - let eta; + downloader(args.link.href, args.proxy != null ? ['--proxy', proxy[args.proxy].ip] : null, filePath) + .on('error', async err => { + if (err.includes('HTTP Error 429: Too Many Requests')) { + if (args.proxy != null) { + args.proxy = args.proxy + 1; + } else { + args.proxy = 0; + args.proxyAuto = true; + } - handbrake.on('progress', progress => { - percentComplete = progress.percentComplete; - eta = progress.eta; - }); + if (!proxy[args.proxy]) return message.channel.send('`HTTP Error 429: Too Many Requests.`\nThe website you tried to download from probably has the bot blocked along with its proxy'); - // Every 5 seconds update the compress message with the % - let editmsg = setInterval(() => { - compressEmbed.setDescription(`Ready in ${eta === '' ? 'soon enough' : eta}. ${percentComplete}% complete.`); - compressmsg.edit(compressEmbed); - }, 5000); + loadingmsg.delete(); + return this.client.commandHandler.runCommand(message, this.client.commandHandler.findCommand('download'), args); + } - handbrake.on('err', (err) => { - clearInterval(editmsg); - compressmsg.delete(); - return message.channel.send(err, { code: true }); - }); + if (err.includes('Error: status code 403')) return message.channel.send('`HTTP Error 403: Forbidden.`\nThe video you tried to download is not publicly available therefor the bot can\'t download it.'); - handbrake.on('end', (output) => { - clearInterval(editmsg); - file = fs.statSync(output); - fileSize = file.size / 1000000.0; + return message.channel.send(err, { code: true }); + }) + .on('end', async output => { + let file = fs.statSync(output); + let fileSize = file.size / 1000000.0; - if (fileSize > 8) return message.channel.send('End results is too big for discord.'); + if (fileSize > 8) { // File bigger than 8 mb, it need compressing + filePath = `${filePath.substring(0, filePath.length - 4)}compressed.mp4`; + loadingmsg.delete(); + let compressmsg = await message.channel.send(compressEmbed); + + let handbrake = compress(output, filePath); + + let percentComplete; + let eta; + + handbrake.on('progress', progress => { + percentComplete = progress.percentComplete; + eta = progress.eta; + }); + + // Every 5 seconds update the compress message with the % + let editmsg = setInterval(() => { + compressEmbed.setDescription(`Ready in ${eta === '' ? 'soon enough' : eta}. ${percentComplete}% complete.`); + compressmsg.edit(compressEmbed); + }, 5000); + + handbrake.on('err', (err) => { + clearInterval(editmsg); + compressmsg.delete(); + return message.channel.send(err, { code: true }); + }); + + handbrake.on('end', (output) => { + clearInterval(editmsg); + file = fs.statSync(output); + fileSize = file.size / 1000000.0; + + if (fileSize > 8) return message.channel.send('End results is too big for discord.'); + + return message.channel.send({embed: Embed, files: [output]}) + .catch(err => { + compressmsg.delete(); + console.error(err); + return message.channel.send(`${err.name}: ${err.message} ${err.message === 'Request entity too large' ? 'The file size is too big' : ''}`); + }) + .then(() => { + compressmsg.delete(); + // Delete file after it has been sent + fs.unlinkSync(output); + message.delete(); + }); + }); + } else { return message.channel.send({embed: Embed, files: [output]}) .catch(err => { - compressmsg.delete(); + loadingmsg.delete(); console.error(err); return message.channel.send(`${err.name}: ${err.message} ${err.message === 'Request entity too large' ? 'The file size is too big' : ''}`); }) .then(() => { - compressmsg.delete(); + loadingmsg.delete(); // Delete file after it has been sent fs.unlinkSync(output); message.delete(); }); - }); - } else { - return message.channel.send({embed: Embed, files: [output]}) - .catch(err => { - loadingmsg.delete(); - console.error(err); - return message.channel.send(`${err.name}: ${err.message} ${err.message === 'Request entity too large' ? 'The file size is too big' : ''}`); - }) - .then(() => { - loadingmsg.delete(); - // Delete file after it has been sent - fs.unlinkSync(output); - message.delete(); - }); - } - }); + } + }); + } } } + module.exports = DownloadCommand; \ No newline at end of file