Apache-MiniWiki
view release on metacpan or search on metacpan
MiniWiki.pm view on Meta::CPAN
if ($@) {
return fatal_error($r, "Error while retrieving $fileuri: $@");
}
}
my $text = "";
if ($preview_wikitext) {
$text .= qq(<div class="previewborder">);
$text .= &render(&prettify("PREVIEW of " . $preview_wikitext));
$text .= qq(</div>);
}
$text .= &prettify("Edit: $fileuri");
$text .= "<form method=\"post\" action=\"${vroot}/(save)${uri}\" enctype=\"multipart/form-data\"><fieldset>\n";
if (is_binary($fileuri)) {
$text .= "<input type=\"file\" name=\"text\">\n";
} else {
$text .= "<textarea rows=20 cols=80 class='areas' name=\"text\" wrap=virtual>\n";
if ($preview_wikitext) {
$text .= $preview_wikitext;
} elsif (-f "${datadir}/${fileuri},v") {
open (IN, '<', "${datadir}/${fileuri}")
|| return fatal_error($r, "Couldn't read ${fileuri}");
$text .= encode_entities(join('', <IN>));
close (IN);
}
$text .= "</textarea>"
}
$text .= qq(<p>Comment: <input type=text size=30 maxlength=60 name=comment value="$comment"> );
$text .= qq(<input type="submit" name="Save" value="Preview">\n);
$text .= qq(<input type="submit" name="Save" value="Save"></fieldset></form>);
$template->param('vroot', $vroot);
$template->param('title', $uri);
$template->param('body', $text);
$template->param('editlink', "$vroot/\(edit\)\/$uri");
$template->param('loglink', "$vroot/\(log\)\/$uri");
$template->param("lastmod", &get_lastmod("${datadir}/${fileuri},v"));
my $output = $template->output;
$output =~ s/\n(\s*)\n(\s*)\n/\n\n/g;
$r->send_http_header('text/html');
print $output;
return OK;
}
## This function determines when a given file was last changed
## and returns a string about that.
sub get_lastmod {
my ($filename) = @_;
my $lastmod = "never";
if (-f $filename) {
my $mtime = stat($filename)->mtime;
my $date = &ParseDateString("epoch $mtime");
$lastmod = &UnixDate($date, "%B %d, %Y %i:%M %p");
}
return "$lastmod";
}
# This function is the standard viewer. It loads a file and displays it
# to the user.
sub view_function {
my ($r, $uri, $revision) = @_;
my $mvtime;
if (not $revision) {
$revision = '';
}
elsif ($revision =~ /^([\d\.]+)$/) {
$revision = $1;
}
else {
return &pretty_error($r, "Invalid revision");
}
my $fileuri = uri_to_filename($uri);
# If the file doesn't exist as an RCS file,
# then we return NOT_FOUND to Apache.
if (! (-f "${datadir}/${fileuri},v" and -r "${datadir}/${fileuri},v")) {
return NOT_FOUND;
}
# If we don't have a checked out file, check it out. Can't really do caching here,
# as we also deal with multiple revisions of the files. If there is a performance
# bottleneck here, in the future we may need to look at other means of caching.
my $file;
eval {
$file = &rcs_open($r, $fileuri);
$file->co("-r$revision");
};
if ($@) {
return fatal_error($r, "Error retriving $fileuri, check revision: $@");
}
if (is_binary($fileuri)) {
# If we're running under mod_perl, we can use its interface
# to Apache's I/O routines to send binary files more efficiently.
my ($img_ext) = &is_img($fileuri);
if (exists $ENV{MOD_PERL}) {
return send_file($r, "${datadir}/${fileuri}");
} else {
if ($img_ext) {
$r->send_http_header("image/$img_ext");
} else {
$r->send_http_header("application/octet-stream");
}
my $file;
open (FILE, "${datadir}/${fileuri}");
{ local undef $/; $file = <FILE>; }
print $file;
MiniWiki.pm view on Meta::CPAN
}
}
$template->param('vroot', $vroot || "no vroot");
$template->param('title', $uri);
$template->param('body', $newtext);
$template->param('editlink', "$vroot/\(edit\)\/$uri");
$template->param('loglink', "$vroot/\(log\)\/$uri");
$template->param('pageurl', "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}$ENV{REQUEST_URI}");
$template->param("lastmod", &get_lastmod("${datadir}/${fileuri},v"));
my $output = $template->output;
$output =~ s/\n(\s*)\n(\s*)\n/\n\n/g;
$r->send_http_header('text/html');
print $output;
}
return OK;
}
# returns a string containing the contents of the given filename
sub get_file($) {
my ($filename) = @_;
my $data = "";
open (FILE, "$filename") || die "$filename - $!";
while (<FILE>) {
$data .= $_;
}
close (FILE);
return $data;
}
# write the given data to the given filename
sub put_file($$) {
my ($filename, $data) = @_;
open (OUT, "> $filename") || die $!;
print OUT $data;
close(OUT);
}
# returns the name of the last page that was editted in the wiki
sub get_lastchanged {
open (CMD, "cd ${datadir}; /bin/ls -1at *,v | head -1 |") || die $!;
my $filename = <CMD>;
close (CMD);
$filename =~ s/\t|\r|\n//g;
$filename =~ s/ $//g;
$filename =~ s/^ //g;
return $filename;
}
# returns the timestamp of the given filename in the datadir
sub get_mtime($) {
my ($filename) = @_;
if (-f "$datadir/$filename") {
my $mtime = stat("$datadir/$filename")->mtime;
}
}
sub render($) {
my ($newtext) = @_;
# While the text contains Wiki-style links, we go through each one and
# change them into proper HTML links.
while ($newtext =~ /\[\[([^\]|]*)\|?([^\]]*)\]\]/) {
my $rawname = $1;
my $revision;
if ($rawname =~ /\//) {
($rawname, $revision) = split (/\//, $rawname);
}
my $desc = $2 || $rawname;
my $tmplink;
my $tmppath = uri_to_filename($rawname);
$tmppath =~ s/^_//;
if (-f "${datadir}/$tmppath,v") {
my $link;
if (is_img($rawname)) {
$link = qq{<a href="$vroot/$rawname"><img src="$vroot/(thumb)$rawname" alt="$desc"></a>};
}
else {
$link = qq{<a href="$vroot/$rawname">$desc</a>};
}
if (is_binary($rawname) || is_img($rawname)) {
$link .= qq { <sup><a href="$vroot/(edit)$rawname">[E]</a></sup>};
}
$newtext =~ s/\[\[[^\]]*\]\]/$link/;
} else {
$tmplink = "$desc <a href=\"${vroot}\/(edit)/${rawname}\"><sup>?<\/sup><\/a>";
$newtext =~ s/\[\[[^\]]*\]\]/$tmplink/;
}
}
$newtext =~ s/\\\[\\\[/\[\[/g;
$newtext =~ s/-{3,}/<hr\/>/g;
return $newtext;
}
# this function gets the diff for a file and displays it to the user
# in a semi-nice format.
sub diff_function {
my ($r, $uri) = @_;
my %args = $r->args;
my (@rev) = grep { defined } @args{qw(rev1 rev2)};
for (@rev) {
if (/^([0-9\.]+)$/) {
$_ = $1;
} else {
&pretty_error($r, "Invalid revision, must be a digit.");
}
}
MiniWiki.pm view on Meta::CPAN
if ($@) {
return fatal_error($r, "Error generating log for $fileuri : $@");
}
my $logbody = "History for $uri\n\n";
$logbody = &prettify($logbody);
$logbody .= qq|<a href="#diff_form">Compare revisions</a><br/><br/>\n|;
my $server = $r->server->server_hostname;
foreach my $line (@rlog_complete) {
if ($line =~ /Initial checkin|empty log message|=============/) {
next;
} elsif ($line !~ /:/ && $line !~ /----/ && $line !~ /revision|date/i) {
chomp($line);
$line = " " x 5 . "<i>$line</i><br/>\n" if $line;
} elsif ($line !~ /^(revision |date: )/) {
next;
} elsif ($line =~ /^revision /) {
my ($word, $revision) = split (' ', $line);
$line = qq|<a href="${vroot}/$uri?rev=$revision">View</a> or |;
$line .= qq|<a href="${vroot}/(diff)/$uri?rev1=$revision">Diff</a> or |;
$line .= qq|<a href="${vroot}/(revert)/$uri?rev=$revision">Revert</a> |;
$line .= qq|revision $revision:<br/>\n|;
$line .= " " x 5;
} elsif ($line =~ /date:/ and $line =~ /state:/) {
$line =~ s/\n|\t//g;
$line .= "<br/>\n";
} else {
$line .= "<br/>";
}
$logbody .= "$line";
}
$logbody .= &diff_form($uri);
$template->param('vroot', $vroot);
$template->param('title', $uri);
$template->param('body', $logbody);
$template->param('editlink', "$vroot/\(edit\)\/$uri");
$template->param('loglink', "$vroot/\(log\)\/$uri");
$template->param("lastmod", &get_lastmod("${datadir}/${fileuri},v"));
$r->send_http_header('text/html');
print $template->output;
return OK;
}
# this function creates a thumbnail on the fly for the given uri.
# if the image is bigger then the cutoff, it gets resized. If not, it
# is left alone.
sub thumb_function {
my ($r, $uri, $revision) = @_;
my $fileuri = $datadir . "/" . uri_to_filename($uri);
my $thumburi = $datadir . "/THUMB_" . uri_to_filename($uri);
my $file_mtime = stat($fileuri)->mtime;
my ($subtype) = &is_img($uri);
#$r->send_http_header("image/$subtype");
if (-f $thumburi && stat($thumburi)->mtime > $file_mtime) {
# if the thumbnail is newer then the big image,
# then obviously a new one hasn't been uploaded.
# Don't call ImageMagick to check the size.
# Use the existing thumb.
return send_file($r, $thumburi);
}
use Image::Magick;
my $image = Image::Magick->new;
my ($width, $height, $size, $format) = $image->Ping($fileuri);
if ($width < $max_width && $height < $max_height) {
# don't scale it down
return send_file($r, $fileuri);
}
else {
if (!-f $thumburi || stat($thumburi)->mtime < $file_mtime) {
my $resize_ratio;
if ($width > $height) {
# eg. .2 = 1200 / 240
$resize_ratio = $width / $max_width;
} else {
$resize_ratio = $height / $max_height;
}
$width /= $resize_ratio;
$height /= $resize_ratio;
$image->Read($fileuri);
$image->Resize("${width}x${height}");
$image->Write($thumburi);
}
return send_file($r, $thumburi);
}
}
## let mod_perl efficiently take care of sending a file to the browser
sub send_file {
my ($r, $filename) = @_;
my $subr = $r->lookup_file($filename);
$r->headers_out(%{$subr->headers_out});
$r->send_http_header($subr->content_type);
return $subr->run;
}
# this function returns the HTML for a form that allows the
# user to specify two revisions to compare, in either unidiff or context
# formats. It is called by the log and diff viewing functions,
# diff_function and log_function.
sub diff_form($) {
my ($uri) = @_;
my $form .= <<END;
<hr/>
<a name="#diff_form">
<form method=get action="$vroot/(diff)/$uri">
1st revision: <input type=text size=5 name=rev1>
2nd revision: <input type=text size=5 name=rev2>
Format: <select name=m>
<option value=>Normal</c>
<option value=c>Context</c>
</select>
<input type=submit value=" Compare "><br/>
<i>(Leave 2nd revision field blank to compare against latest)</i>
</form>
END
$form;
}
# This function loads the template, if one exists. If there is no template,
# then a default template consisting of just a plain body is used.
sub get_template {
my ($r) = @_;
if (!( -f "${datadir}/template,v" and -r "${datadir}/template,v")) {
$r->log_error("${datadir}/template,v is not a readable file! Using default.");
my $template_text = <<END_TEMPLATE;
( run in 1.443 second using v1.01-cache-2.11-cpan-39bf76dae61 )