First Successful Install

July 4, 2008 at 11:02 | Posted in Uncategorized | Leave a comment

I ran my first successful install today! I wated more control of the installation, so included some code to install all the prerequisites in wxCPAN, instead of using CPANPLUS::Backend. I still need to work on code for installing into arbitrary directories, but at least this is a great start! Here is a screenshot of the log:

Log of first successful install as root.

Log of first successful install as root.


Fixed Prerequisites, Module List Fully Works

July 4, 2008 at 09:07 | Posted in Perl, Summer of Code | Leave a comment

After much consternation over not being able to get the prerequisites for a module until installation, I have finally come accross a solution! I have added a method to, `$mod_tree->GetPrereqs($modulename)`, which properly returns the Prerequisites of a module. It does this by using the YAML module to parse the META.yml file which can be found at This method is a lot faster than downloading each module’s archive, then getting the META.yml file from the downloaded file. I have also added a method to update the display of the prerequisites tree in the info notebook.

I have also added the appropriate code so all the toolbar items work! You can now display modules in the following ways:

  • All modules by Module Name
  • All modules by Author Name
  • All modules by Category
  • Installed modules by Module Name
  • Installed modules by Author Name
  • Installed modules by Category
  • Uninstalled modules by Module Name
  • Uninstalled modules by Author Name
  • Uninstalled modules by Category
  • Updated modules by Module Name
  • Updated modules by Author Name
  • Updated modules by Category

Also, there are a few more bugs I need to work on, but I am hoping to have my first successful install using wxCPAN by this weekend!

POD Reader Finished!

July 1, 2008 at 21:01 | Posted in Perl, Summer of Code | Leave a comment

Lately, I have spent so much energy and time on getting bugs out of existing code, i had to take a break from bug-squishing and try to start something new. I decided to give a try at creating a POD reader for wxCPAN. I didn’t put too much time into it, and am pleasantly surprised with the outcome. I used the HTML POD parser, and the wxHTMLWindow for displaying the output. The biggest challenge was figuring out how to handle the links so we can pass the values to the Search() method. As a caveat, there are two basic versions, a Frame for a dialog, and a Panel, which can be used for embedding into a notebook or anything else. Here is a screenshot of how it is embedded into wxCPAN. It looks a little weird with the two search bars, but it’s intuitive, at least.

wxCPAN With the POD Reader Embedded into the main Notebook.

Week[4] Report: Tests and Squishes

June 29, 2008 at 11:22 | Posted in Perl, Summer of Code | Leave a comment

This week has moved kind of slow. I have completed this week’s goals, and have tried to squash some bugs.

Today, i am working on the “Search by All” type of search.

The big hurdle this week is in UI design and wait times. Since CPANPLUS takes time to fetch a few desired attributes from CPAN, I have modularized a lot of the code that happens when the user selects a module from the main module list view. (As of last week, when the user selected an item, she had to wait while CPANPLUS retrieved several files from CPAN.) There are now a few more tabs in the info pane, and only the ‘Info’ tab gets updated when the user makes a selection. This sped up the selection process from about 45 seconds to less tha 1 second. Most of my time this week was used up in testing various methods for retrieving data (threads, progressbars, etc.). But I decided on placing a button in every tab in the info pane which retrieves that pane’s information. A typical selection process is outlined here:

1. The user selects a module from the module list and the Info tab gets populated immediately.

2. If the user wants to read the module’s README file, they can click on the Readme.txt tab and click on the Get README button in that tab.

3. If the user wants to populate all the tabs in the pane below the list of modules (the info pane), they can click on the button labelled “Get Extended Info” in the Actions tab.

I plan on adding a button to display the appropriate POD in the POD Reader window (coming soon!).

I have also added a couple of pages to the wiki on googlecode this week. One page lists all the CPANPLUS modules and their methods/accessors, as well as where to get the information using the GUI and whether it is fully implemented or not. I am using this as a checklist of all the remaining work that needs to be done.

Another page lists ideas for future implementation. These items are to be done after gSoC’08, and will be a roadmap for future development. They are mainly feature requests from other people I have discussed this project with. (There is only one so far – a pretty big undertaking!)

Look for more big decisions and big designs in the week to come!

Week[3] Report: On-Schedule and More Features!

