package WWW::SourceForge::Project; use Cwd; use WWW::Mechanize; use vars qw($VERSION); $VERSION = '0.06'; =head1 NAME WWW::Source::Project - A class presenting sourceforge projects. =head1 SYNOPSIS use strict; use WWW::SourceForge::Project; use Data::Dumper; my $pname = 'gaim'; my $proj = WWW::SourceForge::Project->new($pname); print Dumper $proj->Member; =head1 DESCRIPTION This object use L to grab any informations of a project from sourceforge website. =head1 METHODS =head2 new($unixname) Return an object of project with given unixname. =cut sub new { my ($class,$pname) = @_; my $url = _projurl($pname); my $proj; my $wa = WWW::Mechanize->new( autocheck => 1); $wa->get($url); my $content = $wa->content; # Project description my ($foo,$meta) = $content =~ m{

\s+\s+\w+?.*?\s+(.*?)\s+(.+?)\s+\s+}g) { my ($realName,$loginname,$position,$email) = ($1,$2,$3,$4); $email =~ s/\s+at\s+/@/; $position =~ s/\s*\(.+\)\s*//; # strip inline comments. $position =~ s/^\s+//; $position ||= 'No specific role'; if ($realName =~ m{(.+?){$position}||=[]} , { realName => $realName, loginName => $loginname, position => $position, email => $email, }; } $self->{members} = $members; return $self->{members}; } sub Tracker { my $s = shift; my $r; foreach (qw/Bugs Supports Patches Features/) { $r->{$_} = [$s->{"o$_"}, $s->{"n$_"}]; } return $r; } sub Forum {} sub DocManager {} sub TaskManager {} sub Latestnews {} # yawp! sub MakeDonation {} =head2 FetchCVSRepository( ) Fetch and save the cvs repository tarball into current working directory. =cut sub FetchCVSRepository { my $self = shift; my $project = $self->{unixname}; my $url = "http://cvs.sourceforge.net/cvstarballs/${project}-cvsroot.tar.bz2"; my $wa = WWW::Mechanize->new( autocheck => 1); $wa->get($url, ":content_file" => "${project}-cvsroot.tar.bz2" ); } # privates sub _projurl { return "http://sourceforge.net/projects/" . $_[0]; } "True";

(.+?)

(?:.+?)

    (.+?)
}s; $foo =~ s/^\s+//s; $foo =~ s/\s+$//s; $proj = {unixname => $pname, description => $foo}; @$proj{name} = $content =~ m{SourceForge.net: Project Info - (.+)}; foreach (split(/
  • /,$meta)) { s/\s*
    //; my ($k,$v) = split /: /; next unless $k; $v =~ s{]+?>(.+?)}{$1}g; if ($v =~ /,/) { my @vlist = split(/\s*,\s*/,$v); $proj->{$k} = \@vlist; } else { $proj->{$k} = $v; } } # Parse Track Numbers @$proj{'Homepage'} = $content =~ m{ Project Home Page}s; @$proj{'oBugs','nBugs'} = $content =~ m{Bugs\s+\( (\d+?) open / (\d+?) total \)}; @$proj{'oSupports','nSupports'} = $content =~ m{Requests\s+\( (\d+?) open / (\d+?) total \)
    }; @$proj{'oPatches','nPatches'} = $content =~ m{Patches\s+\( (\d+?) open / (\d+?) total \)
    }; @$proj{'oFeatures','nFeatures'} = $content =~ m{Feature Requests\s+\( (\d+) open / (\d+) total \)}; # Parse Admin my @admin; my ($prjadmins) = $content =~ m{Project Admins:
    (.+?)
    }s; while ($prjadmins =~ m{\w+?(.*?)
    }sg) { push @admin,$1; } $proj->{Admin} = \@admin; # Find important links my %links; $links{home} = $wa->uri; $links{developers} = ($wa->find_link(text_regex => qr/View Members/))->url; $proj->{links} = \%links; $proj->{_wa} = $wa; $proj->{members} = {}; return bless($proj,$class); } # More site function here. =head2 Admin Return a list, or arrayref, of member objects who are project administrators. =cut sub Admin { my $self = shift; my $admin = $self->{Admin}; return wantarray? @$admin : $admin ; } =head2 Member($param) Return a hashref of all project members. Organized as $pm->{}->{} =cut sub Member { my($self,$param) = @_; my $wa = WWW::Mechanize->new; $wa->get($self->{links}->{home}); $wa->follow_link(url=>$self->{links}->{developers}); my $content = $wa->content; my $members = $self->{members}; $members = $self->{members} = {} if ($param->{refresh}); return $members if(keys %$members); while ($content =~ m{
  • (.+?)