* Change %renderedfiles to store an array of files rendered from a given
authorjoey <joey@0fa5a96a-9a0e-0410-b3b2-a0fd24251071>
Sun, 8 Oct 2006 21:56:50 +0000 (21:56 +0000)
committerjoey <joey@0fa5a96a-9a0e-0410-b3b2-a0fd24251071>
Sun, 8 Oct 2006 21:56:50 +0000 (21:56 +0000)
  source file, to allow tracking of extra rendered files like rss feeds.
* Note that plugins that accessed this variable will need to be updated!
  The plugin interface has been increased to version 1.01 for this change.
* Add will_render function to the plugin interface, used to register that a
  page renders a destination file, and do some security checks.
* Use will_render in the inline and linkmap plugins.
* Previously but no longer rendered files will be cleaned up.
* You will need to rebuild your wiki on upgrade to this version.

12 files changed:
IkiWiki.pm
IkiWiki/Plugin/inline.pm
IkiWiki/Plugin/linkmap.pm
IkiWiki/Plugin/search.pm
IkiWiki/Render.pm
debian/NEWS
debian/changelog
debian/postinst
doc/bugs/rss_feed_cleanup_on_delete.mdwn
doc/plugins/contrib/img/discussion.mdwn
doc/plugins/write.mdwn
t/linkify.t

index 5c62c7f9bd5eb5deaa583228ded3040544ad0c64..6c0bc1f60eb5a4e8eabf0a5d3a72fae492abb054 100644 (file)
@@ -8,14 +8,15 @@ use HTML::Entities;
 use open qw{:utf8 :std};
 
 use vars qw{%config %links %oldlinks %oldpagemtime %pagectime %pagecase
 use open qw{:utf8 :std};
 
 use vars qw{%config %links %oldlinks %oldpagemtime %pagectime %pagecase
-            %renderedfiles %pagesources %depends %hooks %forcerebuild};
+            %renderedfiles %oldrenderedfiles %pagesources %depends %hooks
+           %forcerebuild};
 
 use Exporter q{import};
 our @EXPORT = qw(hook debug error template htmlpage add_depends pagespec_match
                  bestlink htmllink readfile writefile pagetype srcfile pagename
                  displaytime
                  %config %links %renderedfiles %pagesources);
 
 use Exporter q{import};
 our @EXPORT = qw(hook debug error template htmlpage add_depends pagespec_match
                  bestlink htmllink readfile writefile pagetype srcfile pagename
                  displaytime
                  %config %links %renderedfiles %pagesources);
-our $VERSION = 1.00;
+our $VERSION = 1.01;
 
 # Optimisation.
 use Memoize;
 
 # Optimisation.
 use Memoize;
@@ -261,6 +262,25 @@ sub writefile ($$$;$) { #{{{
        close OUT;
 } #}}}
 
        close OUT;
 } #}}}
 
