Skip to content

Instantly share code, notes, and snippets.

@ashbb
Created August 5, 2010 13:04
Show Gist options
  • Select an option

  • Save ashbb/509697 to your computer and use it in GitHub Desktop.

Select an option

Save ashbb/509697 to your computer and use it in GitHub Desktop.
# 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