lib/knj/google_sitemap.rb in knjrbfw-0.0.21 vs lib/knj/google_sitemap.rb in knjrbfw-0.0.22
- old
+ new
@@ -1,59 +1,98 @@
class Knj::Google_sitemap
attr_reader :doc
def initialize(args = {})
+ raise "No block given." if !block_given?
+
@args = args
#used for Time.iso8601.
require "time"
- @doc = REXML::Document.new
- @doc << REXML::XMLDecl.new("1.0", "UTF-8")
+ #REXML is known to leak memory - use subprocess.
+ @subproc = Knj::Process_meta.new("id" => "google_sitemap", "debug_err" => true)
- @urlset = @doc.add_element("urlset")
- @urlset.add_attributes("xmlns" => "http://www.sitemaps.org/schemas/sitemap/0.9")
+ begin
+ @subproc.static("Object", "require", "rexml/rexml")
+ @subproc.static("Object", "require", "rexml/document")
+
+ @doc = @subproc.new("REXML::Document")
+
+ xmldecl = @subproc.new("REXML::XMLDecl", "1.0", "UTF-8")
+ @doc._pm_send_noret("<<", xmldecl)
+
+ urlset = @subproc.proxy_from_call(@doc, "add_element", "urlset")
+ urlset._pm_send_noret("add_attributes", {"xmlns" => "http://www.sitemaps.org/schemas/sitemap/0.9"})
+
+ @root = @subproc.proxy_from_call(@doc, "root")
+ yield(self)
+ ensure
+ @doc = nil
+ @root = nil
+ @subproc.destroy
+ @subproc = nil
+ end
end
def add_url(url_value, lastmod_value, cf_value = nil, priority_value = nil)
- el = REXML::Element.new("url")
-
- loc = el.add_element("loc")
- loc.text = url_value
-
if !lastmod_value or lastmod_value.to_i == 0
raise sprintf("Invalid date: %1$s, url: %2$s", lastmod_value.to_s, url_value)
end
- lm = el.add_element("lastmod")
+ el = @subproc.new("REXML::Element", "url")
+
+ loc = @subproc.proxy_from_call(el, "add_element", "loc")
+ loc._pm_send_noret("text=", url_value)
+
+ lm = @subproc.proxy_from_call(el, "add_element", "lastmod")
if @args.key?(:date_min) and @args[:date_min] > lastmod_value
lastmod_value = @args[:date_min]
end
- lm.text = lastmod_value.iso8601
+ lm._pm_send_noret("text=", lastmod_value.iso8601)
if cf_value
- cf = el.add_element("changefreq")
- cf.text = cf_value
+ cf = @subproc.proxy_from_call(el, "add_element", "changefreq")
+ cf._pm_send_noret("text=", cf_value)
end
if priority_value
- priority = el.add_element("priority")
- priority.text = priority_value
+ priority = @subproc.proxy_from_call("el", "add_element", "priority")
+ priority._pm_send_noret("text=", priority_value)
end
- @doc.root << el
+ @root._pm_send_noret("<<", el)
end
+ #This will return a non-human-readable XML-string.
def to_xml
return @doc.to_s
end
+ #This will return a non-human-readable XML-string.
def to_s
return @doc.to_s
end
+ #This will print the result.
def write
- writer = REXML::Formatters::Pretty.new(5)
- writer.write(@doc, $stdout)
+ #Require and spawn StringIO in the subprocess.
+ @subproc.static("Object", "require", "stringio")
+ string_io = @subproc.spawn_object("StringIO")
+
+ #We want a human-readable print.
+ writer = @subproc.spawn_object("REXML::Formatters::Pretty", 5)
+ writer._pm_send_noret("write", @doc, string_io)
+
+ #Prepare printing by rewinding StringIO to read from beginning.
+ string_io._pm_send_noret("rewind")
+
+ #Buffer results from subprocess in order to speed up printing.
+ string_io._process_meta_block_buffer_use = true
+
+ #Print out the result in bits to avoid raping the memory (subprocess is already raped - no question there...).
+ string_io._pm_send_noret("each", 4096) do |str|
+ print str
+ end
end
end
\ No newline at end of file