1 # Copyright (C) 2002 Stanislav Sinyagin
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.
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.
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.
17 # $Id: Renderer.pm,v 1.2 2010-12-27 08:40:19 ivan Exp $
18 # Stanislav Sinyagin <ssinyagin@yahoo.com>
20 package Torrus::Renderer;
23 use Digest::MD5 qw(md5_hex);
26 use Torrus::ConfigTree;
27 use Torrus::TimeStamp;
30 use Torrus::SiteConfig;
32 use Torrus::Renderer::HTML;
33 use Torrus::Renderer::RRDtool;
35 # Inherit methods from these modules
36 use base qw(Torrus::Renderer::HTML
37 Torrus::Renderer::RRDtool
38 Torrus::Renderer::Frontpage
39 Torrus::Renderer::AdmInfo
40 Torrus::Renderer::Freeside
49 if( not defined $Torrus::Global::cacheDir )
51 Error('$Torrus::Global::cacheDir must be defined');
54 elsif( not -d $Torrus::Global::cacheDir )
56 Error("No such directory: $Torrus::Global::cacheDir");
60 $self->{'db'} = new Torrus::DB('render_cache', -WriteAccess => 1);
61 if( not defined( $self->{'db'} ) )
72 # Returns the absolute filename and MIME type:
74 # my($fname, $mimetype) = $renderer->render($config_tree, $token, $view);
80 my $config_tree = shift;
85 # If no options given, preserve the existing ones
88 $self->{'options'} = \%new_options;
91 $self->checkAndClearCache( $config_tree );
93 my($t_render, $t_expires, $filename, $mime_type);
95 my $tree = $config_tree->treeName();
97 if( not $config_tree->isTset($token) )
99 if( my $alias = $config_tree->isAlias($token) )
103 if( not defined( $config_tree->path($token) ) )
105 Error("No such token: $token");
110 $view = $config_tree->getDefaultView($token) unless defined $view;
113 if( $self->{'options'}->{'uid'} )
115 $uid = $self->{'options'}->{'uid'};
118 my $cachekey = $self->cacheKey( $uid . ':' . $tree . ':' .
119 $token . ':' . $view );
121 ($t_render, $t_expires, $filename, $mime_type) =
122 $self->getCache( $cachekey );
124 my $not_in_cache = 0;
126 if( not defined( $filename ) )
128 $filename = Torrus::Renderer::newCacheFileName( $cachekey );
132 my $cachefile = $Torrus::Global::cacheDir.'/'.$filename;
134 if( ( not $not_in_cache ) and
136 $t_expires >= time() )
138 return ($cachefile, $mime_type, $t_expires - time());
141 my $method = 'render_' . $config_tree->getParam($view, 'view-type');
143 ($t_expires, $mime_type) =
144 $self->$method( $config_tree, $token, $view, $cachefile );
148 $self->{'options'} = undef;
152 if( defined($t_expires) and defined($mime_type) )
154 $self->setCache($cachekey, time(), $t_expires, $filename, $mime_type);
155 @ret = ($cachefile, $mime_type, $t_expires - time());
165 my $keystring = shift;
167 if( ref( $self->{'options'}->{'variables'} ) )
169 foreach my $name ( sort keys %{$self->{'options'}->{'variables'}} )
171 my $val = $self->{'options'}->{'variables'}->{$name};
172 $keystring .= ':' . $name . '=' . $val;
182 my $keystring = shift;
184 my $cacheval = $self->{'db'}->get( $keystring );
186 if( defined($cacheval) )
188 return split(':', $cacheval);
200 my $keystring = shift;
201 my $t_render = shift;
202 my $t_expires = shift;
203 my $filename = shift;
204 my $mime_type = shift;
206 $self->{'db'}->put( $keystring,
208 ($t_render, $t_expires, $filename, $mime_type)));
213 sub checkAndClearCache
216 my $config_tree = shift;
218 my $tree = $config_tree->treeName();
220 Torrus::TimeStamp::init();
221 my $known_ts = Torrus::TimeStamp::get($tree . ':renderer_cache');
222 my $actual_ts = $config_tree->getTimestamp();
223 if( $actual_ts >= $known_ts or
224 time() >= $known_ts + $Torrus::Renderer::cacheMaxAge )
227 Torrus::TimeStamp::setNow($tree . ':renderer_cache');
229 Torrus::TimeStamp::release();
237 Debug('Clearing renderer cache');
238 my $cursor = $self->{'db'}->cursor( -Write => 1 );
239 while( my ($key, $val) = $self->{'db'}->next( $cursor ) )
241 my($t_render, $t_expires, $filename, $mime_type) = split(':', $val);
243 unlink $Torrus::Global::cacheDir.'/'.$filename;
244 $self->{'db'}->c_del( $cursor );
247 Debug('Renderer cache cleared');
253 my $cachekey = shift;
254 return sprintf('%s_%.5d', md5_hex($cachekey), rand(1e5));
261 # Remove spaces in the head and tail.
265 # Unscreen special characters
266 $txt =~ s/{COLON}/:/ogm;
267 $txt =~ s/{SEMICOL}/;/ogm;
268 $txt =~ s/{PERCENT}/%/ogm;
270 $txt =~ s/\&/\&\;/ogm;
271 $txt =~ s/\</\<\;/ogm;
272 $txt =~ s/\>/\>\;/ogm;
273 $txt =~ s/\'/\&apos\;/ogm;
274 $txt =~ s/\"/\"\;/ogm;
286 # indent-tabs-mode: nil
287 # perl-indent-level: 4