File Coverage

blib/lib/WWW/ARDB/Cache.pm
Criterion Covered Total %
statement 48 56 85.7
branch 9 16 56.2
condition 2 9 22.2
subroutine 11 12 91.6
pod 3 3 100.0
total 73 96 76.0


line stmt bran cond sub pod time code
1             package WWW::ARDB::Cache;
2             our $AUTHORITY = 'cpan:GETTY';
3              
4             # ABSTRACT: File-based cache for WWW::ARDB
5              
6 6     6   181578 use Moo;
  6         10161  
  6         50  
7 6     6   8154 use Types::Standard qw( Str InstanceOf );
  6         759575  
  6         78  
8 6     6   23950 use Path::Tiny qw( path );
  6         92927  
  6         606  
9 6     6   60 use Digest::MD5 qw( md5_hex );
  6         14  
  6         419  
10 6     6   429 use JSON::MaybeXS qw( encode_json decode_json );
  6         9708  
  6         319  
11 6     6   450 use namespace::clean;
  6         20787  
  6         81  
12              
13             our $VERSION = '0.002';
14              
15              
16             has cache_dir => (
17             is => 'lazy',
18             isa => InstanceOf['Path::Tiny'],
19             coerce => sub { ref $_[0] ? $_[0] : path($_[0]) },
20             builder => '_build_cache_dir',
21             );
22              
23              
24             sub _build_cache_dir {
25 0     0   0 my $self = shift;
26              
27 0         0 my $base;
28 0 0       0 if ($^O eq 'MSWin32') {
29 0   0     0 $base = path($ENV{LOCALAPPDATA} || $ENV{APPDATA} || $ENV{HOME});
30             } else {
31 0   0     0 $base = path($ENV{XDG_CACHE_HOME} || "$ENV{HOME}/.cache");
32             }
33              
34 0         0 my $dir = $base->child('ardb');
35 0 0       0 $dir->mkpath unless $dir->exists;
36              
37 0         0 return $dir;
38             }
39              
40             has namespace => (
41             is => 'ro',
42             isa => Str,
43             default => 'default',
44             );
45              
46              
47             sub get {
48 10     10 1 6612 my ($self, $endpoint, $params) = @_;
49              
50 10         31 my $file = $self->_cache_file($endpoint, $params);
51 10 100       584 return unless $file->exists;
52              
53 4         117 my $content = $file->slurp_utf8;
54 4         749 my $cached = decode_json($content);
55              
56 4         30 return $cached->{data};
57             }
58              
59              
60             sub set {
61 6     6 1 1051 my ($self, $endpoint, $params, $data) = @_;
62              
63 6         19 my $file = $self->_cache_file($endpoint, $params);
64 6 50       301 $file->parent->mkpath unless $file->parent->exists;
65              
66 6         506 my $cache_data = {
67             timestamp => time(),
68             endpoint => $endpoint,
69             data => $data,
70             };
71              
72 6         124 $file->spew_utf8(encode_json($cache_data));
73             }
74              
75              
76             sub clear {
77 4     4 1 597 my ($self, $endpoint) = @_;
78              
79 4 100       13 if ($endpoint) {
80 2         8 my $pattern = $self->_cache_key($endpoint, {});
81 2         19 $pattern =~ s/_[a-f0-9]+$//;
82 2         57 for my $file ($self->cache_dir->children) {
83 3 50       470 if ($file->basename =~ /^\Q$pattern\E/) {
84 3         145 $file->remove;
85             }
86             }
87             } else {
88 2         57 for my $file ($self->cache_dir->children) {
89 3 50       410 $file->remove if $file->is_file;
90             }
91             }
92             }
93              
94              
95             sub _cache_key {
96 18     18   30 my ($self, $endpoint, $params) = @_;
97              
98 18         67 my $key = $self->namespace . '_' . $endpoint;
99 18         78 $key =~ s/[\/\s]/_/g;
100              
101 18 100 66     91 if ($params && %$params) {
102 2         9 my $param_str = encode_json($params);
103 2         9 $key .= '_' . md5_hex($param_str);
104             }
105              
106 18         39 return $key;
107             }
108              
109             sub _cache_file {
110 16     16   30 my ($self, $endpoint, $params) = @_;
111              
112 16         36 my $key = $self->_cache_key($endpoint, $params);
113 16         424 return $self->cache_dir->child($key . '.json');
114             }
115              
116             1;
117              
118             __END__