File Coverage

blib/lib/Plack/Middleware/Matomo.pm
Criterion Covered Total %
statement 62 66 93.9
branch 9 12 75.0
condition 5 10 50.0
subroutine 11 12 91.6
pod 1 1 100.0
total 88 101 87.1


line stmt bran cond sub pod time code
1             package Plack::Middleware::Matomo;
2              
3             our $VERSION = '0.05';
4              
5 1     1   68662 use strict;
  1         11  
  1         29  
6 1     1   6 use warnings;
  1         1  
  1         25  
7 1     1   622 use AnyEvent::HTTP;
  1         36758  
  1         152  
8 1     1   542 use Log::Any '$log';
  1         10544  
  1         5  
9 1     1   2657 use Plack::Request;
  1         77503  
  1         47  
10             use Plack::Util::Accessor
11 1     1   460 qw(apiv base_url idsite token_auth time_format oai_identifier_format view_paths download_paths);
  1         339  
  1         7  
12 1     1   96 use URI;
  1         2  
  1         24  
13              
14 1     1   5 use parent 'Plack::Middleware';
  1         2  
  1         8  
15              
16             sub call {
17 3     3 1 28134 my ($self, $env) = @_;
18              
19 3         27 my $request = Plack::Request->new($env);
20 3         54 my $res = $self->app->($env);
21              
22             # only get requests
23 3 50       422 return $res unless $request->method =~ m{^get$}i;
24              
25 3         40 my ($action, $id);
26 3         14 my $view_paths = $self->view_paths;
27 3         22 my $download_paths = $self->download_paths;
28              
29 3         21 $log->info("Entering Matomo middleware at " . $request->path);
30              
31 3         44 foreach my $p (@$view_paths) {
32 3 100       21 if ($request->path =~ /$p/) {
33 1         24 $id = $1;
34 1         8 $action = "view";
35 1         3 last;
36             }
37             }
38 3         23 foreach my $p (@$download_paths) {
39 3 100       10 if ($request->path =~ /$p/) {
40 1         12 $id = $1;
41 1         3 $action = "download";
42 1         3 last;
43             }
44             }
45              
46 3 100       34 return $res unless $action;
47 2         11 $log->info("Action: $action");
48              
49 2   50     13 my $time_format = $self->time_format // '%Y-%m-%dT%H:%M:%SZ';
50 2         26 my $ip = $self->_anonymize_ip($request->address);
51 2         8 my $oai_id = sprintf($self->oai_identifier_format, $id);
52 2         20 my $cvar = '{"1":["oaipmhID","' . $oai_id . '"]}';
53              
54 2         6 my $rand = int(rand(10000));
55              
56 2   50     10 my $event = {
      50        
      50        
      50        
57             _id => $request->session // '',
58             action_name => $action,
59             apiv => $self->apiv // 1,
60             cvar => $cvar,
61             idsite => $self->idsite,
62             rand => $rand,
63             rec => 1,
64             token_auth => $self->token_auth,
65             ua => $request->user_agent // 'Mozilla',
66             url => $request->uri,
67             urlref => $request->referer // '',
68             visitIP => $ip,
69             };
70              
71 2 100       1338 if ($action eq 'download') {
72 1         4 $event->{download} = $request->uri;
73             }
74              
75 2         217 $self->_push_to_matomo($event);
76              
77 2         23956 return $res;
78             }
79              
80             sub _anonymize_ip {
81 2     2   21 my ($self, $ip) = @_;
82              
83 2         14 $ip =~ s/\.\d+?$/\.0/;
84              
85 2         8 return $ip;
86             }
87              
88             sub _push_to_matomo {
89 2     2   10 my ($self, $event) = @_;
90              
91 2         10 my $uri = URI->new($self->base_url);
92 2         147 $uri->query_form($event);
93              
94 2         979 $log->debug("URL: " . $uri->as_string);
95              
96             http_head $uri->as_string, sub {
97 0     0     my ($body, $hdr) = @_;
98              
99 0 0         if ($hdr->{Status} =~ /^2/) {
100 0           $log->debug("Ok matomo endpoint: $hdr->{Status} $hdr->{Reason} for " . $uri->as_string);
101             } else {
102 0           $log->error("Could not reach matomo endpoint: $hdr->{Status} $hdr->{Reason} for " . $uri->as_string);
103             }
104 2         29 };
105             }
106              
107             1;
108              
109             __END__