| SETI-WebStats documentation | Contained in the SETI-WebStats distribution. |
SETI::WebStats - Gather SETI@home statistics from the SETI@home web server
use SETI::WebStats;
my $seti = SETI::WebStats->new;
# get individual user statistics...
if ($seti->fetchUserStats('foo@bar.org')) {
print "My rank current rank is " . $seti->rank, "\n";
print "I have processed " . $seti->numResults . " units.";
}
my $cpuTime = $seti->cpuTime;
my $userInfo = $seti->userInfo;
for (keys(%$userInfo)) {
print $_, "->", $userInfo->{$_}, "\n";
}
# get group statistics...
if ($seti->fetchGroupStats('perlmonks')) {
print $seti->groupFounderName . " founded the group.\n";
print "We have " . $seti->numGroupMembers . "members.\n";
print "We've processed " . $seti->numGroupResults . " units.\n";
print "For a total group CPU time of " . $seti->totalGroupCPU;
}
A simple Perl interface to SETI@home User & Group statistics.
The SETI::WebStats module queries the SETI@home web server to retrieve user and group statistics via XML. The data availible from the server is the same as that displayed on the Individual User Statistics and Group Statistics web pages. In order to query the server, you will need a valid SETI@home account (i.e email address) or valid group name.
Load the module as normal.
use SETI::WebStats
Create a WebStats object.
my $seti = SETI::WebStats->new;
$seti->fetchUserStats('foo@bar.org');
The fetchUserStats method takes a mandatory email address as it's only argument. The SETI@home web server will be queried and the XML output parsed. Returns 1 on success, 0 on failure.
You can then extract the user stats in one go:
my $userInfo = $seti->userInfo;
Returns a hash reference:
$userInfo = {
usertime => '3.530 years',
avecpu => '15 hr 54 min 36.3 sec',
numresults => '670',
regdate => 'Fri May 28 20:28:45 1999',
resultsperday => '0.51',
lastresulttime => 'Sat Jun 8 03:47:50 2002',
cputime => ' 1.217 years',
name => 'John Doe'};
Alternatively, instead of calling userInfo, you can extract each user statistic individually:
my $userTime = $seti->userTime; my $aveCpu = $seti->aveCpu; my $procd = $seti->numResults; my $registerDate = $seti->regDate; my $dailyResults = $seti->resultsPerDay; my $lastUnit = $seti->lastResultTime; my $cpuTime = $seti->cpuTime; my $accountName = $seti->name;
You can extract rank stats in one go:
my $rankInfo = $seti->rankInfo;
Returns a hash reference:
$rankInfo = {
num_samerank => '3',
ranktotalusers => '4152567',
top_rankpct => '0.516',
rank => '21410'};
Alternatively, instead of calling rankInfo, you can extract each rank statistic individually:
my $usersWithSameRank = $seti->haveSameRank; my $totalUsers = $seti->totalUsers; my $percentComparedTo = $seti->rankPercent; my $rank = $seti->rank;
$seti->fetchGroupStats('some_group_name');
The fetchGroupStats method takes a mandatory group name as it's only argument. The SETI@home web server will be queried and the XML output parsed. Returns 1 on success, 0 on failure.
You can then extract each group statistic.
my $groupName = $seti->groupName; my $groupURL = $seti->groupURL; my $founder = $seti->groupFounderName; my $founderURL = $seti->groupFounderURL; my $groupResults = $seti->numGroupResults; my $groupMembers = $seti->numGroupMembers; my $groupCPU = $seti->totalGroupCPU;
None that I'm aware of but be sure to let me know if you find one.
Kevin Spencer <vek@perlmonk.org>
| SETI-WebStats documentation | Contained in the SETI-WebStats distribution. |
# $Id: WebStats.pm,v 1.9 2003/10/10 01:57:57 vek Exp $ package SETI::WebStats; use Carp qw(croak); use LWP::UserAgent; use XML::Simple; use strict; use vars qw($VERSION); $VERSION = '1.03'; use constant USERURL => "http://setiathome.ssl.berkeley.edu/fcgi-bin/fcgi?cmd=user_xml&email=%s"; use constant GROUPURL => "http://setiathome.ssl.berkeley.edu/fcgi-bin/fcgi?cmd=team_lookup_xml&name=%s"; sub new { my ($class, $emailAddr) = @_; my $self = {}; $self->{version} = $VERSION; bless $self, $class; # still allowing emailAddr in constructor for # backwards compatability... if ($emailAddr) { return $self->fetchUserStats($emailAddr); } return $self; } ############################################################################### # Public methods ############################################################################### sub fetchUserStats { my ($self, $emailAddr) = @_; if (! $emailAddr) { croak("You must specify an email address"); return 0; } my $url = sprintf(USERURL, $emailAddr); $self->_mode('user'); return $self->_fetch($url); } sub fetchGroupStats { my ($self, $groupName) = @_; if (! $groupName) { croak("You must specify a group name"); return 0; } my $url = sprintf(GROUPURL, $groupName); $self->_mode('group'); return $self->_fetch($url); } # userinfo methods sub userInfo { my $self = shift; return $self->{data}->{userinfo}; } sub userTime { my $self = shift; return $self->{data}->{userinfo}->{usertime}; } sub aveCpu { my $self = shift; return $self->{data}->{userinfo}->{avecpu}; } sub numResults { my $self = shift; return $self->{data}->{userinfo}->{numresults}; } sub regDate { my $self = shift; return $self->{data}->{userinfo}->{regdate}; } sub profileURL { my $self = shift; if ($self->{data}->{userinfo}->{userprofile}) { return $self->{data}->{userinfo}->{userprofile}->{a}->{href}; } else { return "No URL"; } } sub resultsPerDay { my $self = shift; return $self->{data}->{userinfo}->{resultsperday}; } sub lastResultTime { my $self = shift; return $self->{data}->{userinfo}->{lastresulttime} || 0; } sub cpuTime { my $self = shift; return $self->{data}->{userinfo}->{cputime}; } sub name { my $self = shift; if (ref $self->{data}->{userinfo}->{name}) { return $self->{data}->{userinfo}->{name}->{a}->{content}; } else { return $self->{data}->{userinfo}->{name}; } } sub homePage { my $self = shift; if (ref $self->{data}->{userinfo}->{name}) { if ($self->{data}->{userinfo}->{name}->{a}->{href}) { return $self->{data}->{userinfo}->{name}->{a}->{href}; } else { return "No Home Page"; } } else { return "No Home Page"; } } # rankinfo methods sub rankInfo { my $self = shift; return $self->{data}->{rankinfo}; } sub haveSameRank { my $self = shift; return $self->{data}->{rankinfo}->{num_samerank}; } sub totalUsers { my $self = shift; return $self->{data}->{rankinfo}->{ranktotalusers}; } sub rankPercent { my $self = shift; return (100 - $self->{data}->{rankinfo}->{top_rankpct}); } sub rank { my $self = shift; return $self->{data}->{rankinfo}->{rank}; } # groupinfo methods from individual user query... sub groupInfo { my $self = shift; return $self->{data}->{groupinfo}->{group} ? $self->{data}->{groupinfo}->{group}->{a} : undef; } sub groupName { my $self = shift; return $self->{data}->{groupinfo}->{group} ? $self->{data}->{groupinfo}->{group}->{a}->{content} : undef; } sub groupUrl { my $self = shift; return $self->{data}->{groupinfo}->{group} ? $self->{data}->{groupinfo}->{group}->{a}->{href} : undef; } # group methods (from group query) sub groupURL { my $self = shift; return $self->{groupdata} ? ($self->{groupdata}->{url} || undef) : undef; } sub numGroupResults { my $self = shift; return $self->{groupdata} ? ($self->{groupdata}->{numresults} || undef) : undef; } sub numGroupMembers { my $self = shift; return $self->{groupdata} ? ($self->{groupdata}->{nummembers} || undef) : undef; } sub totalGroupCPU { my $self = shift; return $self->{groupdata} ? ($self->{groupdata}->{totalcpu} || undef) : undef; } sub nameOfGroup { my $self = shift; return $self->{groupdata} ? ($self->{groupdata}->{name} || undef) : undef; } sub groupFounderName { my $self = shift; return $self->{groupdata} ? ($self->{groupdata}->{founder}->{name} || undef) : undef; } sub groupFounderURL { my $self = shift; return $self->{groupdata} ? ($self->{groupdata}->{founder}->{url} || undef) : undef; } ############################################################################### # Private methods ############################################################################### sub _fetch { my ($self, $URL) = @_; my $ua = LWP::UserAgent->new; $ua->agent("SETI::WebStats/$VERSION " . $ua->agent); my $req = HTTP::Request->new('GET', $URL); my $resp = $ua->request($req); return 0 if (! $resp->is_success); if ($resp->content =~ /No user|No such group/) { croak($resp->content); return 0; } local ($^W) = 0; # silence XML::SAX::Expat if ($self->_mode eq 'user') { $self->{data} = XMLin($resp->content); } else { $self->{groupdata} = XMLin($resp->content); } local ($^W) = 1; return 1; } sub _mode { my ($self, $mode) = @_; if (defined $mode) { $self->{mode} = $mode; return $self; } else { return $self->{mode} || undef; } } 1; __END__