#!/usr/bin/perl
use strict;
use Search;
local $| = 1; # Do not buffer output (localized for mod_perl)
# Configuration/constant variables:
use vars qw(@RcDays @HtmlPairs @HtmlSingle
$TempDir $LockDir $DataDir $HtmlDir $UserDir $KeepDir $PageDir
$InterFile $RcFile $RcOldFile $IndexFile $FullUrl $SiteName $HomePage
$LogoUrl $RcDefault $IndentLimit $RecentTop $EditAllowed $UseDiff
$UseSubpage $UseCache $RawHtml $SimpleLinks $NonEnglish $LogoLeft
$KeepDays $HtmlTags $HtmlLinks $UseDiffLog $KeepMajor $KeepAuthor
$FreeUpper $EmailNotify $SendMail $EmailFrom $FastGlob $EmbedWiki
$ScriptTZ $BracketText $UseAmPm $UseConfig $UseIndex $UseLookup
$RedirType $AdminPass $EditPass $UseHeadings $NetworkFile $BracketWiki
$FreeLinks $WikiLinks $AdminDelete $FreeLinkPattern $RCName $RunCGI
$ShowEdits $ThinLine $LinkPattern $InterLinkPattern $InterSitePattern
$UrlProtocols $UrlPattern $ImageExtensions $RFCPattern $ISBNPattern
$PostcodePattern $LatLongPattern $RevisionPattern $PFLinkPattern
$FS $FS1 $FS2 $FS3 $CookieName $SiteBase $StyleSheet $NotFoundPg
$FooterNote $EditNote $MaxPost $NewText $NotifyDefault $HttpCharset
$UserGotoBar $UseBuiltinDiff);
# Note: $NotifyDefault is kept because it was a config variable in 0.90
# Other global variables:
use vars qw(%Page %Section %Text %InterSite %SaveUrl %SaveNumUrl
%KeptRevisions %UserCookie %SetCookie %UserData %IndexHash %Translate
%LinkIndex $InterSiteInit $SaveUrlIndex $SaveNumUrlIndex $MainPage
$OpenPageName @KeptList @IndexList $IndexInit
$q $Now $UserID $TimeZoneOffset $ScriptName $BrowseCode $OtherCode);
# == Configuration =====================================================
$DataDir = "data"; # Main wiki directory
$UseConfig = 0; # 1 = use config file, 0 = do not look for config
# Default configuration (used if UseConfig is 0)
$CookieName = "ToothyWiki"; # Name for this wiki (for multi-wiki sites)
$SiteName = "ToothyWiki"; # Name of site (used for titles)
$HomePage = "ToothyWiki"; # Home page (change space to _)
$RCName = "RecentChanges"; # Name of changes page (change space to _)
$LogoUrl = "/img/text_logo.jpg"; # URL for site logo ("" for no logo)
$ENV{PATH} = "/usr/bin/"; # Path used to find "diff"
$ScriptTZ = ""; # Local time zone ("" means do not print)
$RcDefault = 7; # Default number of RecentChanges days
@RcDays = qw(1 3 7 30 90); # Days for links on RecentChanges
$KeepDays = 365; # Days to keep old revisions
$SiteBase = ""; # Full URL for
(.|\n)*?\<\/pre>/ /ig;
$text =~ s/(.|\n)*?\<\/code>/ /ig;
{
my $fl = $FreeLinkPattern;
$text =~ s/\[ToothyWiki:$fl [^\]]+\]/push(@links, &FreeToNormal($1)), ' '/ge;
}
{
$text =~ s/$InterLinkPattern/ /g;
}
{
$text =~ s/$UrlPattern/ /g;
}
if ($FreeLinks) {
my $fl = $FreeLinkPattern;
$text =~ s/\[\[$fl\|[^\]]+\]\]/push(@links, &FreeToNormal($1)), ' '/ge;
$text =~ s/\[\[$fl\]\]/push(@links, &FreeToNormal($1)), ' '/ge;
}
if ($WikiLinks) {
$text =~ s/$LinkPattern/push(@links, &StripUrlPunct($1)), ' '/ge;
}
$text =~ s/ --([A-Z][A-Za-z0-9]*) /push(@links, &StripUrlPunct($1)), ' '/ge;
return @links;
}
sub GetPageLinks {
my ($name) = @_;
&OpenPage($name);
&OpenDefaultText();
return &ExtractLinks($Text{'text'});
}
sub OpenNewSection {
my ($name, $data) = @_;
%Section = ();
$Section{'name'} = $name;
$Section{'version'} = 1; # Data format version
$Section{'revision'} = 0; # Number of edited times
$Section{'tscreate'} = $Now; # Set once at creation
$Section{'ts'} = $Now; # Updated every edit
$Section{'ip'} = $ENV{REMOTE_ADDR};
$Section{'host'} = ''; # Updated only for real edits (can be slow)
$Section{'id'} = $UserID;
$Section{'username'} = &GetParam("username", "");
$Section{'data'} = $data;
$Page{$name} = join($FS2, %Section); # Replace with save?
}
sub OpenNewText {
my ($name) = @_; # Name of text (usually "default")
%Text = ();
# Later consider translation of new-page message? (per-user difference?)
if ($NewText ne '') {
$Text{'text'} = T($NewText);
} else {
$Text{'text'} = T('Describe the new page here.') . "\n";
}
$Text{'text'} .= "\n" if (substr($Text{'text'}, -1, 1) ne "\n");
$Text{'minor'} = 0; # Default as major edit
$Text{'newauthor'} = 1; # Default as new author
$Text{'summary'} = '';
&OpenNewSection("text_$name", join($FS3, %Text));
}
sub OpenSection {
my ($name) = @_;
if (!defined($Page{$name})) {
&OpenNewSection($name, "");
} else {
%Section = split(/$FS2/, $Page{$name}, -1);
}
}
sub OpenText {
my ($name) = @_;
if (!defined($Page{"text_$name"})) {
&OpenNewText($name);
} else {
&OpenSection("text_$name");
%Text = split(/$FS3/, $Section{'data'}, -1);
}
}
sub OpenDefaultText {
&OpenText('default');
}
sub GetPageDirectory {
my ($id) = @_;
if ($id =~ /^([a-zA-Z])/) {
return uc($1);
}
return "other";
}
sub GetPageFile {
my ($id) = @_;
return $PageDir . "/" . &GetPageDirectory($id) . "/$id.db";
}
sub OpenPage {
my ($id) = @_;
my ($fname, $data);
if ($OpenPageName eq $id) {
return;
}
%Section = ();
%Text = ();
$fname = &GetPageFile($id);
if (-f $fname) {
$data = &ReadFileOrDie($fname);
%Page = split(/$FS1/, $data, -1); # -1 keeps trailing null fields
} else {
die ("$id doesn't exist!");
}
$OpenPageName = $id;
}
sub ReadFile {
my ($fileName) = @_;
my ($data);
local $/ = undef; # Read complete files
if (open(IN, "<$fileName")) {
$data=;
close IN;
return (1, $data);
}
return (0, "");
}
sub ReadFileOrDie {
my ($fileName) = @_;
my ($status, $data);
($status, $data) = &ReadFile($fileName);
if (!$status) {
die(Ts('Can not open %s', $fileName) . ": $!");
}
return $data;
}
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);
}
sub AllPagesList {
return &GenerateAllPagesList();
}
# ---------------------------------
&InitLinkPatterns();
if ($#ARGV < 1)
{
die "Usage: searchtest.pl (fetch|update|delete) pagename [entries..]\n";
}
my $command = shift @ARGV;
my $pagename = shift @ARGV;
if ($command eq "reindex")
{
&ReIndex();
}
elsif ($command eq "fetch")
{
my $results = Fetch ("searchdb/", $pagename);
foreach my $result (@$results)
{
print $result."\n";
}
}
elsif ($command eq "update")
{
Update ("searchdb/", $pagename, \@ARGV);
}
elsif ($command eq "delete")
{
Delete ("searchdb/", $pagename);
}
else
{
die "Usage: searchtest.pl (fetch|update|delete|reindex) pagename [entries..]\n";
}