#!/usr/bin/perl # TmNetWiki version 0.4 (September 11, 2002) # Copyright (C) 2002 Adam Brate # # Based on the GPLed UseModWiki 0.92 # Copyright (C) 2000-2001 Clifford A. Adams # or # Based on the GPLed AtisWiki 0.3 (C) 1998 Markus Denker # # ...which was based on # the LGPLed CVWiki CVS-patches (C) 1997 Peter Merel # and The Original WikiWikiWeb (C) Ward Cunningham # (code reused with permission) # Email and ThinLine options by Jim Mahoney # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the # Free Software Foundation, Inc. # 59 Temple Place, Suite 330 # Boston, MA 02111-1307 USA package Wiki::index; use strict; # needs subs Wiki::utility: GetParam # Wiki::lock: RequestLockDir, ReleaseLockDir # Wiki::file: WriteStringToFile # Wiki::template: GetCommonFooter, GetPageLink # Wiki::translate: Ts # Wiki::page: IsRedirect # needs consts $FastGlob, $PageDir, $IndexFile # needs vars $IndexInit, %IndexHash use base 'Exporter'; use Wiki::consts; use Wiki::utility; use Wiki::lock; use Wiki::file; use Wiki::template; use Wiki::translate; use Wiki::page; #if ($^V and $^V gt v5.6.0) { # our @EXPORT; #else { use vars qw(@EXPORT); #} @EXPORT = qw( DoIndex PrintPageList AllPagesList ); # index print sub DoIndex; sub PrintPageList; # index utilities (Wiki::index::utility) sub AllPagesList; sub GenerateAllPagesList; sub RequestIndexLock; sub ReleaseIndexLock; sub DoIndex { print &GetHeader('', T('Index of all pages'), ''); print '
'; &PrintPageList(&AllPagesList()); print &GetCommonFooter(); } # used by DoIndex, DoSearch sub PrintPageList { my $pagename; print "

", Ts('%s pages found:', ($#_ + 1)), "

\n"; foreach $pagename (@_) { print ".... " if ($pagename =~ m|/|); print &Wiki::template::GetPageLink($pagename), "
\n"; } } # utilities sub GenerateAllPagesList { my (@pages, @dirs, $id, $dir, @pageFiles, @subpageFiles, $subId); @pages = (); if ($FastGlob) { # The following was inspired by the FastGlob code by Marc W. Mengel. # Thanks to Bob Showalter for pointing out the improvement. opendir(PAGELIST, $PageDir); @dirs = readdir(PAGELIST); closedir(PAGELIST); @dirs = sort(@dirs); foreach $dir (@dirs) { next if (($dir eq '.') || ($dir eq '..')); opendir(PAGELIST, "$PageDir/$dir"); @pageFiles = readdir(PAGELIST); closedir(PAGELIST); foreach $id (@pageFiles) { next if (($id eq '.') || ($id eq '..')); if (substr($id, -3) eq '.db') { push(@pages, substr($id, 0, -3)); } elsif (substr($id, -4) ne '.lck') { opendir(PAGELIST, "$PageDir/$dir/$id"); @subpageFiles = readdir(PAGELIST); closedir(PAGELIST); foreach $subId (@subpageFiles) { if (substr($subId, -3) eq '.db') { push(@pages, "$id/" . substr($subId, 0, -3)); } } } } } } else { # Old slow/compatible method. @dirs = qw(A B C D E F G H I J K L M N O P Q R S T U V W X Y Z other); foreach $dir (@dirs) { if (-e "$PageDir/$dir") { # Thanks to Tim Holt while (<$PageDir/$dir/*.db $PageDir/$dir/*/*.db>) { s|^$PageDir/||; m|^[^/]+/(\S*).db|; $id = $1; push(@pages, $id); } } } } return sort(@pages); } =head2 AllPagesList([OPT]) Returns a list of pages. =over 4 =item Parameters =over 4 =item OPT Hash ref of options: currently valid are 'nodates' and 'nosubpages'. =back =item Return value List of page names. =item Dependencies global consts: $UseIndex, $IndexFile global vars: $IndexInit, @IndexList, %IndexHash subs: ReadFile, WriteStringToFile package subs: GenerateAllPagesList, RequestIndexLock, ReleaseIndexLock =back =cut sub AllPagesList { my ($opt) = @_; my ($rawIndex, $refresh, $status,@list); if (!$UseIndex) { @list = &GenerateAllPagesList(); } else { $refresh = &GetParam("refresh", 0); if ($IndexInit && !$refresh) { # Note for mod_perl: $IndexInit is reset for each query # Eventually consider some timestamp-solution to keep cache? @list = @IndexList; } elsif ((!$refresh) && (-f $IndexFile)) { ($status, $rawIndex) = &ReadFile($IndexFile); if ($status) { %IndexHash = split(/\s+/, $rawIndex); @IndexList = sort(keys %IndexHash); $IndexInit = 1; @list = @IndexList; } # If open fails just refresh the index } else { @IndexList = (); %IndexHash = (); @IndexList = &GenerateAllPagesList(); foreach (@IndexList) { $IndexHash{$_} = 1; } $IndexInit = 1; # Initialized for this run of the script # Try to write out the list for future runs &RequestIndexLock() or return @IndexList; &WriteStringToFile($IndexFile, join(" ", %IndexHash)); &ReleaseIndexLock(); @list = @IndexList; } } # here's where we can process the list if ($opt->{nodates}) { @list = grep (!/^\d{4}$/,@list); } if ($opt->{nosubpages}) { @list = grep (!/\//,@list); } if ($opt->{noredirects}) { @list = grep (!&Wiki::page::IsRedirect($_),@list); } return @list; } # Index lock is not very important--just return error if not available sub RequestIndexLock { # 1 try, 2 second wait, do not die on error return &RequestLockDir('index', 1, 2, 0); } sub ReleaseIndexLock { &ReleaseLockDir('index'); }