Skip to content

Instantly share code, notes, and snippets.

@Woody2143
Last active February 2, 2018 14:44
Show Gist options
  • Save Woody2143/830d5eae396f5ddcae4f6b7668690659 to your computer and use it in GitHub Desktop.
Save Woody2143/830d5eae396f5ddcae4f6b7668690659 to your computer and use it in GitHub Desktop.
@graymouser (https://gist.github.com/graymouser/a33fbb75f94f08af7e36) came up with the initial bit of javascript code to paste in to a console window on the humble bundle site to download files. The resulting discussion lead to some nice code by @oxguy3 but I wanted one last addition on that. So below is my code to save the file as the title of…
/*
This no longer works. They changed how their page renders. The good news is that an alternative is in the works.
There is a single request fo their order API that gives a JSON response with all of the download links. A quick
script to parse that should generate a list of download links and files to save as. Stand-by...
*/
/* I've added MP3 below for MP3 audio books, you could also add FLAC if you wanted, but those file sizes... */
var pattern = /(MOBI|EPUB|PDF( ?\(H.\))?|CBZ|Download|MP3)$/i;
var nodes = document.getElementsByTagName('a');
var downloadCmd = '';
for (i in nodes) {
var a = nodes[i];
if (a && a.text && pattern.test(a.text.trim()) && a.attributes['data-web']) {
var name = a.parentNode.parentNode.parentNode.parentNode.parentNode.getAttribute("data-human-name");
name = name.replace(/\s+/g, '_'); /* change spaces to underscores */
name = name.replace(/'/g, ''); /* don't want single quotes */
name = name.replace(/:/g, '_-'); /* change : to _- for looks */
name = name.replace(/,/g, ''); /* don't need commas */
name = name.replace(/&/g, 'and'); /* taking out the pesky & */
name = name.replace(/!/g, ''); /* taking out the pesky ! */
var extension;
/* This isn't the best way to do this I'm sure, but my regex skills are failing me at this point, so I'm moving on */
if (/\_optimized\./.test(a.attributes['data-web'].value)) {
/* likely the below URL regex will need corrected at some point */
extension = /https:\/\/dl\.humble\.com\/.*(_optimized\..*)\?gamekey.*/.exec(a.attributes['data-web'].value);
} else {
extension = /https:\/\/dl\.humble\.com\/.*(\..*)\?gamekey.*/.exec(a.attributes['data-web'].value);
}
name += extension[1];
downloadCmd += 'wget --output-document="' + name + '" --content-disposition "' + a.attributes['data-web'].value + "\"\n";
}
}
downloadCmd += "\n";
var output = document.createElement("pre");
output.textContent = downloadCmd;
document.getElementById("papers-content").prepend(output);
@jimmckeeth
Copy link

I don't see any documentation on the Order API. Can you share the details of the request?

@Woody2143
Copy link
Author

There is a blog post by @oxguy3 that details his work with the Humble Bundle API. But ultimately I found that it really boils down to two API calls and a single cookie.

All you need to query the below APIs is a single cookie, '_simpleauth_sess', which you can get from your browser after you log in. The post by @OxGuy talks about how to make calls to the API to log in and get the AuthTokey (for 2FA) sent via text, but I stumbled a bit there and decided to just shortcut straight to the cookie from the browser.

A call to 'https://www.humblebundle.com/api/v1/user/order' returns a JSON array where each item is a hash with a single key, 'gamekey'.

From there you can call 'https://www.humblebundle.com/api/v1/order/$gamekey' and you'll get a large JSON object with everything about that specific order, the name of the bundle, how much you paid, etc, but most importantly it contains the name and download link to every book/mp3/game/whatever inside that order. So you can then parse that object to download your files.

I'm about 80% done with a perl script that gets all of the orders and you can then selectively download what you want. I initially had it working just to parse the order json and it would automatically download all the files and check the downloads against their MD5 hashes but I wanted to expand it a bit after finding the other API call. I'll get my code up on github soon, but right now it's pretty incomplete and ugly looking.

@Woody2143
Copy link
Author

There could also be a pretty simple script to just drop in a browser to read out that data and print out wget commands like the original above, I've just not taken the time to explore that option.

@jimmckeeth
Copy link

Thanks!

@Woody2143
Copy link
Author

I do have a script started that does the bulk download; see here:
HumbleBundleDL

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment