File Coverage

blib/lib/Net/Gotify.pm
Criterion Covered Total %
statement 41 218 18.8
branch 0 74 0.0
condition 0 23 0.0
subroutine 14 44 31.8
pod 28 28 100.0
total 83 387 21.4


line stmt bran cond sub pod time code
1             package Net::Gotify;
2              
3 1     1   290075 use 5.010000;
  1         3  
4 1     1   4 use strict;
  1         1  
  1         17  
5 1     1   16 use warnings;
  1         2  
  1         47  
6 1     1   421 use utf8;
  1         192  
  1         4  
7              
8 1     1   23 use Carp();
  1         2  
  1         11  
9 1     1   578 use Moo;
  1         7216  
  1         5  
10 1     1   2282 use HTTP::Tiny;
  1         56035  
  1         128  
11 1     1   15 use JSON::PP qw(encode_json decode_json);
  1         7  
  1         107  
12              
13 1     1   460 use Net::Gotify::Application;
  1         15  
  1         71  
14 1     1   637 use Net::Gotify::Client;
  1         4  
  1         45  
15 1     1   623 use Net::Gotify::Error;
  1         5  
  1         59  
16 1     1   584 use Net::Gotify::Message;
  1         4  
  1         46  
17 1     1   717 use Net::Gotify::Plugin;
  1         5  
  1         50  
18 1     1   578 use Net::Gotify::User;
  1         4  
  1         3977  
19              
20             our $VERSION = '1.00';
21              
22             $Carp::Internal{(__PACKAGE__)}++;
23              
24             has base_url => (is => 'ro', required => 1);
25             has app_token => (is => 'ro');
26             has client_token => (is => 'ro');
27             has verify_ssl => (is => 'ro');
28             has logger => (is => 'ro');
29              
30             sub _get_token {
31              
32 0     0     my ($self, $type) = @_;
33              
34 0           my $token = undef;
35              
36 0 0         if (lc($type) eq 'app') {
37 0 0         $token = $self->app_token or Carp::croak 'Missing "app" token';
38             }
39              
40 0 0         if (lc($type) eq 'client') {
41 0 0         $token = $self->client_token or Carp::croak 'Missing "client" token';
42             }
43              
44 0           return $token;
45             }
46              
47             sub _hash_to_snake_case {
48              
49 0     0     my $hash = shift;
50 0           my $output = {};
51              
52 0           foreach my $key (keys %{$hash}) {
  0            
53 0           (my $snake_key = $key) =~ s/([a-z0-9])([A-Z])/$1_\L$2/g;
54 0           $output->{lc($snake_key)} = $hash->{$key};
55             }
56              
57 0           return $output;
58              
59             }
60              
61             sub request {
62              
63 0     0 1   my ($self, %params) = @_;
64              
65 0 0         my $method = delete $params{method} or Carp::croak 'Specify request "method"';
66 0   0       my $token_type = delete $params{token_type} || 'client';
67 0 0         my $path = delete $params{path} or Carp::croak 'Specify request "path"';
68 0   0       my $data = delete $params{data} || {};
69 0           my $options = {};
70              
71 0           $method = uc $method;
72 0           $path =~ s{^/}{};
73              
74 0           (my $agent = ref $self) =~ s{::}{-}g;
75              
76 0           my $ua = HTTP::Tiny->new(
77             verify_SSL => $self->verify_ssl,
78             default_headers => {'Content-Type' => 'application/json', 'X-Gotify-Key' => $self->_get_token($token_type)},
79             agent => sprintf('%s/%s', $agent, $self->VERSION),
80             );
81              
82 0           my $url = sprintf '%s/%s', $self->base_url, $path;
83              
84 0 0         if (ref $data eq 'HASH') {
85 0           delete @$data{grep { not defined $data->{$_} } keys %{$data}};
  0            
  0            
86 0           $options = {content => encode_json($data)};
87             }
88              
89 0           my $response = $ua->request($method, $url, $options);
90              
91 0 0         if (my $logger = $self->logger) {
92 0           $logger->info(sprintf('%s %s', $method, $url));
93 0           $logger->debug(sprintf('[%s %s] %s', $response->{status}, $response->{reason}, $response->{content}));
94             }
95              
96 0   0       my $output = eval { decode_json($response->{content}) } || {};
97              
98 0 0         if (!$response->{success}) {
99              
100             my $error = Net::Gotify::Error->new(
101             error => $output->{error} || $response->{reason},
102             code => $output->{errorCode} || $response->{status},
103             description => $output->{errorDescription} || $response->{content},
104 0   0       );
      0        
      0        
105              
106 0 0         if (my $logger = $self->logger) {
107 0           $logger->error($error->description);
108             }
109              
110 0           Carp::croak $error;
111              
112             }
113              
114 0           return $output;
115              
116             }
117              
118              
119             # Messages
120              
121             sub create_message {
122              
123 0     0 1   my ($self, %params) = @_;
124              
125 0           my $title = delete $params{title};
126 0 0         my $message = delete $params{message} or Carp::croak 'Specify "message"';
127 0           my $priority = delete $params{priority};
128 0   0       my $extras = delete $params{extras} || {};
129              
130 0           my $data = {title => $title, message => $message, priority => $priority, extras => $extras};
131              
132 0           my $response = $self->request(method => 'POST', path => '/message', data => $data, token_type => 'app');
133              
134 0           return Net::Gotify::Message->new(%{$response});
  0            
135              
136             }
137              
138             sub delete_message {
139              
140 0     0 1   my ($self, $id) = @_;
141              
142 0 0         Carp::croak 'Specify message "id"' unless $id;
143              
144 0           $self->request(method => 'DELETE', path => sprintf('/message/%s', $id));
145              
146 0           return 1;
147              
148             }
149              
150             sub delete_messages {
151              
152 0     0 1   my ($self, %params) = @_;
153              
154 0           my $app_id = delete $params{app_id};
155 0 0         my $path = $app_id ? sprintf('/application/%s/message', $app_id) : '/message';
156              
157 0           $self->request(method => 'DELETE', path => $path);
158              
159 0           return 1;
160              
161             }
162              
163             sub get_messages {
164              
165 0     0 1   my ($self, %params) = @_;
166              
167 0           my $app_id = delete $params{app_id};
168 0   0       my $limit = delete $params{limit} || 100;
169 0           my $since = delete $params{since};
170              
171 0           my $params = HTTP::Tiny->www_form_urlencode({limit => $limit, since => $since});
172 0 0         my $path = $app_id ? "/application/$app_id/message" : '/message';
173              
174 0           my $response = $self->request(method => 'GET', path => "$path?$params");
175              
176 0           my @messages = map { Net::Gotify::Message->new(%{$_}) } @{$response->{messages}};
  0            
  0            
  0            
177              
178 0 0         return wantarray ? @messages : \@messages;
179              
180             }
181              
182              
183             # Clients
184              
185             sub get_clients {
186              
187 0     0 1   my ($self) = @_;
188              
189 0           my $response = $self->request(method => 'GET', path => '/client');
190              
191 0           my @clients = map { Net::Gotify::Client->new(%{_hash_to_snake_case($_)}) } @{$response};
  0            
  0            
  0            
192              
193 0 0         return wantarray ? @clients : \@clients;
194              
195             }
196              
197             sub create_client {
198              
199 0     0 1   my ($self, %params) = @_;
200              
201 0 0         my $name = delete $params{name} or Carp::croak 'Specify client "name"';
202              
203 0           my $response = $self->request(method => 'POST', path => '/client', data => {name => $name});
204              
205 0           return Net::Gotify::Client->new(%{_hash_to_snake_case($response)});
  0            
206              
207             }
208              
209             sub update_client {
210              
211 0     0 1   my ($self, $id, %params) = @_;
212              
213 0 0         Carp::croak 'Specify client "id"' unless $id;
214              
215 0 0         my $name = delete $params{name} or Carp::croak 'Specify client "name"';
216              
217 0           my $response = $self->request(method => 'PUT', path => "/client/$id", data => {name => $name});
218              
219 0           return Net::Gotify::Client->new(%{_hash_to_snake_case($response)});
  0            
220              
221             }
222              
223             sub delete_client {
224              
225 0     0 1   my ($self, $id) = @_;
226              
227 0 0         Carp::croak 'Specify client "id"' unless $id;
228              
229 0           $self->request(method => 'DELETE', path => "/client/$id");
230 0           return 1;
231              
232             }
233              
234              
235             # Applications
236              
237             sub get_applications {
238              
239 0     0 1   my ($self) = @_;
240              
241 0           my $response = $self->request(method => 'GET', path => '/application');
242 0           my @applications = map { Net::Gotify::Application->new(%{_hash_to_snake_case($_)}) } @{$response};
  0            
  0            
  0            
243              
244 0 0         return wantarray ? @applications : \@applications;
245              
246             }
247              
248             sub create_application {
249              
250 0     0 1   my ($self, %params) = @_;
251              
252 0 0         my $name = delete $params{name} or Carp::croak 'Specify application "name"';
253 0           my $description = delete $params{description};
254 0   0       my $default_priority = delete $params{default_priority} || 0;
255              
256 0           my $response = $self->request(
257             method => 'POST',
258             path => '/application',
259             data => {name => $name, description => $description, default_priority => $default_priority}
260             );
261              
262 0           return Net::Gotify::Application->new(%{_hash_to_snake_case($response)});
  0            
263              
264             }
265              
266             sub update_application {
267              
268 0     0 1   my ($self, $id, %params) = @_;
269              
270 0 0         my $name = delete $params{name} or Carp::croak 'Specify application "name"';
271 0           my $description = delete $params{description};
272 0   0       my $default_priority = delete $params{default_priority} || 0;
273              
274 0           my $response = $self->request(
275             method => 'PUT',
276             path => "/application/$id",
277             data => {name => $name, description => $description, default_priority => $default_priority}
278             );
279              
280 0           return Net::Gotify::Application->new(%{_hash_to_snake_case($response)});
  0            
281              
282             }
283              
284             sub delete_application {
285              
286 0     0 1   my ($self, $id) = @_;
287              
288 0 0         Carp::croak 'Specify application "id"' unless $id;
289              
290 0           $self->request(method => 'DELETE', path => "/application/$id");
291 0           return 1;
292              
293             }
294              
295 0     0 1   sub update_application_image { Carp::carp 'Method not implemented' }
296 0     0 1   sub delete_application_image { Carp::carp 'Method not implemented' }
297              
298              
299             # Plugins
300              
301             sub get_plugins {
302              
303 0     0 1   my ($self) = @_;
304              
305 0           my $response = $self->request(method => 'GET', path => '/plugin');
306 0           my @plugins = map { Net::Gotify::Plugin->new(%{_hash_to_snake_case($_)}) } @{$response};
  0            
  0            
  0            
307              
308 0 0         return wantarray ? @plugins : \@plugins;
309              
310             }
311              
312 0     0 1   sub get_plugin_config { Carp::carp 'Method not implemented' }
313 0     0 1   sub update_plugin_config { Carp::carp 'Method not implemented' }
314              
315             sub enable_plugin {
316              
317 0     0 1   my ($self, $id) = @_;
318              
319 0 0         Carp::croak 'Specify plugin "id"' unless $id;
320              
321 0           $self->request(method => 'POST', path => "/plugin/$id/enable");
322 0           return 1;
323              
324             }
325              
326             sub disable_plugin {
327              
328 0     0 1   my ($self, $id) = @_;
329              
330 0 0         Carp::croak 'Specify plugin "id"' unless $id;
331              
332 0           $self->request(method => 'POST', path => "/plugin/$id/disable");
333 0           return 1;
334              
335             }
336              
337 0     0 1   sub get_plugin { Carp::carp 'Method not implemented' }
338              
339              
340             # Users
341              
342             sub current_user {
343              
344 0     0 1   my ($self) = @_;
345              
346 0           my $response = $self->request(method => 'GET', path => '/current/user');
347 0           return Net::Gotify::User->new(%{_hash_to_snake_case($response)});
  0            
348              
349             }
350              
351             sub update_current_user_password {
352              
353 0     0 1   my ($self, $pass) = @_;
354              
355 0 0         Carp::croak 'Specify the new "password" for current user' unless $pass;
356              
357 0           my $response = $self->request(method => 'POST', path => '/current/user/password', data => {pass => $pass});
358              
359 0           return 1;
360              
361             }
362              
363             sub get_users {
364              
365 0     0 1   my ($self) = @_;
366              
367 0           my $response = $self->request(method => 'GET', path => '/user');
368 0           my @users = map { Net::Gotify::User->new(%{_hash_to_snake_case($_)}) } @{$response};
  0            
  0            
  0            
369              
370 0 0         return wantarray ? @users : \@users;
371              
372             }
373              
374             sub create_user {
375              
376 0     0 1   my ($self, %params) = @_;
377              
378 0 0         my $name = delete $params{name} or Carp::croak 'Specify user "name"';
379 0 0         my $admin = delete $params{admin} or Carp::croak 'Specify user "admin" flag';
380 0 0         my $pass = delete $params{pass} or Carp::croak 'Specify user "pass"';
381              
382 0           my $response
383             = $self->request(method => 'POST', path => '/user', data => {name => $name, admin => $admin, pass => $pass});
384              
385 0           return Net::Gotify::User->new(%{_hash_to_snake_case($response)});
  0            
386              
387             }
388              
389             sub get_user {
390              
391 0     0 1   my ($self, $id) = @_;
392              
393 0 0         Carp::croak 'Specify user "id"' unless $id;
394              
395 0           my $response = $self->request(method => 'GET', path => "/user/$id");
396              
397 0           return Net::Gotify::User->new(%{_hash_to_snake_case($response)});
  0            
398              
399             }
400              
401             sub update_user {
402              
403 0     0 1   my ($self, $id, %params) = @_;
404              
405 0 0         Carp::croak 'Specify user "id"' unless $id;
406              
407 0 0         my $name = delete $params{name} or Carp::croak 'Specify user "name"';
408 0 0         my $admin = delete $params{admin} or Carp::croak 'Specify user "admin" flag';
409 0           my $pass = delete $params{pass};
410              
411 0           my $response = $self->request(method => 'POST', path => "/user/$id",
412             data => {name => $name, admin => $admin, pass => $pass});
413              
414 0           return Net::Gotify::User->new(%{_hash_to_snake_case($response)});
  0            
415              
416             }
417              
418             sub delete_user {
419              
420 0     0 1   my ($self, $id) = @_;
421              
422 0 0         Carp::croak 'Specify user "id"' unless $id;
423              
424 0           $self->request(method => 'DELETE', path => "/user/$id");
425 0           return 1;
426              
427             }
428              
429             1;
430              
431             __END__