+sub will_render ($$;$) { #{{{
+       my $page=shift;
+       my $dest=shift;
+       my $clear=shift;
+
+       # Important security check.
+       if (-e "$config{destdir}/$dest" && ! $config{rebuild} &&
+           ! grep { $_ eq $dest } (@{$renderedfiles{$page}}, @{$oldrenderedfiles{$page}})) {
+               error("$config{destdir}/$dest independently created, not overwriting with version from $page");
+       }
+
+       if (! $clear) {
+               $renderedfiles{$page}=[$dest, grep { $_ ne $dest } @{$renderedfiles{$page}}];
+       }
+       else {
+               $renderedfiles{$page}=[$dest];
+       }
+} #}}}
+
 sub bestlink ($$) { #{{{
        my $page=shift;
        my $link=shift;
 sub bestlink ($$) { #{{{
        my $page=shift;
        my $link=shift;
@@ -366,10 +386,10 @@ sub htmllink ($$$;$$$) { #{{{
        # TODO BUG: %renderedfiles may not have it, if the linked to page
        # was also added and isn't yet rendered! Note that this bug is
        # masked by the bug that makes all new files be rendered twice.
        # TODO BUG: %renderedfiles may not have it, if the linked to page
        # was also added and isn't yet rendered! Note that this bug is
        # masked by the bug that makes all new files be rendered twice.
-       if (! grep { $_ eq $bestlink } values %renderedfiles) {
+       if (! grep { $_ eq $bestlink } map { @{$_} } values %renderedfiles) {
                $bestlink=htmlpage($bestlink);
        }
                $bestlink=htmlpage($bestlink);
        }
-       if (! grep { $_ eq $bestlink } values %renderedfiles) {
+       if (! grep { $_ eq $bestlink } map { @{$_} } values %renderedfiles) {
                return "<span><a href=\"".
                        cgiurl(do => "create", page => lc($link), from => $page).
                        "\">?</a>$linktext</span>"
                return "<span><a href=\"".
                        cgiurl(do => "create", page => lc($link), from => $page).
                        "\">?</a>$linktext</span>"
@@ -529,6 +549,7 @@ sub loadindex () { #{{{
                chomp;
                my %items;
                $items{link}=[];
                chomp;
                my %items;
                $items{link}=[];
+               $items{dest}=[];
                foreach my $i (split(/ /, $_)) {
                        my ($item, $val)=split(/=/, $i, 2);
                        push @{$items{$item}}, decode_entities($val);
                foreach my $i (split(/ /, $_)) {
                        my ($item, $val)=split(/=/, $i, 2);
                        push @{$items{$item}}, decode_entities($val);
@@ -543,7 +564,8 @@ sub loadindex () { #{{{
                        $oldlinks{$page}=[@{$items{link}}];
                        $links{$page}=[@{$items{link}}];
                        $depends{$page}=$items{depends}[0] if exists $items{depends};
                        $oldlinks{$page}=[@{$items{link}}];
                        $links{$page}=[@{$items{link}}];
                        $depends{$page}=$items{depends}[0] if exists $items{depends};
-                       $renderedfiles{$page}=$items{dest}[0];
+                       $renderedfiles{$page}=[@{$items{dest}}];
+                       $oldrenderedfiles{$page}=[@{$items{dest}}];
                        $pagecase{lc $page}=$page;
                }
                $pagectime{$page}=$items{ctime}[0];
                        $pagecase{lc $page}=$page;
                }
                $pagectime{$page}=$items{ctime}[0];
@@ -563,8 +585,8 @@ sub saveindex () { #{{{
                next unless $oldpagemtime{$page};
                my $line="mtime=$oldpagemtime{$page} ".
                        "ctime=$pagectime{$page} ".
                next unless $oldpagemtime{$page};
                my $line="mtime=$oldpagemtime{$page} ".
                        "ctime=$pagectime{$page} ".
-                       "src=$pagesources{$page} ".
-                       "dest=$renderedfiles{$page}";
+                       "src=$pagesources{$page}";
+               $line.=" dest=$_" foreach @{$renderedfiles{$page}};
                $line.=" link=$_" foreach @{$links{$page}};
                if (exists $depends{$page}) {
                        $line.=" depends=".encode_entities($depends{$page}, " \t\n");
                $line.=" link=$_" foreach @{$links{$page}};
                if (exists $depends{$page}) {
                        $line.=" depends=".encode_entities($depends{$page}, " \t\n");
index 868f3816fa6d7e21bcdaed64b28042e3205e866c..c7cafee12e2e5330e859af78b8e3f29a7f33958a 100644 (file)
@@ -4,7 +4,7 @@ package IkiWiki::Plugin::inline;
 
 use warnings;
 use strict;
 
 use warnings;
 use strict;
-use IkiWiki;
+use IkiWiki 1.00;
 use IkiWiki::Render; # for displaytime
 use URI;
 
 use IkiWiki::Render; # for displaytime
 use URI;
 
@@ -154,10 +154,8 @@ sub preprocess_inline (@) { #{{{
                }
        }
        
                }
        }
        
-       # TODO: should really add this to renderedfiles and call
-       # check_overwrite, but currently renderedfiles
-       # only supports listing one file per page.
        if ($config{rss} && $rss) {
        if ($config{rss} && $rss) {
+               will_render($params{page}, rsspage($params{page}));
                writefile(rsspage($params{page}), $config{destdir},
                        genrss($desc, $params{page}, @list));
                $toping{$params{page}}=1 unless $config{rebuild};
                writefile(rsspage($params{page}), $config{destdir},
                        genrss($desc, $params{page}, @list));
                $toping{$params{page}}=1 unless $config{rebuild};
@@ -233,9 +231,7 @@ sub genrss ($$@) { #{{{
        my $itemtemplate=template("rssitem.tmpl", blind_cache => 1);
        my $content="";
        foreach my $p (@pages) {
        my $itemtemplate=template("rssitem.tmpl", blind_cache => 1);
        my $content="";
        foreach my $p (@pages) {
-               next unless exists $renderedfiles{$p};
-
-               my $u=URI->new(encode_utf8("$config{url}/$renderedfiles{$p}"));
+               my $u=URI->new(encode_utf8($config{url}."/".htmlpage($p)));
 
                $itemtemplate->param(
                        title => pagetitle(basename($p)),
 
                $itemtemplate->param(
                        title => pagetitle(basename($p)),
index 497b1ef43485dbdd4cb77043072f42c4a3b2898e..d7dffc941d93c828ca22ea091ebdde6062af26d2 100644 (file)
@@ -57,12 +57,10 @@ sub genmap ($) { #{{{
 
        # Use ikiwiki's function to create the file, this makes sure needed
        # subdirs are there and does some sanity checking.
 
        # Use ikiwiki's function to create the file, this makes sure needed
        # subdirs are there and does some sanity checking.
-       writefile("$params{page}.png", $config{destdir}, "");
+       will_render($params{page}, $params{page}.".png");
+       writefile($params{page}.".png", $config{destdir}, "");
 
        # Run dot to create the graphic and get the map data.
 
        # Run dot to create the graphic and get the map data.
-       # TODO: should really add the png to renderedfiles and call
-       # check_overwrite, but currently renderedfiles
-       # only supports listing one file per page.
        my $pid;
        my $sigpipe=0;;
        $SIG{PIPE}=sub { $sigpipe=1 };
        my $pid;
        my $sigpipe=0;;
        $SIG{PIPE}=sub { $sigpipe=1 };
index 5a4dfd491a896047e354b46af7f389ff3b994db5..a57a8404819b07f8449b634e0de32772a8c76ff8 100644 (file)
@@ -63,7 +63,8 @@ sub change (@) { #{{{
        debug("updating hyperestraier search index");
        estcmd("gather -cm -bc -cl -sd",
                map {
        debug("updating hyperestraier search index");
        estcmd("gather -cm -bc -cl -sd",
                map {
-                       Encode::encode_utf8($config{destdir}."/".$renderedfiles{pagename($_)})
+                       Encode::encode_utf8($config{destdir}."/".$_)
+                               foreach @{$renderedfiles{pagename($_)}};
                } @_
        );
        estcfg();
                } @_
        );
        estcfg();
index 48a25bef7a6fe417a2aa49498dbc010fcd1fefbb..deec539ae4b43fed8b3d4161baee55604dfdcc7b 100644 (file)
@@ -113,17 +113,6 @@ sub genpage ($$$) { #{{{
        return $content;
 } #}}}
 
        return $content;
 } #}}}
 
-sub check_overwrite ($$) { #{{{
-       # Important security check. Make sure to call this before saving
-       # any files to the source directory.
-       my $dest=shift;
-       my $src=shift;
-       
-       if (! exists $renderedfiles{$src} && -e $dest && ! $config{rebuild}) {
-               error("$dest already exists and was not rendered from $src before");
-       }
-} #}}}
-
 sub mtime ($) { #{{{
        my $file=shift;
        
 sub mtime ($) { #{{{
        my $file=shift;
        
@@ -157,6 +146,7 @@ sub render ($) { #{{{
                my $content=readfile($srcfile);
                my $page=pagename($file);
                delete $depends{$page};
                my $content=readfile($srcfile);
                my $page=pagename($file);
                delete $depends{$page};
+               will_render($page, htmlpage($page), 1);
                
                $content=filter($page, $content);
                
                
                $content=filter($page, $content);
                
@@ -166,20 +156,17 @@ sub render ($) { #{{{
                $content=linkify($page, $page, $content);
                $content=htmlize($page, $type, $content);
                
                $content=linkify($page, $page, $content);
                $content=htmlize($page, $type, $content);
                
-               check_overwrite("$config{destdir}/".htmlpage($page), $page);
                writefile(htmlpage($page), $config{destdir},
                        genpage($page, $content, mtime($srcfile)));
                $oldpagemtime{$page}=time;
                writefile(htmlpage($page), $config{destdir},
                        genpage($page, $content, mtime($srcfile)));
                $oldpagemtime{$page}=time;
-               $renderedfiles{$page}=htmlpage($page);
        }
        else {
                my $content=readfile($srcfile, 1);
                $links{$file}=[];
                delete $depends{$file};
        }
        else {
                my $content=readfile($srcfile, 1);
                $links{$file}=[];
                delete $depends{$file};
-               check_overwrite("$config{destdir}/$file", $file);
+               will_render($file, $file, 1);
                writefile($file, $config{destdir}, $content, 1);
                $oldpagemtime{$file}=time;
                writefile($file, $config{destdir}, $content, 1);
                $oldpagemtime{$file}=time;
-               $renderedfiles{$file}=$file;
        }
 } #}}}
 
        }
 } #}}}
 
@@ -269,9 +256,10 @@ sub refresh () { #{{{
                if (! $exists{$page}) {
                        debug("removing old page $page");
                        push @del, $pagesources{$page};
                if (! $exists{$page}) {
                        debug("removing old page $page");
                        push @del, $pagesources{$page};
-                       prune($config{destdir}."/".$renderedfiles{$page});
-                       delete $renderedfiles{$page};
+                       $renderedfiles{$page}=[];
                        $oldpagemtime{$page}=0;
                        $oldpagemtime{$page}=0;
+                       prune($config{destdir}."/".$_)
+                               foreach @{$oldrenderedfiles{$page}};
                        delete $pagesources{$page};
                }
        }
                        delete $pagesources{$page};
                }
        }
@@ -366,6 +354,17 @@ FILE:              foreach my $file (@files) {
                }
        }
 
                }
        }
 
+       # Remove no longer rendered files.
+       foreach my $src (keys %rendered) {
+               my $page=pagename($src);
+               foreach my $file (@{$oldrenderedfiles{$page}}) {
+                       if (! grep { $_ eq $file } @{$renderedfiles{$page}}) {
+                               debug("removing $file, no longer rendered by $page");
+                               prune($config{destdir}."/".$file);
+                       }
+               }
+       }
+
        if (@del) {
                run_hooks(delete => sub { shift->(@del) });
        }
        if (@del) {
                run_hooks(delete => sub { shift->(@del) });
        }
index a921d0c0ee4d615706cf3edf665ef0d8f5ff0d4d..f3556d622b942d6d4226fe909fb698a6c6324904 100644 (file)
@@ -1,8 +1,21 @@
+ikiwiki (1.29) unstable; urgency=low
+
+  Wikis need to be rebuilt on upgrade to this version. If you listed your wiki
+  in /etc/ikiwiki/wikilist this will be done automatically when the Debian
+  package is upgraded. Or use ikiwiki-mass-rebuild to force a rebuild.
+
+  There is a change to the plugin interface in this version. Plugins that use
+  %renderedfiles will need to be updated, as the hash's values are now arrays
+  of rendered files. Plugins that cause a page to render additional files
+  should use the new will_render function to register the files.
+
+ -- Joey Hess <joeyh@debian.org>  Sun,  8 Oct 2006 17:27:56 -0400
+
 ikiwiki (1.22) unstable; urgency=low
   
   Due to some changes in the CSS, wikis should be rebuilt on upgrade to this
   version. If you listed your wiki in /etc/ikiwiki/wikilist this will be done
 ikiwiki (1.22) unstable; urgency=low
   
   Due to some changes in the CSS, wikis should be rebuilt on upgrade to this
   version. If you listed your wiki in /etc/ikiwiki/wikilist this will be done
-  automatically when the Debian package is upgraded. Or use ikiiki-mass-rebuild
+  automatically when the Debian package is upgraded. Or use ikiwiki-mass-rebuild
   to force a rebuild.
 
   If you have modified versions of ikiwiki's html templates, you will need
   to force a rebuild.
 
   If you have modified versions of ikiwiki's html templates, you will need
index b037b517a95d1f7cfee8f0c6a3a638aeceaf2515..758a81c478fa59b98dc259fe7d442f8926564ef2 100644 (file)
@@ -5,8 +5,17 @@ ikiwiki (1.29) UNRELEASED; urgency=low
     using HTTP Authentication instead of ikiwiki's built in authentication.
     Useful for eg, large sites with their own previously existing user auth
     setup. Closes: #384534
     using HTTP Authentication instead of ikiwiki's built in authentication.
     Useful for eg, large sites with their own previously existing user auth
     setup. Closes: #384534
-
- -- Joey Hess <joeyh@debian.org>  Mon,  2 Oct 2006 18:50:29 -0400
+  * Change %renderedfiles to store an array of files rendered from a given
+    source file, to allow tracking of extra rendered files like rss feeds.
+  * Note that plugins that accessed this variable will need to be updated!
+    The plugin interface has been increased to version 1.01 for this change.
+  * Add will_render function to the plugin interface, used to register that a
+    page renders a destination file, and do some security checks.
+  * Use will_render in the inline and linkmap plugins.
+  * Previously but no longer rendered files will be cleaned up.
+  * You will need to rebuild your wiki on upgrade to this version.
+
+ -- Joey Hess <joeyh@debian.org>  Sun,  8 Oct 2006 16:53:17 -0400
 
 ikiwiki (1.28) unstable; urgency=low
 
 
 ikiwiki (1.28) unstable; urgency=low
 
index 006325b4adbbfd22980dbacdd7592974791918ed..96572ea62d2a24348c8ee9ef20e491ce7bf81eb2 100755 (executable)
@@ -4,7 +4,7 @@ set -e
 
 # Change this when some incompatible change is made that requires
 # rebuilding all wikis.
 
 # Change this when some incompatible change is made that requires
 # rebuilding all wikis.
-firstcompat=1.22
+firstcompat=1.29
 
 if [ "$1" = configure ] && \
    dpkg --compare-versions "$2" lt "$firstcompat"; then
 
 if [ "$1" = configure ] && \
    dpkg --compare-versions "$2" lt "$firstcompat"; then
index 32cdba0ccc0b91b28049250e453aa3e5e6582ae7..fe0400ff89d49c8b071d05a7467a010c93ba364b 100644 (file)
@@ -2,3 +2,5 @@ If a page stops inlining anthing, its rss feed file will linger around and
 not be deleted.
 
 (The linkmap plugin has the same problem with the png files it creates.)
 not be deleted.
 
 (The linkmap plugin has the same problem with the png files it creates.)
+
+[[bugs/done]]
index c72752cf11a70859936af3fa69a405b662c5fff2..d4b38fb61dc365e287df3bd3b92c9cdc870b86e5 100644 (file)
@@ -43,9 +43,9 @@ Benefits of not scaling:
 1. Avoids any security issues with imagemagick.
 2. Avoids issue of how to clean up old scaled images that are no longer being
    used. (Granted, this is a general ikiwiki problem that will eventually
 1. Avoids any security issues with imagemagick.
 2. Avoids issue of how to clean up old scaled images that are no longer being
    used. (Granted, this is a general ikiwiki problem that will eventually
-   be fixed in a general way.)
+   be fixed in a general way. (Update: now fixed in a general way, use the
+   will_render function.))
 3. Makes clicking on thumbnails display the full version really fast, since
    it's cached. :-)
 
 3. Makes clicking on thumbnails display the full version really fast, since
    it's cached. :-)
 
-
 --[[Joey]]
 --[[Joey]]
index 57521687e10a7534e55df59be277a9e000a9dfff..8145a35627581c2b4def8017e54d5685896efbb2 100644 (file)
@@ -197,7 +197,8 @@ use the following hashes, using a page name as the key:
 
 * `%links` lists the names of each page that a page links to, in an array
   reference.
 
 * `%links` lists the names of each page that a page links to, in an array
   reference.
-* `%renderedfiles` contains the name of the file rendered by a page.
+* `%renderedfiles` lists names of the files rendered by a page, in an array
+  reference.
 * `%pagesources` contains the name of the source file for a page.
 
 ### Library functions
 * `%pagesources` contains the name of the source file for a page.
 
 ### Library functions
@@ -293,6 +294,13 @@ A failure to write the file will result in it dying with an error.
 
 If the destination directory doesn't exist, it will first be created.
 
 
 If the destination directory doesn't exist, it will first be created.
 
+### `will_render($$)`
+
+Given a page name and a destination file name (not including the base
+destination directory), register that the page will result in that file
+being rendered. It's important to call this before writing to any file in
+the destination directory.
+
 #### `pagetype($)`
 
 Given the name of a source file, returns the type of page it is, if it's
 #### `pagetype($)`
 
 Given the name of a source file, returns the type of page it is, if it's
index 74747e1270339104e53f0edfd2e9b80c301a1adc..4de2b51ae74b78b42bec0bc9c2aa1b489a9a1e09 100755 (executable)
@@ -19,7 +19,7 @@ sub linkify ($$$$) {
        foreach my $page (@existing_pages) {
                $IkiWiki::pagecase{lc $page}=$page;
                $links{$page}=[];
        foreach my $page (@existing_pages) {
                $IkiWiki::pagecase{lc $page}=$page;
                $links{$page}=[];
-               $renderedfiles{"$page.mdwn"}=$page;
+               $renderedfiles{"$page.mdwn"}=[$page];
        }
        %config=IkiWiki::defaultconfig();
 
        }
        %config=IkiWiki::defaultconfig();