X-Git-Url: https://sipb.mit.edu/gitweb.cgi/ikiwiki.git/blobdiff_plain/3479809f96fa9c7a5d9f86c18c581f9a343a3aef..c2d3fa435273e7ccad5c2404debdfdab04168b39:/ikiwiki-transition diff --git a/ikiwiki-transition b/ikiwiki-transition index 0e2bd4e22..ce1807309 100755 --- a/ikiwiki-transition +++ b/ikiwiki-transition @@ -1,4 +1,4 @@ -#!/usr/bin/perl -i +#!/usr/bin/perl use warnings; use strict; use IkiWiki; @@ -42,21 +42,41 @@ sub handle_directive { } sub prefix_directives { - $/=undef; # process whole files at once - - while (<>) { - s{$regex}{handle_directive($1, $2, $3, $4)}eg; - print; + my $setup=shift; + if (! defined $setup) { + usage(); } -} -sub indexdb { - $config{wikistatedir}=shift()."/.ikiwiki"; + require IkiWiki::Setup; + require IkiWiki::Plugin::aggregate; - if (! defined $config{wikistatedir}) { - usage(); + %config = IkiWiki::defaultconfig(); + IkiWiki::Setup::load($setup); + IkiWiki::loadplugins(); + IkiWiki::checkconfig(); + IkiWiki::loadindex(); + + if (! %pagesources) { + error "ikiwiki has not built this wiki yet, cannot transition"; } + foreach my $page (values %pagesources) { + next unless defined pagetype($page) && + -f $config{srcdir}."/".$page; + my $content=readfile($config{srcdir}."/".$page); + my $oldcontent=$content; + $content=~s{$regex}{handle_directive($1, $2, $3, $4)}eg; + if ($oldcontent ne $content) { + writefile($page, $config{srcdir}, $content); + } + } +} + +sub indexdb { + setstatedir(shift); + + # Note: No lockwiki here because ikiwiki already locks it + # before calling this. if (! IkiWiki::oldloadindex()) { die "failed to load index\n"; } @@ -71,11 +91,166 @@ sub indexdb { } } +sub hashpassword { + setstatedir(shift); + + eval q{use IkiWiki::UserInfo}; + eval q{use Authen::Passphrase::BlowfishCrypt}; + if ($@) { + error("ikiwiki-transition hashpassword: failed to load Authen::Passphrase, passwords not hashed"); + } + + IkiWiki::lockwiki(); + IkiWiki::loadplugin("passwordauth"); + my $userinfo = IkiWiki::userinfo_retrieve(); + foreach my $user (keys %{$userinfo}) { + if (ref $userinfo->{$user} && + exists $userinfo->{$user}->{password} && + length $userinfo->{$user}->{password} && + ! exists $userinfo->{$user}->{cryptpassword}) { + IkiWiki::Plugin::passwordauth::setpassword($user, $userinfo->{$user}->{password}); + } + } +} + +sub aggregateinternal { + my $setup=shift; + if (! defined $setup) { + usage(); + } + + require IkiWiki::Setup; + require IkiWiki::Plugin::aggregate; + + %config = IkiWiki::defaultconfig(); + IkiWiki::Setup::load($setup); + IkiWiki::checkconfig(); + + IkiWiki::Plugin::aggregate::migrate_to_internal(); +} + +sub setupformat { + my $setup=shift; + if (! defined $setup) { + usage(); + } + + require IkiWiki::Setup; + + %config = IkiWiki::defaultconfig(); + IkiWiki::Setup::load($setup); + IkiWiki::checkconfig(); + + # unpack old-format wrappers setting into new fields + my $cgi_seen=0; + my $rcs_seen=0; + foreach my $wrapper (@{$config{wrappers}}) { + if ($wrapper->{cgi}) { + if ($cgi_seen) { + die "don't know what to do with second cgi wrapper ".$wrapper->{wrapper}."\n"; + } + $cgi_seen++; + print "setting cgi_wrapper to ".$wrapper->{wrapper}."\n"; + $config{cgi_wrapper}=$wrapper->{wrapper}; + $config{cgi_wrappermode}=$wrapper->{wrappermode} + if exists $wrapper->{wrappermode}; + } + elsif ($config{rcs}) { + if ($rcs_seen) { + die "don't know what to do with second rcs wrapper ".$wrapper->{wrapper}."\n"; + } + $rcs_seen++; + print "setting $config{rcs}_wrapper to ".$wrapper->{wrapper}."\n"; + $config{$config{rcs}."_wrapper"}=$wrapper->{wrapper}; + $config{$config{rcs}."_wrappermode"}=$wrapper->{wrappermode} + if exists $wrapper->{wrappermode}; + } + else { + die "don't know what to do with wrapper ".$wrapper->{wrapper}."\n"; + } + } + + IkiWiki::Setup::dump($setup); +} + +sub moveprefs { + my $setup=shift; + if (! defined $setup) { + usage(); + } + + require IkiWiki::Setup; + + %config = IkiWiki::defaultconfig(); + IkiWiki::Setup::load($setup); + IkiWiki::checkconfig(); + + eval q{use IkiWiki::UserInfo}; + error $@ if $@; + + foreach my $field (qw{allowed_attachments locked_pages}) { + my $orig=$config{$field}; + foreach my $admin (@{$config{adminuser}}) { + my $a=IkiWiki::userinfo_get($admin, $field); + if (defined $a && length $a && + # might already have been moved + (! defined $orig || $a ne $orig)) { + if (defined $config{$field} && + length $config{$field}) { + $config{$field}=IkiWiki::pagespec_merge($config{$field}, $a); + } + else { + $config{$field}=$a; + } + } + } + } + + my %banned=map { $_ => 1 } @{$config{banned_users}}, IkiWiki::get_banned_users(); + $config{banned_users}=[sort keys %banned]; + + IkiWiki::Setup::dump($setup); +} + +sub deduplinks { + setstatdir(shift); + IkiWiki::loadindex(); + foreach my $page (keys %links) { + my %l; + $l{$_}=1 foreach @{$links{$page}}; + $links{$page}=[keys %l] + } + IkiWiki::saveindex(); +} + +sub setstatedir { + my $dir=shift; + + if (! defined $dir) { + usage(); + } + + if (! -d $dir) { + error("ikiwiki-transition: $dir does not exist"); + } + + $config{wikistatedir}=$dir."/.ikiwiki"; + + if (! -d $config{wikistatedir}) { + error("ikiwiki-transition: $config{wikistatedir} does not exist"); + } +} + sub usage { print STDERR "Usage: ikiwiki-transition type ...\n"; print STDERR "Currently supported transition subcommands:\n"; - print STDERR " prefix_directives file\n"; - print STDERR " indexdb srcdir\n"; + print STDERR "\tprefix_directives setupfile ...\n"; + print STDERR "\taggregateinternal setupfile\n"; + print STDERR "\tsetupformat setupfile\n"; + print STDERR "\tmoveprefs setupfile\n"; + print STDERR "\thashpassword srcdir\n"; + print STDERR "\tindexdb srcdir\n"; + print STDERR "\tdeduplinks srcdir\n"; exit 1; } @@ -85,15 +260,31 @@ my $mode=shift; if ($mode eq 'prefix_directives') { prefix_directives(@ARGV); } +elsif ($mode eq 'hashpassword') { + hashpassword(@ARGV); +} elsif ($mode eq 'indexdb') { indexdb(@ARGV); } +elsif ($mode eq 'aggregateinternal') { + aggregateinternal(@ARGV); +} +elsif ($mode eq 'setupformat') { + setupformat(@ARGV); +} +elsif ($mode eq 'moveprefs') { + moveprefs(@ARGV); +} +elsif ($mode eq 'deduplinks') { + deduplinks(@ARGV); +} else { usage(); } package IkiWiki; +# A slightly modified version of the old loadindex function. sub oldloadindex { %oldrenderedfiles=%pagectime=(); if (! $config{rebuild}) { @@ -131,5 +322,28 @@ sub oldloadindex { $oldrenderedfiles{$page}=[@{$items{dest}}]; $pagectime{$page}=$items{ctime}[0]; } + + # saveindex relies on %hooks being populated, else it won't save + # the page state owned by a given hook. But no plugins are loaded + # by this program, so populate %hooks with all hook ids that + # currently have page state. + foreach my $page (keys %pagemtime) { + foreach my $id (keys %{$pagestate{$page}}) { + $hooks{_dummy}{$id}=1; + } + } + return close($in); } + +# Used to be in IkiWiki/UserInfo, but only used here now. +sub get_banned_users () { + my @ret; + my $userinfo=userinfo_retrieve(); + foreach my $user (keys %{$userinfo}) { + push @ret, $user if $userinfo->{$user}->{banned}; + } + return @ret; +} + +1