line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Kwiki::GDGraphGenerator; |
2
|
1
|
|
|
1
|
|
45010
|
use strict; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
40
|
|
3
|
1
|
|
|
1
|
|
5
|
use warnings; |
|
1
|
|
|
|
|
4
|
|
|
1
|
|
|
|
|
30
|
|
4
|
|
|
|
|
|
|
|
5
|
1
|
|
|
1
|
|
595
|
use Kwiki::Plugin '-Base'; |
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
6
|
|
|
|
|
|
|
use Kwiki::Installer '-base'; |
7
|
|
|
|
|
|
|
|
8
|
|
|
|
|
|
|
our $VERSION = "0.04"; |
9
|
|
|
|
|
|
|
|
10
|
|
|
|
|
|
|
const class_title => 'Kwiki graphs'; |
11
|
|
|
|
|
|
|
const class_id => 'graphgenerator'; |
12
|
|
|
|
|
|
|
|
13
|
|
|
|
|
|
|
sub register { |
14
|
|
|
|
|
|
|
my $registry = shift; |
15
|
|
|
|
|
|
|
$registry->add( wafl => graph => 'Kwiki::GDGraphGenerator::Wafl' ); |
16
|
|
|
|
|
|
|
} |
17
|
|
|
|
|
|
|
|
18
|
|
|
|
|
|
|
package Kwiki::GDGraphGenerator::Wafl; |
19
|
|
|
|
|
|
|
use Spiffy '-Base'; |
20
|
|
|
|
|
|
|
use base 'Spoon::Formatter::WaflBlock'; |
21
|
|
|
|
|
|
|
|
22
|
|
|
|
|
|
|
field 'config'; |
23
|
|
|
|
|
|
|
|
24
|
|
|
|
|
|
|
sub to_html { |
25
|
|
|
|
|
|
|
|
26
|
|
|
|
|
|
|
# parse the config, make sure options are there |
27
|
|
|
|
|
|
|
require YAML; |
28
|
|
|
|
|
|
|
$self->config( eval { YAML::Load( $self->block_text ) } ); |
29
|
|
|
|
|
|
|
return $self->error("make sure your YAML is correct") if $@; |
30
|
|
|
|
|
|
|
return $self->error("graph config isn't a hash") |
31
|
|
|
|
|
|
|
unless $self->config && ref $self->config eq 'HASH'; |
32
|
|
|
|
|
|
|
foreach (qw( id data type )) { |
33
|
|
|
|
|
|
|
return $self->error("graph config must specify '$_'") |
34
|
|
|
|
|
|
|
unless exists $self->config->{$_}; |
35
|
|
|
|
|
|
|
} |
36
|
|
|
|
|
|
|
|
37
|
|
|
|
|
|
|
# check to see if the graph exists -- if not, create it |
38
|
|
|
|
|
|
|
my $error = $self->generate_image |
39
|
|
|
|
|
|
|
unless -e $self->checksum_path |
40
|
|
|
|
|
|
|
&& io( $self->checksum_path )->assert->scalar eq $self->checksum; |
41
|
|
|
|
|
|
|
return $self->error($error) if $error; |
42
|
|
|
|
|
|
|
|
43
|
|
|
|
|
|
|
# return a simple link |
44
|
|
|
|
|
|
|
$self->hub->template->process( 'graphgenerator_inline.html', |
45
|
|
|
|
|
|
|
src => $self->image_path ); |
46
|
|
|
|
|
|
|
} |
47
|
|
|
|
|
|
|
|
48
|
|
|
|
|
|
|
sub error { |
49
|
|
|
|
|
|
|
$self->hub->template->process( 'graphgenerator_error.html', |
50
|
|
|
|
|
|
|
msg => "Couldn't create graph: " . shift ); |
51
|
|
|
|
|
|
|
} |
52
|
|
|
|
|
|
|
|
53
|
|
|
|
|
|
|
sub checksum { |
54
|
|
|
|
|
|
|
require Data::Dumper; |
55
|
|
|
|
|
|
|
require Digest::MD5; |
56
|
|
|
|
|
|
|
my $d = new Data::Dumper( [ $self->config ] ); |
57
|
|
|
|
|
|
|
Digest::MD5::md5_hex( $d->Sortkeys(1)->Indent(0)->Dump ); |
58
|
|
|
|
|
|
|
} |
59
|
|
|
|
|
|
|
|
60
|
|
|
|
|
|
|
sub image_path { |
61
|
|
|
|
|
|
|
$self->hub->cgi->button; |
62
|
|
|
|
|
|
|
$self->hub->graphgenerator->plugin_directory . '/' |
63
|
|
|
|
|
|
|
. $self->hub->pages->current->id . '.' |
64
|
|
|
|
|
|
|
. $self->config->{id} . '.png'; |
65
|
|
|
|
|
|
|
} |
66
|
|
|
|
|
|
|
|
67
|
|
|
|
|
|
|
sub checksum_path { |
68
|
|
|
|
|
|
|
$self->image_path . '.config.md5'; |
69
|
|
|
|
|
|
|
} |
70
|
|
|
|
|
|
|
|
71
|
|
|
|
|
|
|
sub generate_image { |
72
|
|
|
|
|
|
|
|
73
|
|
|
|
|
|
|
# load config, put things in variables and strip out |
74
|
|
|
|
|
|
|
# options we're not going to give to set() |
75
|
|
|
|
|
|
|
# (NOTE: width and height are read-only) |
76
|
|
|
|
|
|
|
my %config = %{ $self->config }; |
77
|
|
|
|
|
|
|
my ( $type, $width, $height, $data ) |
78
|
|
|
|
|
|
|
= @config{qw( type width height data )}; |
79
|
|
|
|
|
|
|
delete @config{qw( type width height data id )}; |
80
|
|
|
|
|
|
|
$width ||= 300; |
81
|
|
|
|
|
|
|
$height ||= 300; |
82
|
|
|
|
|
|
|
|
83
|
|
|
|
|
|
|
# check for keys we don't allow |
84
|
|
|
|
|
|
|
foreach my $key (qw( logo )) { |
85
|
|
|
|
|
|
|
return "specifying $key is not permitted" if $config{$key}; |
86
|
|
|
|
|
|
|
} |
87
|
|
|
|
|
|
|
|
88
|
|
|
|
|
|
|
# create a new graph object |
89
|
|
|
|
|
|
|
require GD::Graph; |
90
|
|
|
|
|
|
|
my $class = "GD::Graph::$type"; |
91
|
|
|
|
|
|
|
eval "require $class;"; |
92
|
|
|
|
|
|
|
return "couldn't create new $class" if $@; |
93
|
|
|
|
|
|
|
my $graph = $class->new( $width, $height ); |
94
|
|
|
|
|
|
|
|
95
|
|
|
|
|
|
|
# set the options and plot the data |
96
|
|
|
|
|
|
|
$graph->set(%config) |
97
|
|
|
|
|
|
|
or return "couldn't use config: " . $graph->error; |
98
|
|
|
|
|
|
|
my $gd = $graph->plot($data) |
99
|
|
|
|
|
|
|
or return "couldn't plot graph: " . $graph->error; |
100
|
|
|
|
|
|
|
|
101
|
|
|
|
|
|
|
# save to the files |
102
|
|
|
|
|
|
|
io( $self->image_path ) < $gd->png; |
103
|
|
|
|
|
|
|
io( $self->checksum_path ) < $self->checksum; |
104
|
|
|
|
|
|
|
|
105
|
|
|
|
|
|
|
# undef means no error |
106
|
|
|
|
|
|
|
return; |
107
|
|
|
|
|
|
|
} |
108
|
|
|
|
|
|
|
|
109
|
|
|
|
|
|
|
package Kwiki::GDGraphGenerator; |
110
|
|
|
|
|
|
|
1; |
111
|
|
|
|
|
|
|
|
112
|
|
|
|
|
|
|
__DATA__ |