# A shoes script (www.shoooes.net) to split a Wordpress WXR file into # smaller files for easier importing to Wordpress # Copyright Cecil Coupe (2008) # ccoupe@cableone.net # Use it anyway you like. An email to author is appreciated. # # One could change all the @console.puts (str) to @console.contents << str+'\n' # One could get really tired to doing that a lot of times. class Shoes::Para def puts(str) self.contents << str self.contents << "\n" # if I could force a redraw on the gui at this point that would be nice end end class SplitWXR < Shoes url "/", :setup # this is the method the Shoes.app calls (because of the url declaration) def setup @infn = "Your WXR File" @outfn = File.basename(@infn.delete(' '))+'-' @outMB = "1.75" # its a string stack :margin => 10 do tagline "Split WXR Files" para ["Select a Wordpress Export file and create and create a bunch of ", "little files that you can import. Pick your file size to match what ", "your host allows for PHP file_uploads."] flow :margin => 10 do # bonus points for scanning the dir for "wordpress*.xml" fnbox = edit_line @infn, :width => 300 button "Select WXR File..." do @infn = ask_open_file if @infn fnbox.text = @infn @outfn = File.basename(@infn,'.*')+'-' @outfnbox.text = @outfn Dir.chdir(File.dirname(@infn)) end end end para ["Pick the size of each output file ", "or enter your own MB (the default is 1.75MB)."] flow :margin => 10 do # how to set the list_box's default? lb = list_box :items => ["1 MB", "2 MB", "3 MB", "4 MB", "5 MB", "6 MB"] do @outMB = lb.text.split()[0] @el.text = @outMB end @el = edit_line @outMB, :width => 40 do @outMB = @el.text end end para "The output files will be in the same folder as the input file" para ["You should enter a partial file name (without an .ext) that ", "I'll append \"1.wxr\" and 2.wxr and so on"] @outfnbox = edit_line @outfn, :width => 300 do @outfn = @outfnbox.text end flow :margin => 30 do button "Quit" do exit end para " ", :width => 200 # just make the layout pleasing. button "Make Little WXR's" do if !File.readable?(@infn) alert("The file \"#{@infn}\" isn't readable") return # exit the button block end @progressBlock.show() @console.puts "Writing to Folder #{File.dirname(@infn)}" # open and parse inf = File.open(@infn, 'r') self.loadWXR(inf) # it closes the file # now I write the smaller files chunk = 1 chunksz = 0 osz = ((2**20)*@outMB.to_f).to_i @console.puts "Chunksize = #{osz}" outf = nextfile(chunk) # open the file, writes the preamble # start a new thread to output things and keep the GUI alive #th = Thread.new() do @items.each do |item| item.each do |ln| outf.puts ln chunksz += ln.length end if chunksz > osz @postamble.each {|t| outf.puts t} outf.close chunk += 1 chunksz = 0 outf = nextfile(chunk) end end #end #th.join # finish the last one @postamble.each {|t| outf.puts t} outf.close @console.puts "Done" end end #@progressBlock = stack :width => 1.0, :height => -50 do # The above line causes the ask_file_open to fail -- Really! @progressBlock = stack :width => 1.0, :margin_right => 20, :height => 200, :scroll => true do background "#555" @console = para "Progress Messages\n", :font => "Monospace 12px", :stroke => "#dfa" #p @console.methods # figure out para.contents #p @console.contents[0].class end #@progressBlock.hide() # there's show when the button is pushed. end # top stack end # end of the setup method def loadWXR(infile) @preamble = [] @postamble = [] @items = [] @inPre = true @inItems = false @inPosta = false @curItem = [] infile.each do |ln| if @inPre if ln[//i] @inPre = false @inItems = true @curItem << ln else @preamble << ln end elsif @inItems == true if ln[/<\/channel>/] @inItems = false @postamble[0] = ln @inPosta = true next end if ln[/<\/item>/] # Finalize item - move curItem to items @curItem << ln @items << @curItem elsif ln[//] # start new item @curItem = ln else @curItem << ln end elsif @inPosta == true @postamble << ln else # an error in the state machine $stderr.puts "Should not get here\n" @curItem << ln end end @console.puts "#{@preamble.length} Preamble Lines" @console.puts "#{@items.length} Entrys" @console.puts "#{@postamble.length} Postamble Lines" infile.close() end # loadWXR def nextfile(ctr) fn = @outfn+ctr.to_s+".wxr" @console.puts "Writing #{fn}" # returns the handle h = File.new(fn,'w') @preamble.each {|ln| h.puts ln} return h end end # the next line fires up the GUI, calling the "/" url which maps to the setup # method in the SplitWXR class. Shoes.app :width => 600, :height => 640, :margin => 10