source: subversion/applications/share/map-icons/create_overview.pl @ 6675

Last change on this file since 6675 was 6507, checked in by joerg, 12 years ago

map-icons/create_overview.pl: better wording, use one column on right top corner

  • Property svn:executable set to *
File size: 17.6 KB
Line 
1#!/usr/bin/perl
2#####################################################################
3#
4#  This script handles the XML-Files for the POI-Types in gpsdrive.
5#  It has to be run from the data directory.
6
7#  Default actions, when no options are given:
8#  - Create overview.html from the XML-File to show all
9#    available poi_types and icons.
10
11#use diagnostics;
12use strict;
13use warnings;
14
15use utf8;
16use IO::File;
17use File::Find;
18use Getopt::Std;
19use Pod::Usage;
20use File::Basename;
21use File::Copy;
22use File::Path;
23use Data::Dumper;
24use XML::Simple;
25use Image::Info;
26use Cwd;
27
28our ($opt_b, $opt_h, $opt_i, $opt_j, $opt_l, $opt_n, $opt_p, $opt_r,$opt_s,$opt_v, $opt_D, $opt_F, $opt_L, $opt_P,$opt_S) = 0;
29getopts('bhijlnprsvF:D:L:P:S:') or $opt_h = 1;
30pod2usage( -exitval => '1', 
31           -verbose => '1') if $opt_h;
32
33$opt_b ||=0;
34my $cwd = cwd;
35my $languages = $opt_L || "en,de";
36my $base_dir = $opt_D || cwd;
37my $file_xml = $opt_F || './icons.xml';
38my $i = 0;
39my $poi_reserved = 30;
40my $poi_type_id_base = $poi_reserved;
41my $VERBOSE = $opt_v;
42$opt_P ||= "overview";
43
44my @ALL_TYPES = qw(square.big square.small classic.big classic.small svg japan );
45
46my $SVN_STATUS={};
47my $SVN_VERSION = '';
48
49my $svn_status2color={
50    "_" =>'',
51    "?" => "blue",
52    "M" => "green",
53    "D" => "red",
54    "C" => "purple",
55    "derived" => "#E5E5E5",
56};
57
58sub html_head($);
59sub get_svn_status($);
60sub update_overview($$);
61
62#####################################################################
63#
64#  M A I N
65#
66#
67unless (-e $file_xml)
68{
69  create_xml(); # Create a new XML-File if none exists
70}
71my $svn_base_dir = $opt_S;
72if ( ! $svn_base_dir ){
73    $svn_base_dir= $base_dir ;
74    $svn_base_dir =~ s,(/build|build/|build),,;
75}
76get_svn_status($svn_base_dir);
77
78my $rules = XMLin("$file_xml",ForceArray => ['description','title','condition']);
79my @rules=@{$rules->{rule}};
80
81
82for my $lang ( split ( ",", $languages)){
83    update_overview($lang,\@rules);      # update html overview from XML-File
84}
85
86exit (0);
87
88##################################################################
89# Get the licence from a svg File
90# RETURNS:
91#     'PD' for PublicDomain
92#     '?'  if unknown
93sub get_svg_license($){
94    my $icon_file=shift;
95    my $icon = XMLin($icon_file,ForceArray => ['description','title','condition']);
96    my $license = $icon->{'metadata'}->{'rdf:RDF'}->{'cc:Work'}->{'cc:license'}->{'rdf:resource'};
97    #print Dumper(\$license);
98    return "?" unless $license;
99    return "PD" if $license eq "http://web.resource.org/cc/PublicDomain";
100    $license =~ s,http://creativecommons.org/licenses/LGPL/?,LGPL-,;
101    return $license;
102}
103
104sub get_png_license($){
105    my $filename = shift;
106    my $comment = get_png_comment($filename);
107    return "?" unless $comment;
108    $comment =~ s/Created with The GIMP//;
109    $comment =~ s,Created with Inkscape \(http://www.inkscape.org/\),,;
110    $comment =~ s,Generator: Adobe Illustrator 10.0\, SVG Export Plug-In \. SVG Version: [\d\.]+ Build \d+\),,g;
111    $comment =~ s/^\s*//g;
112    $comment =~ s/\s*$//g;
113    $comment =~ s,http://creativecommons.org/licenses/LGPL/?,LGPL-,;
114       
115    print "Comment($filename): $comment\n" if $VERBOSE && $comment;
116    return "PD" if $comment =~ m/Public.*Domain/i;
117    return "?" unless $comment;
118    return $comment if $comment && $comment =~ m/license/;
119}
120
121# Get Comment Field from a PNG
122sub get_png_comment($){
123    my $filename = shift;
124    my ($s1,$s2)=Image::Info::image_info($filename);
125    my $comment = $s1->{'Comment'};
126}
127
128#####################################################################
129#
130# Get the "svn status" for all icons Files
131#
132sub get_svn_status($) {
133    my $svn_base_dir = shift;
134
135    return unless $opt_s || $opt_n;
136
137    $SVN_VERSION = `svnversion $svn_base_dir`;
138    chomp($SVN_VERSION);
139    $SVN_VERSION =~ s/M//;
140    my $svn_status = `svn -v status $svn_base_dir`;
141    for my $line (split(/[\r\n]+/,$svn_status)) {
142        chomp $line;
143        $line =~ s/^ /_/;
144        $line =~ s,$svn_base_dir/,,;
145        my ($status,$rev,$rev_ci,$user,$file) = (split(/\s+/,$line),('')x5);
146        if ( $status eq "?" ) {
147            $file = $rev; 
148            $rev ='';
149        }
150        $SVN_STATUS->{$file}="$status,$rev,$rev_ci,$user";
151        #print STDERR "SVN STATUS: $status,$rev,$rev_ci,$user   '$file'\n" if $VERBOSE;
152    }
153}
154
155sub html_head($){
156    my $lang = shift;
157    # html 'template'
158    my $html_head =
159        "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\"\n".
160        "  \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n".
161        "<html xmlns=\"http://www.w3.org/1999/xhtml\" lang=\"en\" ".
162        "xml:lang=\"en\">\n".
163        "<head>\n".
164        "<meta http-equiv=\"Content-Type\" ".
165        "content=\"text/html; charset=utf-8\" />\n".
166        "\n".
167        "<title>Available POI-Types in gpsdrive</title>\n".
168        "<style type=\"text/css\">\n".
169        "       table            { width:100%;  background-color:#fff8B2; }\n".
170        "       tr               { border-top:5px solid black; }\n".
171        "       tr.id            { background-color:#6666ff; color:white; font-weight:bold; }\n".
172        "       td.id            { text-align:right; vertical-align:top;}\n".
173        "       td.icon          { text-align:center; vertical-align:top;}\n".
174        "       td.status        { text-align:left; vertical-align:top;}\n".
175        "       td.empty         { text-align:center; height:32px; }\n".
176        "       img.square_big   { width:32px; height:32px; }\n".
177        "       img.square_small { width:16px; height:16px; }\n".
178        "       img.classic      { max-height:32px; }\n".
179        "       img.svg          { max-height:32px; }\n".
180        "       img.japan        { max-height:32px; }\n".
181        "       span.desc        { font:x-small italic condensed }\n".
182        "</style>\n".
183        "</head>\n";
184    $html_head .= "<body>\n";
185   
186    # Legende
187    $html_head .= "<table border=\"1\">\n";
188    $html_head .= "<tr>\n";
189    if ( 1 ) { # Content with links
190        $html_head .= "<td valign=\"top\">\n";
191        if ( $lang eq "de" ) {
192            $html_head .= "<h3>Kategorien</h3>\n";
193        } else {
194            $html_head .= "<h3>Categories</h3>\n";
195        }
196        $html_head .= "<ul>\n";
197        #for my $rule (@{$rules}) {
198        for my $top_level ( # XXX This List should not be hardcoded !!!!!!
199                            sort qw(accommodation  food incomming  nautical  public shopping transport waypoint
200           education      geocache  misc       people    recreation  sightseeing  unknown    wlan
201           empty          health    money      places    religion    sports       vehicle)
202            ) {
203            $html_head .= "     <li><a href=\"\#$top_level\">$top_level</a></li>\n";
204        }
205        $html_head .= "</ul>\n";
206        $html_head .= "</td>\n";
207    }
208
209    $html_head .= "\n";
210    $html_head .= "<td valign=\"top\">\n";
211
212    $html_head .= "\n";
213    $html_head .= "<table border=\"1\">\n";
214    $html_head .= "<td valign=\"top\">\n";
215    $html_head .= "<a href=\"overview.en.html\">Without License Info in English</a><br/>\n";
216    $html_head .= "<a href=\"overview.de.html\">Without License Info in German</a><br/>\n";
217    $html_head .= "<a href=\"overview_lic.en.html\">With License Info in English</a><br/>\n";
218    $html_head .= "<a href=\"overview_lic.de.html\">With License Info in German</a><br/>\n";
219    $html_head .= "</td>\n";
220    $html_head .= "</table>\n";
221
222    if ( $opt_l ) { # Add license Information
223        $html_head .= "<table border=\"1\">\n";
224        $html_head .= "<tr><td><font color=\"green\">lic:PD</font></td> <td>Public Domain License</td></tr>\n";
225        $html_head .= "<tr><td><font color=\"green\">lic:LGPL</font></td> <td>LGPL</td></tr>\n";
226        $html_head .= "<tr><td><font color=\"purple\">lic:?</font></td> <td>No license information available about this icon</td></tr>\n";
227        $html_head .= "<tr><td><font color=\"red\">lic:</font></td> <td>License has no known/predefined category</td></tr>\n";
228        $html_head .= "</table>\n";
229#       $html_head .= "</td>\n";
230        }
231    $html_head .= "\n";
232    if ( $opt_s ) { # Add SVN Status Information
233#       $html_head .= "<td valign=\"top\">\n";
234        $html_head .= "<table border=\"1\">\n";
235        for my $status ( keys %{$svn_status2color} ) {
236            $html_head .= "<tr><td bgcolor=\"$svn_status2color->{$status}\">SVN Status $status</td></tr>\n";
237        }
238        $html_head .= "</table>\n";
239        }
240
241
242    $html_head .= "</td>\n";
243    $html_head .= "</tr>\n";
244    $html_head .= "</table>\n";
245    $html_head .= "\n";
246    $html_head .= "\n";
247
248
249    $html_head .= "<table border=\"$opt_b\">\n";
250    $html_head .= "  <tr>";
251    $html_head .= "    <th>ID</th>" if $opt_j;
252    $html_head .= "    <th>Name</th>\n";
253    $html_head .= "    <th>Path</th>\n" if $opt_p;
254    $html_head .= "    <th colspan=\"".(2*scalar(@ALL_TYPES))."\">Icons</th>\n";
255    $html_head .= "    <th>Description</th>\n";
256    $html_head .= "    <th>condition</th>\n";
257    $html_head .= "  </tr>\n";
258    return $html_head;
259}
260
261# Header with a list of all types used in one <tr> line
262sub all_type_header(){
263    my $all_type_header= "<tr>";
264    $all_type_header .= "<td></td>" if $opt_j;
265    $all_type_header .= " <td></td>";
266    $all_type_header .= " <td></td>\n" if $opt_p;
267    for my $type ( @ALL_TYPES  ) {
268        my $txt=$type;
269        $txt=~s/\.$//;
270        $txt=~s/\./<br>/;
271        $all_type_header .= "  <td  colspan=\"2\" valign=\"top\"><font size=\"-3\">$txt</font></td>\n";
272#       $all_type_header .= " <td></td>";
273    }
274    $all_type_header .= " <td></td>\n";
275    $all_type_header .= " <td></td>\n";
276    $all_type_header .= " <td></td>\n";
277    $all_type_header .= " </tr>\n\n";
278    return $all_type_header;
279}
280
281#####################################################################
282#
283#  Update HTML Overview of available Icons and POI-Types
284#
285#
286sub update_overview($$){
287    my $lang  = shift || 'en';
288    my $rules = shift;
289    my $file_html = "$base_dir/${opt_P}.${lang}.html";
290
291    print STDOUT "----- Updating HTML Overview '$file_html' -----\n";
292   
293    my %out;
294
295    my $ID_SEEN={};
296    for my $rule (@{$rules}) {
297        #print Dumper(\$rule);
298        my $content = '';
299        my $id = $rule->{'geoinfo'}->{'poi_type_id'};
300        my $nm = $rule->{'geoinfo'}->{'name'};
301        my $restricted = $rule->{'geoinfo'}->{'restricted'};
302
303        if ( $ID_SEEN->{$id} ){
304            die "$id was already seen at $ID_SEEN->{$id}. Here in $nm\n";
305        };
306        $ID_SEEN->{$id}=$nm;
307
308        if ( $restricted && not $opt_r ){
309            next;
310        }
311
312        my $title='';
313        for my $t ( @{$rule->{'title'}||[]} ){
314            $title = $t->{content}
315            if $t->{'lang'} eq $lang && $t->{content};
316        }
317       
318        my $descr ='';
319        for my $d (@{$rule->{'description'}}) {
320            my $c = $d->{content};
321            if ($d->{'lang'} eq $lang && $c) {
322                $descr = '<span class="desc">&nbsp;&nbsp;'.$c.'</span>';
323            }
324        }
325       
326        my $conditions='';
327        for my $c (@{$rule->{'condition'}}) {
328            next if $c->{k} eq "poi";
329            $conditions .= "$c->{k}=$c->{v}<br>";
330        }
331
332        my $icon = $nm;
333        my $ind = $nm;
334
335        # accentuate base categories
336        my $header_line=0;
337        if ($id <= $poi_reserved || ( $icon !~ m,\.,) ) {
338            $content .= "  <tr><td>&nbsp;</td></tr>\n";
339            $content .=     all_type_header();
340            $content .= "  <tr class=\"id\">\n";
341            $content .= "     <td class=\"id\">$id</td>\n" if $opt_j;
342            $content .= "     <td>&nbsp;<a name=\"$nm\">$nm</a></td>\n";
343            $header_line++;
344        } else {
345            my $level = ($icon =~ tr,\.,/,);
346            my $html_space = '';
347            while ($level)
348            { $html_space .='&nbsp;&nbsp;&nbsp;&nbsp;&rsaquo;&nbsp;'; $level--; };
349            $nm =~ s,.*\.,,g;
350            $content .= "<tr>\n";
351            $content .= "    <td class=\"id\">$id</td>" if $opt_j;
352            $content .= "    <td>&nbsp;$html_space$nm</td>\n";
353        }
354
355        # Add filename+path column
356        $content .= "<td><font size=-4>$icon</font></td>\n" 
357            if $opt_p;
358
359        # display all icons
360        for my $type ( @ALL_TYPES  ) {
361            my $icon_s = "${type}/$icon.svg";
362            my $icon_p = "${type}/$icon.png";
363            my $icon_t = "${type}_png/${icon}.png";
364            my $class = $type;
365            $class =~ s/\./_/g;
366
367            my $icon_path_current;
368            if ( -s "$base_dir/$icon_t" ) { $icon_path_current = $icon_t; }
369            else {              $icon_path_current = $icon_p;   };
370            my $icon_path_svn="$svn_base_dir/$icon_path_current";
371            $icon_path_svn =~ s,/([^/]+)\.(...)$,/.svn/text-base/$1.$2.svn-base,;
372
373            my $svn_bgcolor='';
374            my $status_line = $SVN_STATUS->{$icon_s};
375            $status_line ||= $SVN_STATUS->{$icon_p};
376            $status_line ||= '';
377            my ($status,$rev,$rev_ci,$user,$file) =
378                (split(/,/, $status_line),('')x5);
379            print STDERR "svn_status($icon_p): '$status_line'\n" if $VERBOSE;
380           
381            #print STDERR "svn_status($icon_p)[$icon_path_svn]: '$status'\n" if $VERBOSE;
382            if ( $status eq "" ) {
383                if ( -$icon_path_svn # Im original svn Verzeichnis
384                     || -s "$icon_s"
385                     || -s "$icon_p"
386                     || -s "$icon_t"
387                     ) {
388                    $svn_bgcolor='';
389                } else {
390                    $status = "derived";
391#                   $svn_bgcolor=' bgcolor="#E5E5E5" ';
392                }
393            } 
394            if ( $svn_status2color->{$status}  ) { 
395                $svn_bgcolor=" bgcolor=\"$svn_status2color->{$status} \" ";
396            } else {
397#               $svn_bgcolor=' bgcolor="red" ';
398            }
399           
400            $content .=  "    <td ";
401            my $empty= ! ( -s "$base_dir/$icon_p" or -s "$base_dir/$icon_s");
402            if ( $empty && ! $status  ){
403                $svn_bgcolor='';
404            }
405            if ( $empty ) { # exchange empty or missing icon files with a char for faster display
406                $content .=  " class=\"empty\" " unless $header_line;
407                $content .=  $svn_bgcolor;
408                $content .=  " >";
409            } elsif ( $restricted && not $opt_r ){
410                $content .=  " class=\"empty\" " unless $header_line;
411                $content .=  $svn_bgcolor;
412                $content .=  " >";
413            } else {
414                $content .=  " class=\"icon\" " unless $header_line;
415                $content .= $svn_bgcolor;
416                $content .=  " >";
417            }
418
419            if ( $opt_s && $status ) { # modified icons .... we show old icon too
420                $content .= "    <img src=\"$icon_path_svn\" /> ==> " 
421                    if -s $icon_path_svn && $status =~ "M|D";
422            }
423            if ( $empty ) { # exchange empty or missing icon files with a char for faster display
424                $content .=  ".";
425            } elsif ( $restricted && not $opt_r ){
426                $content .=   "r";
427            } else {
428                if ( -s "$base_dir/$icon_path_current" ){
429                    $content .= "     <a href=\"$icon_path_current\" >";
430                    $content .= "         <img title=\"$nm\" src=\"$icon_path_current\" class=\"$class\" alt=\"$nm\" />";
431                    $content .= "</a>";
432                }
433            }
434            $content .= "</td>\n";
435
436
437            # Status Column
438            $content .= "<td class=\"status\">\n";
439
440            # -------------- Add license Information
441            if ( ! $empty && $opt_l ) {
442                my $license='';
443                if ( -s "$icon_s"  ) {
444                    $license = get_svg_license($icon_s);
445                } elsif ( -s "$icon_p" ) {
446                    $license = get_png_license($icon_p);
447                }
448                my $lic_color=' color="red" ';
449                $lic_color = ' color="purple" ' if $license eq "?";
450                $lic_color = ' color="green" ' if $license eq "PD";
451                $lic_color = ' color="green" ' if $license =~ m/^LGPL/;
452                $content .= "<font $lic_color size=\"-2\">lic:$license</font><br/>";
453                print "License($type/$icon): $license\n"
454                    if $VERBOSE && $license && $license ne "?";
455            }
456
457            # ----------- add SVN Status Info
458            if ( ($opt_s || $opt_n)&& $status ) {
459                #$status_line =~ s/guenther/g/;
460                #$status_line =~ s/joerg/j/;
461                #$status_line =~ s/ulf/u/;
462                #$status_line =~ s/$SVN_VERSION//;
463                $content .= "<font size=\"-3\">";
464                $content .= "svn:$status<br>\n" if $opt_s && $status;
465                $content .= "$user<br>\n";
466                $content .= "rev: $rev_ci" if $rev_ci;
467                $content .= "</font>";
468            }
469
470            $content .= "</td>\n";
471        }
472        $content .= "    <td>$title<br>$descr</td>\n";
473        $content .= "    <td><font size=-1>$conditions</font></td>\n";
474        $content .= "  </tr>\n";
475        $out{$ind} = $content;
476    } 
477
478    # create backup of old overview.html
479
480    my $fo = IO::File->new(">$file_html");
481    $fo ||die "Cannot write to '$file_html': $!\n";
482    $fo->binmode(":utf8");
483    print $fo html_head($lang);
484    # sorted output
485    foreach ( sort keys(%out) )  {
486        print $fo $out{$_};
487    }
488
489    print $fo "</table>\n";
490    if ( $opt_i ) {
491        print $fo "<h3>Incomming Directories</h3>\n";
492       
493        for my $theme ( @ALL_TYPES ) {
494            my $ext = "png";
495            $ext = "svg" if $theme =~ m/svg|japan/;
496            print $fo "<br>\n";
497            print $fo "Incomming for $theme\n";
498            print $fo "<table border=\"1\">\n";
499            print $fo "<tr>\n";
500            my $count=0;
501            print STDERR "glob($theme/incomming/*.$ext)\n";
502            for my $icon ( glob("$theme/incomming/*.$ext" ) ){
503                print STDERR "$icon\n" if $VERBOSE;
504                my $name = $icon;
505                $name =~ s/.*\/incomming\///;
506                $name =~ s/\.(svg|png)$//;
507                my $icon_t = $icon;
508                $icon_t =~ s/\//_png\//;
509                $icon_t =~ s/\.svg/\.png/;
510                print STDERR "thumb: $icon_t\n" if $VERBOSE;
511                $icon_t = $icon unless -s $icon_t;
512                my $content = "     <a href=\"$icon_t\" >";
513                $content .= "         <img alt=\"$icon\" title=\"$icon\" src=\"$icon_t\" />";
514                $content .= "<br/>$name\n";
515                $content .= "</a>\n";
516                print $fo "    <td>$content</td>";
517
518                if ( $count++ > 5) {
519                    $count=0;
520                    print $fo "</tr><tr>\n";
521                }
522            }
523            print $fo "</tr>\n";
524            print $fo "</table>\n";
525
526        }
527    }
528    print $fo "\n</body>\n</html>";
529    $fo->close();
530    return;
531
532}
533
534
535__END__
536
537
538=head1 SYNOPSIS
539 
540create_overview.pl [-h] [-v] [-i] [-r] [-s] [-F XML-FILE] [-D DIR] [-P FILENAME_PREFIX]
541 
542=head1 OPTIONS
543 
544=over 2
545 
546=item B<--h>
547
548Show this help
549
550=item B<-F> XML-FILE
551
552Set file, that holds all the necessary icon and poi_type information.
553The default file is 'icons.xml'.
554
555=item B<-D> DIRECTORY
556
557The directory to search for the icons. Default it CWD (./)
558
559=item B<-v>
560
561Enable verbose output
562
563=item B<-i>
564
565Add incomming directory to the end of the
566overview.*.html file.
567
568=item B<-j>
569
570show internal gpsdrive-mysql id in html page
571
572=item B<-l>
573
574Add licence to overview where known (Currently only svg)
575
576=item B<-r>
577
578Include restricted icons in overview.html
579
580=item B<-p>
581
582Show path of Filename
583
584=item B<-b>
585
586Add Border to Table
587
588=item B<-s>
589
590 add svn status to overview
591    grey is missing in svn
592    green is modified
593    red is any other condition
594 this also shows the old and new icon if it is found in the
595 .svn/ directory
596
597If the working path ends with /build this is truncated, since
598I expect the real svn co one level above.
599
600=item B<-n>
601
602Show the svn revision numbers and user too
603This needs option -s to work
604
605=item B<-L language>
606
607Update only this language. Default is en,de
608
609=item B<-P FILENAME-PREFIX>
610
611Use this for the filename Prefix. Default: overview
612
613=item B<-S SVN-BASE>
614
615Use the Directory  SVN-BASE as Base for determining SVN Status
616
617=back
Note: See TracBrowser for help on using the repository browser.