source: subversion/applications/rendering/tilesAtHome/lib/TahConf.pm @ 11415

Last change on this file since 11415 was 11415, checked in by deelkar, 11 years ago

refine inkscape version regex

File size: 13.6 KB
Line 
1# A Config class for t@h.
2#
3# Copyright 2008, by Matthias Julius
4# licensed under the GPL v2 or (at your option) any later version.
5
6package TahConf;
7
8use strict;
9use AppConfig qw(:argcount);
10use Config; #needed to check flock availability
11
12my $instance = undef; # Singleton instance of Config class
13
14#-----------------------------------------------------------------------
15# returns the AppConfig object that can be globally used throughout the
16# application and initializes it if called for the first time.
17# This method is called on the class, and not on an instance.
18#-----------------------------------------------------------------------
19sub getConfig 
20{
21    my $class = shift;
22
23    if (defined($instance))
24    {
25        # already initialized, do nothing
26        return $instance;
27    }
28
29    # not yet initialized
30    my $self = {};       # TahConf instance
31
32
33    my $Config = AppConfig->new(
34                 {CREATE => 1,              # Autocreate unknown config variables
35                  GLOBAL => {DEFAULT  => undef, # Create undefined Variables by default
36                  ARGCOUNT => ARGCOUNT_ONE} # Simple Values (no arrays, no hashmaps)
37                 });
38    $Config->define("help|usage!");
39    $Config->define("nodownload=s");
40    $Config->set("nodownload",0);
41    $Config->file("config.defaults", "layers.conf", "tilesAtHome.conf", "authentication.conf");
42    $Config->args();                # overwrite config options with command line options
43    $Config->file("general.conf");  # overwrite with hardcoded values that must not be changed
44
45    $self->{Config} = $Config;
46
47    bless $self, $class;
48    $instance = $self;
49    return $self;
50}
51
52
53#-----------------------------------------------------------------------------
54# retrieve a specific config setting
55#-----------------------------------------------------------------------------
56sub get
57{
58    my $self = shift;
59    return $self->{Config}->get(shift);
60}
61
62
63#-----------------------------------------------------------------------------
64# set a config setting
65#-----------------------------------------------------------------------------
66sub set
67{
68    my $self = shift();
69    return $self->{Config}->set(@_);
70}
71
72#-----------------------------------------------------------------------------
73# get a hash of config settings matching regex
74#-----------------------------------------------------------------------------
75sub varlist
76{
77    my $self = shift();
78    return $self->{Config}->varlist(@_);
79}
80
81#--------------------------------------------------------------------------
82# Checks a tiles@home basic configuration which is needed for uploading
83# also sets some runtime environment information
84#--------------------------------------------------------------------------
85sub CheckBasicConfig
86{
87    my $self = shift();
88    my %EnvironmentInfo;
89    my $cmd;
90
91    #------
92    ## switch on verbose mode if Debug is set
93    if ($self->get("Debug"))
94    {
95        $self->set("Verbose",10);
96    }
97
98    #------
99    ## check and set the WorkingDirectory.
100    #  NOTE: it will contain no trailing slash after we are finished
101    if ($self->get("WorkingDirectory"))
102    {
103        $self->set("WorkingDirectory", 
104                    File::Spec->rel2abs($self->get("WorkingDirectory")));
105    }
106    else
107    {   # no WorkingDir set in config file. Use system default tmp dir
108        $self->set("WorkingDirectory", File::Spec->tmpdir());
109    }
110
111    #------
112    ## Finally create the WorkingDir if necessary.
113    printf "- Using working directory %s\n", $self->get("WorkingDirectory");
114    File::Path::mkpath($self->get("WorkingDirectory"));
115
116    #------
117    printf "- Using process log file %s\n", $self->get("ProcessLogFile") if ($self->get("ProcessLog"));
118
119    #------
120    if ($self->get("Subversion"))
121    {
122        $cmd=$self->get("Subversion");
123        my $SubversionV = `\"$cmd\" --version`;
124        $EnvironmentInfo{"Subversion"}=$SubversionV;
125        # die here if svn executable not found, but before enabling try on windows machines wether --version works.
126    }
127    else
128    {
129        die ("! no subversion command set");
130    }
131
132    #------
133    # LocalSplippymap
134    if ($self->get("LocalSlippymap"))
135    {
136        print "- Writing LOCAL slippy map directory hierarchy, no uploading\n";
137    }
138    else
139    {
140        if($self->get("DeleteZipFilesAfterUpload") == 0){
141            print "- Keeping ZIP files after upload\n";
142        }
143    }
144
145    #------
146    if ($self->get("UploadToDirectory"))
147    {
148        if (! -d $self->get("UploadTargetDirectory")) {
149            # we chose to upload to directory, but it does not exist!
150            print "- Upload Directory does not exist. Trying to create ",
151                   $self->get("UploadTargetDirectory"),"\n";
152            File::Path::mkpath $self->get("UploadTargetDirectory");
153           if (! -d $self->get("UploadTargetDirectory")) {
154               die "! Failed to create Upload directory.";
155           }
156        }
157    }
158
159    #------
160    # Zip version
161    $cmd=$self->get("Zip");
162    my $ZipV = `\"$cmd\" -v`;
163    $EnvironmentInfo{Zip}=$ZipV;
164    if ($EnvironmentInfo{Zip} eq "") 
165    {
166        die("! Can't find zip (using \"".$self->get("Zip")."\")\n");
167    }
168    #------
169    # check if flock is available on this OS
170    # Theoertically the next 2 lines are correct, but Winows seems to cannot lock directories
171    # even if flock exists. So bypass flock there completely
172    #if (($Config{'d_flock'} && $Config{'d_flock'} eq 'define') or
173    #   ($Config{'d_fcntl_can_lock'} && $Config{'d_fcntl_can_lock'} eq 'define'))
174    if ($^O ne "MSWin32")
175    {
176        # it's a sane OS and flock is there
177        $self->set('flock_available',1);
178    } else {
179        print "! 'flock' not available. Do not run concurrent uploads\n";
180        $self->set('flock_available',0);
181    }
182
183    #------
184    # check a correct pngoptimizer is set
185    if ( ! (($self->get("PngOptimizer") eq "pngcrush") or ($self->get("PngOptimizer") eq "optipng")))
186    {
187        die("! Can't find valid PngOptimizer setting, check config");
188    }
189
190    #------
191    # Check pngcrush version
192    if ($self->get("PngOptimizer") eq "pngcrush")
193    {
194        # PNGCrush version
195        $cmd = $self->get("Pngcrush");
196        my $PngcrushV = `\"$cmd\" -version`;
197
198        if ($PngcrushV !~ /[Pp]ngcrush\s+(\d+\.\d+\.?\d*)/)
199        {
200            print "! Can't find pngcrush (using \"".$self->get("Pngcrush")."\")\n";
201        }
202        else
203        {
204            print "- Pngcrush version $1\n";
205        }
206    }
207    #------
208    # check optipng version
209    if ($self->get("PngOptimizer") eq "optipng")
210    {
211        # Optipng version
212        $cmd = $self->get("Optipng");
213        my $OptipngV = `\"$cmd\" -v`;
214
215        if ($OptipngV !~ /[Oo]pti[Pp][Nn][Gg]\s+(\d+\.\d+\.?\d*)/) 
216        {
217            die("! Can't find OptiPNG (using \"".$self->get("Optipng")."\")\n");
218        }
219        else
220        {
221            print "- OptiPNG version $1\n";
222        }
223    }
224    #------
225    # check pngnq version
226    if ( $self->get("PngQuantizer") eq "pngnq" )
227    {
228        $cmd = $self->get("pngnq");
229        my $PngnqV=`\"$cmd\" -V 2>&1`;
230        if ($PngnqV !~ /pngnq.+(\d+(\.\d+)+)/)
231        {
232            print "! Can't find pngnq (using \"".$self->get("pngnq")."\")\n";
233            print "! disabling pngnq\n";
234            $self->set("PngQuantizer", undef);
235        }
236        else
237        {
238            my $minVersion = "0.5";
239            if ($self->CompareVersions($1, $minVersion) == -1) {
240                print "! pngnq version ${1} too low, needs to be at least ${minVersion}\n";
241                print "! disabling pngnq\n";
242                $self->set("PngQuantizer", undef);
243            } else {
244                print "- pngnq version $1\n";
245            }
246        }
247    } else {
248        print "! no valid PngQuantizer specified\n";
249    }
250    #------
251    # check java version and path separator
252    my @javaInfo = split(/\n/,`java -cp java TestJava`);
253    $self->set("JavaAvailable", $javaInfo[0] eq "JAVATEST");
254    if ($self->get("JavaAvailable"))
255    {
256       $self->set("JavaVersion", $javaInfo[1]);
257       $self->set("JavaSeparator", $javaInfo[2]);
258       print "- Java version $javaInfo[1] is available\n";
259    } 
260    else 
261    {
262       $self->set("JavaVersion", 0);
263       $self->set("JavaSeparator", ":");
264       print "- Java is not available\n";
265    }
266
267    return %EnvironmentInfo;
268
269}
270
271#--------------------------------------------------------------------------
272# Checks a tiles@home configuration which is needed for rendering
273#--------------------------------------------------------------------------
274sub CheckConfig
275{
276    my $self = shift;
277    my $cmd;
278
279    my %EnvironmentInfo = $self->CheckBasicConfig();
280
281    if (!defined($self->get("Layers")))
282    {
283        die("no layers configured");
284    }
285
286    # Rendering through Omsarender/XSLT or or/p
287    if ($self->get("Osmarender") eq "XSLT")
288    {
289        print "- rendering using Osmarender/XSLT\n";
290        die "! Can't find osmarender/xslt/osmarender.xsl" unless (-f "osmarender/xslt/osmarender.xsl");
291
292        # XmlStarlet version
293        $cmd=$self->get("XmlStarlet");
294        my $XmlV = `\"$cmd\" --version`;
295        $EnvironmentInfo{Xml}=$XmlV;
296
297        if($XmlV !~ /(\d+\.\d+\.\d+)/) {
298            die("Can't find xmlstarlet (using \"" . $self->get("XmlStarlet") . "\")\n");
299        }
300        print "- xmlstarlet version $1\n";
301    }
302    elsif ($self->get("Osmarender") eq "orp")
303    {
304        print "- rendering using or/p\n";
305        die "! Can't find osmarender/orp/orp.pl" unless (-f "osmarender/orp/orp.pl");
306    }
307    else
308    {
309        die "! invalid configuration setting for 'Osmarender' - allowed values are 'XSLT', 'orp'";
310    }
311
312    if( ! $self->get('Rasterizer') && $self->get('Batik') ){
313        warn "Deprecated configuration variable Batik found, use Rasterizer instead. For now it will be mapped\n";
314        if( $self->get('Batik') == 1 || $self->get('Batik') == 2 ){
315            $self->set('Rasterizer', 'Batik');
316        } elsif( $self->get('Batik') == 3 ){
317            $self->set('Rasterizer', 'BatikAgent');
318        }
319    }
320
321    if ( $self->get("Rasterizer") eq "Inkscape" )
322    {
323        $cmd = $self->get("inkscape");
324        my $InkscapeV=`\"$cmd\" -V 2>&1`;
325        $InkscapeV =~ /Inkscape.(\d+(\.\d+)+)/;
326        my $minVersion = "0.46";
327        if ($self->CompareVersions($1, $minVersion) == -1 and not $self->get("RenderStripes")) {
328            print "! Inkscape version ${1} too low, needs to be at least ${minVersion} for RenderStripes=0 setting\n";
329        }
330        else 
331        {
332            print "- Inkscape version $1\n";
333        }
334    }
335
336
337    #-------------------------------------------------------------------
338    # check all layers for existing and sane values
339    #------------------------------------------------------------------
340    foreach my $layer(split(/,/, $self->get("LayersCapability")))
341    {
342        if ($self->get($layer."_MaxZoom") < $self->get($layer."_MinZoom"))
343        {
344            die " ! Check MinZoom and MaxZoom for section [".$layer."]\n";
345        } 
346
347        for(my $zoom=$self->get($layer."_MinZoom"); $zoom<=$self->get($layer."_MaxZoom"); $zoom++)
348        {
349            if (!defined($self->get($layer."_Rules.$zoom")))
350            {
351                die " ! config option Rules.".$zoom." is not set for layer".$layer;
352            }
353            if (!-f $self->get($layer."_Rules.".$zoom))
354            {
355                die " ! rules file ".$self->get($layer."_Rules.".$zoom).
356                    " referenced by config option Rules.".$zoom." in section [".$layer."]".
357                    "is not present";
358            }
359        }
360
361        if (!defined($self->get($layer."_Prefix")))
362        {
363            die " ! config option \"Prefix\" is not set for layer ".$layer;
364        }
365
366        if (!defined($self->get($layer."_Transparent")))
367        {
368            die($layer.": Transparent not configured");
369        }
370
371        if (!defined($self->get($layer."_RenderFullTileset")))
372        {
373            die($layer.": RenderFullTileset not configured");
374        }
375
376        if (!defined($self->get($layer."_Preprocessor")))
377        {
378            die(" ! config option \"Preprocessor\" is not set for layer ".$layer);
379        }
380
381        # any combination of comma-separated preprocessor names is allowed
382        die "config option Preprocessor has invalid value in section [".$layer."]" 
383            if (grep { $_ !~ /maplint|close-areas|autocut|noop|area-center/} split(/,/, $self->get($layer."_Preprocessor")));
384
385        foreach my $reqfile(split(/,/, $self->get($layer."_RequiredFiles")))
386        {
387            die " ! file $reqfile required for layer $layer as per config option ".
388                "RequiredFiles in section [".$layer."] not found" unless (-f $reqfile);
389        }
390
391    }
392
393    if($self->get("RequestUrl")){ 
394        ## put back Verbose output to make remote debugging a bit easier
395        print "- Using ".$self->get("RequestUrl")." for Requests\n" if($self->get("Verbose") >=10); 
396    }
397
398    # Misc stuff
399    foreach(qw(NS WE)){
400        if($self->get("Border".$_) > 0.5){
401            printf "Border".$_." looks abnormally large\n";
402        }
403    }
404    return %EnvironmentInfo;
405
406}
407
408#--------------------------------------------------------------------------
409# internal helper function to compare two version numbers
410# works only for dotted numerical numbers like 'x.yy.zz'
411# returns -1 when first is lower, 0 when equal and 1 when first is higher
412#--------------------------------------------------------------------------
413sub CompareVersions {
414    my $self = shift;
415    my ($version1, $version2) = @_;
416    my @v1 = split(/\./, $version1);
417    my @v2 = split(/\./, $version2);
418    for (my $i = 0; ($i <= scalar @v1 - 1) or ($i <= scalar @v2 - 1); $i++) {
419        if ($v1[$i] < $v2[$i]) {
420            return -1;
421        }
422        if ($v1[$i] > $v2[$i]) {
423            return 1;
424        }
425    }
426    return 0;
427}
428
4291;
Note: See TracBrowser for help on using the repository browser.