File Coverage

blib/lib/CanvasCloud/API.pm
Criterion Covered Total %
statement 34 63 53.9
branch 5 22 22.7
condition 8 11 72.7
subroutine 9 12 75.0
pod 5 5 100.0
total 61 113 53.9


line stmt bran cond sub pod time code
1             package CanvasCloud::API;
2             $CanvasCloud::API::VERSION = '0.007';
3             # ABSTRACT: Base Class for talking Canvas LMS API
4              
5 6     6   4225 use Moose;
  6         474493  
  6         43  
6 6     6   41190 use namespace::autoclean;
  6         8575  
  6         52  
7 6     6   4904 use LWP::UserAgent;
  6         276796  
  6         250  
8 6     6   3365 use Hash::Merge qw/merge/;
  6         28182  
  6         344  
9 6     6   67 use URI;
  6         16  
  6         151  
10 6     6   4041 use JSON;
  6         50710  
  6         35  
11              
12             has debug => ( is => 'ro', lazy => 1, default => 0 );
13             has scheme => ( is => 'ro', lazy => 1, default => 'https' );
14             has domain => ( is => 'ro', required => 1 );
15             has token => ( is => 'ro', required => 1 );
16              
17              
18             has ua => ( is => 'ro', lazy => 1, default => sub { LWP::UserAgent->new; } );
19              
20              
21             sub uri {
22 18     18 1 298 my $self = shift;
23 18   100     62 my $rest = inner() || '';
24 18 50 66     170 $rest = '/' if ( defined $rest && $rest && $rest !~ /^\// );
      66        
25 18         526 return sprintf('%s://%s/api/v1', $self->scheme, $self->domain) . $rest;
26             }
27              
28              
29             sub request {
30 12     12 1 46 my ( $self, $method, $uri ) = @_;
31 12         90 my $r = HTTP::Request->new( $method => $uri );
32 12         52336 $r->header( 'Authorization' => 'Bearer '.$self->token );
33 12         1069 return $r;
34             }
35              
36              
37             sub send {
38 6     6 1 19 my ( $self, $request ) = @_;
39 6 50 66     20 $request->header( 'Content-Type' => 'application/x-www-form-urlencoded' ) if ( $request->method eq 'POST' && $request->content_type eq '' );
40 6 50       322 warn join("\n", 'REQUEST:--->',$request->as_string, 'REQUEST:<----'), "\n" if ( $self->debug );
41 6         163 my $resp = $self->ua->request( $request );
42 6 50       10364 warn join("\n", 'RESPONSE:--->',$resp->as_string, 'RESPONSE:<----'), "\n" if ( $self->debug );
43 6         19 my $struct;
44 6 50       37 if ( $resp->is_success ) {
45 0         0 $struct = $self->decode( $resp->content );
46 0 0       0 if ( my $link = $resp->header( 'Link' ) ) {
47 0         0 my $LINK = _parse_link($link);
48 0 0       0 if ( $LINK->{'current'} ne $LINK->{'last'} ) {
49 0         0 $request->uri( $LINK->{'next'} );
50 0         0 $struct = merge( $struct, $self->send( $request ) );
51             }
52             }
53             }
54 6         142 return $struct;
55             }
56              
57              
58 0     0 1   sub decode { from_json $_[1]; }
59              
60             sub _parse_link {
61 0     0     my $link = shift;
62 0           $link =~ s/\R//g;
63 0           my %struct = map { $_ => '' } qw/current next prev first last/;
  0            
64 0           for my $l ( split( /,/, $link ) ) {
65 0           my ($url, $type) = split( /;/, $l );
66 0           my $TYPE = 0;
67 0           for my $t ( keys %struct ) {
68 0 0         if ( $type =~ m/rel="$t"/ ) {
69 0           $url =~ s/^<//;
70 0           $url =~ s/>$//;
71 0           $struct{$t} = $url;
72 0           $TYPE = $t;
73 0           last;
74             }
75             }
76 0 0         die 'Bad Link: none of listed relation found - '.join(', ', keys %struct) unless ( $TYPE );
77             }
78 0           return \%struct;
79             }
80              
81             ## Taken from HTTP::Request::Common
82              
83              
84             sub encode_url {
85 0     0 1   my ( $self, $content ) = @_;
86 0           my $url = URI->new('http:');
87 0 0         $url->query_form( ref($content) eq 'HASH' ? %$content : @$content );
88 0           $content = $url->query;
89 0 0         $content =~ s/(?<!%0D)%0A/%0D%0A/g if defined($content); ## html 4.01 line breaks CR LF
90 0           return $content;
91             }
92              
93             __PACKAGE__->meta->make_immutable;
94              
95             1;
96              
97             __END__
98              
99             =pod
100              
101             =encoding UTF-8
102              
103             =head1 NAME
104              
105             CanvasCloud::API - Base Class for talking Canvas LMS API
106              
107             =head1 VERSION
108              
109             version 0.007
110              
111             =head1 DESCRIPTION
112              
113             Base class to be inherited by CanvasCloud API modules.
114              
115             =head1 ATTRIBUTES
116              
117             =head2 domain
118              
119             I<required:> Domain for your Canvas LMS site.
120              
121             =head2 token
122              
123             I<required:> Your Oauth2 string token
124              
125             =head2 debug
126              
127             I<optional:> 1 or 0 : 0 is default
128              
129             =head2 scheme
130              
131             I<optional:> http or https : https is default
132              
133             =head2 ua
134              
135             LWP::UserAgent
136              
137             =head1 METHODS
138              
139             =head2 uri
140              
141             Base uri for Canvas LMS
142              
143             =head2 request( $method, $uri )
144              
145             returns HTTP::Request;
146              
147             request creates a HTTP::Request->new( $method => $uri ) it then sets the 'Authorization' header
148              
149             =head2 send( $request )
150              
151             Attempts to send request to Canvas recursively depending on return Link header.
152             Finally returns a hashref data structure as response from Canvas.
153              
154             =head2 decode( 'jsonstring' );
155              
156             returns results from from_json on jsonstring
157              
158             =head2 encode_url( $content )
159              
160             encode structure to url
161              
162             =head1 AUTHOR
163              
164             Ted Katseres
165              
166             =head1 COPYRIGHT AND LICENSE
167              
168             This software is copyright (c) 2019 by Ted Katseres.
169              
170             This is free software; you can redistribute it and/or modify it under
171             the same terms as the Perl 5 programming language system itself.
172              
173             =cut