=================================================================== RCS file: /cvs/HOPE/Net-OpenAMD/lib/Net/OpenAMD.pm,v retrieving revision 1.2 retrieving revision 1.17 diff -u -r1.2 -r1.17 --- HOPE/Net-OpenAMD/lib/Net/OpenAMD.pm 2010/06/24 23:10:10 1.2 +++ HOPE/Net-OpenAMD/lib/Net/OpenAMD.pm 2010/07/13 01:13:22 1.17 @@ -1,41 +1,88 @@ package Net::OpenAMD; -# $AFresh1$ +# $AFresh1: OpenAMD.pm,v 1.16 2010/07/09 22:04:21 andrew Exp $ use warnings; use strict; use Carp; -use version; our $VERSION = qv('0.0.1'); +use version; our $VERSION = qv('0.0.4'); +my $BASE_URI = 'https://api.hope.net/api/'; -my $BASE_URL = 'https://api.hope.net/api/'; +use Scalar::Util qw( refaddr ); +*_ident = \&refaddr; -use Class::Std::Utils; - use LWP::UserAgent; +use URI; use Net::OAuth; -use JSON::Any; +use JSON; { - my @attr_refs = \(); + my @attr_refs = \( + my %base_uri_of, + my %ua_of, my %auth_of, my %actions_of, + my %json_of, + ); sub new { my ( $class, $options ) = @_; - my $self = bless anon_scalar(), $class; - my $ident = ident($self); + my $self = bless do { \my $x }, $class; + my $ident = _ident($self); + $options ||= {}; + + croak 'Options should be a hashref' if ref $options ne 'HASH'; + + $base_uri_of{$ident} = $options->{base_uri} || $BASE_URI; + $ua_of{$ident} = $options->{ua} || LWP::UserAgent->new(); + $json_of{$ident} = $options->{json} || JSON->new(); + $actions_of{$ident} = $options->{actions} + || [qw( location speakers talks interests users )]; + + foreach my $action ( @{ $actions_of{$ident} } ) { + ## no critic + no strict 'refs'; + *{$action} = sub { shift->get( $action, @_ ) }; + } + + # XXX Authenticate + return $self; } - sub _get { croak 'Unsupported' } + sub get { + my ( $self, $action, $query ) = @_; + my $ident = _ident($self); - sub location { my $self = shift; return $self->_get( 'location', @_ ) } - sub speakers { my $self = shift; return $self->_get( 'speakers', @_ ) } - sub talks { my $self = shift; return $self->_get( 'talks', @_ ) } - sub interests { my $self = shift; return $self->_get( 'interests', @_ ) } - sub users { my $self = shift; return $self->_get( 'users', @_ ) } + my $uri = URI->new_abs( $action . '/', $base_uri_of{$ident} ); + $uri->query_form($query); + + my $response = $ua_of{$ident}->get($uri); + croak $response->status_line if !$response->is_success; + + my $data; + eval { + $data = $json_of{$ident}->decode( $response->decoded_content ); + }; + croak "Invalid JSON from [$uri]" if $@; + + return $data; + } + sub stats { croak 'Unused feature' } + + sub DESTROY { + my ($self) = @_; + my $ident = _ident $self; + + foreach my $attr_ref (@attr_refs) { + delete $attr_ref->{$ident}; + } + + return; + } + } 1; # Magic true value required at end of module @@ -48,106 +95,134 @@ =head1 VERSION -This document describes Net::OpenAMD version 0.0.1 +This document describes Net::OpenAMD version 0.0.4 =head1 SYNOPSIS use Net::OpenAMD; -=for author to fill in: - Brief code example(s) here showing commonest usage(s). - This section will be as far as many users bother reading - so make it as educational and exeplary as possible. + my $amd = Net::OpenAMD->new(); + + my $location = $amd->location({ area => 'Engressia' }); + - =head1 DESCRIPTION This module is to make it easy to grab information from the OpenAMD project at The Next Hope. +http://wiki.hope.net/Attendee_Meta-Data + http://amd.hope.net/ +http://amd.hope.net/2010/05/openamd-api-released-v1-1-1/ + +http://travisgoodspeed.blogspot.com/2010/06/hacking-next-hope-badge.html + =head1 INTERFACE -=for author to fill in: - Write a separate section listing the public components of the modules - interface. These normally consist of either subroutines that may be - exported, or methods that may be called on objects belonging to the - classes provided by the module. +=head2 new +Create a new object for accessing the OpenAMD API. -=head1 DIAGNOSTICS + my $amd = Net::OpenAMD->new( $options ); -=for author to fill in: - List every single error and warning message that the module can - generate (even the ones that will "never happen"), with a full - explanation of each problem, one or more likely causes, and any - suggested remedies. +$options is a hashref with configuration options. +Current options are + =over -=item C<< Error message here, perhaps with %s placeholders >> +=item base_uri -[Description of error here] +A URL to the API, currently defaults to https://api.hope.net/api/ -=item C<< Another error message here >> +Most likely it should end with a / to make URI happy, so notice that if you +are having 404 errors you don't expect. -[Description of error here] +=item ua -[Et cetera, et cetera] +Should be a pre-configured LWP::UserAgent or similar that returns a +HTTP::Response object when its get method is called with a URI. =back +=head2 get +This is the main method, although probably never used. It has better/easier +ways to access the different actions of the API. + + my $data = $amd->get( $action, $params ); + +$params are anything that are supported by URI->query, they will get passed +on the request. + +Here $data is a the JSON returned by the API converted to Perl reference. + +Helper methods you can call as $amd->method($params) are: + +=over + +=item interests + +=item location + +=item new + +=item speakers + +=item stats + +=item talks + +=item users + +=back + +Unless specified, there is nothing different about any of the action methods +than just calling get($action) instead. Depending on API changes, this may +not always be the case. + +=head1 DIAGNOSTICS + +All methods should croak when an error occurs. +If the remote API returns a successful response that contains valid JSON, that +will be decoded and returned. + =head1 CONFIGURATION AND ENVIRONMENT -=for author to fill in: - A full explanation of any configuration system(s) used by the - module, including the names and locations of any configuration - files, and the meaning of any environment variables or properties - that can be set. These descriptions must also include details of any - configuration language used. - Net::OpenAMD requires no configuration files or environment variables. +Net::OpenAMD uses LWP::UserAgent for requests and environment for that is +not cleared. =head1 DEPENDENCIES -=over +=head3 L -=item LWP::UserAgent +=head3 L -=item Net::OAuth +=head3 L -=item JSON::Any +=head3 L -=back =head1 INCOMPATIBILITIES -=for author to fill in: - A list of any modules that this module cannot be used in conjunction - with. This may be due to name conflicts in the interface, or - competition for system or program resources, or due to internal - limitations of Perl (for example, many modules that use source code - filters are mutually incompatible). - None reported. =head1 BUGS AND LIMITATIONS -=for author to fill in: - A list of known problems with the module, together with some - indication Whether they are likely to be fixed in an upcoming - release. Also a list of restrictions on the features the module - does provide: data types that cannot be handled, performance issues - and the circumstances in which they may arise, practical - limitations on the size of data sets, special cases that are not - (yet) handled, etc. - No bugs have been reported. + +=over + +=item Currently it does not support the OAuth that is required to log into the +API and get information. + +=back Please report any bugs or feature requests to C, or through the web interface at