X-Git-Url: http://git.vanrenterghem.biz/git.ikiwiki.info.git/blobdiff_plain/7cd40ea4eb8955765dc3e61dd3edaf08d1bbab48..0ffcafc1305de5ec242f3f0835064682d408c3d0:/IkiWiki/Plugin/attachment.pm diff --git a/IkiWiki/Plugin/attachment.pm b/IkiWiki/Plugin/attachment.pm index 106660012..1d392589e 100644 --- a/IkiWiki/Plugin/attachment.pm +++ b/IkiWiki/Plugin/attachment.pm @@ -5,9 +5,6 @@ use warnings; use strict; use IkiWiki 2.00; -# TODO move to admin prefs -$config{valid_attachments}="(*.mp3 and maxsize(15mb)) or (!ispage() and maxsize(50kb))"; - sub import { #{{{ hook(type => "checkconfig", id => "attachment", call => \&checkconfig); hook(type => "formbuilder_setup", id => "attachment", call => \&formbuilder_setup); @@ -18,13 +15,73 @@ sub checkconfig () { #{{{ $config{cgi_disable_uploads}=0; } #}}} +sub attachment_location ($) { + my $page=shift; + + # Put the attachment in a subdir of the page it's attached + # to, unless that page is an "index" page. + $page=~s/(^|\/)index//; + $page.="/" if length $page; + + return $page; +} + +sub attachment_list ($) { + my $loc=attachment_location(shift); + + my @ret; + foreach my $f (values %pagesources) { + print STDERR ">>$f\n" if ! defined IkiWiki::pagetype($f); + if (! defined IkiWiki::pagetype($f) && + $f=~m/^\Q$loc\E[^\/]+$/ && + -e "$config{srcdir}/$f") { + push @ret, { + "field-select" => '', + link => $f, + size => (stat(_))[7], + mtime => displaytime($IkiWiki::pagemtime{$f}), + }; + } + } + + return @ret; +} + sub formbuilder_setup (@) { #{{{ my %params=@_; my $form=$params{form}; - return if $form->field("do") ne "edit"; + if ($form->field("do") eq "edit") { + $form->field(name => 'attachment', type => 'file'); + $form->tmpl_param("attachment_list" => [attachment_list($form->field('page'))]); - $form->field(name => 'attachment', type => 'file'); + # These buttons are not put in the usual place, so + # is not added to the normal formbuilder button list. + $form->tmpl_param("field-upload" => ''); + $form->tmpl_param("field-link" => ''); + } + elsif ($form->title eq "preferences") { + my $session=$params{session}; + my $user_name=$session->param("name"); + + $form->field(name => "allowed_attachments", size => 50, + fieldset => "admin", + comment => "(".htmllink("", "", "ikiwiki/PageSpec", noimageinline => 1).")"); + if (! IkiWiki::is_admin($user_name)) { + $form->field(name => "allowed_attachments", type => "hidden"); + } + if (! $form->submitted) { + $form->field(name => "allowed_attachments", force => 1, + value => IkiWiki::userinfo_get($user_name, "allowed_attachments")); + } + if ($form->submitted && $form->submitted eq 'Save Preferences') { + if (defined $form->field("allowed_attachments")) { + IkiWiki::userinfo_set($user_name, "allowed_attachments", + $form->field("allowed_attachments")) || + error("failed to set allowed_attachments"); + } + } + } } #}}} sub formbuilder (@) { #{{{ @@ -33,8 +90,10 @@ sub formbuilder (@) { #{{{ return if $form->field("do") ne "edit"; - if ($form->submitted eq "Upload") { + if ($form->submitted eq "Upload" || $form->submitted eq "Save Page") { my $q=$params{cgi}; + my $session=$params{session}; + my $filename=$q->param('attachment'); if (! defined $filename || ! length $filename) { # no file, so do nothing @@ -45,32 +104,36 @@ sub formbuilder (@) { #{{{ # of the temp file that CGI writes the upload to. my $tempfile=$q->tmpFileName($filename); - # Put the attachment in a subdir of the page it's attached - # to, unless that page is an "index" page. - my $page=$form->field('page'); - $page=~s/(^|\/)index//; - $filename=$page."/".IkiWiki::basename($filename); - - # To untaint the filename, escape any hazardous characters, - # and make sure it isn't pruned. - $filename=IkiWiki::titlepage(IkiWiki::possibly_foolish_untaint($filename)); + $filename=IkiWiki::titlepage( + IkiWiki::possibly_foolish_untaint( + attachment_location($form->field('page')). + IkiWiki::basename($filename))); if (IkiWiki::file_pruned($filename, $config{srcdir})) { error(gettext("bad attachment filename")); } # Check that the user is allowed to edit a page with the # name of the attachment. - IkiWiki::check_canedit($filename, $q, $params{session}, 1); + IkiWiki::check_canedit($filename, $q, $session, 1); - # Use a pagespec to test that the attachment is valid. - if (exists $config{valid_attachments} && - length $config{valid_attachments}) { - my $result=pagespec_match($filename, $config{valid_attachments}, - file => $tempfile); - if (! $result) { - error(gettext("attachment rejected")." ($result)"); + # Use a special pagespec to test that the attachment is valid. + my $allowed=1; + foreach my $admin (@{$config{adminuser}}) { + my $allowed_attachments=IkiWiki::userinfo_get($admin, "allowed_attachments"); + if (defined $allowed_attachments && + length $allowed_attachments) { + $allowed=pagespec_match($filename, + $allowed_attachments, + file => $tempfile); + last if $allowed; } } + if (! $allowed) { + error(gettext("attachment rejected")." ($allowed)"); + } + + # Needed for fast_file_copy and for rendering below. + require IkiWiki::Render; # Move the attachment into place. # Try to use a fast rename; fall back to copying. @@ -87,15 +150,24 @@ sub formbuilder (@) { #{{{ }); } - # TODO add to vcs - - # TODO trigger a wiki build if there's no vcs + # Check the attachment in and trigger a wiki refresh. + if ($config{rcs}) { + IkiWiki::rcs_add($filename); + IkiWiki::disable_commit_hook(); + IkiWiki::rcs_commit($filename, gettext("attachment upload"), + IkiWiki::rcs_prepedit($filename), + $session->param("name"), $ENV{REMOTE_ADDR}); + IkiWiki::enable_commit_hook(); + IkiWiki::rcs_update(); + } + IkiWiki::refresh(); + IkiWiki::saveindex(); } } # }}} package IkiWiki::PageSpec; -sub parsesize { #{{{ +sub parsesize ($) { #{{{ my $size=shift; no warnings; my $base=$size+0; # force to number