File Coverage

blib/lib/TMDB/Session.pm
Criterion Covered Total %
statement 30 87 34.4
branch 0 36 0.0
condition 0 19 0.0
subroutine 10 15 66.6
pod 0 3 0.0
total 40 160 25.0


line stmt bran cond sub pod time code
1             package TMDB::Session;
2              
3             #######################
4             # LOAD CORE MODULES
5             #######################
6 1     1   5 use strict;
  1         2  
  1         47  
7 1     1   487 use warnings FATAL => 'all';
  1         2  
  1         59  
8 1     1   6 use Carp qw(croak carp);
  1         2  
  1         105  
9              
10             #######################
11             # LOAD CPAN MODULES
12             #######################
13 1     1   608 use JSON::MaybeXS;
  1         6007  
  1         83  
14 1     1   814 use Encode qw();
  1         11999  
  1         35  
15 1     1   910 use HTTP::Tiny qw();
  1         42103  
  1         28  
16 1     1   481 use URI::Encode qw();
  1         1096  
  1         25  
17 1     1   5 use Params::Validate qw(validate_with :types);
  1         1  
  1         169  
18 1     1   503 use Locale::Codes::Language qw(all_language_codes);
  1         189567  
  1         75  
19 1     1   7 use Object::Tiny qw(apikey apiurl lang debug client encoder json);
  1         2  
  1         6  
20              
21             #######################
22             # VERSION
23             #######################
24             our $VERSION = '1.1.2';
25              
26             #######################
27             # PACKAGE VARIABLES
28             #######################
29              
30             # Valid language codes
31             my %valid_lang_codes = map { $_ => 1 } all_language_codes('alpha-2');
32              
33             # Default Headers
34             my $default_headers = {
35             'Accept' => 'application/json',
36             'Content-Type' => 'application/json',
37             };
38              
39             # Default User Agent
40             my $default_ua = 'perl-tmdb-client';
41              
42             #######################
43             # PUBLIC METHODS
44             #######################
45              
46             ## ====================
47             ## Constructor
48             ## ====================
49             sub new {
50 0     0 0   my $class = shift;
51             my %opts = validate_with(
52             params => \@_,
53             spec => {
54             apikey => {
55             type => SCALAR,
56             },
57             apiurl => {
58             type => SCALAR,
59             optional => 1,
60             default => 'https://api.themoviedb.org/3',
61             },
62             lang => {
63             type => SCALAR,
64             optional => 1,
65             callbacks => {
66             'valid language code' =>
67 0     0     sub { $valid_lang_codes{ lc $_[0] } },
68             },
69             },
70 0           client => {
71             type => OBJECT,
72             isa => 'HTTP::Tiny',
73             optional => 1,
74             default => HTTP::Tiny->new(
75             agent => $default_ua,
76             default_headers => $default_headers,
77             ),
78             },
79             encoder => {
80             type => OBJECT,
81             isa => 'URI::Encode',
82             optional => 1,
83             default => URI::Encode->new(),
84             },
85             json => {
86             type => OBJECT,
87             can => 'Load',
88             optional => 1,
89             default => JSON::MaybeXS->new(
90             utf8 => 1,
91             ),
92             },
93             debug => {
94             type => BOOLEAN,
95             optional => 1,
96             default => 0,
97             },
98             },
99             );
100              
101 0 0         $opts{lang} = lc $opts{lang} if $opts{lang};
102 0           my $self = $class->SUPER::new(%opts);
103 0           return $self;
104             } ## end sub new
105              
106             ## ====================
107             ## Talk
108             ## ====================
109             sub talk {
110 0     0 0   my ( $self, $args ) = @_;
111              
112             # Build Call
113 0           my $url
114             = $self->apiurl . '/' . $args->{method} . '?api_key=' . $self->apikey;
115 0 0         if ( $args->{params} ) {
116 0           foreach
117 0           my $param ( sort { lc $a cmp lc $b } keys %{ $args->{params} } )
  0            
118             {
119 0 0         next unless defined $args->{params}->{$param};
120 0           $url .= "&${param}=" . $args->{params}->{$param};
121             } ## end foreach my $param ( sort { ...})
122             } ## end if ( $args->{params} )
123              
124             # Encode
125 0           $url = $self->encoder->encode($url);
126              
127             # Talk
128 0 0         warn "DEBUG: GET -> $url\n" if $self->debug;
129 0           my $response = $self->client->get($url);
130              
131             # Debug
132 0 0         if ( $self->debug ) {
133 0 0         warn "DEBUG: Got a successful response\n" if $response->{success};
134 0           warn "DEBUG: Got Status -> $response->{status}\n";
135 0 0         warn "DEBUG: Got Reason -> $response->{reason}\n"
136             if $response->{reason};
137 0 0         warn "DEBUG: Got Content -> $response->{content}\n"
138             if $response->{content};
139             } ## end if ( $self->debug )
140              
141             # Return
142 0 0         return unless $self->_check_status($response);
143 0 0 0       if ( $args->{want_headers} and exists $response->{headers} ) {
144              
145             # Return headers only
146 0           return $response->{headers};
147             } ## end if ( $args->{want_headers...})
148 0 0         return unless $response->{content}; # Blank Content
149 0           return $self->json->decode(
150             Encode::decode( 'utf-8-strict', $response->{content} ) ); # Real Response
151             } ## end sub talk
152              
153             ## ====================
154             ## PAGINATE RESULTS
155             ## ====================
156             sub paginate_results {
157 0     0 0   my ( $self, $args ) = @_;
158              
159 0           my $response = $self->talk($args);
160 0   0       my $results = $response->{results} || [];
161              
162             # Paginate
163 0 0 0       if ( $response->{page}
      0        
164             and $response->{total_pages}
165             and ( $response->{total_pages} > $response->{page} ) )
166             {
167 0   0       my $page_limit = $args->{max_pages} || '1';
168 0           my $current_page = $response->{page};
169 0           while ($page_limit) {
170 0 0         last if ( $current_page == $page_limit );
171 0           $current_page++;
172 0           $args->{params}->{page} = $current_page;
173 0           my $next_page = $self->talk($args);
174 0           push @$results, @{ $next_page->{results} },;
  0            
175 0 0         last if ( $next_page->{page} == $next_page->{total_pages} );
176 0           $page_limit--;
177             } ## end while ($page_limit)
178             } ## end if ( $response->{page}...)
179              
180             # Done
181 0 0         return @$results if wantarray;
182 0           return $results;
183             } ## end sub paginate_results
184              
185             #######################
186             # INTERNAL
187             #######################
188              
189             # Check Response status
190             sub _check_status {
191 0     0     my ( $self, $response ) = @_;
192              
193 0 0         if ( $response->{success} ) {
194 0           return 1;
195             }
196              
197 0 0         if ( $response->{content} ) {
198 0           my ( $code, $message );
199 0           my $ok = eval {
200              
201 0           my $status = $self->json->decode(
202             Encode::decode( 'utf-8-strict', $response->{content} ) );
203              
204 0           $code = $status->{status_code};
205 0           $message = $status->{status_message};
206              
207 0           1;
208             };
209              
210 0 0 0       if ( $ok and $code and $message ) {
      0        
211 0           carp sprintf( 'TMDB API Error (%s): %s', $code, $message );
212             }
213             } ## end if ( $response->{content...})
214              
215 0           return;
216             } ## end sub _check_status
217              
218             #######################
219             1;