Skip to content

Instantly share code, notes, and snippets.

@nneul
Created December 19, 2018 00:42
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save nneul/6eda98fd87a58a623b857523247f3471 to your computer and use it in GitHub Desktop.
Save nneul/6eda98fd87a58a623b857523247f3471 to your computer and use it in GitHub Desktop.
Quick ugly script for bulk download of packt ebooks from your own account
#!/usr/bin/perl
$| = 1;
use URI::Escape;
use LWP;
use JSON;
my $user = 'email@domain.com';
my $pw = 'my-password';
my $download_path = "/home/myuser/packt";
my $debug = 0;
my $ua = new LWP::UserAgent;
my $req = HTTP::Request->new( POST => "https://services.packtpub.com/auth-v1/users/tokens" );
my $login = {
username => $user,
password => $pw
};
my $content = encode_json($login);
$req->content($content);
$req->content_type("application/json");
my $res = $ua->request($req);
my $rinfo = decode_json( $res->content );
my $atoken = $rinfo->{data}->{access};
my $offset = 0;
my $max = 0;
my $page = 20;
my $baseurl = "https://services.packtpub.com/entitlements-v1/users/me/products?sort=createdAt:DESC&limit=$page";
my @results = ();
while ( !$max || $total < $max ) {
print "Requesting at offset $offset";
if ($max) {
print ", total $max";
}
print "...";
my $tmpurl = $baseurl . "&offset=$offset";
my $req = HTTP::Request->new( GET => $tmpurl );
$req->header( "Authorization" => "Bearer $atoken" );
my $res = $ua->request($req);
my $rinfo = decode_json( $res->content );
$max = $rinfo->{count};
my @recs = @{ $rinfo->{data} };
my $rcnt = scalar(@recs);
print " received $rcnt answers.\n";
$total += $rcnt;
push( @results, @recs );
$offset += $rcnt;
}
foreach my $book (@results) {
my $name = $book->{productName};
my $pid = $book->{productId};
my $fname = $name;
$fname =~ s|\s*\[ebook\]\s*$||gio;
$fname =~ s|/|_|gio;
$fname =~ tr/[a-z0-9\-\.A-Z ]//cd;
my $path = "$download_path/${fname}.pdf";
if ( !-e $path ) {
print "need to download $name\n";
my $infourl = "https://services.packtpub.com/products-v1/products/$pid/files/pdf";
my $req = HTTP::Request->new( GET => $infourl );
$req->header( "Authorization" => "Bearer $atoken" );
my $infores = $ua->request($req);
my $pdfinfo = decode_json( $infores->content );
my $pdfurl = $pdfinfo->{data};
if ( $pdfurl =~ m|^http(s)+://|o ) {
print "Downloading ($pdfurl).\n";
my $dlreq = HTTP::Request->new( GET => $pdfurl );
my $dlres = $ua->request($dlreq);
if ( $dlres->is_success ) {
open( my $out, ">${path}" );
print $out $dlres->content;
close($out);
}
else {
print "Failed download: " . $res->as_string, "\n";
}
}
}
else {
$debug && print "already have $path\n";
}
}
@zagrebzagreb
Copy link

Nice work!
How to download code, epub and mobi?
I tried changing pdf in "https://services.packtpub.com/products-v1/products/$pid/files/pdf" but no luck.

@chappy84
Copy link

chappy84 commented Mar 18, 2019

@zagrebzagreb do bear in mind that it also is hard coded to give the downloaded file a .pdf extension on line #71, regardless of the format you tell it to download on line #75.
You can either update this manually, use @davidcollom's modified version: https://gist.github.com/davidcollom/f7673bc4a6920535ac33f3027b8970fe , or use my alternate php downloader: https://gist.github.com/chappy84/c3b1533cec4ac0589b2dcc318b4e6606

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