]> git.vanrenterghem.biz Git - git.ikiwiki.info.git/blobdiff - IkiWiki.pm
major optimisation idea
[git.ikiwiki.info.git] / IkiWiki.pm
index 7035cb034d96bdf3f2a92a8655e94e2b597bf39e..87ddb1b5643dc279a5a5ea037b9c7ce398d69ba2 100644 (file)
@@ -20,9 +20,9 @@ use Exporter q{import};
 our @EXPORT = qw(hook debug error htmlpage template template_depends
        deptype add_depends pagespec_match pagespec_match_list bestlink
        htmllink readfile writefile pagetype srcfile pagename
 our @EXPORT = qw(hook debug error htmlpage template template_depends
        deptype add_depends pagespec_match pagespec_match_list bestlink
        htmllink readfile writefile pagetype srcfile pagename
-       displaytime will_render gettext ngettext urlto targetpage
+       displaytime strftime_utf8 will_render gettext ngettext urlto targetpage
        add_underlay pagetitle titlepage linkpage newpagefile
        add_underlay pagetitle titlepage linkpage newpagefile
-       inject add_link add_autofile
+       inject add_link add_autofile useragent
        %config %links %pagestate %wikistate %renderedfiles
        %pagesources %destsources %typedlinks);
 our $VERSION = 3.00; # plugin interface version, next is ikiwiki version
        %config %links %pagestate %wikistate %renderedfiles
        %pagesources %destsources %typedlinks);
 our $VERSION = 3.00; # plugin interface version, next is ikiwiki version
@@ -118,6 +118,22 @@ sub getsetup () {
                safe => 0,
                rebuild => 0,
        },
                safe => 0,
                rebuild => 0,
        },
