I keep seeing tweets with URLs to cartridges that I should check out. I'm super lazy so I wrote a tool to download the cart automatically.
Should run on any Linux and probably OSX:
#!/usr/bin/env perl use strict; use warnings; use feature 'say'; use HTTP::Tiny; use File::Path 'mkpath'; my $ua = HTTP::Tiny->new; my $re = qr{ <a \s+ href=/(bbs/cposts/[^>]+.png)>\n\s+ <b><font \s+ color=\#ff0080 \s+ size=3>(.+) \s+ (.+)</font></b></a> }xi; my $res = $ua->get(shift); if ($res->{content} =~ $re) { my ($url, $name, $ver) = ($1, $2, $3); my $dir = "$ENV{HOME}/.lexaloffle/pico-8/carts/dl/"; mkpath($dir); my $path = $dir . lc $name . '.png'; say "Downloading $name v$ver Cart to $path"; $ua->mirror("https://lexaloffle.com/$url", $path); } else { die "Could not find game data; are you sure it was a valid URL?\n" } |
I run ./get-cartridge and it should download all the cartridges?
Any idea whats causing this error?
Use of uninitialized value $url in pattern match (m//) at /usr/share/perl5/core_perl/HTTP/Tiny.pm line 785.
Use of uninitialized value $url in concatenation (.) or string at /usr/share/perl5/core_perl/HTTP/Tiny.pm line 785.
Could not find game data; are you sure it was a valid URL?
EDIT:
No worries, I figured out im supposed to run it like this: ./get-cartridge "pageContainingCartridgesURL"
I wanted to be able to download all the cartridges with a single script so I added to yours to achieve that.
Instructions:
Save the following script to a perl file and run it.
It will download all the cartridges published on the BBS to the dl directory inside the pico8 cartridges directory.
#!/usr/bin/env perl use strict; use warnings; use feature 'say'; use HTTP::Tiny; use File::Path 'mkpath'; #get html of page listing cartridges my $indexConnection = HTTP::Tiny->new; my $indexURL = "https://www.lexaloffle.com/bbs/?cat=7&sub=2"; my $indexHTML = ($indexConnection->get($indexURL))->{content}; #find out how many pages there are if($indexHTML =~ m/Page \d of (\d)/){ my $pageCount = $1; } #concatenate the HTML of all pages to $indexHTML for(my $i = 1; $i <= 3; $i++){ $indexHTML = $indexHTML . ($indexConnection->get($indexURL . "&page=" . $i))->{content}; } #run the downloader on each cartridge page my @results = ($indexHTML =~ m/tid=([0-9]+)&autoplay=1#pp/g); for my $result (@results) { my $url = "https://www.lexaloffle.com/bbs/?tid=" . $result; downloadCartridge($url); } #downloads the cartridge on the passed url sub downloadCartridge { my $ua = HTTP::Tiny->new; my $re = qr{ <a \s+ href=/(bbs/cposts/[^>]+.png)>\n\s+ <b><font \s+ color=\#ff0080 \s+ size=3>(.+?)(\s\d\..+)?</font></b></a> }xi; my $res = $ua->get(shift); if ($res->{content} =~ $re) { my ($url, $name, $ver) = ($1, $2, $3); my $dir = "$ENV{HOME}/.lexaloffle/pico-8/carts/dl/"; mkpath($dir); my $filename = lc $name; $filename =~ s/\s+/-/g; my $path = $dir . $filename . '.png'; say "Downloading $name v$ver Cart to $path"; $ua->mirror("https://lexaloffle.com/$url", $path); } else { die "Could not find game data; are you sure it was a valid URL?\n" } } |
I've edited the script to work as of 2019-07-04. It is not pretty, but it works for me.
Remember to change the download dir shown in the code.
#!/usr/bin/env perl use strict; use warnings; use feature 'say'; use HTTP::Tiny; use File::Path 'mkpath'; say "Init download script"; #get html of page listing cartridges my $indexConnection = HTTP::Tiny->new; my $indexURL = "https://www.lexaloffle.com/bbs/?cat=7&sub=2"; my $indexHTML = ($indexConnection->get($indexURL))->{content}; #find out how many pages there are if($indexHTML =~ m/Page \d of (\d)/){ my $pageCount = $1; } #concatenate the HTML of all pages to $indexHTML for(my $i = 1; $i <= 99; $i++){ say "Getting page " . $i . " of 99"; $indexHTML = $indexHTML . ($indexConnection->get($indexURL . "&page=" . $i))->{content}; } #run the downloader on each cartridge page my @results = ($indexHTML =~ m/tid=([0-9]+)/g); say scalar @results; for my $result (@results) { say "result: " . $result; my $url = "https://www.lexaloffle.com/bbs/?tid=" . $result; downloadCartridge($url); } say "-- END OF SCRIPT --"; #downloads the cartridge on the passed url sub downloadCartridge { say "downloadCartridge reached"; my $ua = HTTP::Tiny->new; my $re = "(\/bbs\/cposts\/[a-z0-9]{1,}\/([a-zA-Z0-9_]{1,})-{0,}([0-9]){0,}\.p8\.png)"; my $res = $ua->get(shift); if ($res->{content} =~ $re) { say "legit cart"; my ($url, $name) = ('https://www.lexaloffle.com' . $1, $2); my $ver = 0; if (defined $3) { if (length($3) > 0) { $ver = $3; } } say "url: " . $url; # --- CHANGE THIS TO YOUR PREFERED DOWNLOAD LOCATION --- # my $dir = "D:/pico-8_win32/carts/"; # ------------------------------------------------------ # mkpath($dir); my $filename = lc $name; $filename =~ s/\s+/-/g; my $path = $dir . $filename . '.p8.png'; say "Downloading $name v$ver Cart to $path"; $ua->mirror($url, $path); } else { say "Could not find game data; are you sure it was a valid URL?\n" } } |
sorry I am a newbie where do these scripts output the cartridges? can I make a local copy of them in my own dir? eg downloads
pico, on the script there's this part:
--- CHANGE THIS TO YOUR PREFERED DOWNLOAD LOCATION ---
my $dir = "D:/pico-8_win32/carts/";
# ------------------------------------------------------ #
you can change that to specify the download folder :)
I've updated the script to download only the featured carts. This will download 473 cartridges in total. The script will need to be tweaked when more pages are added.
#!/usr/bin/env perl use strict; use warnings; use feature 'say'; use HTTP::Tiny; use File::Path 'mkpath'; say "Init download script"; # Initialize connection my $indexConnection = HTTP::Tiny->new; my $indexURL = "https://www.lexaloffle.com/bbs/?cat=7&sub=2"; # Get HTML of all pages (page 1 to page 16) my $indexHTML = ""; for (my $i = 1; $i <= 16; $i++) { say "Getting page " . $i . " of 16"; $indexHTML .= ($indexConnection->get($indexURL . "&page=" . $i))->{content}; } # Run the downloader on each cartridge page my @results = ($indexHTML =~ m/tid=([0-9]+)/g); say scalar @results; # This will print the number of cartridges found for my $result (@results) { say "result: " . $result; my $url = "https://www.lexaloffle.com/bbs/?tid=" . $result; downloadCartridge($url); } say "-- END OF SCRIPT --"; # Downloads the cartridge on the passed URL sub downloadCartridge { say "downloadCartridge reached"; my $ua = HTTP::Tiny->new; my $re = "(\/bbs\/cposts\/[a-z0-9]{1,}\/([a-zA-Z0-9_]{1,})-{0,}([0-9]){0,}\.p8\.png)"; my $res = $ua->get(shift); if ($res->{content} =~ $re) { say "legit cart"; my ($url, $name) = ('https://www.lexaloffle.com' . $1, $2); my $ver = 0; if (defined $3) { if (length($3) > 0) { $ver = $3; } } say "url: " . $url; # --- CHANGE THIS TO YOUR PREFERED DOWNLOAD LOCATION --- # my $dir = "C:/Users/Misc/Downloads/pico-8/carts/"; # ------------------------------------------------------ # mkpath($dir); my $filename = lc $name; $filename =~ s/\s+/-/g; my $path = $dir . $filename . '.p8.png'; say "Downloading $name v$ver Cart to $path"; $ua->mirror($url, $path); } else { say "Could not find game data; are you sure it was a valid URL?\n"; } } |
[Please log in to post a comment]