#!/usr/bin/perl -w # # Kwiki to Foswiki text converter # # Copyright (c) 2009 Herbert Liechti, herbert.liechti@thinx.ch # # Acknowledgements: # Thanks to http://www.thinx.ch/ for giving me # permission to distribute this. # # Adapted from: # Copyright (c) 2003 Fred Morris, m3047 at inwa d0t net # Thanks to http://www.graysoft.com/ for giving me # permission to distribute this. # # # Dolphin to TWiki text converter # # Copyright (C) 2001 Peter Thoeny, peter@thoeny.com # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details, published at # http://www.gnu.org/copyleft/gpl.html # # # # # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! important !!!!!!!!!!!!!!!!!!!!!! # steps before and after using this tool. This tool is quick and dirty hack # for migration kwiki wikis to foswiki. It assumes, that the archive # kwiki plugin is active and checks wether attachments exists for # a topic # # Kwiki::VimMode plugin of kwiki (.vim) is also rewritten in this script # you need the SyntaxHighlightingPlugin in foswiki # # STEPS: # # * of course you have a backup of both systems # * Go to the kwiki repository and cd to the database directory # * Delete unwanted wiki pages (i.e. all Kwiki* pages) # * to a recode of all files from utf8 to the charset defined in the foswiki # unless you use utf8 in foswiki. Important!! # use the recode program # for i in * # do # recode utf8..latin1 $i # done # * Go to the plugin/archive directory of the kwiki # * repeat the recode for all rcs files (,v) # * open foswiki admin in your browser and add a new web # * place this script in the data directory of your foswiki installation # (debian /var/lib/foswiki/data), set the users variables below in this script to the correct values and start # the script # * after migration unlock all rcs files (kwiki files are always locked) in the foswiki web directory # rcs files are named as topic.txt,v # do this as the user who owns the lock # # ex. shellscript # for i in *.txt,v # do # rcs -u $i # unlock stuff # done # * be sure that the ownership ist correct for the migrated wiki. # * kwiki allows any word to be a wikiword. if you have kwiki pages # starting with lowercase or are not wikiwords you can use # the next tool wikify.pl which replace interactively the content # in your wiki with correct WikiWords # * if you have attachments change configuration of your web so that attachments # are shown automatically use lib ( '.' ); use lib ( '../lib' ); use Regexp::Common qw /URI/; use File::Copy; # ------------------------- User variables settings ----------------------------------------- $outDir = '/var/lib/foswiki/data/ContentX/'; # path of foswiki web $inDir = '/var/www/cxWiki/database/'; # path of origin kwiki $arDir = '/var/www/cxWiki/plugin/archive/'; # path of origin kwiki rcs files $attachDir = '/var/www/cxWiki/plugin/attachments/'; # path of origin kwiki attachments $attachOutDir = '/var/lib/foswiki/pub/ContentX'; # path of target attachment dir in foswiki # ------------------------- End User variables settings ------------------------------------- # these variables will be set by TWiki.cfg: $revCiDateCmd = ""; $defaultUserName = ""; # read the configuration part do "TWiki.cfg"; # Not quite, appears some things have changed in Twiki.cfg since # Thoeny wrote the original proggie. -- FWM %settingsHash = @storeSettings; $revCiDateCmd = $settingsHash{ciDateCmd}; # On with the show.. #if( @ARGV ) { #$inDir = $ARGV[0] if $ARGV[0]; #$outDir = $ARGV[1] if $ARGV[1]; #$inDir = "" unless -d $inDir; #$outDir = "" unless -d $outDir; # #} &main(); sub main { print "Kwiki to foswiki text converter. Copyright (C) 2009, Herbert Liechti\n"; print "Kwiki to TWiki text converter. Copyright (C) 2003, Fred Morris, m3047 at inwa d0t net\n"; print " Copyright (C) 2001, Peter Thoeny, http://TWiki.org/\n"; if( ! $inDir || ! $outDir ) { print "example% kwiki2twiki fromDir toDir\n"; print "fromDir: Directory containing Kwiki text files\n"; print "toDir: Directory where converted .txt and .txt,v files are stored\n"; print "Attention: toDir is assumed to be empty. Existing files will be overwritten!\n"; return; } if( $inDir eq $outDir ) { print "Error: toDir and fromDir must be different!\n"; return; } opendir( DIR, "$inDir" ) or die "could not open $inDir"; my @inList = grep /^\w/, readdir DIR; closedir DIR; my $text = ""; my $time = 0; foreach( @inList ) { #foreach( qw/FranklinGothic PerlJournals YuiDnd HomePage/ ) { print "- $_: read"; $text = readFile( "$inDir/$_" ); print ", convert"; ( $text, $time ) = convertText( $text, $_ ); print ", copy rcs"; copyrcsFile( $_ ); $outf = "$outDir/$_" . '.txt'; print ", save"; saveFile( $outf, $text ); print ", attachments"; attachFiles( $_ ); print "\n"; } } # ========================= sub convertText { my( $theText, $file ) = @_; my $utime = (stat("$inDir$file"))[9]; print ", utime $inDir$file $utime"; my $revision = '1.1'; if ( -f "$arDir/${file},v") { my $pid = open (PH, "rlog -r $arDir/${file},v |") or die $!; print ", rcs rlog PID $pid"; for my $l () { if ( $l =~ m/^head: (.*)$/ ) { $revision = $1; next; } } close PH; } my $text = '%META:TOPICINFO{author="BaseUserMapping_333" ' . ' date="' . $utime . '" format="1.0" version="'. $revision . '"}%' . "\n"; my $time = 0; my $verbatim = 0; my $verbatimblock = 0; my $vim = 0; $theText =~ s/\r//gos; foreach( split( /\n/, $theText ) ) { # in a verbatim block if ($verbatim) { if ( m/^ /o ) { $text .= "$_\n"; next; } else { $text .= "\n"; $verbatim = 0; } } # in a verbatim block if ($verbatimblock) { if ( m/^\.pre/ ) { $text .= "\n"; $verbatimblock = 0; next; } else { $text .= "$_\n"; next; } } # in a vim block if ($vim) { if ($vim == 1) { if ( m/filetype:\s+(.*)/ ) { $text .= "%CODE{\"$1\"}%\n"; } else { $text .= "%CODE{\"...\"}%\n$_"; } $vim++; next; } if ( m/^\.vim\s*$/ ) { $text .= "%ENDCODE%\n"; $vim = 0; next; } else { $text .= "$_\n"; next; } } # start a verbatim block if ( m/^\.pre/ ) { $text .= "\n"; $verbatimblock = 1; next; } # start a vim block if ( m/^\.vim\s*$/ ) { $vim = 1; next; } # start a verbatim block if ( m/^ /o ) { $text .= "\n$_\n"; $verbatim = 1; next; } # = Head --> ---+ Head if ( m/^(=+)\s+(.*)/o ) { my $indent = $1; my $header = $2; $indent =~ s/=/+/go; $header =~ s/=+$//o; $_ = "---$indent $header"; } # [=code] --> =code= s/\[=(.*?)]/=$1=/go; # [Wikiword] --> [[Wikiwor]] s/\[(\w+)\]/##$1££/go; s/\[($RE{URI})\s+([^\]]*)\]/[[$1][$2]]/g; s/\[(.*)\s+($RE{URI})\]/[[$2][$1]]/g; # /*bolditalic*/ --> __bolditalic__ s/(^|\s)\/\*(\S.*?\S)\*\/(\W|$)/$1__$2__$3/go; # /italic/ --> _italic_ s/(^|\s)\/(\S.*?\S)\/(\W|$)/$1_$2_$3/go; # & --> & s/&/&/go; # < --> < s/ --> > s/>/>/gi; # !WikiWord --> WikiWord s/!([A-Z]\S+)/$1/go; # * list --> * list if ( m/^([*]+)\s*(.*)/go ) { my $indent = $1; my $item = $2; $indent =~ s/./\t/go; $_ = $indent . '* ' . $item; } # 0 list --> 1 list if ( m/^([0-9]+)\s*(.*)/go ) { my $indent = $1; my $item = $2; $indent =~ s/./\t/go; $_ = $indent . '1 ' . $item; } s/##/[[/go; s/££/]]/go; $text .= "$_\n"; } $text =~ s/\n\n+/\n\n/gos; return ( $text, $time ); } # ========================= sub readFile { my( $theName ) = @_; my $data = ""; undef $/; # set to read to EOF open( IN_FILE, "<$theName" ) || return ""; $data = ; $/ = "\n"; close( IN_FILE ); return $data; } # ========================= sub saveFile { my( $theName, $theText ) = @_; open( FILE, ">$theName" ) or warn "Can't create file $theName"; print FILE $theText; close( FILE); } # ========================= sub copyrcsFile { my $file = shift; if ( -f "$arDir/${file},v") { copy( "$arDir/${file},v", "$outDir/${file}.txt,v" ) or die $!; } } sub attachFiles { my $file = shift; if ( -d "$attachDir/${file}") { unless ( -d "$attachOutDir/$file" ) { mkdir "$attachOutDir/$file" or die $! ; } opendir( DIR, "$attachDir/${file}" ) or die "could not open $attachDir/$file"; my @inList = grep /^\w/, readdir DIR; closedir DIR; for (@inList) { print "\n attaching file $_"; copy( "$attachDir/$file/$_", "$attachOutDir/${file}/$_" ) or die $!; } } }