package WWW::Ohloh::API::Stack; use strict; use warnings; use Carp; use Object::InsideOut; use XML::LibXML; use Readonly; use Scalar::Util qw/ weaken /; use Date::Parse; use Time::Piece; use WWW::Ohloh::API::StackEntry; our $VERSION = '0.3.0'; my @ohloh_of : Field : Arg(ohloh); my @request_url_of : Field : Arg(request_url) : Get( request_url ); my @xml_of : Field : Arg(xml); my @api_fields = qw/ id updated_at project_count stack_entries account_id account /; __PACKAGE__->create_field( '@' . $_, ":Set(_set_$_)", ":Get($_)" ) for qw/ id updated_at project_count account_id /; my @stack_entries_of : Field; my @account_of : Field; #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ sub _init : Init { my $self = shift; my $dom = $xml_of[$$self] or return; for my $f (qw/ id project_count account_id /) { my $method = "_set_$f"; $self->$method( $dom->findvalue("$f/text()") ); } $self->_set_updated_at( Time::Piece->new( str2time( $dom->findvalue("updated_at/text()") ) ) ); if ( my ($account_xml) = $dom->findnodes('account[1]') ) { $account_of[$$self] = WWW::Ohloh::API::Account->new( ohloh => $ohloh_of[$$self], xml => $account_xml, ); } $stack_entries_of[$$self] = [ map WWW::Ohloh::API::StackEntry->new( ohloh => $ohloh_of[$$self], xml => $_, ) => $dom->findnodes('stack_entries/stack_entry') ]; return; } #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ sub stack_entries { my $self = shift; return @{ $stack_entries_of[$$self] }; } #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ sub as_xml { my $self = shift; my $xml; my $w = XML::Writer->new( OUTPUT => \$xml ); $w->startTag('stack'); for my $f (qw/ id updated_at project_count account_id /) { $w->dataElement( $f => $self->$f ); } if ( my $account = $account_of[$$self] ) { $xml .= $account->as_xml; } if ( my @entries = @{ $stack_entries_of[$$self] } ) { $w->startTag('stack_entries'); $xml .= $_->as_xml for @entries; $w->endTag; } $w->endTag; return $xml; } #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ sub account { my $self = shift; my $retrieve = shift; $retrieve = 1 unless defined $retrieve; if ($retrieve) { $account_of[$$self] ||= $ohloh_of[$$self]->get_account( id => $self->account_id ); } return $account_of[$$self]; } sub set_account : Private( WWW::Ohloh::API::Account ) { my $self = shift; weaken( $account_of[$$self] = shift ); return; } 'end of WWW::Ohloh::API::Stack'; __END__ =begin test use lib 't'; use FakeOhloh; use WWW::Ohloh::API::Stack; my $ohloh = Fake::Ohloh->new; $ohloh->stash( 'yadah', 'stack.xml' ); my $thingy = $ohloh->get_account_stack( 123 ); =end test =head1 NAME WWW::Ohloh::API::Stack - a collection of projects used by a person =head1 SYNOPSIS use WWW::Ohloh::API; my $ohloh = WWW::Ohloh::API->new( api_key => $my_api_key ); # get the stack of a person my $stack = $ohloh->get_account_stack( $account_id ); # get stacks containing a project my @stacks = $ohloh->get_project_stacks( $project_id ); =head1 DESCRIPTION W::O::A::Stack represents a collection of projects used by a person. =head1 METHODS =for test ignore =head2 API Data Accessors =for test =head3 id Returns the unique id for the stack. =for test is $result[0] => 21420, 'id()'; =head3 updated_at Returns the most recent time at which any projects were added to or removed from this stack as a L object. =for test isa_ok $result[0], 'Time::Piece'; is $result[0], 'Mon Mar 17 13:09:16 2008', 'updated_at()'; =head3 project_count Returns the number of projects in the stack. =head3 stack_entries Returns a list of the entries contained by the stack as L objects. =for test isa_ok $_, 'WWW::Ohloh::API::StackEntry' for @result; is @result => 35, '35 stack entries'; =head3 account_id Returns the id of the account owning the stack. =for test $ohloh->stash( 'account', 'account.xml' ); my $retrieve = 1; =head3 account( I<$retrieve> ) Returns the account associated to the stack as a L object. If the account information was not present at the object's creation time, it will be queried from the ohloh server, unless I<$retrieve> is defined and set to false. =for test isa_ok $result[0], 'WWW::Ohloh::API::Account'; # querying it again shouldn't cause a fetch is $thingy->account => $result[0], 'querying again'; =for test ignore =head2 Other Methods =for test =head3 as_xml Returns the stack as an XML string. Note that this is not the same xml document as returned by the Ohloh server. =for test use XML::LibXML; ok( XML::LibXML->new->parse_string( $result[0] ), 'as_xml' ); =head1 SEE ALSO =over =item * L. =item * Ohloh API reference: http://www.ohloh.net/api/getting_started =item * Ohloh Account API reference: http://www.ohloh.net/api/reference/stack =back =head1 VERSION This document describes WWW::Ohloh::API version 0.3.0 =head1 BUGS AND LIMITATIONS WWW::Ohloh::API is very extremely alpha quality. It'll improve, but till then: I. Please report any bugs or feature requests to C, or through the web interface at L. =head1 AUTHOR Yanick Champoux C<< >> =head1 LICENCE AND COPYRIGHT Copyright (c) 2008, Yanick Champoux C<< >>. All rights reserved. This module is free software; you can redistribute it and/or modify it under the same terms as Perl itself. See L. =cut