X-Git-Url: https://git.deb.at/?p=pkg%2Fblosxom.git;a=blobdiff_plain;f=blosxom.cgi;h=2c6b6ee17d1e7e5692668cba4f5be2d3297ff4dd;hp=1ddc9dfdd461883d1fd8c6ed1f26477c5502ba60;hb=2e7cf5294e63848b2f862b9ce828d54994a7ab52;hpb=2d1453cfbb56bcad6bba07eb0ad3b2aa08849ba5 diff --git a/blosxom.cgi b/blosxom.cgi index 1ddc9df..2c6b6ee 100755 --- a/blosxom.cgi +++ b/blosxom.cgi @@ -47,14 +47,17 @@ $show_future_entries = 0; # --- Plugins (Optional) ----- -# File listing plugins blosxom should load (if empty blosxom will walk $plugin_dir) +# File listing plugins blosxom should load +# (if empty blosxom will load all plugins in $plugin_path directories) $plugin_list = ""; -# Where are my plugins kept? -$plugin_dir = ""; +# Where are my plugins kept? +# List of directories, separated by ';' on windows, ':' everywhere else +$plugin_path = ""; -# Where should my modules keep their state information? -$plugin_state_dir = "$plugin_dir/state"; +# Where should my plugins keep their state information? +$plugin_state_dir = ""; +#$plugin_state_dir = "/var/lib/blosxom/state"; # --- Static Rendering ----- @@ -73,7 +76,7 @@ $static_entries = 0; # -------------------------------- -use vars qw! $version $blog_title $blog_description $blog_language $blog_encoding $datadir $url %template $template $depth $num_entries $file_extension $default_flavour $static_or_dynamic $config_dir $plugin_list $plugin_dir $plugin_state_dir @plugins %plugins $static_dir $static_password @static_flavours $static_entries $path_info $path_info_yr $path_info_mo $path_info_da $path_info_mo_num $flavour $static_or_dynamic %month2num @num2month $interpolate $entries $output $header $show_future_entries %files %indexes %others !; +use vars qw! $version $blog_title $blog_description $blog_language $blog_encoding $datadir $url %template $template $depth $num_entries $file_extension $default_flavour $static_or_dynamic $config_dir $plugin_list $plugin_path $plugin_dir $plugin_state_dir @plugins %plugins $static_dir $static_password @static_flavours $static_entries $path_info $path_info_yr $path_info_mo $path_info_da $path_info_mo_num $flavour $static_or_dynamic %month2num @num2month $interpolate $entries $output $header $show_future_entries %files %indexes %others !; use strict; use FileHandle; @@ -134,13 +137,22 @@ $url =~ s!/$!!; $datadir =~ s!/$!!; $plugin_dir =~ s!/$!!; $static_dir =~ s!/$!!; # Fix depth to take into account datadir's path -$depth and $depth += ($datadir =~ tr[/][]) - 1; +$depth += ($datadir =~ tr[/][]) - 1 if $depth; # Global variable to be used in head/foot.{flavour} templates $path_info = ''; -$static_or_dynamic = (!$ENV{GATEWAY_INTERFACE} and param('-password') and $static_password and param('-password') eq $static_password) ? 'static' : 'dynamic'; -$static_or_dynamic eq 'dynamic' and param(-name=>'-quiet', -value=>1); +if ( !$ENV{GATEWAY_INTERFACE} + and param('-password') + and $static_password + and param('-password') eq $static_password ) +{ + $static_or_dynamic = 'static'; +} +else { + $static_or_dynamic = 'dynamic'; + param( -name => '-quiet', -value => 1 ); +} # Path Info Magic # Take a gander at HTTP's PATH_INFO for optional blog name, archive yr/mo/day @@ -154,7 +166,7 @@ $flavour = ''; if ( $path_info[$#path_info] =~ /(.+)\.(.+)$/ ) { $flavour = $2; - $1 ne 'index' and $path_info .= "/$1.$2"; + $path_info .= "/$1.$2" if $1 ne 'index'; pop @path_info; } else { $flavour = param('flav') || $default_flavour; @@ -195,7 +207,10 @@ while () { } # Plugins: Start +my $path_sep = $^O eq 'MSWin32' ? ';' : ':'; +my @plugin_dirs = split /$path_sep/, ($plugin_path || $plugin_dir); my @plugin_list = (); +my %plugin_hash = (); # If $plugin_list is set, read plugins to use from that file $plugin_list = "$config_dir/$plugin_list" @@ -204,28 +219,41 @@ if ( $plugin_list and -r $plugin_list and $fh->open("< $plugin_list") ) { @plugin_list = map { chomp $_; $_ } grep { /\S/ && ! /^#/ } <$fh>; $fh->close; } -# Otherwise walk $plugin_dir to get list of plugins to use -elsif ( $plugin_dir and opendir PLUGINS, $plugin_dir ) { - @plugin_list = grep { /^[\w:]+$/ && ! /~$/ && -f "$plugin_dir/$_" } sort readdir(PLUGINS); - closedir PLUGINS; +# Otherwise walk @plugin_dirs to get list of plugins to use +elsif ( @plugin_dirs ) { + for my $plugin_dir ( @plugin_dirs ) { + next unless -d $plugin_dir; + if ( opendir PLUGINS, $plugin_dir ) { + for my $plugin ( grep { /^[\w:]+$/ && ! /~$/ && -f "$plugin_dir/$_" } readdir(PLUGINS) ) { + # Ignore duplicates + next if $plugin_hash{ $plugin }; + # Add to @plugin_list and %plugin_hash + $plugin_hash{ $plugin } = "$plugin_dir/$plugin"; + push @plugin_list, $plugin; + } + closedir PLUGINS; + } + } + @plugin_list = sort @plugin_list; } -unshift @INC, $plugin_dir; +# Load all plugins in @plugin_list +unshift @INC, @plugin_dirs; foreach my $plugin ( @plugin_list ) { my($plugin_name, $off) = $plugin =~ /^\d*([\w:]+?)(_?)$/; my $on_off = $off eq '_' ? -1 : 1; # Allow perl module plugins - if ($plugin =~ m/::/ && -z "$plugin_dir/$plugin") { + if ($plugin =~ m/::/ && -z $plugin_hash{ $plugin }) { # For Blosxom::Plugin::Foo style plugins, we need to use a string require eval "require $plugin_name"; } else { eval { require $plugin }; } - $@ and warn "error finding or loading blosxom plugin $plugin_name - skipping\n" and next; + $@ and warn "$@ error finding or loading blosxom plugin $plugin_name - skipping\n" and next; $plugin_name->start() and ( $plugins{$plugin_name} = $on_off ) and push @plugins, $plugin_name; } -shift @INC; +shift @INC foreach @plugin_dirs; # Plugins: Template # Allow for the first encountered plugin::template subroutine to override the @@ -253,32 +281,33 @@ $entries = # not an index, .file, and is readable and $2 ne 'index' and $2 !~ /^\./ and (-r $File::Find::name) ) { + # read modification time + my $mtime = stat($File::Find::name)->mtime or return; + # to show or not to show future entries - ( - $show_future_entries - or stat($File::Find::name)->mtime < time - ) + return unless ($show_future_entries or $mtime < time); # add the file and its associated mtime to the list of files - and $files{$File::Find::name} = stat($File::Find::name)->mtime + $files{$File::Find::name} = $mtime; # static rendering bits - and ( - param('-all') - or !-f "$static_dir/$1/index." . $static_flavours[0] - or stat("$static_dir/$1/index." . $static_flavours[0])->mtime < stat($File::Find::name)->mtime - ) - and $indexes{$1} = 1 - and $d = join('/', (nice_date($files{$File::Find::name}))[5,2,3]) - - and $indexes{$d} = $d - and $static_entries and $indexes{ ($1 ? "$1/" : '') . "$2.$file_extension" } = 1 - - } - else { - !-d $File::Find::name and -r $File::Find::name and $others{$File::Find::name} = stat($File::Find::name)->mtime - } + my $static_file = "$static_dir/$1/index." . $static_flavours[0]; + if (param('-all') + or !-f $static_file + or stat($static_file)->mtime < $mtime) + { + $indexes{$1} = 1; + $d = join('/', (nice_date($mtime))[5,2,3]); + $indexes{$d} = $d; + $indexes{ ($1 ? "$1/" : '') . "$2.$file_extension" } = 1 if $static_entries; + } + } + # not an entries match + elsif (!-d $File::Find::name and -r $File::Find::name) + { + $others{$File::Find::name} = stat($File::Find::name)->mtime; + } }, $datadir ); @@ -305,8 +334,8 @@ if (!$ENV{GATEWAY_INTERFACE} and param('-password') and $static_password and par foreach ( ('', split /\//, $path) ) { $p .= "/$_"; $p =~ s!^/!!; - $done{$p}++ and next; - (-d "$static_dir/$p" or $p =~ /\.$file_extension$/) or mkdir "$static_dir/$p", 0755; + next if $done{$p}++; + mkdir "$static_dir/$p", 0755 unless (-d "$static_dir/$p" or $p =~ /\.$file_extension$/); foreach $flavour ( @static_flavours ) { my $content_type = (&$template($p,'content_type',$flavour)); $content_type =~ s!\n.*!!s; @@ -360,7 +389,16 @@ sub generate { # Plugins: Skip # Allow plugins to decide if we can cut short story generation - my $skip; foreach my $plugin ( @plugins ) { $plugins{$plugin} > 0 and $plugin->can('skip') and defined($tmp = $plugin->skip()) and $skip = $tmp and last; } + my $skip; + foreach my $plugin (@plugins) { + if ( $plugins{$plugin} > 0 and $plugin->can('skip') ) { + if ( my $tmp = $plugin->skip() ) { + $skip = $tmp; + last; + } + } + } + # Define default interpolation subroutine $interpolate = @@ -377,13 +415,24 @@ sub generate { # Plugins: Interpolate # Allow for the first encountered plugin::interpolate subroutine to # override the default built-in interpolate subroutine - my $tmp; foreach my $plugin ( @plugins ) { $plugins{$plugin} > 0 and $plugin->can('interpolate') and defined($tmp = $plugin->interpolate()) and $interpolate = $tmp and last; } + foreach my $plugin (@plugins) { + if ( $plugins{$plugin} > 0 and $plugin->can('interpolate') ) { + if ( my $tmp = $plugin->interpolate() ) { + $interpolate = $tmp; + last; + } + } + } # Head my $head = (&$template($currentdir,'head',$flavour)); # Plugins: Head - foreach my $plugin ( @plugins ) { $plugins{$plugin} > 0 and $plugin->can('head') and $entries = $plugin->head($currentdir, \$head) } + foreach my $plugin (@plugins) { + if ( $plugins{$plugin} > 0 and $plugin->can('head') ) { + $entries = $plugin->head( $currentdir, \$head ); + } + } $head = &$interpolate($head); @@ -410,7 +459,14 @@ sub generate { # Plugins: Sort # Allow for the first encountered plugin::sort subroutine to override the # default built-in sort subroutine - my $tmp; foreach my $plugin ( @plugins ) { $plugins{$plugin} > 0 and $plugin->can('sort') and defined($tmp = $plugin->sort()) and $sort = $tmp and last; } + foreach my $plugin (@plugins) { + if ( $plugins{$plugin} > 0 and $plugin->can('sort') ) { + if ( my $tmp = $plugin->sort() ) { + $sort = $tmp; + last; + } + } + } foreach my $path_file ( &$sort(\%f, \%others) ) { last if $ne <= 0 && $date !~ /\d/; @@ -456,7 +512,11 @@ sub generate { my $story = (&$template($path,'story',$flavour)); # Plugins: Story - foreach my $plugin ( @plugins ) { $plugins{$plugin} > 0 and $plugin->can('story') and $entries = $plugin->story($path, $fn, \$story, \$title, \$body) } + foreach my $plugin (@plugins) { + if ( $plugins{$plugin} > 0 and $plugin->can('story') ) { + $entries = $plugin->story( $path, $fn, \$story, \$title, \$body ); + } + } if ($content_type =~ m{\bxml\b}) { # Escape <, >, and &, and to produce valid RSS @@ -478,18 +538,26 @@ sub generate { my $foot = (&$template($currentdir,'foot',$flavour)); # Plugins: Foot - foreach my $plugin ( @plugins ) { $plugins{$plugin} > 0 and $plugin->can('foot') and $entries = $plugin->foot($currentdir, \$foot) } + foreach my $plugin (@plugins) { + if ( $plugins{$plugin} > 0 and $plugin->can('foot') ) { + $entries = $plugin->foot( $currentdir, \$foot ); + } + } $foot = &$interpolate($foot); $output .= $foot; # Plugins: Last - foreach my $plugin ( @plugins ) { $plugins{$plugin} > 0 and $plugin->can('last') and $entries = $plugin->last() } + foreach my $plugin (@plugins) { + if ( $plugins{$plugin} > 0 and $plugin->can('last') ) { + $entries = $plugin->last(); + } + } } # End skip # Finally, add the header, if any and running dynamically - $static_or_dynamic eq 'dynamic' and $header and $output = header($header) . $output; + $output = header($header) . $output if ($static_or_dynamic eq 'dynamic' and $header); $output; }