More efficient MIRRORS.txt parsing

June 12, 2008 at 18:41 | Posted in Perl, Summer of Code | Leave a comment
Tags:

For the past two days, I have been coding a user selection process for adding mirrors to CPANPLUS::Config. When I first coded it, the method was 125 lines. It is now only 53! This is even shorter than the same function in CPANPLUS::Configure::Setup, which is a mighty 111 lines (from line 1351 to 1462)! The thing I like most about my version is that the arrays and hashes get shorter as the user goes from region to country to state to city! Here is the end result of my 6 hour labor (from begin to end):


sub OnAdd {


my $self = shift;
my ($event) = @_;
my %hosts = (); #hash containing host entries
my %location_tree = (); #a tree of locations

use CPANPLUS::Module::Fake;

use CPANPLUS::Module::Author::Fake;

my $file = $self->{cpan}->_fetch(

fetchdir => $self->{config}->get_conf(‘base’),
module => CPANPLUS::Module::Fake->new(

module => $self->{config}->_get_source(‘hosts’),
path => ”,
package => $self->{config}->_get_source(‘hosts’),
author => CPANPLUS::Module::Author::Fake->new( _id => $self->{cpan}->_id ),
_id => $self->{cpan}->_id,
)

);

#read in the MIRRORS.txt file and parse it
my $curhost = ”;
open F, $file;
foreach $line ( <F> ) {

unless ( $line =~ /^\#/ ) { #skip lines that begin with a comment

$curhost = $1 if ( $line =~ /(^(\S+\.)+\S+)\:/ ); #lines that begin with x.y.z: mean a new entry
$hosts{$curhost}->{$1} = $2 if ( $line =~ /(\w*?)\s*=\s*\”(.*?)\”/ ); #add info to host

}

}
close F;

foreach $key ( keys(%hosts) ) {

my @loc = split( ‘, ‘, $hosts{$key}->{‘dst_location’} ); #split line like “city,state,country,region (lat long)”
$loc[-1] =~ s/\s*\((.*)\)//; #get rid of lat, long coord
$1 =~ /\s*(\-?\d+\.\d+)\s*(\-?\d+\.\d+)/; #search for lat, long
($hosts{$key}->{‘lat’},$hosts{$key}->{‘long’}) = ($1,$2); #assign lat,long
$location_tree{ $loc[-1] }->{ $loc[-2] }->{ $loc[-3] } = $hosts{$key}; #all entries have at least depths
if ( $loc[-4] ){ #some entries have four depths

$location_tree{ $loc[-1] }->{ $loc[-2] }->{ $loc[-3] }={};
$location_tree{ $loc[-1] }->{ $loc[-2] }->{ $loc[-3] }->{ $loc[-4] }=$hosts{$key};

}

}

my $selection = \%location_tree;
my @titles_tree = ( ‘Region’, ‘Country’, ‘State’, ‘City’ );
until ( $selection->{‘dst_location’} ) {

my $title = shift @titles_tree;
my $choice = Wx::GetSingleChoice( “Select $title”, “Select $title:”,[ sort( keys( %{$selection} ) ) ], $self );
return unless $choice;
$selection = $selection->{$choice};

}
print Dumper $selection;

}

Advertisements

Leave a Comment »

RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Create a free website or blog at WordPress.com.
Entries and comments feeds.

%d bloggers like this: