Created
August 5, 2010 13:04
-
-
Save ashbb/509697 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # A shoes script (www.shoooes.net) to split a Wordpress WXR file into | |
| # smaller files for easier importing to Wordpress | |
| # Copyright Cecil Coupe (2008) | |
| # [email protected] | |
| # 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. | |
| Shoes::Para.class_eval do | |
| def puts(str) | |
| self.text += (str + "\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 = [item] if item.class == String | |
| 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! | |
| rect width: 550, height: 200, top: 470, left: 2, fill: "#555" | |
| @progressBlock = stack :width => 1.0, :top => 470, :right => 20, :height => 200, :scroll => true do | |
| @console = para "Progress Messages\n", :font => "Monospace 12px", :stroke => "#dfa", :left=> 20 | |
| #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| | |
| ln = ln.force_encoding 'UTF-8' | |
| if @inPre | |
| if ln[/<item>/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[/<item>/] | |
| # 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 => 690, :margin => 10 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment