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

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

merge changes to inkscape check in stable and unstable

File size: 14.2 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    my $rasterizer = $self->get("Rasterizer");
322    if ( $rasterizer =~ /inkscape/i )
323    {
324        $cmd = $self->get("inkscape"); # this config parameter is deprecated and not present in newer installations
325                                       # http://trac.openstreetmap.org/ticket/1286
326
327        # Fall back un 'inkscape' if the inkscape variable isn't
328        # defined, in the config. As is the case in some
329        # installations.
330        $cmd = 'inkscape' unless defined $cmd;
331
332        my $InkscapeV=`\"$cmd\" -V 2>&1`;
333        $InkscapeV =~ /Inkscape.(\d+(\.\d+)+)/;
334
335        my $minVersion = "0.46";
336
337        if ( $InkscapeV eq '' )
338        {
339            print "* Could not determine your inkscape version\n";
340            print "* You need at least version ${minVersion} for RenderStripes=0 setting\n" unless $self->get("RenderStripes");
341        }
342        elsif ($self->CompareVersions($1, $minVersion) == -1 and not $self->get("RenderStripes")) 
343        {
344            print "! Inkscape version ${1} too low, needs to be at least ${minVersion} for RenderStripes=0 setting\n";
345        }
346        else 
347        {
348            print "- Inkscape version $1\n";
349        }
350    }
351
352
353    #-------------------------------------------------------------------
354    # check all layers for existing and sane values
355    #------------------------------------------------------------------
356    foreach my $layer(split(/,/, $self->get("LayersCapability")))
357    {
358        if ($self->get($layer."_MaxZoom") < $self->get($layer."_MinZoom"))
359        {
360            die " ! Check MinZoom and MaxZoom for section [".$layer."]\n";
361        } 
362
363        for(my $zoom=$self->get($layer."_MinZoom"); $zoom<=$self->get($layer."_MaxZoom"); $zoom++)
364        {
365            if (!defined($self->get($layer."_Rules.$zoom")))
366            {
367                die " ! config option Rules.".$zoom." is not set for layer".$layer;
368            }
369            if (!-f $self->get($layer."_Rules.".$zoom))
370            {
371                die " ! rules file ".$self->get($layer."_Rules.".$zoom).
372                    " referenced by config option Rules.".$zoom." in section [".$layer."]".
373                    "is not present";
374            }
375        }
376
377        if (!defined($self->get($layer."_Prefix")))
378        {
379            die " ! config option \"Prefix\" is not set for layer ".$layer;
380        }
381
382        if (!defined($self->get($layer."_Transparent")))
383        {
384            die($layer.": Transparent not configured");
385        }
386
387        if (!defined($self->get($layer."_RenderFullTileset")))
388        {
389            die($layer.": RenderFullTileset not configured");
390        }
391
392        if (!defined($self->get($layer."_Preprocessor")))
393        {
394            die(" ! config option \"Preprocessor\" is not set for layer ".$layer);
395        }
396
397        # any combination of comma-separated preprocessor names is allowed
398        die "config option Preprocessor has invalid value in section [".$layer."]" 
399            if (grep { $_ !~ /maplint|close-areas|autocut|noop|area-center/} split(/,/, $self->get($layer."_Preprocessor")));
400
401        foreach my $reqfile(split(/,/, $self->get($layer."_RequiredFiles")))
402        {
403            die " ! file $reqfile required for layer $layer as per config option ".
404                "RequiredFiles in section [".$layer."] not found" unless (-f $reqfile);
405        }
406
407    }
408
409    if($self->get("RequestUrl")){ 
410        ## put back Verbose output to make remote debugging a bit easier
411        print "- Using ".$self->get("RequestUrl")." for Requests\n" if($self->get("Verbose") >=10); 
412    }
413
414    # Misc stuff
415    foreach(qw(NS WE)){
416        if($self->get("Border".$_) > 0.5){
417            printf "Border".$_." looks abnormally large\n";
418        }
419    }
420    return %EnvironmentInfo;
421
422}
423
424#--------------------------------------------------------------------------
425# internal helper function to compare two version numbers
426# works only for dotted numerical numbers like 'x.yy.zz'
427# returns -1 when first is lower, 0 when equal and 1 when first is higher
428#--------------------------------------------------------------------------
429sub CompareVersions {
430    my $self = shift;
431    my ($version1, $version2) = @_;
432    my @v1 = split(/\./, $version1);
433    my @v2 = split(/\./, $version2);
434    for (my $i = 0; ($i <= scalar @v1 - 1) or ($i <= scalar @v2 - 1); $i++) {
435        if ($v1[$i] < $v2[$i]) {
436            return -1;
437        }
438        if ($v1[$i] > $v2[$i]) {
439            return 1;
440        }
441    }
442    return 0;
443}
444
4451;
Note: See TracBrowser for help on using the repository browser.