40348a664d822fb75b4a4a2a388f5d0ae93ecf4e
[freeside.git] / torrus / perllib / Torrus / ReportOutput / HTML.pm
1 #  Copyright (C) 2005  Stanislav Sinyagin
2 #
3 #  This program is free software; you can redistribute it and/or modify
4 #  it under the terms of the GNU General Public License as published by
5 #  the Free Software Foundation; either version 2 of the License, or
6 #  (at your option) any later version.
7 #
8 #  This program is distributed in the hope that it will be useful,
9 #  but WITHOUT ANY WARRANTY; without even the implied warranty of
10 #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 #  GNU General Public License for more details.
12 #
13 #  You should have received a copy of the GNU General Public License
14 #  along with this program; if not, write to the Free Software
15 #  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
16
17 # $Id: HTML.pm,v 1.1 2010-12-27 00:03:46 ivan Exp $
18 # Stanislav Sinyagin <ssinyagin@yahoo.com>
19
20 package Torrus::ReportOutput::HTML;
21
22 use strict;
23 use Template;
24 use Date::Format;
25
26 use Torrus::Log;
27 use Torrus::ReportOutput;
28 use Torrus::SiteConfig;
29
30 use base 'Torrus::ReportOutput';
31
32 our @monthNames = qw
33     (January February March April May June
34      July August September October November December);
35
36 sub init
37 {
38     my $self = shift;
39
40     Torrus::SiteConfig::loadStyling();
41     
42     my $htmldir = $self->{'outdir'} . '/html';
43     if( not -d $htmldir )
44     {
45         Verbose('Creating directory: ' . $htmldir);
46         if( not mkdir( $htmldir ) )
47         {
48             Error('Cannot create directory ' . $htmldir . ': ' . $!);
49             return 0;
50         }
51     }
52     $self->{'htmldir'} = $htmldir;
53     
54     $self->{'tt'} =
55         new Template(INCLUDE_PATH => $Torrus::Global::templateDirs,
56                      TRIM => 1);
57     return 1;
58 }
59
60
61 # Print the head page and years reference
62 sub genIntroduction
63 {
64     my $self = shift;
65     my $allReports = shift;
66
67     return $self->render({
68         'filename' => $self->indexFilename(),
69         'template' => 'index',
70         'data' => $allReports });    
71 }
72
73
74 # Print monthly report for a given service ID
75 # The fields argument is a hash of hashes:
76 # serviceid => reportname => month => fieldname => {value, units}
77 sub genSrvIdOutput
78 {
79     my $self = shift;
80     my $year = shift;    
81     my $fields = shift;
82
83     my $ok = 1;
84     while( my( $serviceid, $ref ) = each %{$fields} )
85     {
86         $ok = $self->render({
87             'filename' => $self->srvIdFilename($year, $serviceid),
88             'template' => 'serviceid',
89             'data' => $ref,
90             'serviceid' => $serviceid,
91             'year' => $year }) ? $ok:0; 
92     }
93     return $ok;
94 }
95
96
97 # Print daily report -- NOT IMPLEMENTED YET
98 # Fields structure:
99 # day => reportname => serviceid => fieldname => {value, units}
100 sub genDailyOutput
101 {
102     my $self = shift;
103     my $year = shift;    
104     my $month = shift;    
105     my $fields = shift;
106
107     return 1;
108 }
109
110
111 # Print monthly report
112 # fields:
113 # month => reportname => serviceid => fieldname => {value, units}
114 sub genMonthlyOutput
115 {
116     my $self = shift;
117     my $year = shift;    
118     my $fields = shift;
119
120     my $ok = 1;
121     my @months;
122     while( my( $month, $ref ) = each %{$fields} )
123     {
124         if( $self->render({
125             'filename' => $self->monthlyFilename($year, $month),
126             'template' => 'monthly',
127             'data'     => $ref,
128             'year'     => $year,
129             'month'    => $month }) )
130         {
131             push( @months, $month );
132         }
133         else
134         {
135             $ok = 0;
136         }
137     }
138
139     my @sorted = sort {$a <=>$b} @months;
140     $ok = $self->render({
141         'filename' => $self->yearlyFilename($year),
142         'template' => 'yearly',
143         'data'     => {'months' => \@sorted},
144         'year'     => $year }) ? $ok:0;
145     return $ok;
146 }
147     
148
149 sub indexFilename
150 {
151     return 'index.html';
152 }
153
154
155 sub srvIdFilename
156 {
157     my $self = shift;
158     my $year = shift;
159     my $serviceid = shift;
160
161     return sprintf('%.4d_serviceid_%s.html', $year, $serviceid);
162 }
163
164 sub monthlyFilename
165 {
166     my $self = shift;
167     my $year = shift;
168     my $month = shift;
169
170     return sprintf('%.4d_monthly_%.2d.html', $year, $month);
171 }
172
173 sub yearlyFilename
174 {
175     my $self = shift;
176     my $year = shift;
177
178     return sprintf('%.4d_yearly.html', $year);
179 }
180     
181     
182
183 sub render
184 {
185     my $self = shift;
186     my $opt = shift;
187
188     my $outfile = $self->{'htmldir'} . '/' . $opt->{'filename'};
189     my $tmplfile = $Torrus::ReportOutput::HTML::templates{$opt->{'template'}};
190     Debug('Rendering ' . $outfile . ' from ' . $tmplfile);
191     
192     my $ttvars =
193     {
194         'plainURL'   => $Torrus::Renderer::plainURL,
195         'style'      => sub { return $self->style($_[0]); },
196         'treeName'   => $self->{'options'}->{'Tree'},
197         'companyName'=> $Torrus::Renderer::companyName,
198         'companyURL' => $Torrus::Renderer::companyURL,
199         'siteInfo'   => $Torrus::Renderer::siteInfo,
200         'version'    => $Torrus::Global::version,
201         'xmlnorm'    => \&xmlnormalize,
202         'data'       => $opt->{'data'},
203         'year'       => $opt->{'year'},
204         'month'      => $opt->{'month'},
205         'serviceid'  => $opt->{'serviceid'},
206         'indexUrl'   => sub {
207             return $self->reportUrl($self->indexFilename());},
208         'srvIdUrl'   => sub {
209             return $self->reportUrl($self->srvIdFilename($opt->{'year'},
210                                                          $_[0]));},
211         'monthlyUrl' => sub {
212             return $self->reportUrl($self->monthlyFilename($opt->{'year'},
213                                                            $_[0]));},
214         'yearlyUrl' => sub {
215             return $self->reportUrl($self->yearlyFilename($_[0]));},
216         'monthName' => sub {$self->monthName($_[0]);},
217         'formatValue' => sub {
218             if( ref($_[0]))
219             {
220                 return sprintf('%.2f %s', $_[0]->{'value'}, $_[0]->{'units'});
221             }
222             else
223             {
224                 return 'N/A';
225             }},
226         'timestamp'  => sub { return time2str($Torrus::Renderer::timeFormat,
227                                               time()); },
228     };
229     
230     my $result = $self->{'tt'}->process( $tmplfile, $ttvars, $outfile );
231
232     if( not $result )
233     {
234         Error("Error while rendering " . $outfile . ": " .
235               $self->{'tt'}->error());
236         return 0;
237     }
238     return 1;
239 }
240
241
242 sub style
243 {
244     my $self = shift;
245     my $object = shift;
246
247     my $ret = $Torrus::Renderer::styling{'report'}{$object};
248     if( not defined( $ret ) )
249     {
250         $ret = $Torrus::Renderer::styling{'default'}{$object};
251     }
252
253     return $ret;
254 }
255
256 sub monthName
257 {
258     my $self = shift;
259     my $month = shift;
260
261     return $monthNames[ $month - 1 ];
262 }
263
264
265 sub reportUrl
266 {
267     my $self = shift;
268     my $filename = shift;
269
270     return $Torrus::Renderer::rendererURL . '/' .
271         $self->{'options'}->{'Tree'} . '?htmlreport=' . $filename;
272 }
273
274 sub xmlnormalize
275 {
276     my( $txt )= @_;
277
278     $txt =~ s/\&/\&amp\;/gm;
279     $txt =~ s/\</\&lt\;/gm;
280     $txt =~ s/\>/\&gt\;/gm;
281     $txt =~ s/\'/\&apos\;/gm;
282     $txt =~ s/\"/\&quot\;/gm;
283
284     return $txt;
285 }
286
287     
288
289 1;
290
291
292 # Local Variables:
293 # mode: perl
294 # indent-tabs-mode: nil
295 # perl-indent-level: 4
296 # End: