The Dumbest Downloader That Could Possibly Work (and did)
Posted: 03 Nov 2012, 01:31
I learned a long time ago that, when coding, it is always a good idea to at least try The Dumbest Thing That Could Possibly Work, because if it does you will save yourself a lot of effort.
It seems to have worked.
This Perl program, when run, downloads the card data sets used by MTGO from the same sources as MTGO itself uses when installing and updating.
It basically mimics the updater's logic.
Put simply, the installer uses a Microsoft split installer assembly, and downloads its components piecemeal. This kind of installer keeps its data as nice, convenient XML, including easy-to-use references to where the pieces are.
Half an hour later, I have this:
The files it produces are XML that use IDs to cross-reference each other, it has all sets as far as I can tell, it includes Vanguard (including full oracle text!), flavor text, everything I have thought to look for. Enjoy!
EDIT: Oh, and it's also quite fast. Sub-15min runtime.
It seems to have worked.
This Perl program, when run, downloads the card data sets used by MTGO from the same sources as MTGO itself uses when installing and updating.
It basically mimics the updater's logic.
Put simply, the installer uses a Microsoft split installer assembly, and downloads its components piecemeal. This kind of installer keeps its data as nice, convenient XML, including easy-to-use references to where the pieces are.
Half an hour later, I have this:
- Code: Select all
#!/usr/bin/env perl
use strict;
use warnings;
use v5.14;
use LWP::Simple;
use XML::XQL;
use XML::XQL::DOM;
my $parser = new XML::DOM::Parser;
my %config;
sub doget {
my $file = shift;
my $out = $file;
$out =~ s,^.*/,,;
mirror( $config{server} . $file, $out );
return( $out );
}
sub locateManifest {
my $rootdoc = $parser->parsefile( doget( shift ) );
my ( $result ) = $rootdoc->xql( "/asmv1:assembly/dependency/dependentAssembly" );
my $location = $result->getAttribute( 'codebase' );
$location =~ tr,\\,/,;
$location =~ m,(.*/)(.*),;
my ( $verdir, $fname ) = ( $1, $2 );
return( $verdir, $fname );
}
sub locateData {
my $dir = shift;
my $manifestdoc = $parser->parsefile( doget( $dir . shift ) );
my @results = $manifestdoc->xql( "/asmv1:assembly/file" );
return( map { $dir . $_ } grep { $_ =~ m,^CardDataSource/, } map { $_ =~ tr,\\,/,; $_ } map { $_->getAttribute( 'name' ) } @results );
}
$config{server} = shift(@ARGV);
my $rootfile = "MTGO.application";
map { doget( $_ ) } locateData( locateManifest( $rootfile ) )
The files it produces are XML that use IDs to cross-reference each other, it has all sets as far as I can tell, it includes Vanguard (including full oracle text!), flavor text, everything I have thought to look for. Enjoy!
EDIT: Oh, and it's also quite fast. Sub-15min runtime.