File Coverage

lib/WWW/PushBullet.pm
Criterion Covered Total %
statement 54 142 38.0
branch 7 22 31.8
condition 4 5 80.0
subroutine 14 25 56.0
pod 14 15 93.3
total 93 209 44.5


line stmt bran cond sub pod time code
1             package WWW::PushBullet;
2              
3             =encoding utf8
4              
5             =head1 NAME
6              
7             WWW::PushBullet - Module giving easy access to PushBullet API
8              
9             =head1 DESCRIPTION
10              
11             Module giving easy access to PushBullet API
12              
13             =head1 SYNOPSIS
14              
15             use WWW::PushBullet;
16            
17             my $pb = WWW::PushBullet->new({apikey => $apikey});
18            
19             $pb->push_address({ device_iden => $device_iden, name => $name,
20             address => $address });
21            
22             $pb->push_file({ device_iden => $device_iden, file => $filename);
23            
24             $pb->push_link({ device_iden => $device_iden, title => $title,
25             url => $url });
26            
27             $pb->push_list({ device_iden => $device_iden, title => $title,
28             items => \@items });
29            
30             $pb->push_note({ device_iden => $device_iden, title => $title,
31             body => $body });
32              
33             =cut
34              
35 2     2   167863 use strict;
  2         17  
  2         45  
36 2     2   7 use warnings;
  2         3  
  2         44  
37              
38 2     2   762 use Data::Dump qw(dump);
  2         9554  
  2         90  
39 2     2   1001 use JSON;
  2         15469  
  2         8  
40 2     2   852 use LWP::UserAgent;
  2         36884  
  2         51  
41 2     2   680 use MIME::Types;
  2         6287  
  2         2734  
42              
43             our $VERSION = 'v1.6.0';
44              
45             my %PUSHBULLET = (
46             REALM => 'Pushbullet',
47             SERVER => 'api.pushbullet.com:443',
48             URL_APIV2 => 'https://api.pushbullet.com/v2',
49             );
50              
51             $ENV{PERL_LWP_SSL_VERIFY_HOSTNAME} = 0;
52              
53             =head1 SUBROUTINES/METHODS
54              
55             =head2 new($params)
56              
57             Creates a new instance of PushBullet API
58              
59             my $pb = WWW::PushBullet->new({apikey => $apikey});
60              
61             =cut
62              
63             sub new
64             {
65 3     3 1 3905 my ($class, $params) = @_;
66              
67 3 100       12 return (undef) if (!defined $params->{apikey});
68 2   66     13 my $ua = $params->{ua} || LWP::UserAgent->new;
69 2         2360 $ua->agent("WWW::PushBullet/$VERSION");
70 2 50       103 $ua->proxy('https', $params->{proxy}) if (defined $params->{proxy});
71             $ua->credentials($PUSHBULLET{SERVER}, $PUSHBULLET{REALM},
72 2         18 $params->{apikey}, '');
73              
74             my $self = {
75             _ua => $ua,
76             _apikey => $params->{apikey},
77 2   100     41 _debug => $params->{debug} || 0,
78             _limits => undef
79             };
80              
81 2         15 bless $self, $class;
82              
83 2         5 return ($self);
84             }
85              
86             =head2 DEBUG
87              
88             Prints Debug message when '_debug' is enabled
89              
90             =cut
91              
92             sub DEBUG
93             {
94 2     2 1 16 my ($self, $line) = @_;
95              
96 2 100       16 if ($self->{_debug})
97             {
98 1         6 my $str = sprintf '[DEBUG] %s', $line;
99 1         35 printf "$str\n";
100              
101 1         6 return ($str);
102             }
103              
104 1         3 return (undef);
105             }
106              
107             =head2 api_key()
108              
109             Returns current PushBullet API key
110              
111             my $apikey = $pb->api_key();
112              
113             =cut
114              
115             sub api_key
116             {
117 1     1 1 246 my $self = shift;
118              
119 1         5 return ($self->{_apikey});
120             }
121              
122             =head2 debug_mode
123              
124             Sets Debug mode
125              
126             $pb->debug_mode(1);
127              
128             =cut
129              
130             sub debug_mode
131             {
132 2     2 1 452 my ($self, $mode) = @_;
133              
134 2         3 $self->{_debug} = $mode;
135              
136 2         4 return ($self->{_debug});
137             }
138              
139             sub _update_limits
140             {
141 2     2   5 my ($self, $response) = @_;
142              
143 2         9 my $limits = {
144             'limit' => $response->header('X-Ratelimit-Limit'),
145             'remaining' => $response->header('X-Ratelimit-Remaining'),
146             'reset' => $response->header('X-Ratelimit-Reset')
147             };
148              
149 2         213 $self->{_limits} = $limits;
150             }
151              
152             sub print_limits
153             {
154 0     0 0 0 my $self = shift;
155              
156 0         0 my $l = $self->{_limits};
157             printf "Limits limit: %s - remaining: %s - reset %s\n",
158 0         0 $l->{limit}, $l->{remaining}, $l->{reset};
159             }
160              
161             =head2 contacts()
162              
163             Returns list of contacts
164              
165             my $contacts = $pb->contacts();
166            
167             foreach my $c (@{$contacts})
168             {
169             printf "Contact '%s' (%s) => %s\n", $c->{name}, $c->{iden}, $c->{email};
170             }
171              
172             =cut
173              
174             sub contacts
175             {
176 1     1 1 5 my $self = shift;
177              
178 1         10 my $res = $self->{_ua}->get("$PUSHBULLET{URL_APIV2}/contacts");
179              
180 1 50       10191 if ($res->is_success)
181             {
182 1         18 $self->_update_limits($res);
183 1         15 my $data = JSON->new->decode($res->content);
184 1         34 return ($data->{contacts});
185             }
186             else
187             {
188 0         0 print $res->status_line, "\n";
189 0         0 return (undef);
190             }
191             }
192              
193             =head2 devices()
194            
195             Returns list of devices
196              
197             my $devices = $pb->devices();
198            
199             foreach my $d (@{$devices})
200             {
201             printf "Device '%s' (%s)=> id %s\n",
202             $d->{nickname}, $d->{model}, $d->{iden};
203             }
204              
205             =cut
206              
207             sub devices
208             {
209 1     1 1 413 my $self = shift;
210              
211 1         12 my $res = $self->{_ua}->get("$PUSHBULLET{URL_APIV2}/devices");
212              
213 1 50       1018 if ($res->is_success)
214             {
215 1         9 $self->_update_limits($res);
216 1         5 my $data = JSON->new->decode($res->content);
217 1         30 return ($data->{devices});
218             }
219             else
220             {
221 0         0 print $res->status_line, "\n";
222 0         0 return (undef);
223             }
224             }
225              
226             =head2 _ephemerals
227              
228             Generic ephemerals function (not supposed to be used directly)
229              
230             =cut
231              
232             sub _ephemerals
233             {
234 0     0   0 my ($self, $content) = @_;
235              
236             my $res = $self->{_ua}->post(
237 0         0 "$PUSHBULLET{URL_APIV2}/ephemerals",
238             Content_Type => 'application/json',
239             Content => JSON->new->encode($content)
240             );
241              
242 0 0       0 if ($res->is_success)
243             {
244 0         0 $self->_update_limits($res);
245 0         0 my $data = JSON->new->decode($res->content);
246 0         0 return ($data);
247             }
248             else
249             {
250 0         0 print $res->status_line, "\n";
251 0         0 return (undef);
252             }
253             }
254              
255             =head2 _pushes($content)
256              
257             Generic pushes function (not supposed to be used directly)
258              
259             =cut
260              
261             sub _pushes
262             {
263 0     0   0 my ($self, $content) = @_;
264              
265             my $res = $self->{_ua}->post(
266 0         0 "$PUSHBULLET{URL_APIV2}/pushes",
267             Content_Type => 'application/json',
268             Content => JSON->new->encode($content)
269             );
270              
271 0 0       0 if ($res->is_success)
272             {
273 0         0 $self->_update_limits($res);
274 0         0 my $data = JSON->new->decode($res->content);
275 0         0 return ($data);
276             }
277             else
278             {
279 0         0 print $res->status_line, "\n";
280 0         0 return (undef);
281             }
282             }
283              
284             =head2 _upload_request($file_name, $file_type)
285              
286             Upload request to AWS (used by push_file)
287              
288             =cut
289              
290             sub _upload_request
291             {
292 0     0   0 my ($self, $file_name, $file_type) = @_;
293              
294             my $res = $self->{_ua}->post(
295 0         0 "$PUSHBULLET{URL_APIV2}/upload-request",
296             Content_Type => undef,
297             Content => ['file_name', $file_name, 'file_type', $file_type]
298             );
299              
300 0 0       0 if ($res->is_success)
301             {
302 0         0 $self->_update_limits($res);
303 0         0 my $data = JSON->new->decode($res->content);
304 0         0 my @array_data = %{$data->{data}};
  0         0  
305 0         0 push @array_data, 'file', [$file_name];
306             my $res = $self->{_ua}->post(
307             $data->{upload_url},
308 0         0 Content_Type => 'form-data',
309             Content => \@array_data
310             );
311 0 0       0 if ($res->is_success)
312             {
313 0         0 $self->_update_limits($res);
314 0         0 return ($data->{file_url});
315             }
316             else
317             {
318 0         0 print $res->status_line, "\n";
319 0         0 return (undef);
320             }
321             }
322             else
323             {
324 0         0 print $res->status_line, "\n";
325 0         0 return (undef);
326             }
327             }
328              
329             =head2 push_address($params)
330              
331             Pushes address (with name & address)
332              
333             $pb->push_address(
334             {
335             device_iden => $device_iden,
336             name => 'GooglePlex',
337             address => '1600 Amphitheatre Pkwy, Mountain View, CA 94043, Etats-Unis'
338             }
339             );
340              
341             =cut
342              
343             sub push_address
344             {
345 0     0 1 0 my ($self, $params) = @_;
346              
347 0         0 $params->{type} = 'address';
348 0         0 $self->DEBUG(sprintf('push_address: %s', dump($params)));
349 0         0 my $result = $self->_pushes($params);
350              
351 0         0 return ($result);
352             }
353              
354             =head2 push_file($params)
355              
356             Pushes file
357              
358             $pb->push_file(
359             {
360             device_iden => $device_iden,
361             file_name => '/var/www/index.html',
362             body => 'File Description'
363             }
364             );
365              
366             =cut
367              
368             sub push_file
369             {
370 0     0 1 0 my ($self, $params) = @_;
371              
372 0         0 my $mt = MIME::Types->new();
373 0         0 my $type = $mt->mimeTypeOf($params->{file_name});
374 0         0 $self->DEBUG(sprintf('push_file: %s', dump($params)));
375 0         0 my $file_url = $self->_upload_request($params->{file_name}, $type->type());
376 0 0       0 if (defined $file_url)
377             {
378 0         0 $params->{type} = 'file';
379 0         0 $params->{file_type} = $type->type();
380 0         0 $params->{file_url} = $file_url;
381 0         0 my $result = $self->_pushes($params);
382              
383 0         0 return ($result);
384             }
385              
386 0         0 return (undef);
387             }
388              
389             =head2 push_link($params)
390              
391             Pushes link (with title & url)
392              
393             $pb->push_link(
394             {
395             device_iden => $device_iden,
396             title => 'WWW::PushBullet Perl module on GitHub',
397             url => 'https://github.com/sebthebert/WWW-PushBullet'
398             }
399             );
400              
401             =cut
402              
403             sub push_link
404             {
405 0     0 1 0 my ($self, $params) = @_;
406              
407 0         0 $params->{type} = 'link';
408 0         0 $self->DEBUG(sprintf('push_link: %s', dump($params)));
409 0         0 my $result = $self->_pushes($params);
410              
411 0         0 return ($result);
412             }
413              
414             =head2 push_list($params)
415              
416             Pushes list (with title & items)
417              
418             $pb->push_list(
419             {
420             device_iden => $device_iden,
421             title => 'One list with 3 items',
422             items => [ 'One', 'Two', 'Three' ]
423             }
424             );
425              
426             =cut
427              
428             sub push_list
429             {
430 0     0 1 0 my ($self, $params) = @_;
431              
432 0         0 $params->{type} = 'list';
433              
434             #$params->{items} = join(',', @{$params->{items}});
435 0         0 $self->DEBUG(sprintf('push_list: %s', dump($params)));
436 0         0 my $result = $self->_pushes($params);
437              
438 0         0 return ($result);
439             }
440              
441             =head2 push_note($params)
442              
443             Pushes note (with title & body)
444              
445             $pb->push_note(
446             {
447             device_iden => $device_iden,
448             title => 'Note Title',
449             body => 'Note Body'
450             }
451             );
452              
453             =cut
454              
455             sub push_note
456             {
457 0     0 1 0 my ($self, $params) = @_;
458              
459 0         0 $params->{type} = 'note';
460 0         0 $self->DEBUG(sprintf('push_note: %s', dump($params)));
461 0         0 my $result = $self->_pushes($params);
462              
463 0         0 return ($result);
464             }
465              
466             =head2 push_sms($params)
467              
468             Push SMS
469              
470             $pb->push_sms(
471             {
472             conversation_iden => $mobile,
473             message => $sms,
474             target_device_iden => $conf->{default_sms_device}
475             }
476             );
477              
478             =cut
479              
480             sub push_sms
481             {
482 0     0 1 0 my ($self, $params) = @_;
483              
484 0         0 my $user_info = $self->user_info();
485              
486 0         0 my $ephemeral = {type => 'push', push => $params};
487 0         0 $ephemeral->{push}->{package_name} = 'com.pushbullet.android';
488 0         0 $ephemeral->{push}->{source_user_iden} = $user_info->{iden};
489 0         0 $ephemeral->{push}->{type} = 'messaging_extension_reply';
490              
491 0         0 $self->DEBUG(sprintf('push_sms: %s', dump($ephemeral)));
492 0         0 my $result = $self->_ephemerals($ephemeral);
493              
494 0         0 return ($result);
495             }
496              
497             =head2 user_info()
498              
499             Returns PushBullet's user information (name, email, iden...)
500              
501             my $user_info = $pb->user_info();
502              
503             =cut
504              
505             sub user_info
506             {
507 0     0 1 0 my $self = shift;
508              
509 0         0 my $res = $self->{_ua}->get("$PUSHBULLET{URL_APIV2}/users/me");
510              
511 0 0       0 if ($res->is_success)
512             {
513 0         0 $self->_update_limits($res);
514 0         0 my $data = JSON->new->decode($res->content);
515 0         0 return ($data);
516             }
517             else
518             {
519 0         0 print $res->status_line, "\n";
520 0         0 return (undef);
521             }
522             }
523              
524             =head2 version()
525              
526             Returns WWW::PushBullet module version
527              
528             =cut
529              
530             sub version
531             {
532 1     1 1 217 return ($VERSION);
533             }
534              
535             1;
536              
537             =head1 LICENSE
538            
539             This program is free software; you can redistribute it and/or modify it
540             under the same terms as Perl itself.
541              
542             =head1 REPOSITORY
543              
544             L
545              
546             =head1 AUTHOR
547              
548             Sébastien Thébert
549              
550             =cut