use warnings;
use strict;
-use IkiWiki 2.00;
+use IkiWiki 3.00;
-my %units=( #{{{ # size in bytes
+my %units=( # size in bytes
B => 1,
byte => 1,
KB => 2 ** 10,
# ikiwiki, if you find you need larger data quantities, either modify
# yourself to add them, or travel back in time to 2008 and kill me.
# -- Joey
-); #}}}
+);
-sub parsesize ($) { #{{{
+sub import {
+ hook(type => "getsetup", id => "filecheck", call => \&getsetup);
+}
+
+sub getsetup () {
+ return
+ plugin => {
+ safe => 1,
+ rebuild => undef,
+ },
+}
+
+sub parsesize ($) {
my $size=shift;
no warnings;
}
}
return $base;
-} #}}}
+}
# This is provided for other plugins that want to convert back the other way.
-sub humansize ($) { #{{{
+sub humansize ($) {
my $size=shift;
foreach my $unit (reverse sort { $units{$a} <=> $units{$b} || $b cmp $a } keys %units) {
}
}
return $size; # near zero, or negative
-} #}}}
+}
package IkiWiki::PageSpec;
-sub match_maxsize ($$;@) { #{{{
+sub match_maxsize ($$;@) {
my $page=shift;
my $maxsize=eval{IkiWiki::Plugin::filecheck::parsesize(shift)};
if ($@) {
- return IkiWiki::FailReason->new("unable to parse maxsize (or number too large)");
+ return IkiWiki::ErrorReason->new("unable to parse maxsize (or number too large)");
}
my %params=@_;
- my $file=exists $params{file} ? $params{file} : $IkiWiki::pagesources{$page};
+ my $file=exists $params{file} ? $params{file} : IkiWiki::srcfile($IkiWiki::pagesources{$page});
if (! defined $file) {
- return IkiWiki::FailReason->new("no file specified");
+ return IkiWiki::ErrorReason->new("file does not exist");
}
if (-s $file > $maxsize) {
else {
return IkiWiki::SuccessReason->new("file not too large");
}
-} #}}}
+}
-sub match_minsize ($$;@) { #{{{
+sub match_minsize ($$;@) {
my $page=shift;
my $minsize=eval{IkiWiki::Plugin::filecheck::parsesize(shift)};
if ($@) {
- return IkiWiki::FailReason->new("unable to parse minsize (or number too large)");
+ return IkiWiki::ErrorReason->new("unable to parse minsize (or number too large)");
}
my %params=@_;
- my $file=exists $params{file} ? $params{file} : $IkiWiki::pagesources{$page};
+ my $file=exists $params{file} ? $params{file} : IkiWiki::srcfile($IkiWiki::pagesources{$page});
if (! defined $file) {
- return IkiWiki::FailReason->new("no file specified");
+ return IkiWiki::ErrorReason->new("file does not exist");
}
if (-s $file < $minsize) {
else {
return IkiWiki::SuccessReason->new("file not too small");
}
-} #}}}
+}
-sub match_mimetype ($$;@) { #{{{
+sub match_mimetype ($$;@) {
my $page=shift;
my $wanted=shift;
my %params=@_;
- my $file=exists $params{file} ? $params{file} : $IkiWiki::pagesources{$page};
+ my $file=exists $params{file} ? $params{file} : IkiWiki::srcfile($IkiWiki::pagesources{$page});
if (! defined $file) {
- return IkiWiki::FailReason->new("no file specified");
+ return IkiWiki::ErrorReason->new("file does not exist");
}
- # Use ::magic to get the mime type, the idea is to only trust
- # data obtained by examining the actual file contents.
+ # Get the mime type.
+ #
+ # First, try File::Mimeinfo. This is fast, but doesn't recognise
+ # all files.
eval q{use File::MimeInfo::Magic};
- if ($@) {
- return IkiWiki::FailReason->new("failed to load File::MimeInfo::Magic ($@); cannot check MIME type");
+ my $mimeinfo_ok=! $@;
+ my $mimetype;
+ if ($mimeinfo_ok) {
+ $mimetype=File::MimeInfo::Magic::magic($file);
}
- my $mimetype=File::MimeInfo::Magic::magic($file);
+
+ # Fall back to using file, which has a more complete
+ # magic database.
if (! defined $mimetype) {
- $mimetype=File::MimeInfo::Magic::default($file);
+ open(my $file_h, "-|", "file", "-bi", $file);
+ $mimetype=<$file_h>;
+ chomp $mimetype;
+ close $file_h;
+ }
+ if (! defined $mimetype || $mimetype !~s /;.*//) {
+ # Fall back to default value.
+ $mimetype=File::MimeInfo::Magic::default($file)
+ if $mimeinfo_ok;
if (! defined $mimetype) {
$mimetype="unknown";
}
}
my $regexp=IkiWiki::glob2re($wanted);
- if ($mimetype!~/^$regexp$/i) {
+ if ($mimetype!~$regexp) {
return IkiWiki::FailReason->new("file MIME type is $mimetype, not $wanted");
}
else {
return IkiWiki::SuccessReason->new("file MIME type is $mimetype");
}
-} #}}}
+}
-sub match_virusfree ($$;@) { #{{{
+sub match_virusfree ($$;@) {
my $page=shift;
my $wanted=shift;
my %params=@_;
- my $file=exists $params{file} ? $params{file} : $IkiWiki::pagesources{$page};
+ my $file=exists $params{file} ? $params{file} : IkiWiki::srcfile($IkiWiki::pagesources{$page});
if (! defined $file) {
- return IkiWiki::FailReason->new("no file specified");
+ return IkiWiki::ErrorReason->new("file does not exist");
}
if (! exists $IkiWiki::config{virus_checker} ||
! length $IkiWiki::config{virus_checker}) {
- return IkiWiki::FailReason->new("no virus_checker configured");
+ return IkiWiki::ErrorReason->new("no virus_checker configured");
}
# The file needs to be fed into the virus checker on stdin,
# used, clamd would fail to read it.
eval q{use IPC::Open2};
error($@) if $@;
- open (IN, "<", $file) || return IkiWiki::FailReason->new("failed to read file");
+ open (IN, "<", $file) || return IkiWiki::ErrorReason->new("failed to read file");
binmode(IN);
my $sigpipe=0;
$SIG{PIPE} = sub { $sigpipe=1 };
else {
return IkiWiki::SuccessReason->new("file seems virusfree ($reason)");
}
-} #}}}
+}
-sub match_ispage ($$;@) { #{{{
+sub match_ispage ($$;@) {
my $filename=shift;
if (defined IkiWiki::pagetype($filename)) {
else {
return IkiWiki::FailReason->new("file is not a wiki page");
}
-} #}}}
+}