diff --git a/app/controllers/application.rb b/app/controllers/application.rb index 42c1abe2..670bea1e 100644 --- a/app/controllers/application.rb +++ b/app/controllers/application.rb @@ -71,7 +71,7 @@ class ApplicationController < ActionController::Base not @web_name.nil? end - @@REMEMBER_NOT = ['locked', 'save', 'back', 'file', 'pic'] + @@REMEMBER_NOT = ['locked', 'save', 'back', 'file', 'pic', 'import'] def remember_location if @response.headers['Status'] == '200 OK' unless @@REMEMBER_NOT.include? action_name or @request.method != :get diff --git a/app/controllers/file_controller.rb b/app/controllers/file_controller.rb index 6d37744d..b09a0d29 100644 --- a/app/controllers/file_controller.rb +++ b/app/controllers/file_controller.rb @@ -45,6 +45,44 @@ class FileController < ApplicationController end end + def import + check_authorization + if @params['file'] + logger.info 'Importing pages from a file' + import_file_name = "#{@web.address}-import-#{Time.now.strftime('%Y-%m-%d-%H-%M-%S')}.zip" + file_yard.upload_file(import_file_name, @params['file']) + zip = Zip::ZipInputStream.open(file_yard.file_path(import_file_name)) + problems = [] + while (entry = zip.get_next_entry) do + ext_length = File.extname(entry.name).length + page_name = entry.name[0..-(ext_length + 1)] + page_content = entry.get_input_stream.read + + logger.info "Processing page '#{page_name}'" + begin + if @wiki.read_page(@web.address, page_name) + logger.info "Page '#{page_name}' already exists. Adding a new revision to it." + wiki.revise_page(@web.address, page_name, page_content, Time.now, 'Importer') + else + wiki.write_page(@web.address, page_name, page_content, Time.now, 'Importer') + end + rescue Instiki::ValidationError => e + logger.error(e) + problems << e.message + end + end + logger.info 'Import finished' + if problems.empty? + flash[:info] = 'Import successfully finished' + else + flash[:info] = "Import finished, but some pages were not imported:
  • " + + problems.join('
  • ') + '
  • ' + end + return_to_last_remembered + else + # to template + end + end protected diff --git a/app/models/file_yard.rb b/app/models/file_yard.rb index 9f6ca101..db617238 100644 --- a/app/models/file_yard.rb +++ b/app/models/file_yard.rb @@ -1,3 +1,4 @@ +require 'fileutils' require 'instiki_errors' class FileYard @@ -6,6 +7,7 @@ class FileYard def initialize(files_path) @files_path = files_path + FileUtils.mkdir_p(files_path) unless File.exist?(files_path) @files = Dir["#{files_path}/*"].collect{|path| File.basename(path) if File.file?(path) }.compact end diff --git a/app/views/file/import.rhtml b/app/views/file/import.rhtml new file mode 100644 index 00000000..251ffc28 --- /dev/null +++ b/app/views/file/import.rhtml @@ -0,0 +1,23 @@ +

    +<%= form_tag({}, {:multipart => true}) %> +

    + File to upload: +
    + +

    +

    + System password: +
    + +

    +

    + as + + <% if @page %> + | Cancel (unlocks page) + <% end %> + +

    +<%= end_form_tag %> +

    \ No newline at end of file diff --git a/libraries/url_rewriting_hack.rb b/libraries/url_rewriting_hack.rb index f7ad1c50..746ceaab 100644 --- a/libraries/url_rewriting_hack.rb +++ b/libraries/url_rewriting_hack.rb @@ -63,7 +63,8 @@ class DispatchServlet @@action_to_controller_map = { 'file' => 'file', - 'pic' => 'file' + 'pic' => 'file', + 'import' => 'file' } def self.map_to_controller(action) diff --git a/script/import_wiki.rb b/script/import_wiki.rb deleted file mode 100644 index e0925841..00000000 --- a/script/import_wiki.rb +++ /dev/null @@ -1,85 +0,0 @@ -require 'optparse' - -puts 'Instiki import' -puts - -ARGV << '-t' << 'tmp-instiki' << '/rails.zip' - -IMPORT_OPTIONS = { - -} - -argv_before_parsing_by_import = ARGV.dup - -ARGV.options do |opts| - script_name = File.basename($0) - opts.banner = "Usage: ruby #{script_name} [options] [import file]" - - opts.separator '' - - opts.on('-w', '--web-address', - 'Web address to import ' - ) { IMPORT_OPTIONS[:web] } - opts.on('-t', '--storage=storage', String, - 'Makes Instiki use the specified directory for storage.', - 'Default: ./storage/[port]') { |IMPORT_OPTIONS[:storage]| } - - opts.separator '' - - opts.on('-h', '--help', - 'Show this help message.') { puts opts; exit } - - opts.parse! -end - -raise 'Please specify the import file' if ARGV.empty? -import_file = ARGV.last -raise "Import file not found: #{import_file}" unless File.file?(import_file) -raise "Can not read import file: #{import_file}" unless File.readable?(import_file) - -raise 'Please specify the storage path' unless IMPORT_OPTIONS[:storage] - -INSTIKI_BATCH_JOB = true -ARGV.clear -argv_before_parsing_by_import.each { |arg| ARGV << arg } - -load "#{File.dirname(__FILE__)}/server" - -wiki = WikiService.instance - -web_address = IMPORT_OPTIONS[:web] - -if web_address.nil? - if wiki.webs.empty? - puts "Instiki storage at #{IMPORT_OPTIONS[:storage]} is new (no webs)." - puts "Creating a new web named 'wiki', without a password" - web = wiki.create_web('Wiki', 'wiki') - elsif wiki.webs.values.size == 1 - web = wiki.webs.values.first - puts "Instiki storage at #{IMPORT_OPTIONS[:storage]} contains one web, '#{web.address}'." - puts "Pages are imported into this web" - end -else - web = wiki.webs[web_address] - if web.nil? - raise "Instiki storage at #{IMPORT_OPTIONS[:storage]} has no web named '#{web_address}'" - end -end - -zip = Zip::ZipInputStream.open(import_file) - -while (entry = zip.get_next_entry) do - ext_length = File.extname(entry.name).length - page_name = entry.name[0..-(ext_length + 1)] - page_content = entry.get_input_stream.read - - puts "Processing page '#{page_name}'" - - if wiki.read_page(web_address, page_name) - wiki.revise_page(web.address, page_name, page_content, Time.now, 'Importer') - else - wiki.write_page(web.address, page_name, page_content, Time.now, 'Importer') - end -end - -puts "Import finished" diff --git a/test/unit/url_rewriting_hack_test.rb b/test/unit/url_rewriting_hack_test.rb index da1317b2..515ef974 100755 --- a/test/unit/url_rewriting_hack_test.rb +++ b/test/unit/url_rewriting_hack_test.rb @@ -83,7 +83,9 @@ class UrlRewritingHackTest < Test::Unit::TestCase ur.rewrite(:controller => 'file', :action => 'pic', :id => 'abc.jpg') assert_equal 'http://test.host/web/pic/abc.jpg', ur.rewrite(:web => 'web', :controller => 'file', :action => 'pic', :id => 'abc.jpg') - + assert_equal 'http://test.host/web/import', + ur.rewrite(:web => 'web', :controller => 'file', :action => 'import') + # default option is wiki assert_equal 'http://test.host/unknown_action', ur.rewrite(:controller => 'wiki', :action => 'unknown_action')