Re: [webmin-devel] Building a Google Gears manifest file of Webminstatic files

David Harrison <[email protected]> Tue, 17 Feb 2009 22:37:02 +1300
Newsgroups gmane.comp.web.webmin.devel
Message-ID <[email protected]>
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: [email protected]
# 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);
         }
}

------------------------------------------------------------------------------
Open Source Business Conference (OSBC), March 24-25, 2009, San Francisco, CA
-OSBC tackles the biggest issue in open source: Open Sourcing the Enterprise
-Strategies to boost innovation and cut costs with open source participation
-Receive a $600 discount off the registration fee with the source code: SFAD
http://p.sf.net/sfu/XcvMzF8H
-
Forwarded by the Webmin development list at [email protected]
To remove yourself from this list, go to
http://lists.sourceforge.net/lists/listinfo/webadmin-devel