Log In  


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"
}

May receive updates here

7


Could you make version for the worst OS ever (Crapdows)?


@darkhog it'll work on windows if you install perl :)


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"
    }
}

Nice rukai!


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]