added --getctime
authorjoey <joey@0fa5a96a-9a0e-0410-b3b2-a0fd24251071>
Sun, 26 Mar 2006 02:30:44 +0000 (02:30 +0000)
committerjoey <joey@0fa5a96a-9a0e-0410-b3b2-a0fd24251071>
Sun, 26 Mar 2006 02:30:44 +0000 (02:30 +0000)
IkiWiki/Rcs/SVN.pm
IkiWiki/Rcs/Stub.pm
IkiWiki/Wrapper.pm
doc/security.mdwn
doc/todo/blogging.mdwn
doc/usage.mdwn
ikiwiki

index 946412320a35d305e3a9d6aff15411f3ad15eec5..083b869df23906ad6cf2c1c29ac510493820d688 100644 (file)
@@ -1,10 +1,12 @@
-#!/usr/bin/perl -T
+#!/usr/bin/perl
 # For subversion support.
 
 use warnings;
 use strict;
 
 package IkiWiki;
+               
+my $svn_log_infoline=qr/^r(\d+)\s+\|\s+([^\s]+)\s+\|\s+(\d+-\d+-\d+\s+\d+:\d+:\d+\s+[-+]?\d+).*/;
 
 sub svn_info ($$) { #{{{
        my $field=shift;
@@ -107,7 +109,6 @@ sub rcs_recentchanges ($) { #{{{
                my ($svn_base)=$svn_url=~m!(/trunk(?:/.*)?)$!;
                
                my $div=qr/^--------------------+$/;
-               my $infoline=qr/^r(\d+)\s+\|\s+([^\s]+)\s+\|\s+(\d+-\d+-\d+\s+\d+:\d+:\d+\s+[-+]?\d+).*/;
                my $state='start';
                my ($rev, $user, $when, @pages, @message);
                foreach (`LANG=C svn log --limit $num -v '$svn_url'`) {
@@ -115,7 +116,7 @@ sub rcs_recentchanges ($) { #{{{
                        if ($state eq 'start' && /$div/) {
                                $state='header';
                        }
-                       elsif ($state eq 'header' && /$infoline/) {
+                       elsif ($state eq 'header' && /$svn_log_infoline/) {
                                $rev=$1;
                                $user=$2;
                                $when=concise(ago(time - str2time($3)));
@@ -166,4 +167,31 @@ sub rcs_recentchanges ($) { #{{{
        return @ret;
 } #}}}
 
+sub rcs_getctime () { #{{{
+       eval q{use Date::Parse};
+       foreach my $page (keys %pagectime) {
+               my $file="$config{srcdir}/$pagesources{$page}";
+               my $child = open(SVNLOG, "-|");
+               if (! $child) {
+                       exec("svn", "log", $file) || error("svn log $file failed to run");
+               }
+
+               my $date;
+               while (<SVNLOG>) {
+                       if (/$svn_log_infoline/) {
+                               $date=$3;
+                       }
+               }
+               close SVNLOG || warn "svn log $file exited $?";
+
+               if (! defined $date) {
+                       warn "failed to parse svn log for $file\n";
+                       next;
+               }
+               
+               $pagectime{$page}=$date=str2time($date);
+               debug("found ctime ".localtime($date)." for $page");
+       }
+} #}}}
+
 1
index d3b72b5ea97bf3505e138fc8098007598bd1687a..d2a6ad003afca02868e0e587d22d8e0649e1703d 100644 (file)
@@ -1,4 +1,4 @@
-#!/usr/bin/perl -T
+#!/usr/bin/perl
 # Stubs for no revision control.
 
 use warnings;
@@ -23,4 +23,8 @@ sub rcs_add ($) {
 sub rcs_recentchanges ($) {
 }
 
+sub rcs_getctime () {
+       error "getctime not implemented";
+}
+
 1
index 4966c453ab99732369efa6428e54b84b4ed146da..85d2591175a3904c97f94bf95566b5dd7cf89336 100644 (file)
@@ -38,7 +38,7 @@ EOF
        $configstring=~s/\\/\\\\/g;
        $configstring=~s/"/\\"/g;
        
-       open(OUT, ">ikiwiki-wrap.c") || error("failed to write ikiwiki-wrap.c: $!");;
+       open(OUT, ">$wrapper.c") || error("failed to write $wrapper.c: $!");;
        print OUT <<"EOF";
 /* A wrapper for ikiwiki, can be safely made suid. */
 #define _GNU_SOURCE
@@ -66,10 +66,10 @@ $envsave
 }
 EOF
        close OUT;
-       if (system("gcc", "ikiwiki-wrap.c", "-o", $wrapper) != 0) {
-               error("failed to compile ikiwiki-wrap.c");
+       if (system("gcc", "$wrapper.c", "-o", $wrapper) != 0) {
+               error("failed to compile $wrapper.c");
        }
-       unlink("ikiwiki-wrap.c");
+       unlink("$wrapper.c");
        if (defined $config{wrappermode} &&
            ! chmod(oct($config{wrappermode}), $wrapper)) {
                error("chmod $wrapper: $!");
index c7a6fcd69dd0d91df051d793ce2d1a0bd2299a52..48d82db898c0f1a8c210ecafdcc97e90bf2f5c6a 100644 (file)
@@ -46,7 +46,9 @@ this wiki, BTW.
 
 Anyone with svn commit access can forge "web commit from foo" and make it appear on [[RecentChanges]] like foo committed. One way to avoid this would be to limit web commits to those done by a certian user.
 
-It's actually possible to force a whole series of svn commits to appear to have come just before yours, by forging svn log output. This could be guarded against somewhat by revision number scanning, since the forged revisions would duplicate the numbers of unforged ones. Or subversion could fix svn log to indent commit messages, which would make such forgery impossible..
+It's actually possible to force a whole series of svn commits to appear to
+have come just before yours, by forging svn log output. This could be
+guarded against by using svn log --xml.
 
 ikiwiki escapes any html in svn commit logs to prevent other mischief.
 
index 7d89a9904fd1c44d9da36ab0e383d026483a7664..680570d848d4136bec418a89a375eeca2118d178 100644 (file)
@@ -3,10 +3,4 @@
 - The [[TODO]] page would work better if the first N were shown in full, 
   and then all open items were shown in summary. Maybe add this mode.
 - Add Discussion and Edit links at the bottom of each inlined post.
-- Still not completly comfortable with ikiwiki only knowing when a page was
-  posted based on the on-disk mtime the first time it sees the page. svn doesn't
-  preserve mtimes and also if the index gets broken it will see new mtimes for any
-  pages that were actually modified in the interim. I suppose that info could 
-  be pulled out of svn log by a utility that was run if the index or mtimes 
-  got screwed up.
-- It would be possible to support rss enclosures for eg, podcasts, pretty easily. 
\ No newline at end of file
+- It would be possible to support rss enclosures for eg, podcasts, pretty easily. 
index f36886d7532a9975bf5eead107d899b9dadf6664..aa4978773552d90f0f0e2287dc4fcfd8edc722c6 100644 (file)
@@ -30,6 +30,13 @@ flags such as --verbose can be negated with --no-verbose.
 
   Force a rebuild of all pages.
 
+* --fixctime
+
+  Pull last changed time for all pages out of the revision control system.
+  This rarely used option provides a way to get the real creation times of
+  items in weblogs, for example when building a wiki from a new subversion
+  checkout. It is unoptimised and quite slow.
+
 * --templatedir
 
   Specify the directory that the page [[templates]] are stored in.
diff --git a/ikiwiki b/ikiwiki
index 235a72102f61ee3078871ae7d2be37ccb2de99d2..ab9f3fc2f68d862284787258c699ebc33bdcd410 100755 (executable)
--- a/ikiwiki
+++ b/ikiwiki
@@ -34,6 +34,7 @@ sub getconfig () { #{{{
                        anonok => 0,
                        rss => 0,
                        rebuild => 0,
+                       getctime => 0,
                        wrapper => undef,
                        wrappermode => undef,
                        srcdir => undef,
@@ -49,6 +50,7 @@ sub getconfig () { #{{{
                        "wikiname=s" => \$config{wikiname},
                        "verbose|v!" => \$config{verbose},
                        "rebuild!" => \$config{rebuild},
+                       "getctime" => \$config{getctime},
                        "wrappermode=i" => \$config{wrappermode},
                        "svn!" => \$config{svn},
                        "anonok!" => \$config{anonok},
@@ -486,6 +488,7 @@ sub main () { #{{{
                loadindex();
                require IkiWiki::Render;
                rcs_update();
+               rcs_getctime() if $config{getctime};
                refresh();
                saveindex();
        }