2020-06-17 18:42:52 +02:00
const { Command } = require ( 'discord-akairo' ) ;
const downloader = require ( '../../utils/download' ) ;
const compress = require ( '../../utils/compress' ) ;
2021-02-04 17:14:52 +01:00
const { proxy , Hapi } = require ( '../../config.json' ) ;
2020-06-17 18:42:52 +02:00
const os = require ( 'os' ) ;
const fs = require ( 'fs' ) ;
2021-02-04 17:14:52 +01:00
const fetch = require ( 'node-fetch' ) ;
2020-06-17 18:42:52 +02:00
class DownloadCommand extends Command {
constructor ( ) {
2020-06-18 01:36:09 +02:00
super ( 'download' , {
2020-06-18 00:36:48 +02:00
aliases : [ 'download' , 'dl' ] ,
2020-06-17 18:42:52 +02:00
category : 'utility' ,
clientPermissions : [ 'SEND_MESSAGES' , 'EMBED_LINKS' , 'ATTACH_FILES' ] ,
args : [
{
id : 'link' ,
2020-07-16 09:23:50 +02:00
type : 'url' ,
2020-06-17 18:42:52 +02:00
prompt : {
2020-07-16 09:23:50 +02:00
start : 'Please send the URL of which video you want to download. Say `cancel` to stop the command' ,
2020-08-25 03:11:01 +02:00
retry : 'Please send a valid URL of the video you want to download. Say `cancel` to stop the command' ,
optional : true
2020-07-16 09:23:50 +02:00
} ,
2020-06-17 18:42:52 +02:00
} ,
{
id : 'caption' ,
type : 'string' ,
match : 'rest'
} ,
{
id : 'spoiler' ,
match : 'flag' ,
flag : [ '--spoil' , '--spoiler' , '-s' ]
2020-08-25 02:09:16 +02:00
} ,
{
id : 'proxy' ,
2020-08-25 03:11:01 +02:00
match : 'option' ,
flag : [ '--proxy' ] ,
} ,
{
id : 'listproxy' ,
2020-08-25 02:09:16 +02:00
match : 'flag' ,
2020-08-25 03:11:01 +02:00
flag : [ '--listproxy' , '--proxylist' ]
2020-06-17 18:42:52 +02:00
}
] ,
description : {
2020-09-06 22:53:17 +02:00
content : 'Download videos from different website from the link you provided\n`-s` to make the video as a spoiler\n`--proxy #` to select a proxy\n`--listproxy` to see a list of proxy' ,
2020-06-17 18:42:52 +02:00
usage : '[link] [caption]' ,
2020-08-25 17:21:01 +02:00
examples : [ 'https://www.youtube.com/watch?v=6n3pFFPSlW4 Look at this funny gnome' , 'https://www.youtube.com/watch?v=6n3pFFPSlW4 --proxy 1' , '--listproxy' ]
2020-06-17 18:42:52 +02:00
}
} ) ;
}
async exec ( message , args ) {
2021-02-04 17:17:38 +01:00
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 <a:loadingmin:527579785212329984>' ) ;
if ( Hapi ) {
2021-02-04 17:25:51 +01:00
let error = false ;
2021-02-04 17:17:38 +01:00
const params = new URLSearchParams ( ) ;
params . append ( 'url' , args . link . href ) ;
fetch ( ` ${ Hapi } /download ` , { method : 'POST' , body : params } )
. then ( async res => {
2021-02-04 17:25:51 +01:00
Embed . setFooter ( ` Using Hapi | ${ Embed . footer . text } ` ) ;
compressEmbed . setFooter ( ` Using Hapi | ${ compressEmbed . footer . text } ` ) ;
2021-02-04 17:17:38 +01:00
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 ` ]
} ) ;
} ) ;
} 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 ` ] } ) ;
} ) ;
}
2021-02-04 17:25:51 +01:00
2021-02-04 17:17:38 +01:00
message . delete ( ) ;
loadingmsg . delete ( ) ;
return ;
} )
. catch ( e => {
console . error ( e ) ;
2021-02-04 17:25:51 +01:00
error = true ;
message . channel . send ( 'Hapi server returned an error or is unreachable. Trying standalone download.' ) ;
2021-02-04 17:17:38 +01:00
} ) ;
2021-02-04 17:25:51 +01:00
if ( ! error )
return ;
2021-02-04 17:17:38 +01:00
}
2020-08-25 03:11:01 +02:00
if ( args . listproxy ) {
let proxys = [ ] ;
let i = 0 ;
proxy . forEach ( proxy => {
i ++ ;
2020-08-25 03:14:32 +02:00
proxys . push ( ` [ ${ i } ] ${ proxy . hideip ? '[IP HIDDEN]' : proxy . ip . substring ( 0 , proxy . ip . length - 5 ) } - ${ proxy . country } ` ) ;
2020-08-25 03:11:01 +02:00
} ) ;
const Embed = this . client . util . embed ( )
. setColor ( message . member ? message . member . displayHexColor : 'NAVY' )
. setTitle ( 'List of available proxy' )
. setDescription ( proxys . join ( '\n' ) )
. setFooter ( 'You can help me get more proxy by either donating to me or providing a proxy for me' ) ;
return message . channel . send ( Embed ) ;
}
2020-08-25 03:12:17 +02:00
if ( ! args . link ) return message . channel . send ( 'Please try again with a valid URL.' ) ;
2020-06-17 18:42:52 +02:00
let filename = ` ${ message . id } _video ` ;
2020-09-14 15:37:28 +02:00
if ( args . proxy && ! args . proxyAuto ) { // args.proxyAuto is only provided when the command is run after a error 429
args . proxy = args . proxy - 1 ;
2020-08-25 03:11:01 +02:00
if ( ! proxy [ args . proxy ] ) args . proxy = 0 ;
}
2020-06-17 18:42:52 +02:00
if ( args . spoiler ) {
filename = ` SPOILER_ ${ message . id } _video ` ;
}
2020-08-25 03:32:58 +02:00
downloader ( args . link . href , args . proxy != null ? [ '--proxy' , proxy [ args . proxy ] . ip ] : null , ` ${ os . tmpdir ( ) } / ${ filename } .mp4 ` )
2020-07-16 09:23:50 +02:00
. on ( 'error' , async err => {
2020-09-14 15:37:28 +02:00
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 ;
}
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' ) ;
loadingmsg . delete ( ) ;
return this . client . commandHandler . runCommand ( message , this . client . commandHandler . findCommand ( 'download' ) , args ) ;
}
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.' ) ;
2020-06-17 18:42:52 +02:00
return message . channel . send ( err , { code : true } ) ;
} )
2020-07-11 01:23:58 +02:00
. on ( 'end' , async output => {
2020-06-17 18:42:52 +02:00
let file = fs . statSync ( output ) ;
let fileSize = file . size / 1000000.0 ;
if ( fileSize > 8 ) {
2020-07-16 09:23:50 +02:00
loadingmsg . delete ( ) ;
2020-06-17 18:42:52 +02:00
let compressmsg = await message . channel . send ( compressEmbed ) ;
let handbrake = compress ( output , ` ${ os . tmpdir ( ) } / ${ filename } compressed.mp4 ` ) ;
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 => {
2020-07-16 09:23:50 +02:00
compressmsg . delete ( ) ;
2020-06-17 18:42:52 +02:00
console . error ( err ) ;
2020-07-16 09:23:50 +02:00
return message . channel . send ( ` ${ err . name } : ${ err . message } ${ err . message === 'Request entity too large' ? 'The file size is too big' : '' } ` ) ;
2020-06-17 18:42:52 +02:00
} )
. then ( ( ) => {
2020-07-16 09:23:50 +02:00
compressmsg . delete ( ) ;
2020-06-17 18:42:52 +02:00
// Delete file after it has been sent
fs . unlinkSync ( output ) ;
message . delete ( ) ;
} ) ;
} ) ;
} else {
return message . channel . send ( { embed : Embed , files : [ output ] } )
. catch ( err => {
2020-07-16 09:23:50 +02:00
loadingmsg . delete ( ) ;
2020-06-17 18:42:52 +02:00
console . error ( err ) ;
2020-07-16 09:23:50 +02:00
return message . channel . send ( ` ${ err . name } : ${ err . message } ${ err . message === 'Request entity too large' ? 'The file size is too big' : '' } ` ) ;
2020-06-17 18:42:52 +02:00
} )
. then ( ( ) => {
2020-07-16 09:23:50 +02:00
loadingmsg . delete ( ) ;
2020-06-17 18:42:52 +02:00
// Delete file after it has been sent
fs . unlinkSync ( output ) ;
message . delete ( ) ;
} ) ;
}
} ) ;
}
}
module . exports = DownloadCommand ;