|
/** |
|
* Copyright 2017 Yulio Aleman Jimenez |
|
* |
|
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions |
|
* are met: |
|
* |
|
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. |
|
* |
|
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in |
|
* the documentation and/or other materials provided with the distribution. |
|
* |
|
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived |
|
* from this software without specific prior written permission. |
|
* |
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT |
|
* NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL |
|
* THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
|
*/ |
|
|
|
var fs = require('fs'); |
|
var childProcess = require("child_process"); |
|
var casper = require('casper').create({ |
|
verbose: true, |
|
pageSettings: { |
|
webSecurityEnabled: false, // Disable web security [SSL, TLS] |
|
loadImages: false, // Disable image loading |
|
loadPlugins: false, |
|
} |
|
}); |
|
|
|
// Base URL for downloading service |
|
var baseURL = 'http://video.genyoutube.net/'; |
|
|
|
// Getting parameter's values |
|
var IDOption = 'id' in casper.cli.options ? casper.cli.options.id : false; // Required |
|
var maxWeightOption = 'maxw' in casper.cli.options ? parseFloat(casper.cli.options.maxw) : false; // Required |
|
var formatOption = 'format' in casper.cli.options ? casper.cli.options.format.toUpperCase() : "MP4"; |
|
var novideoOption = 'novideo' in casper.cli.options ? true : false; |
|
var nosoundOption = 'nosound' in casper.cli.options ? true : false; |
|
var uploaderOption = 'uploader' in casper.cli.options ? casper.cli.options.uploader : false; |
|
var rmAfterOption = 'rm-after-upload' in casper.cli.options ? true : false; |
|
var helpmeOption = 'helpme' in casper.cli.options ? true : false; |
|
|
|
// Checking parameters |
|
if (!IDOption || !maxWeightOption || helpmeOption) { |
|
casper.echo("YOUTUBE DOWNLOADER SCRIPT"); |
|
casper.echo("================================================== \n"); |
|
casper.echo("USAGE: casperjs --ignore-ssl-errors=true script.js --id=<YouTube_ID> --maxw=<Max_Weight> --format=<Format> --novideo --nosound --uploader=<Uploader_Script_Path> --rm-after-upload --helpme"); |
|
casper.echo("[--ignore-ssl-errors=true]: ---------- [REQUIRED] To say the script to ignore the SSL errors."); |
|
casper.echo("[script.js]: ------------------------- [REQUIRED] Name of your YouTube Downloader JS script."); |
|
casper.echo("[--id=<YouTube_ID>]: ----------------- [REQUIRED] ID fo the YouTube Video."); |
|
casper.echo("[--maxw=<Max_Weight>]: --------------- [REQUIRED] Max weight of the file (in MB) to download."); |
|
casper.echo("[--format=<Format>]: ----------------- [OPTIONAL] Format of the video or audio for downloading. Possible values are MP4, 3GP, WEBM, M4A. Default format is MP4."); |
|
casper.echo("[--novideo]: ------------------------- [OPTIONAL] Filter download links to not contain Video."); |
|
casper.echo("[--nosound]: ------------------------- [OPTIONAL] Filter download links to not contain Sound."); |
|
casper.echo("[--uploader=<Uploader_Script_Path>]: - [OPTIONAL] Path to the JS script for uploading to personal storage."); |
|
casper.echo("[--rm-after-upload]: ----------------- [OPTIONAL] Remove directory with downloaded file, after upload it to the personal storage. "); |
|
casper.echo("[--helpme]: -------------------------- [OPTIONAL] Only print this help. This parameter avoid the execution of the script content. "); |
|
casper.echo("================================================== \n"); |
|
casper.echo("EXAMPLES: \n"); |
|
casper.echo("1. casperjs --ignore-ssl-errors=true youtube_downloader.js --helpme"); |
|
casper.echo("2. casperjs --ignore-ssl-errors=true youtube_downloader.js --id=NduID48s-B --maxw=60"); |
|
casper.echo("3. casperjs --ignore-ssl-errors=true youtube_downloader.js --id=RsY30mqj-s --maxw=100 --format=WEBM --uploader=/home/jhon/uploader.js --rm-after-upload"); |
|
casper.echo("================================================== "); |
|
casper.echo("Made by Yulio Aleman Jimenez [https://github.com/yulioaj290]"); |
|
casper.echo("================================================== "); |
|
casper.exit(0) ; |
|
} |
|
|
|
// wait 7 seconds before giving up |
|
casper.options.waitTimeout = 10000000 |
|
|
|
casper.onResourceTimeout = function(request) { |
|
casper.echo('Response (#' + request.id + '): ' + JSON.stringify(request)); |
|
}; |
|
|
|
// Config the user agent |
|
// casper.userAgent('Mozilla/5.0 (Macintosh; Intel Mac OS X); Safari'); |
|
casper.userAgent('Mozilla/5.0 (Windows NT 6.1; WOW64; rv:40.0) Gecko/20100101 Firefox/40.1'); |
|
|
|
// Accept any kind of answer for the request, on the page Headers |
|
casper.on('started', function () { |
|
this.page.customHeaders = { 'Accept': '*/*' } |
|
}); |
|
|
|
// casper.on('resource.error',function (request) { |
|
// this.echo('RESOURCE: [' + request.id + '] IN: [' + request.url + '] SAID: [' + request.errorString + ']' ); |
|
// }); |
|
|
|
// Validating the format |
|
if(formatOption != "MP4" && formatOption != "3GP" && formatOption != "WEBM"){ |
|
casper.echo("WARNING: Incorrect video format [" + formatOption + "]."); |
|
casper.echo("INFO: Setting video format to MP4."); |
|
formatOption = "MP4"; |
|
} |
|
|
|
// Initializing the output bash script |
|
var output = "#!/bin/bash \n"; |
|
|
|
casper |
|
.start() |
|
.open(baseURL + IDOption) |
|
.then(function () { |
|
|
|
// Check if the download link list do exist |
|
if(this.exists('div#downloadlist a[data-format="' + formatOption + '"]')){ |
|
casper.echo("Retrieving from download list... \n"); |
|
|
|
// Storing the list of all links that fit the requirements |
|
var listOfLinks = this.evaluate(function(){ |
|
// Getting name, href & weight of each download link |
|
var links = [].map.call($('div#downloadlist .downbuttonbox > a[href!="#"][data-format]'), function(linkItem) { |
|
var name = linkItem.getAttribute("href").split('&title=GenYoutube.net_')[1]; |
|
var url = linkItem.getAttribute('href'); |
|
var weight = linkItem.querySelector("span.label.labelw").textContent ; |
|
var format = linkItem.getAttribute('data-format'); |
|
var no_video = linkItem.querySelector(".glyphicon.glyphicon-music") != null ? true : false; |
|
var no_sound = linkItem.querySelector(".glyphicon.glyphicon-volume-off") != null ? true : false; |
|
// [name, url, weight, format, no_video, no_sound] |
|
return [name, url, weight, format, no_video, no_sound]; |
|
}); |
|
|
|
return links; |
|
}); |
|
|
|
// require('utils').dump(listOfLinks); |
|
|
|
var bestChoice = -1; |
|
var mayor = 0; |
|
|
|
|
|
if(listOfLinks != null && listOfLinks.length > 0){ |
|
// Choosing the best link to download |
|
for(var i = 0; i < listOfLinks.length; i++){ |
|
|
|
var videoWeight = listOfLinks[i][2]; |
|
var realWeight = parseFloat(videoWeight.split('MB')[0]); |
|
|
|
if(realWeight < maxWeightOption && |
|
realWeight > mayor && |
|
formatOption == listOfLinks[i][3] && |
|
novideoOption == listOfLinks[i][4] && |
|
nosoundOption == listOfLinks[i][5] |
|
){ |
|
bestChoice = i; |
|
mayor = realWeight; |
|
} |
|
} |
|
|
|
// Print download link list |
|
casper.echo("DOWNLOAD LINKS FOR YOUTUBE VIDEO "); |
|
casper.echo("[" + listOfLinks[0][0] + "]"); |
|
casper.echo("[" + IDOption + "]"); |
|
casper.echo("============================================================================== "); |
|
for(var i = 0; i < listOfLinks.length; i++){ |
|
casper.echo("[" + (i < 9 ? " " : "") + (i + 1) + "] " + (bestChoice == i ? "[X]" : " ") + " [" + listOfLinks[i][2] + "][" + listOfLinks[i][3] + "]" + (listOfLinks[i][4] ? "[No Video]" : "") + (listOfLinks[i][5] ? "[No Sound]" : "") + (bestChoice == i ? "[SELECTED]" : "")); |
|
casper.echo("--------------------------------------------------"); |
|
} |
|
casper.echo("==============================================================================\n"); |
|
|
|
if(bestChoice != -1){ |
|
// Add download instruction to the output bash script |
|
output += 'mkdir tmpvideo \n'; |
|
output += 'wget -O "' + listOfLinks[bestChoice][0] + '" "' + listOfLinks[bestChoice][1] + '" \n'; |
|
output += 'mv ' + listOfLinks[bestChoice][0] + ' tmpvideo \n'; |
|
|
|
if(!!uploaderOption){ |
|
if(!fs.isFile(uploaderOption)){ |
|
casper.echo("ERROR: The file [" + uploaderOption + "] don't exist."); |
|
} else { |
|
output += 'casperjs --ignore-ssl-errors=true ' + uploaderOption + ' tmpvideo/ \n'; |
|
output += 'echo "INFO: Uploaded file to personal storage." \n'; |
|
if(rmAfterOption){ |
|
output += 'rm -rf tmpvideo \n'; |
|
output += 'echo "INFO: Removed downloaded files." \n'; |
|
} |
|
} |
|
} |
|
|
|
// Writing instructions on the final bash script |
|
this.then(function(){ |
|
// output += 'mv ' + listOfLinks[bestChoice][0] + '* upload/ \n'; |
|
fs.write("video.sh", output, 'w'); |
|
|
|
// Execute the bash script |
|
// casper.waitForExec('/bin/bash -c', ['{video.sh}']); |
|
if (childProcess) { |
|
// childProcess.execFile("/bin/bash", ["video.sh"]); |
|
var myscript = childProcess.exec('sh video.sh', function (error, stdout, stderr) { |
|
casper.echo('stdout: ' + stdout); |
|
casper.echo('stderr: ' + stderr); |
|
if (error !== null) { |
|
casper.echo('exec error: ' + error); |
|
} |
|
}); |
|
} else { |
|
this.log("Unable to require child process!", "warning"); |
|
} |
|
|
|
if(rmAfterOption){ |
|
fs.remove("video.sh"); |
|
casper.echo("INFO: File video.sh removed successfully!"); |
|
} |
|
}); |
|
} else { |
|
casper.echo("WARNING: There is no links to satisfy your requirements!"); |
|
casper.echo("Change your requirements to get success."); |
|
} |
|
} else { |
|
casper.echo("WARNING: There is no links to download video!"); |
|
} |
|
|
|
} |
|
|
|
casper.echo("INFO: Operation done!!!"); |
|
|
|
}); |
|
|
|
// Running the script |
|
casper.run(); |