instiki/script/import_storage
Ben Bleything 7aaa35ae4a Ye olde converter script.
* Script now parses the madeleine storage into SQL
  * Added a new option, -o/--outfile to specify where the output from
    the script should go
  * ./import_storage -t /home/joe/instiki/storage/2500 \
      -i /home/joe/instiki -o /home/joe/export.sql

Exporting the instiki.org snapshot I have takes about 40 seconds (with
output to screen) and generates an approximately 17 meg SQL script from
the ~900k Madeleine snapshot.  Oh well.

Tested with MySQL.
2005-08-22 16:57:01 +00:00

159 lines
4.6 KiB
Ruby
Executable file

#!/usr/bin/env ruby
require 'optparse'
OPTIONS = {
:instiki_root => nil,
:storage => nil,
}
ARGV.options do |opts|
script_name = File.basename($0)
opts.banner = "Usage: ruby #{script_name} [options]"
opts.separator ""
opts.on("-t", "--storage /full/path/to/storage", String,
"Full path to your storage, ",
"such as /home/joe/instiki/storage/2500",
"It should be the directory that ",
"contains .snapshot files.") do |storage|
OPTIONS[:storage] = storage
end
opts.separator ""
opts.on("-i", "--instiki /full/path/to/instiki", String,
"Full path to your Instiki installation, ",
"such as /home/joe/instiki") do |instiki|
OPTIONS[:instiki] = instiki
end
opts.separator ""
opts.on("-o", "--outfile /full/path/to/output_file", String,
"Full path (including filename!) to where ",
"you want the SQL output placed, such as ",
"/home/joe/instiki.sql") do |outfile|
OPTIONS[:outfile] = outfile
end
opts.separator ""
opts.on_tail("-h", "--help",
"Show this help message.") { puts opts; exit }
opts.parse!
end
if OPTIONS[:instiki].nil? or OPTIONS[:storage].nil? or OPTIONS[:outfile].nil?
$stderr.puts "Please specify full paths to Instiki installation and storage,"
$stderr.puts "as well as the path to the output file"
$stderr.puts
puts ARGV.options
exit -1
end
if FileTest.exists? OPTIONS[:outfile]
$stderr.puts "Output file #{OPTIONS[:outfile]} already exists!"
$stderr.puts "Please specify a new file"
$stderr.puts
puts ARGV.options
exit -1
end
raise "Directory #{OPTIONS[:instiki]} not found" unless File.directory?(OPTIONS[:instiki])
raise "Directory #{OPTIONS[:storage]} not found" unless File.directory?(OPTIONS[:storage])
expected_page_rb_path = File.join(OPTIONS[:instiki], 'app/models/page.rb')
raise "Instiki installation not found in #{OPTIONS[:instiki]}" unless File.file?(expected_page_rb_path)
expected_snapshot_pattern = File.join(OPTIONS[:storage], '*.snapshot')
raise "No snapshots found in OPTIONS[:storage]" if Dir[expected_snapshot_pattern].empty?
INSTIKI_ROOT = File.expand_path(OPTIONS[:instiki])
ADDITIONAL_LOAD_PATHS = %w(
app/models
lib
vendor/madeleine-0.7.1/lib
vendor/RedCloth-3.0.3/lib
vendor/rubyzip-0.5.8/lib
).map { |dir| "#{File.expand_path(File.join(INSTIKI_ROOT, dir))}"
}.delete_if { |dir| not File.exist?(dir) }
# Prepend to $LOAD_PATH
ADDITIONAL_LOAD_PATHS.reverse.each { |dir| $:.unshift(dir) if File.directory?(dir) }
require 'webrick'
require 'wiki_service'
class Revision
alias :__display_content :display_content
def display_content
return self
end
end
def sql_insert(table, hash)
output = "INSERT INTO #{table} ("
output << hash.keys.join(", ")
output << ") VALUES ('"
output << hash.values.map{|v| v.to_s.gsub("'", "\\\\'")}.join("', '")
output << "');"
return output
end
WikiService.storage_path = OPTIONS[:storage]
wiki = WikiService.instance
File.open(OPTIONS[:outfile], 'w') { |outfile|
wiki.webs.each_pair do |web_name, web|
outfile.puts sql_insert(:webs, {
:id => web.object_id,
:name => web.name,
:address => web.address,
:password => web.password,
:additional_style => web.additional_style,
:allow_uploads => web.allow_uploads,
:published => web.published,
:count_pages => web.count_pages,
:markup => web.markup,
:color => web.color,
:max_upload_size => web.max_upload_size,
:safe_mode => web.safe_mode,
:brackets_only => web.brackets_only,
})
puts "Web #{web_name} has #{web.pages.keys.size} pages"
web.pages.each_pair do |page_name, page|
outfile.puts sql_insert(:pages, {
:id => page.object_id,
:web_id => web.object_id,
:locked_by => page.locked_by,
:name => page.name
})
puts " Page #{page_name} has #{page.revisions.size} revisions"
page.revisions.each_with_index do |rev, i|
outfile.puts sql_insert(:revisions, {
:id => rev.object_id,
:page_id => page.object_id,
:content => rev.content,
:author => rev.author,
:ip => '0.0.0.0',
})
puts " Revision #{i} created at #{rev.created_at}"
end
end
end
['webs', 'pages', 'revisions'].each do |table|
outfile.puts "UPDATE #{table} SET created_at = NOW();"
outfile.puts "UPDATE #{table} SET updated_at = NOW();"
end
outfile.puts "UPDATE revisions SET revised_at = NOW();"
}