root/WWW-OpenSearch/branches/WWW-OpenSearch-rewrite/lib/WWW/OpenSearch/Response.pm

Revision 1802 (checked in by bricas, 15 years ago)

Initial Import of rewrite branch

Line 
1 package WWW::OpenSearch::Response;
2
3 use strict;
4 use warnings;
5
6 use base qw( HTTP::Response Class::Accessor::Fast );
7
8 use XML::Feed;
9 use Data::Page;
10
11 __PACKAGE__->mk_accessors( qw( feed pager parent ) );
12
13 sub new {
14     my $class    = shift;
15     my $parent   = shift;
16     my $response = shift;
17    
18     my $self = bless $response, $class;
19
20     $self->parent( $parent );
21     return $self unless $self->is_success;
22    
23     $self->parse_response;
24    
25     return $self;
26 }
27
28 sub parse_response {
29     my $self = shift;
30
31     my $content = $self->content;
32     my $feed    = XML::Feed->parse( \$content );
33
34     return if XML::Feed->errstr;
35     $self->feed( $feed );
36    
37     $self->parse_feed;
38 }
39
40 sub parse_feed {
41     my $self  = shift;
42     my $pager = Data::Page->new;
43
44     my $feed   = $self->feed;
45     my $format = $feed->format;
46     my $ns     = $self->parent->description->ns;
47    
48     # TODO
49     # adapt these for any number of opensearch elements in
50     # the feed or in each entry
51    
52     if( my $atom = $feed->{ atom } ) {
53         my $total   = $atom->get( $ns, 'totalResults' );
54         my $perpage = $atom->get( $ns, 'itemsPerPage' );
55         my $start   = $atom->get( $ns, 'startIndex' );
56        
57         undef $start if $start eq 'null';
58        
59         $pager->total_entries( $total );
60         $pager->entries_per_page( $perpage );
61         $pager->current_page( $start ? ( $start - 1 ) / $perpage + 1 : 0 )
62     }
63     elsif( my $rss = $feed->{ rss } ) {
64         if ( my $page = $rss->channel->{ $ns } ) {
65             $pager->total_entries(    $page->{ totalResults } );
66             $pager->entries_per_page( $page->{ itemsPerPage } );
67             my $start = $page->{ startIndex };
68             $pager->current_page( $start ? ( $start - 1 ) / $page->{ itemsPerPage } + 1 : 0 )
69         }
70     }   
71     $self->pager( $pager );
72 }
73
74 # TODO
75 # handle pervious/next page on POST
76
77 sub next_page {
78     my $self  = shift;
79     my $pager = $self->pager;
80     my $page  = $pager->next_page;
81     return unless $page;
82    
83     my $link = $self->_get_link( 'next' );
84     return $self->parent->do_search( $link, $self->request->method ) if $link;
85    
86     my $url   = $self->request->uri->clone;
87     my %query = $url->query_form;
88     my $param;
89
90     my $template = $self->parent->description->get_best_url;
91
92     if( $param = $template->macros->{ startPage } ) {
93         $query{ $param } = $pager->next_page
94     }
95     elsif( $param = $template->macros->{ startIndex } ) {
96         $query{ $param } ? $query{ $param } += $pager->entries_per_page
97                          : $query{ $param }  = $pager->entries_per_page + 1;
98     }
99
100     $url->query_form( \%query );
101     return $self->parent->do_search( $url, $self->request->method );
102 }
103
104 sub previous_page {
105     my $self  = shift;
106     my $pager = $self->pager;
107     my $page  = $pager->previous_page;
108     return unless $page;
109
110     my $link = $self->_get_link( 'previous' );
111     return $self->parent->do_search( $link, $self->request->method ) if $link;
112    
113     my $url   = $self->request->uri->clone;
114     my %query = $url->query_form;
115     my $param;
116    
117     my $template = $self->parent->description->get_best_url;
118    
119     if( $param = $template->macros->{ startPage } ) {
120         $query{ $param } = $pager->previous_page
121     }
122     elsif( $param = $template->macros->{ startIndex } ) {
123         $query{ $param } ? $query{ $param } -= $pager->entries_per_page
124                          : $query{ $param }  = 1;
125     }
126    
127     $url->query_form( \%query );
128     return $self->parent->do_search( $url, $self->request->method );
129 }
130
131 sub _get_link {
132     my $self = shift;
133     my $type = shift;
134     my $feed = $self->feed->{ atom };
135    
136     return unless $feed;
137    
138     for( $feed->link_libxml ) {
139         return $_->get( 'href' ) if $_->get( 'rel' ) eq $type;
140     }
141    
142 }
143
144 1;
Note: See TracBrowser for help on using the browser.