File Coverage

blib/lib/Catalyst/View/RRDGraph.pm
Criterion Covered Total %
statement 19 21 90.4
branch n/a
condition n/a
subroutine 7 7 100.0
pod n/a
total 26 28 92.8


line stmt bran cond sub pod time code
1             package Catalyst::View::RRDGraph;
2             {
3             $Catalyst::View::RRDGraph::VERSION = '0.10';
4             }
5              
6 1     1   1105 use strict;
  1         3  
  1         44  
7 1     1   7 use warnings;
  1         2  
  1         41  
8              
9 1     1   5 use base 'Catalyst::View';
  1         4  
  1         599  
10              
11 1     1   6 use RRDs;
  1         2  
  1         38  
12 1     1   1349 use File::Temp qw();
  1         23926  
  1         25  
13 1     1   919 use MRO::Compat;
  1         3297  
  1         30  
14              
15 1     1   511 use Catalyst::Exception;
  0            
  0            
16              
17             sub new {
18             my ($class, $c, $arguments) = @_;
19             my $config = {
20             'IMG_DIR' => '/tmp/',
21             'IMG_FORMAT' => 'PNG',
22             'ON_ERROR_SERVE' => undef,
23             %{ $class->config },
24             (defined($arguments)?%{$arguments}:()),
25             };
26              
27             my $self = $class->next::method(
28             $c, { %$config },
29             );
30              
31             $self->config($config);
32              
33             return ($self);
34             }
35              
36             sub process {
37             my ($self, $c) = @_;
38              
39             my $props = $c->stash->{'graph'};
40             die "No graph in the stash" if (not defined $props);
41             die "graph must be an ARRAYREF" if (ref($props) ne 'ARRAY');
42              
43             my $tempfile = File::Temp->new( TEMPLATE => 'cat_view_rrd_XXXXXX',
44             DIR => $self->config->{'IMG_DIR'},
45             SUFFIX => '.' . lc($self->config->{'IMG_FORMAT'}));
46              
47             RRDs::graph($tempfile->filename,
48             '--imgformat', $self->config->{'IMG_FORMAT'},
49             @$props);
50              
51             if (RRDs::error) {
52             $self->_handle_error($c, RRDs::error);
53             return;
54             }
55             if (-s $tempfile->filename == 0) {
56             $self->_handle_error($c, "RRDgraph is 0 bytes");
57             return;
58             }
59              
60             $c->serve_static_file($tempfile->filename);
61             }
62              
63             sub _handle_error {
64             my ($self, $c, $error) = @_;
65             if (not defined $self->config->{'ON_ERROR_SERVE'}){
66             Catalyst::Exception->throw($error);
67             } elsif (ref($self->config->{'ON_ERROR_SERVE'}) eq 'CODE') {
68             #Call the custom handler
69             $self->config->{'ON_ERROR_SERVE'}($self, $c, $error);
70             } else {
71             $c->log->error($error);
72             $c->serve_static_file($self->config->{'ON_ERROR_SERVE'});
73             }
74              
75             }
76              
77             #################### main pod documentation begin ###################
78             ## Below is the stub of documentation for your module.
79             ## You better edit it!
80              
81              
82             =head1 NAME
83              
84             Catalyst::View::RRDGraph - RRD Graph View Class
85              
86             =head1 SYNOPSIS
87              
88             use the helper to create your View myapp_create.pl view RRDGraph RRDGraph
89              
90             from the controller:
91              
92             sub routine :Local {
93             my ($self, $c) = @_;
94              
95             $c->stash->{'graph'} = [
96             "--lower-limit", "0",
97             "--start", "end-1d",
98             "--vertical-label", "My Label",
99             "--height", 600,
100             "--width", 300,
101             "DEF:Data=/path/to/rrd.rrd:data:AVERAGE",
102             "AREA:Data#0000FF:Data "
103             ];
104             $c->forward('MyApp::View::RRDGraph');
105             }
106              
107             =head1 DESCRIPTION
108              
109             This view generates RRD graph images from the graph defintion placed in the
110             stash. The controller is responsable of placing an ARRAYREF in
111             B<$c->stash->{'graph'}> with the same data as to generate a graph with the RRDs
112             module, except for I<filename>, that will be automatically generated by the
113             view.
114              
115             It doesn't depend on RRDs, but I<does> need it to work (and for the tests to
116             pass). You can install RRDs, for instance, using L<Alien::RRDtool>, or
117             compiling it manually from L<http://oss.oetiker.ch/rrdtool/>
118              
119             =head1 CONFIGURATION
120              
121             Configurations for the view are:
122              
123             =head2 IMG_DIR
124              
125             Directory to generate temporary image files. Defaults to B</tmp/>
126              
127             =head2 IMG_FORMAT
128              
129             Image format for the generated files. 'PNG' by default.
130              
131             =head2 ON_ERROR_SERVE
132              
133             On error, if this config value is set, the file to which it points will be
134             served (so you can serve an "error image" file to the user). Alternately, it
135             can be set to a code reference, that will called with B<$self>, B<$c> and
136             B<$error>. You can then generate your own content in this handler. Default
137             (leaving undefined) is to throw an expception.
138              
139             See L<http://oss.oetiker.ch/rrdtool/doc/rrdgraph.en.html> for more info.
140              
141             =head1 METHODS
142              
143             =head2 new
144              
145             Constructor.
146              
147             =head2 process
148              
149             Called internally by Catalyst when the view is used.
150              
151             =head1 AUTHOR
152              
153             Jose Luis Martinez
154             CPAN ID: JLMARTIN
155             CAPSiDE
156             jlmartinez@capside.com
157             L<http://www.pplusdomain.net>
158              
159             =head1 THANKS
160              
161             To Ton Voon for sending in patches, tests, and ideas.
162              
163             Alexander Kabenin
164              
165             =head1 COPYRIGHT
166              
167             This program is free software; you can redistribute
168             it and/or modify it under the same terms as Perl itself.
169              
170             The full text of the license can be found in the
171             LICENSE file included with this module.
172              
173              
174             =head1 SEE ALSO
175              
176             RRDs: L<http://oss.oetiker.ch/rrdtool/prog/RRDs.en.html>
177              
178             RRD graph docs:
179             L<http://oss.oetiker.ch/rrdtool/doc/rrdgraph.en.html>,
180             L<http://oss.oetiker.ch/rrdtool/doc/rrdgraph_data.en.html>,
181             L<http://oss.oetiker.ch/rrdtool/doc/rrdgraph_graph.en.html>
182              
183             =cut
184              
185             #################### main pod documentation end ###################
186              
187              
188             1;
189             # The preceding line will help the module return a true value
190