line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Ordeal::Model::Backend::PlainFile; |
2
|
|
|
|
|
|
|
|
3
|
|
|
|
|
|
|
# vim: ts=3 sts=3 sw=3 et ai : |
4
|
|
|
|
|
|
|
|
5
|
5
|
|
|
5
|
|
3597
|
use 5.020; |
|
5
|
|
|
|
|
19
|
|
6
|
5
|
|
|
5
|
|
29
|
use strict; # redundant, but still useful to document |
|
5
|
|
|
|
|
10
|
|
|
5
|
|
|
|
|
102
|
|
7
|
5
|
|
|
5
|
|
24
|
use warnings; |
|
5
|
|
|
|
|
9
|
|
|
5
|
|
|
|
|
229
|
|
8
|
|
|
|
|
|
|
{ our $VERSION = '0.004'; } |
9
|
5
|
|
|
5
|
|
32
|
use Mo qw< default >; |
|
5
|
|
|
|
|
9
|
|
|
5
|
|
|
|
|
33
|
|
10
|
5
|
|
|
5
|
|
1096
|
use Path::Tiny; |
|
5
|
|
|
|
|
17
|
|
|
5
|
|
|
|
|
303
|
|
11
|
5
|
|
|
5
|
|
32
|
use Ouch; |
|
5
|
|
|
|
|
10
|
|
|
5
|
|
|
|
|
33
|
|
12
|
5
|
|
|
5
|
|
1972
|
use autodie; |
|
5
|
|
|
|
|
46581
|
|
|
5
|
|
|
|
|
29
|
|
13
|
|
|
|
|
|
|
|
14
|
5
|
|
|
5
|
|
32239
|
use experimental qw< signatures postderef >; |
|
5
|
|
|
|
|
10
|
|
|
5
|
|
|
|
|
42
|
|
15
|
5
|
|
|
5
|
|
870
|
no warnings qw< experimental::signatures experimental::postderef >; |
|
5
|
|
|
|
|
11
|
|
|
5
|
|
|
|
|
198
|
|
16
|
|
|
|
|
|
|
|
17
|
5
|
|
|
5
|
|
2092
|
use Ordeal::Model::Card; |
|
5
|
|
|
|
|
15
|
|
|
5
|
|
|
|
|
155
|
|
18
|
5
|
|
|
5
|
|
32
|
use Ordeal::Model::Deck; |
|
5
|
|
|
|
|
10
|
|
|
5
|
|
|
|
|
3948
|
|
19
|
|
|
|
|
|
|
|
20
|
|
|
|
|
|
|
has base_directory => (default => 'ordeal-assets'); |
21
|
|
|
|
|
|
|
|
22
|
29
|
|
|
29
|
1
|
377
|
sub card ($self, $id) { |
|
29
|
|
|
|
|
47
|
|
|
29
|
|
|
|
|
44
|
|
|
29
|
|
|
|
|
100
|
|
23
|
29
|
100
|
|
|
|
205
|
my ($name, $extension) = $id =~ m{\A (.*) \. (.*) \z}mxs |
24
|
|
|
|
|
|
|
or ouch 400, 'invalid identifier', $id; |
25
|
28
|
|
|
|
|
78
|
my $content_type = $self->content_type_for($extension); |
26
|
27
|
|
|
|
|
83
|
my $path = $self->path_for(cards => $id); |
27
|
|
|
|
|
|
|
return Ordeal::Model::Card->new( |
28
|
|
|
|
|
|
|
content_type => $content_type, |
29
|
|
|
|
|
|
|
group => '', |
30
|
|
|
|
|
|
|
id => $id, |
31
|
|
|
|
|
|
|
name => $name, |
32
|
1
|
|
|
1
|
|
4
|
data => sub { $path->slurp_raw }, |
33
|
26
|
|
|
|
|
231
|
); |
34
|
|
|
|
|
|
|
} ## end sub get_card |
35
|
|
|
|
|
|
|
|
36
|
28
|
|
|
28
|
1
|
42
|
sub content_type_for ($self, $extension) { |
|
28
|
|
|
|
|
47
|
|
|
28
|
|
|
|
|
41
|
|
|
28
|
|
|
|
|
48
|
|
37
|
28
|
|
|
|
|
64
|
state $content_type_for = { |
38
|
|
|
|
|
|
|
png => 'image/png', |
39
|
|
|
|
|
|
|
jpg => 'image/jpeg', |
40
|
|
|
|
|
|
|
svg => 'image/svg+xml', |
41
|
|
|
|
|
|
|
}; |
42
|
28
|
100
|
|
|
|
105
|
my $content_type = $content_type_for->{lc($extension)} |
43
|
|
|
|
|
|
|
or ouch 400, 'invalid extension', $extension; |
44
|
27
|
|
|
|
|
54
|
return $content_type; |
45
|
|
|
|
|
|
|
} |
46
|
|
|
|
|
|
|
|
47
|
5
|
|
|
5
|
1
|
33
|
sub deck ($self, $id) { |
|
5
|
|
|
|
|
6
|
|
|
5
|
|
|
|
|
11
|
|
|
5
|
|
|
|
|
6
|
|
48
|
5
|
|
|
|
|
17
|
my $path = $self->path_for(decks => $id); |
49
|
|
|
|
|
|
|
|
50
|
4
|
|
|
|
|
9
|
my @cards; |
51
|
4
|
50
|
|
|
|
13
|
if ($path->is_dir) { |
52
|
|
|
|
|
|
|
@cards = |
53
|
20
|
|
|
|
|
3768
|
map { $_->realpath->basename } |
54
|
4
|
|
|
|
|
84
|
sort { $a->basename cmp $b->basename } $path->children; |
|
28
|
|
|
|
|
1650
|
|
55
|
|
|
|
|
|
|
} |
56
|
|
|
|
|
|
|
else { |
57
|
0
|
|
|
|
|
0
|
@cards = $path->lines({chomp => 1}); |
58
|
|
|
|
|
|
|
} |
59
|
4
|
|
|
|
|
940
|
$_ = $self->card($_) for @cards; |
60
|
|
|
|
|
|
|
|
61
|
4
|
|
|
|
|
85
|
return Ordeal::Model::Deck->new( |
62
|
|
|
|
|
|
|
group => '', |
63
|
|
|
|
|
|
|
id => $id, |
64
|
|
|
|
|
|
|
name => $id, |
65
|
|
|
|
|
|
|
cards => \@cards, |
66
|
|
|
|
|
|
|
); |
67
|
|
|
|
|
|
|
} |
68
|
|
|
|
|
|
|
|
69
|
0
|
|
|
0
|
1
|
0
|
sub decks ($s) { |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
70
|
|
|
|
|
|
|
return |
71
|
0
|
|
|
|
|
0
|
grep { ! m{\A [._]}mxs } # nothing hidden or starting with underscore |
72
|
0
|
|
|
|
|
0
|
map { $_->basename } # return identifiers of decks |
|
0
|
|
|
|
|
0
|
|
73
|
|
|
|
|
|
|
path($s->base_directory)->children; |
74
|
|
|
|
|
|
|
} |
75
|
|
|
|
|
|
|
|
76
|
32
|
|
|
32
|
1
|
51
|
sub path_for ($self, $type, $id) { |
|
32
|
|
|
|
|
50
|
|
|
32
|
|
|
|
|
42
|
|
|
32
|
|
|
|
|
50
|
|
|
32
|
|
|
|
|
44
|
|
77
|
32
|
|
|
|
|
85
|
my $path = path($self->base_directory)->child($type => $id); |
78
|
32
|
100
|
|
|
|
1872
|
$path->exists or ouch 404, 'not found', $id; |
79
|
30
|
|
|
|
|
775
|
return $path; |
80
|
|
|
|
|
|
|
} |
81
|
|
|
|
|
|
|
|
82
|
|
|
|
|
|
|
1; |
83
|
|
|
|
|
|
|
__END__ |