|
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);
}
}
|