File Coverage

blib/lib/WWW/Shorten/Naver.pm
Criterion Covered Total %
statement 21 21 100.0
branch n/a
condition n/a
subroutine 7 7 100.0
pod n/a
total 28 28 100.0


line stmt bran cond sub pod time code
1             package WWW::Shorten::Naver;
2 1     1   700 use strict;
  1         1  
  1         29  
3 1     1   3 use warnings;
  1         1  
  1         28  
4 1     1   11 use Carp ();
  1         1  
  1         12  
5 1     1   477 use JSON::MaybeXS;
  1         4686  
  1         71  
6 1     1   655 use URI ();
  1         3443  
  1         18  
7 1     1   5 use Scalar::Util qw(blessed);
  1         1  
  1         63  
8 1     1   624 use parent qw( WWW::Shorten::generic Exporter );
  1         327  
  1         7  
9             our @EXPORT = qw(new VERSION);
10              
11             our $VERSION = '0.02';
12             $VERSION = eval $VERSION;
13              
14             use constant NAVER_SHORTEN_API_ENDPOINT => $ENV{NAVER_SHORTEN_API_URL} || 'https://openapi.naver.com/v1/util/shorturl';
15              
16             sub _attr {
17             my $self = shift;
18             my $attr = lc(_trim(shift) || '');
19             # attribute list is small enough to just grep each time. meh.
20             Carp::croak("Invalid attribute") unless grep {$attr eq $_} @{_attrs()};
21             return $self->{$attr} unless @_;
22              
23             my $val = shift;
24             unless (defined($val)) {
25             $self->{$attr} = undef;
26             return $self;
27             }
28             $self->{$attr} = $val;
29             return $self;
30             }
31              
32             # _attrs (static, private)
33             {
34             my $attrs; # mimic the state keyword
35             sub _attrs {
36             return [@{$attrs}] if $attrs;
37             $attrs = [
38             qw(username password access_token client_id client_secret),
39             ];
40             return [@{$attrs}];
41             }
42             }
43              
44             sub _request {
45             my ($self, $url) = @_;
46            
47             Carp::croak("Invalid URI object") unless $url && blessed($url) && $url->isa('URI');
48            
49             my $ua = __PACKAGE__->ua();
50             $ua->default_header( 'X-Naver-Client-ID' => $self->client_id );
51             $ua->default_header( 'X-Naver-Client-Secret' => $self->client_secret );
52              
53             my $res = $ua->get($url);
54             Carp::croak("Invalid response") unless $res;
55             unless ($res->is_success) {
56             Carp::croak($res->status_line);
57             }
58              
59             my $content_type = $res->header('Content-Type');
60             my $content = $res->decoded_content();
61             unless ($content_type && $content_type =~ m{application/json}) {
62             Carp::croak("Unexpected response: $content");
63             }
64             my $json = decode_json($content);
65             Carp::croak("Invalid data returned: $content") unless $json;
66             return $json->{result};
67             }
68              
69             # _parse_args (static, private)
70             sub _parse_args {
71             my $args;
72             if ( @_ == 1 && ref $_[0] ) {
73             my %copy = eval { %{ $_[0] } }; # try shallow copy
74             Carp::croak("Argument to method could not be dereferenced as a hash") if $@;
75             $args = \%copy;
76             }
77             elsif (@_==1 && !ref($_[0])) {
78             $args = {single_arg => $_[0]};
79             }
80             elsif ( @_ % 2 == 0 ) {
81             $args = {@_};
82             }
83             else {
84             Carp::croak("Method got an odd number of elements");
85             }
86             return $args;
87             }
88              
89             # _trim (static, private)
90             sub _trim {
91             my $input = shift;
92             return $input unless defined $input && !ref($input) && length($input);
93             $input =~ s/\A\s*//;
94             $input =~ s/\s*\z//;
95             return $input;
96             }
97              
98             sub new {
99             my $class = shift;
100             my $args;
101             if ( @_ == 1 && ref $_[0] ) {
102             my %copy = eval { %{ $_[0] } }; # try shallow copy
103             Carp::croak("Argument to $class->new() could not be dereferenced as a hash") if $@;
104             $args = \%copy;
105             }
106             elsif ( @_ % 2 == 0 ) {
107             $args = {@_};
108             }
109             else {
110             Carp::croak("$class->new() got an odd number of elements");
111             }
112              
113             my $attrs = _attrs();
114             my $href = {};
115             for my $key (%{$args}) {
116             $href->{$key} = $args->{$key};
117             }
118             return bless $href, $class;
119             }
120              
121              
122             sub client_id { return shift->_attr('client_id', @_); }
123              
124             sub client_secret { return shift->_attr('client_secret', @_); }
125              
126             sub makeashorterlink {
127             my $self;
128             if ($_[0] && blessed($_[0]) && $_[0]->isa('WWW::Shorten::Naver')) {
129             $self = shift;
130             }
131             my $url = shift or Carp::croak('No URL passed to makeashorterlink');
132             $self ||= __PACKAGE__->new(@_);
133             my $res = $self->shorten( url => $url, @_);
134             return $res->{url};
135             }
136              
137             sub makealongerlink { }
138              
139              
140             sub shorten {
141             my $self = shift;
142              
143             my $args = _parse_args(@_);
144              
145             my $long_url = $args->{url};
146             unless ($long_url) {
147             Carp::croak("A longUrl parameter is required.\n");
148             }
149              
150             my $url = URI->new(NAVER_SHORTEN_API_ENDPOINT);
151             $url->query_form(
152             url => $long_url,
153             );
154             return $self->_request($url, $args);
155             }
156              
157             1; # End of WWW::Shorten::Naver
158             __END__