+       cgi_overload_delay => {
+               type => "string",
+               default => '',
+               example => "10",
+               description => "number of seconds to delay CGI requests when overloaded",
+               safe => 1,
+               rebuild => 0,
+       },
+       cgi_overload_message => {
+               type => "string",
+               default => '',
+               example => "Please wait",
+               description => "message to display when overloaded (may contain html)",
+               safe => 1,
+               rebuild => 0,
+       },
        rcs => {
                type => "string",
                default => '',
        rcs => {
                type => "string",
                default => '',
@@ -305,9 +321,9 @@ sub getsetup () {
                rebuild => 0,
        },
        umask => {
                rebuild => 0,
        },
        umask => {
-               type => "integer",
-               example => "022",
-               description => "force ikiwiki to use a particular umask",
+               type => "string",
+               example => "public",
+               description => "force ikiwiki to use a particular umask (keywords public, group or private, or a number)",
                advanced => 1,
                safe => 0, # paranoia
                rebuild => 0,
                advanced => 1,
                safe => 0, # paranoia
                rebuild => 0,
@@ -497,6 +513,13 @@ sub getsetup () {
                safe => 0,
                rebuild => 0,
        },
                safe => 0,
                rebuild => 0,
        },
+       cookiejar => {
+               type => "string",
+               default => { file => "$ENV{HOME}/.ikiwiki/cookies" },
+               description => "cookie control",
+               safe => 0, # hooks into perl module internals
+               rebuild => 0,
+       },
 }
 
 sub defaultconfig () {
 }
 
 sub defaultconfig () {
@@ -587,7 +610,23 @@ sub checkconfig () {
                unless exists $config{wikistatedir} && defined $config{wikistatedir};
 
        if (defined $config{umask}) {
                unless exists $config{wikistatedir} && defined $config{wikistatedir};
 
        if (defined $config{umask}) {
-               umask(possibly_foolish_untaint($config{umask}));
+               my $u = possibly_foolish_untaint($config{umask});
+
+               if ($u =~ m/^\d+$/) {
+                       umask($u);
+               }
+               elsif ($u eq 'private') {
+                       umask(077);
+               }
+               elsif ($u eq 'group') {
+                       umask(027);
+               }
+               elsif ($u eq 'public') {
+                       umask(022);
+               }
+               else {
+                       error(sprintf(gettext("unsupported umask setting %s"), $u));
+               }
        }
 
        run_hooks(checkconfig => sub { shift->() });
        }
 
        run_hooks(checkconfig => sub { shift->() });
@@ -1076,6 +1115,11 @@ sub cgiurl (@) {
                join("&", map $_."=".uri_escape_utf8($params{$_}), keys %params);
 }
 
                join("&", map $_."=".uri_escape_utf8($params{$_}), keys %params);
 }
 
+sub cgiurl_abs (@) {
+       eval q{use URI};
+       URI->new_abs(cgiurl(@_), $config{cgiurl});
+}
+
 sub baseurl (;$) {
        my $page=shift;
 
 sub baseurl (;$) {
        my $page=shift;
 
@@ -1132,9 +1176,19 @@ sub formattime ($;$) {
                $format=$config{timeformat};
        }
 
                $format=$config{timeformat};
        }
 
+       return strftime_utf8($format, localtime($time));
+}
+
+my $strftime_encoding;
+sub strftime_utf8 {
        # strftime doesn't know about encodings, so make sure
        # strftime doesn't know about encodings, so make sure
-       # its output is properly treated as utf8
-       return decode_utf8(POSIX::strftime($format, localtime($time)));
+       # its output is properly treated as utf8.
+       # Note that this does not handle utf-8 in the format string.
+       ($strftime_encoding) = POSIX::setlocale(&POSIX::LC_TIME) =~ m#\.([^@]+)#
+               unless defined $strftime_encoding;
+       $strftime_encoding
+               ? Encode::decode($strftime_encoding, POSIX::strftime(@_))
+               : POSIX::strftime(@_);
 }
 
 sub date_3339 ($) {
 }
 
 sub date_3339 ($) {
@@ -1237,7 +1291,7 @@ sub htmllink ($$$;@) {
                                $cgilink = "<a href=\"".
                                        cgiurl(
                                                do => "create",
                                $cgilink = "<a href=\"".
                                        cgiurl(
                                                do => "create",
-                                               page => lc($link),
+                                               page => $link,
                                                from => $lpage
                                        )."\" rel=\"nofollow\">?</a>";
                        }
                                                from => $lpage
                                        )."\" rel=\"nofollow\">?</a>";
                        }
@@ -1386,7 +1440,7 @@ sub preprocess ($$$;$$) {
                        # consider it significant.
                        my @params;
                        while ($params =~ m{
                        # consider it significant.
                        my @params;
                        while ($params =~ m{
-                               (?:([-\w]+)=)?          # 1: named parameter key?
+                               (?:([-.\w]+)=)?         # 1: named parameter key?
                                (?:
                                        """(.*?)"""     # 2: triple-quoted value
                                |
                                (?:
                                        """(.*?)"""     # 2: triple-quoted value
                                |
@@ -1394,7 +1448,8 @@ sub preprocess ($$$;$$) {
                                |
                                        '''(.*?)'''     # 4: triple-single-quote
                                |
                                |
                                        '''(.*?)'''     # 4: triple-single-quote
                                |
-                                       <<(?<start>[a-zA-Z]+)\n(?<heredoc>.*?)\n\k<start> # 5, 6: heredoc'd value.
+                                       <<([a-zA-Z]+)\n # 5: heredoc start
+                                       (.*?)\n\5       # 6: heredoc value
                                |
                                        (\S+)           # 7: unquoted value
                                )
                                |
                                        (\S+)           # 7: unquoted value
                                )
@@ -1417,8 +1472,8 @@ sub preprocess ($$$;$$) {
                                elsif (defined $7) {
                                        $val=$7;
                                }
                                elsif (defined $7) {
                                        $val=$7;
                                }
-                               elsif (defined $+{heredoc}) {
-                                       $val=$+{heredoc};
+                               elsif (defined $6) {
+                                       $val=$6;
                                }
 
                                if (defined $key) {
                                }
 
                                if (defined $key) {
@@ -1482,15 +1537,16 @@ sub preprocess ($$$;$$) {
                        (               # 4: the parameters..
                                \s+     # Must have space if parameters present
                                (?:
                        (               # 4: the parameters..
                                \s+     # Must have space if parameters present
                                (?:
-                                       (?:[-\w]+=)?            # named parameter key?
+                                       (?:[-.\w]+=)?           # named parameter key?
                                        (?:
                                                """.*?"""       # triple-quoted value
                                                |
                                                "[^"]*?"        # single-quoted value
                                                |
                                        (?:
                                                """.*?"""       # triple-quoted value
                                                |
                                                "[^"]*?"        # single-quoted value
                                                |
-                                               <<(?<start>[a-zA-Z]+)\n(?<heredoc>.*?)\n\k<start> # heredoc'd value.
+                                               '''.*?'''       # triple-single-quote
                                                |
                                                |
-                                               '''.*?''' # triple-single-quoted value
+                                               <<([a-zA-Z]+)\n # 5: heredoc start
+                                               (?:.*?)\n\5     # heredoc value
                                                |
                                                [^"\s\]]+       # unquoted value
                                        )
                                                |
                                                [^"\s\]]+       # unquoted value
                                        )
@@ -1509,15 +1565,16 @@ sub preprocess ($$$;$$) {
                        \s+
                        (               # 4: the parameters..
                                (?:
                        \s+
                        (               # 4: the parameters..
                                (?:
-                                       (?:[-\w]+=)?            # named parameter key?
+                                       (?:[-.\w]+=)?           # named parameter key?
                                        (?:
                                                """.*?"""       # triple-quoted value
                                                |
                                                "[^"]*?"        # single-quoted value
                                                |
                                        (?:
                                                """.*?"""       # triple-quoted value
                                                |
                                                "[^"]*?"        # single-quoted value
                                                |
-                                               '''.*?'''       # triple-single-quoted value
+                                               '''.*?'''       # triple-single-quote
                                                |
                                                |
-                                               <<(?<start>[a-zA-Z]+)\n(?<heredoc>.*?)\n\k<start> # heredoc'd value.
+                                               <<([a-zA-Z]+)\n # 5: heredoc start
+                                               (?:.*?)\n\5     # heredoc value
                                                |
                                                [^"\s\]]+       # unquoted value
                                        )
                                                |
                                                [^"\s\]]+       # unquoted value
                                        )
@@ -2224,6 +2281,13 @@ sub add_autofile ($$$) {
        $autofiles{$file}{generator}=$generator;
 }
 
        $autofiles{$file}{generator}=$generator;
 }
 
+sub useragent () {
+       return LWP::UserAgent->new(
+               cookie_jar => $config{cookiejar},
+               env_proxy => 1,         # respect proxy env vars
+       );
+}
+
 sub sortspec_translate ($$) {
        my $spec = shift;
        my $reverse = shift;
 sub sortspec_translate ($$) {
        my $spec = shift;
        my $reverse = shift;
@@ -2628,8 +2692,14 @@ sub match_link ($$;@) {
 }
 
 sub match_backlink ($$;@) {
 }
 
 sub match_backlink ($$;@) {
-       my $ret=match_link($_[1], $_[0], @_);
-       $ret->influences($_[1] => $IkiWiki::DEPEND_LINKS);
+       my $page=shift;
+       my $testpage=shift;
+       my %params=@_;
+       if ($testpage eq '.') {
+               $testpage = $params{'location'}
+       }
+       my $ret=match_link($testpage, $page, @_);
+       $ret->influences($testpage => $IkiWiki::DEPEND_LINKS);
        return $ret;
 }
 
        return $ret;
 }
 
@@ -2720,12 +2790,12 @@ sub match_user ($$;@) {
        my $user=shift;
        my %params=@_;
        
        my $user=shift;
        my %params=@_;
        
-       my $regexp=IkiWiki::glob2re($user);
-       
        if (! exists $params{user}) {
                return IkiWiki::ErrorReason->new("no user specified");
        }
 
        if (! exists $params{user}) {
                return IkiWiki::ErrorReason->new("no user specified");
        }
 
+       my $regexp=IkiWiki::glob2re($user);
+       
        if (defined $params{user} && $params{user}=~$regexp) {
                return IkiWiki::SuccessReason->new("user is $user");
        }
        if (defined $params{user} && $params{user}=~$regexp) {
                return IkiWiki::SuccessReason->new("user is $user");
        }
@@ -2765,8 +2835,10 @@ sub match_ip ($$;@) {
        if (! exists $params{ip}) {
                return IkiWiki::ErrorReason->new("no IP specified");
        }
        if (! exists $params{ip}) {
                return IkiWiki::ErrorReason->new("no IP specified");
        }
+       
+       my $regexp=IkiWiki::glob2re(lc $ip);
 
 
-       if (defined $params{ip} && lc $params{ip} eq lc $ip) {
+       if (defined $params{ip} && lc $params{ip}=~$regexp) {
                return IkiWiki::SuccessReason->new("IP is $ip");
        }
        else {
                return IkiWiki::SuccessReason->new("IP is $ip");
        }
        else {
@@ -2789,6 +2861,7 @@ sub cmp_title {
        IkiWiki::pagetitle(IkiWiki::basename($b))
 }
 
        IkiWiki::pagetitle(IkiWiki::basename($b))
 }
 
+sub cmp_path { IkiWiki::pagetitle($a) cmp IkiWiki::pagetitle($b) }
 sub cmp_mtime { $IkiWiki::pagemtime{$b} <=> $IkiWiki::pagemtime{$a} }
 sub cmp_age { $IkiWiki::pagectime{$b} <=> $IkiWiki::pagectime{$a} }
 
 sub cmp_mtime { $IkiWiki::pagemtime{$b} <=> $IkiWiki::pagemtime{$a} }
 sub cmp_age { $IkiWiki::pagectime{$b} <=> $IkiWiki::pagectime{$a} }