June 22, 2008 at 14:21 | Posted in Perl, Summer of Code | Leave a comment

This week has been exciting for me! I have completed the code for listing all installed modules by Name, Author, and Category (‘chapterid’). Here is a list of features I have also implemented:

I finished the search algorithm. You can search by exact query, or search with regex, using ‘/$searchtext/$mods’, just like regular regex in perl. I am going to implement an “Any” function for searching within any of the required type for CPANPLUS’s search() function.

The toolbar now works. If you are downloading the code, the XRC file specifies the tools in the toolbar, but since I can’t update the icons, I delete them all, then insert new tools. I plan on removing the ‘Update List’ button later, as I am using it for testing purposes.

The Module List
I worked very hard on the code which lists the modules by the various information. It still needs some work, but will do for now. Listing the modules by category was the hardest part. (See previous entry for explanation.) I poured over the code, and re-worked a bit of it to get the actual sorting routine from 4 minutes average, down to 1.5 minutes. A more than 50% reduction in time! The routine that inserts the items into the list originally averaged 30 seconds, (no icons in list), but now averages 1 minute, with the icons displayed. I think this is acceptable. Overall, my execution went from 5-8 minutes, down to 2-3 minutes. Not bad! As for improving this, I am not sure I can, except to give the user the option of displaying icons, but there will be no way to tell the module’s status, except for clicking on it and waiting for the other information to update. Eventually, I am going to put a reference to the generated list in the ListCtrl module, so if the user goes back to a previous view, the update won’t take so long.

The Actions Collector [placeholder]
This tab was added to the main display. It is not implemented yet, but will hold all a list of all the actions a user has selected, so if she wishes to do a mass update/install/remove, she will be able to review her changes before it begins. The “Update List” toolbar item will be changed to “Update Installation” (or something like that).

Status and Information Tabs
I have almost fully completed this. The method to update the display takes 5-10 seconds to complete. I have several information-related tabs: Info, Actions, Files, Readme.txt, Status, and Prerequisites.

Info [works]
displays various module-related information, like author, package, etc.
Actions [not implemented yet]
This is where the user can install different versions of a module or remove it.
Files [problems]
This lists all of the files in an installed module. Apparently, the CPANPLUS::Module::files() method only works for the installed version, so I need a way to get the module object for the installed version.
Readme.txt [works]
This is where the module’s README file is displayed. wxPerl v0.83 is preferred, as previous versions seemed to have a limit on text size in a TextCtrl. This is an unverified claim, but when I updated wxPerl to 0.83, the full file displayed properly.
Status [problems]
This is where most of the information from $module->status() is displayed. It is mostly checkboxes and textfields. I am not sure where or even if there is a problem, but almost all modules return a status object with all values set to undef. Maybe status() is only used during installation? Needs further testing – possibly ask Mr. Boumans, but I don’t want to waste his time.
Prerequisites [major problems]
This is a tree display of all the prerequisites for a module. It doesn’t seem to work with any modules. I am attempting to fix this.

Here is a screenshot to show what the main window looks like as of today.

wxCPAN in action!

GUI Decision: Progress in Status Bar vs Dialog

June 20, 2008 at 16:11 | Posted in Perl, Summer of Code | Leave a comment

I have been working on an algorithm to sort various data (installed modules, updated modules, etc.) into different categories, as it is on Since CPANPLUS::Module does not have a ‘chapterid’ section, I have had to write my own method to sort data into the 27 different categories, called ‘chapters’. This ‘chapterid’ information is stored in a file called Since CPANPLUS DOES download the file, i can read the already downloaded file’s contents, which is nothing more than an array reference with all the data I need. Then I sort the data into the different categories. This was fairly easy.
Then came the difficult part. It takes a long time, about 3-5 minutes, to sort the data into categories, then another 2 or 3 minutes to populate the wxTreeCtrl with the data. So I needed a way to communicate to the user what’s going on. Initially, the whole UI would freeze while all this sorting was taking place. So I looked into a few solutions for this:

Solution 1: Threads
I immediately thought about threads, because I like to use them when i can. They are a great feature if what you’re doing doesn’t depend on anything else. I read quite a bit about Perl’s thread support, and found out that it works best if the Perl Modules you are using also support threads. Wx has its own thread support through the Wx::Thread class. I tried both Wx’s and Perl’s threads,and they both worked equally well. They solved the initial problem (both with object access warnings), but nothing was telling the user what was going on, and I didn’t want the user to sit there wondering what was happening for eight minutes, so I needed something more.

