require 'cgi' require 'drb/drb' require 'rinda/ring' require 'singleton' class RWikiProxy include Singleton class RWikiFinder RWIKI_URI = 'druby://localhost:8470' def initialize(use_ring=true) @use_ring = use_ring end def get_obj if @use_ring lookup_rwiki[0] else DRbObject.new(nil, RWIKI_URI) end end def lookup_rwiki ts = Rinda::RingFinger.primary ts.read_all([:name, :RWiki, nil, nil]).collect do |tuple| tuple[2] end end end class Page def initialize(name, proxy) @name = name @proxy = proxy @last = Time.at(1) @body = '' @links = [] @revlinks = [] end attr_reader :body, :modified, :links, :revlinks, :hot_links, :name attr_reader :last, :section_prop def update page = @proxy.rwiki.page(@name) @body = page.body_html({'ref_name'=>@proxy.ref_proc}) @empty = page.empty? @modified = page.modified @links = page.links @revlinks = page.revlinks @hot_links = page.hotlinks.collect {|pg| pg.name} @section_prop = page.prop(:section) || {} @last = Time.now end def empty? @empty end end def initialize @cache = {} @ref_proc = Proc.new {|cmd, name| escape(name)} @rwiki = nil @recent_expires = Time.at(1) @recent = nil end attr_reader :ref_proc def rwiki return @rwiki if @rwiki @rwiki = RWikiFinder.new(true).get_obj @rwiki end def path2name(path) if /\/(.+)$/ =~ path #/ unescape($1) else nil end end def escape(name) CGI.escape(name).gsub(/\%/, "@") + '.html' end def unescape(enc) CGI.unescape(enc.sub(/\.html$/, '').gsub(/\@/, "%")) end def update(name) modified = nil v = (@cache[name] ||= Page.new(name, self)) v.update if v.last < Time.now - 300 return v end def fetch(name) update(name) end def update_recent @recent = @rwiki.recent_changes @recent_expire = Time.now + 300 end def recent_changes update_recent if @recent_expires < Time.now @recent end end