From: David H. <dav...@st...> - 2009-02-17 09:37:16
|
On 17/02/2009, at 7:56 AM, Jamie Cameron wrote: > Assuming you just want to cache all images and .js files, you could > build a full list with code like : > > open(FIND, "find $root_directory -type f -name '*.{gif,png,jpg,js}' > |"); > while($file = <FIND>) { > chop($file); > $file =~ s/^\Q$root_directory\E//; > $file = $gconfig{'webprefix'}.$file; > $manifest .= "{ \"url\" : \"$file\" },"; > } > print $manifest; > > Does that help? Thanks Jamie, Based on the snippet you provided I've built a far more flexible manifest generation script. I chose to use File::Find rather than the command line 'find' tool as it seemed to keep me more platform neutral. Now rather than caching just a couple of hundred files all of a Webmin installs static content (excluding other themes) is cached. For my test Webmin installation this turned out to be 2,400-odd files. I've had to do a bit of a quick hack job on the init_config function in order to get around the referrer check. This is due to Gears operating as a separate process and not including any referrer details when making the manifest request. What I've done probably isn't that efficient, but for what's required it seems to do the trick :-) David theme-stressfree/manifest.cgi ---------------------------------------- #!/usr/bin/perl use File::Find; ########################################################################### # # Email: dav...@st... # Internet: http://www.stress-free.co.nz # # Javascript version originally contributed by Dwi Kristianto # ########################################################################### do './web-lib.pl'; init_manifest_config(); my @themes = &list_themes(); my $manifest; File::Find::find( {wanted => \&wanted}, $root_directory); if (length $manifest > 0) { chop $manifest; } my $manifestfile = $root_directory . "/theme-stressfree/manifest.cgi"; my $write_secs = (stat($manifestfile))[9]; print "Content-type: text/javascript\n\n"; print "{\n"; print "\"betaManifestVersion\" : 1,\n"; print "\"version\" : \"wmg-$write_secs\",\n"; print "\"entries\" : ["; print $manifest; print "\n]}"; sub wanted { if ((/\.jpg$/) || (/\.png$/) || (/\.gif$/) || (/\.js$/) || (/\.css $/) || (/\.htc$/) ){ my $file = $File::Find::name; $file =~ s/^\Q$root_directory\E//; foreach $theme (@themes) { if ($file =~ m/^\/$theme/) { return }; } $file = $gconfig{'webprefix'}.$file; $manifest .= "\n{ \"url\" : \"$file\" },"; } } sub list_themes { local @rv; opendir(DIR, $root_directory); foreach $m (readdir(DIR)) { local %tinfo; next if ($m =~ /^\./); next if ($m eq "theme-stressfree"); next if (!&read_file_cached("$root_directory/$m/theme.info", \ %tinfo)); push(@rv, $m); } closedir(DIR); return @rv; } sub init_manifest_config { # This is a direct copy of the Webmin init_config function without the referrer test. # Testing for a referrer fails with Gears as it makes a direct call without assigning a referrer URL. $config_file = "$config_directory/config"; %gconfig = ( ); &read_file_cached($config_file, \%gconfig); $null_file = $gconfig{'os_type'} eq 'windows' ? "NUL" : "/dev/null"; $path_separator = $gconfig{'os_type'} eq 'windows' ? ';' : ':'; # Set PATH and LD_LIBRARY_PATH if ($gconfig{'path'}) { if ($gconfig{'syspath'}) { # Webmin only $ENV{'PATH'} = $gconfig{'path'}; } else { # Include OS too $ENV{'PATH'} = $gconfig{'path'}.$path_separator. $ENV{'PATH'}; } } $ENV{$gconfig{'ld_env'}} = $gconfig{'ld_path'} if ($gconfig{'ld_env'}); # Set http_proxy and ftp_proxy environment variables, based on Webmin settings if ($gconfig{'http_proxy'}) { $ENV{'http_proxy'} = $gconfig{'http_proxy'}; } if ($gconfig{'ftp_proxy'}) { $ENV{'ftp_proxy'} = $gconfig{'ftp_proxy'}; } if ($gconfig{'noproxy'}) { $ENV{'no_proxy'} = $gconfig{'noproxy'}; } # Find all root directories local %miniserv; if (&get_miniserv_config(\%miniserv)) { @root_directories = ( $miniserv{'root'} ); for($i=0; defined($miniserv{"extraroot_$i"}); $i++) { push(@root_directories, $miniserv{"extraroot_$i"}); } } # Work out which module we are in, and read the per-module config file $0 =~ s/\\/\//g; # Force consistent path on Windows if (defined($ENV{'FOREIGN_MODULE_NAME'})) { # In a foreign call - use the module name given $root_directory = $ENV{'FOREIGN_ROOT_DIRECTORY'}; $module_name = $ENV{'FOREIGN_MODULE_NAME'}; @root_directories = ( $root_directory ) if (! @root_directories); } elsif ($ENV{'SCRIPT_NAME'}) { local $sn = $ENV{'SCRIPT_NAME'}; $sn =~ s/^$gconfig{'webprefix'}// if (!$gconfig{'webprefixnoredir'}); if ($sn =~ /^\/([^\/]+)\//) { # Get module name from CGI path $module_name = $1; } if ($ENV{'SERVER_ROOT'}) { $root_directory = $ENV{'SERVER_ROOT'}; } elsif ($ENV{'SCRIPT_FILENAME'}) { $root_directory = $ENV{'SCRIPT_FILENAME'}; $root_directory =~ s/$sn$//; } @root_directories = ( $root_directory ) if (! @root_directories); } else { # Get root directory from miniserv.conf, and deduce module name from $0 $root_directory = $root_directories[0]; local $r; local $rok = 0; foreach $r (@root_directories) { if ($0 =~ /^$r\/([^\/]+)\/[^\/]+$/i) { # Under a module directory $module_name = $1; $rok = 1; last; } elsif ($0 =~ /^$root_directory\/[^\/]+$/i) { # At the top level $rok = 1; last; } } &error("Script was not run with full path (failed to find $0 under $root_directory)") if (!$rok); } } |