Week[4] Report: Tests and Squishes

June 29, 2008 at 11:22 | In Perl, Summer of Code | Leave a Comment
Tags:

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 | 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:

Search
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.

Toolbar
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 | In Perl, Summer of Code | Leave a Comment
Tags:

I have been working on an algorithm to sort various data (installed modules, updated modules, etc.) into different categories, as it is on http://search.cpan.org. 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 03modlist.data.gz. 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 | In Perl, Summer of Code | Leave a Comment
Tags:

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 | 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;

}

XRC Solutions

June 4, 2008 at 12:14 | In Uncategorized | Leave a Comment
Tags:

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 http://wxcpan.googlecode.com

Fixed SVN and Prefs method

June 3, 2008 at 16:48 | In Summer of Code | Leave a Comment
Tags:

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.

Week[0] = Ahead of Schedule; SVN Problems Ensue

June 1, 2008 at 12:03 | In Uncategorized | 1 Comment
Tags:

This week, I have finished the Preferences window design, and am slowly implementing the controls.

However, I have run into some problems with my svn repo – mainly that I keep getting an error saying that a file already exists when I try to commit any files. I have looked this problem up, and am short on answers.

Here is the error I get:

Some of selected resources were not committed.
svn: Commit failed (details follow):
svn: Path ‘/svn/branches/development/wxcpan/CPANPLUS-Shell-Wx-0.01′ already exists

Blog at WordPress.com. | Theme: Pool by Borja Fernandez.
Entries and comments feeds.