Solution 2: wxStatusBar
I tried updating the main window’s Status Bar with and without threads. Without threads, the UI wouldn’t even display anyhting. With threads, the Status bar worked, but the UI worked sporadically, as the Status Bar’s text was updated, which was quite frequently. So I shortened the update, which, to my dismay, did not solve the sporadic UI problem. Also, I noticed about a 33% increase in the time it took to sort all those modules. I did not want this. I needed something that would tell the user what was happening, and not freeze the UI.

Solution 3: wxProgressBar or wxProgressDialog?
Finally, I looked into using a ProgressBar. Wx has two flavors of progress bars: a single progress bar that you can use in any window, or a Dialog Box with a progress indicator. This was a design decision that was quite difficult to make. Should I use a wxProgressDialog, or put a wxProgressBar right in to the main window? Since the user isn’t really supposed to do anything while the sorting is taking place, I decided on a wxProgressDialog. Programmatically, it is easy to use and doesn’t require a redesign of any windows. It has all the functionality i needed: A progress bar and text to let the user know what’s going on. (That’s all the features a wxProgressDialog has.) Whe I tested it, I was amazed! I expected the main window to freeze, like before, and the dialog to update accordingly, but, to my surprise, the main window did not freeze. I also expected the sorting time to decrease substantially, because of all the progress bar updates, but the decrease was negligible. I took out all the threading code at first, because I did not know how the progress dialog would respond to threads. As it turns out, threads were unneccessary.

Overall, this experience was very educational, both for the Wx widget set and for Perl’s threading support. I am still having sorting issues, but at least the user has something to look at while she waits!

Look for my Week[3] report in the next couple of days!

Week[2] Report: Preferences and Logging!

June 14, 2008 at 20:37 | Posted in Perl, Summer of Code | Leave a comment

This past week I have been working on finishing up the last few subclasses for the Preferences dialog, which is an interface to CPANPLUS::Configure. Everything seems to be in working order! The $config->get_conf(‘hosts’) interface was the biggest pain, as I had to parse the contents of the MIRRORS.txt file (see previous post). I put in quite a bit of time optimizing this function.

During all of this writingtesting recursion, I noticed quite a bit of print() statements were being used. This meant I had to run the program, test it, then switch back to the console to see output. Since I have been using the wxPerl demo to see available options, I noticed Wx’s LogXXX functions. So I wondered how difficult it would be to implement a logging facility for wxCPAN. It took very little time to implemet, but quite a bit to find a facility that actually worked! I settled on adding a tab in the main window to display log messages. Right now, the tab is visible, but when I implement the toolbar, the tabs will not be visible.

Next week: Displaying installed modules!

More efficient MIRRORS.txt parsing

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

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;


XRC Solutions

June 4, 2008 at 12:14 | Posted in Uncategorized | Leave a comment

I chose to create the Preferences dialog with the least amount of code. I set the Name attribute in the XRC file to the path in the CPANPLUS::Configure object. Foe example: The ‘conf’ section has the key ‘show_startup_tip’, so the name of the control is ‘conf/show_startup_tip’. During creation of the control, the name is converted into code, then eval()’ed. Here’s where it got really complicated: There is no post-creation code in wxWidgets, so I searched high and low for some way to overload a built-in method for the control. There is no post-creation code, so I looked into the types of events that were available. There it was: EVT_WINDOW_CREATE(). So I managed to get all this working with just a bit of code.  If you wish to see the code, go to

Fixed SVN and Prefs method

June 3, 2008 at 16:48 | Posted in Summer of Code | Leave a comment

I have hopefully fixed the problems in my SVN repository. I deleted everything, then re-committed everything. If you subscribe to my commit feed, then you will hopefully see the commits from now on.

As for the method for the CPAN preferences window, I chose to go with the method of least code. I have created a few subclasses of the controls and am using the name as an identifier to set/get the values from the config module. As of today, all the checkboxes are almost implemented. I just need to find a way to pass the config object to all the control subclasses. I have a few ideas on how to do that, which I am investigating.

« Previous PageNext Page »

Blog at
Entries and comments feeds.