X-Git-Url: http://erislabs.net/gitweb/?a=blobdiff_plain;f=lib%2FWWW%2FOpenSearch%2FResponse.pm;h=97efcd035c24e2cf60507ec07056ab129bcf91e6;hb=fe2ef623df476f636013170716c174cb3adab0f2;hp=816476a9abcc9d2a2697281144ea546c3ffa2ec8;hpb=51d6cd8e2223091f60850c0eecab47a50a21fb30;p=libwww-opensearch-perl.git diff --git a/lib/WWW/OpenSearch/Response.pm b/lib/WWW/OpenSearch/Response.pm index 816476a..97efcd0 100644 --- a/lib/WWW/OpenSearch/Response.pm +++ b/lib/WWW/OpenSearch/Response.pm @@ -6,10 +6,11 @@ use warnings; use base qw( HTTP::Response Class::Accessor::Fast ); use XML::Feed; -use URI; use Data::Page; +use WWW::OpenSearch::Agent; +use WWW::OpenSearch::Request; -__PACKAGE__->mk_accessors( qw( feed pager parent ) ); +__PACKAGE__->mk_accessors( qw( feed pager ) ); =head1 NAME @@ -43,11 +44,10 @@ See http://opensearch.a9.com/spec/1.1/response/ for details. =head1 CONSTRUCTOR -=head2 new( $parent, $response ) +=head2 new( $response ) -Constructs a new instance of WWW::OpenSearch::Response. Arguments -include the WWW::OpenSearch object which initiated the search (parent) -and the HTTP::Response returned by the search request. +Constructs a new instance of WWW::OpenSearch::Response from the +WWWW::OpenSearch:Response returned by the search request. =head1 METHODS @@ -82,8 +82,6 @@ is equal to $type. =head2 pager( ) -=head2 parent( ) - =head1 AUTHOR =over 4 @@ -96,7 +94,7 @@ is equal to $type. =head1 COPYRIGHT AND LICENSE -Copyright 2006 by Tatsuhiko Miyagawa and Brian Cassidy +Copyright 2007 by Tatsuhiko Miyagawa and Brian Cassidy This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. @@ -105,16 +103,14 @@ it under the same terms as Perl itself. sub new { my $class = shift; - my $parent = shift; my $response = shift; - + my $self = bless $response, $class; - $self->parent( $parent ); return $self unless $self->is_success; - + $self->parse_response; - + return $self; } @@ -126,7 +122,7 @@ sub parse_response { return if XML::Feed->errstr; $self->feed( $feed ); - + $self->parse_feed; } @@ -136,95 +132,110 @@ sub parse_feed { my $feed = $self->feed; my $format = $feed->format; - my $ns = $self->parent->description->ns; - + my $ns = $self->request->opensearch_url->ns; + # TODO # adapt these for any number of opensearch elements in # the feed or in each entry - - if( my $atom = $feed->{ atom } ) { + + if ( my $atom = $feed->{ atom } ) { my $total = $atom->get( $ns, 'totalResults' ); my $perpage = $atom->get( $ns, 'itemsPerPage' ); my $start = $atom->get( $ns, 'startIndex' ); - + $pager->total_entries( $total ); $pager->entries_per_page( $perpage ); - $pager->current_page( $start ? ( $start - 1 ) / $perpage + 1 : 0 ) + $pager->current_page( $start ? ( $start - 1 ) / $perpage + 1 : 0 ); } - elsif( my $rss = $feed->{ rss } ) { - if ( my $page = $rss->channel->{ $ns } ) { - $pager->total_entries( $page->{ totalResults } ); + elsif ( my $rss = $feed->{ rss } ) { + if ( my $page = $rss->channel->{ $ns } ) { + $pager->total_entries( $page->{ totalResults } ); $pager->entries_per_page( $page->{ itemsPerPage } ); my $start = $page->{ startIndex }; - $pager->current_page( $start ? ( $start - 1 ) / $page->{ itemsPerPage } + 1 : 0 ) + $pager->current_page( + $start ? ( $start - 1 ) / $page->{ itemsPerPage } + 1 : 0 ); } - } + } $self->pager( $pager ); } sub next_page { - my $self = shift; + my $self = shift; return $self->_get_page( 'next' ); } sub previous_page { - my $self = shift; + my $self = shift; return $self->_get_page( 'previous' ); } sub _get_page { - my( $self, $direction ) = @_; + my ( $self, $direction ) = @_; my $pager = $self->pager; my $pagermethod = "${direction}_page"; my $page = $pager->$pagermethod; return unless $page; - - my $request = $self->request; - my $method = lc $request->method; - if( $method ne 'post' ) { # force query build on POST - my $link = $self->_get_link( $direction ); - return $self->parent->do_search( $link, $method ) if $link; - } - - my $template = $self->parent->description->get_best_url; - my( $param, $query ); - if( $method eq 'post' ) { - my $uri = URI->new( 'http://foo.com/?' . $request->content ); - $query = { $uri->query_form }; - } - else { - $query = { $self->request->uri->query_form }; - } - - if( $param = $template->macros->{ startPage } ) { - $query->{ $param } = $pager->$pagermethod - } - elsif( $param = $template->macros->{ startIndex } ) { - if( $query->{ $param } ) { - $query->{ $param } = $direction eq 'previous' - ? $query->{ $param } -= $pager->entries_per_page - : $query->{ $param } += $pager->entries_per_page; - } - else { - $query->{ $param } = $direction eq 'previous' - ? 1 - : $pager->entries_per_page + 1; + my $params; + my $osu = $self->request->opensearch_url; + + # this code is too fragile -- deparse depends on the order of query + # params and the like. best just to use the last query params and + # do the paging from there. + # + # if( lc $osu->method ne 'post' ) { # force query build on POST + # my $link = $self->_get_link( $direction ); + # if( $link ) { + # $params = $osu->deparse( $link ); + # } + # } + + # rebuild the query + if ( !$params ) { + $params = $self->request->opensearch_params; + + # handle paging via a page # + $params->{ startPage } = $page; + + # handle paging via an index + if ( exists $params->{ startIndex } ) { + + # start index is pre-existing + if ( $params->{ startIndex } ) { + if ( $direction eq 'previous' ) { + $params->{ startIndex } -= $pager->entries_per_page; + } + else { + $params->{ startIndex } += $pager->entries_per_page; + } + } + + # start index did not exist previously + else { + if ( $direction eq 'previous' ) { + $params->{ startIndex } = 1; + } + else { + $params->{ startIndex } = $pager->entries_per_page + 1; + } + + } } } - return $self->parent->do_search( $template->prepare_query( $query ), $method ); + my $agent = WWW::OpenSearch::Agent->new; + return $agent->search( WWW::OpenSearch::Request->new( $osu, $params ) ); } sub _get_link { my $self = shift; my $type = shift; my $feed = $self->feed->{ atom }; - + return unless $feed; - - for( $feed->link ) { - return $_->get( 'href' ) if $_->get( 'rel' ) eq $type; + + for ( $feed->link ) { + return $_->href if $_->rel eq $type; } return;