ev/tree.rb in rwdschedule-0.93 vs ev/tree.rb in rwdschedule-0.94

- old
+ new

@@ -1,343 +1,343 @@ -require "ev/ruby" -require "ev/net" -require "md5" -require "thread" - -Same = 0 -Down = 1 -Up = 2 -Dummy = 3 - -module TextArray - def textarray - @children.collect do |obj| - [obj.text] << obj.textarray - end.flatten.compact - end -end - - -module ParseTree - def parsetree(premethod="prechildren", postmethod="postchildren", *args) - if @visible - method(premethod).call(*args) if respond_to?(premethod) - - @children.each do |obj| - obj.parsetree(premethod, postmethod, *args) - end - - method(postmethod).call(*args) if respond_to?(postmethod) - end - end - - #def parsetree(premethod="prechildren", postmethod="postchildren", *args) - # stack = [self] - # done = [] - # - # while not stack.empty? - # obj = stack.pop - # - # if not done.include?(obj) - # obj.method(premethod).call(*args) if obj.respond_to?(premethod) - # - # stack.push(obj) - # done.push(obj) - # - # stack.concat obj.children.reverse - # #obj.children.reverse.each do |cobj| - # #stack.push(cobj) - # #end - # else - # obj.method(postmethod).call(*args) if obj.respond_to?(postmethod) - # end - # end - #end -end - -class TreeObject - attr_reader :subtype - attr_writer :subtype - attr_reader :upordown - attr_writer :upordown - attr_reader :level - attr_writer :level - attr_reader :parent - attr_writer :parent - attr_reader :children - attr_writer :children - attr_reader :closed - attr_writer :closed - attr_reader :text - attr_writer :text - attr_reader :visible - attr_writer :visible - - include TextArray - include ParseTree - - def initialize(subtype=nil) - @subtype = subtype - @upordown = Same - @level = nil - @parent = nil - @children = [] - @closed = nil - @visible = true - end - - def inspect - parent, children = @parent, @children - - @parent, @children = parent.id, children.collect{|obj| obj.id} - - res = " " * (level-1) + "#{self.class}(#{@subtype}) #{super}" - - @parent, @children = parent, children - - res - end -end - -class Tree - @@versie = 1 - @@mutex = Mutex.new - - attr_reader :data - attr_writer :data - attr_reader :parent - attr_writer :parent - attr_reader :children - attr_writer :children - attr_reader :visible - attr_writer :visible - - include TextArray - include ParseTree - - def initialize(string) - string = string.join("") if string.kind_of?(Array) - - @data = string - @parent = nil - @children = [] - @objects = [] - @visible = true - @checkvisibility = false - - buildobjects(string) - buildparents - buildchildren - markclosed - deletedummies - - @checkvisibility = true - end - - def self.file(file) - new(File.new(file).readlines) - end - - def self.location(url, form=Hash.new) - s = HTTPClient.get(url, form) - s = "" if s.nil? - new(s) - end - - def self.new_from_cache2(data) - new(data) - end - - def self.new_from_cache(data) - hash = MD5.new("#{@@versie} #{data}") - - dir = "#{temp}/evcache.#{user}/tree.new" - file = "#{dir}/#{hash}" - - tree = nil - - Dir.mkdirrec(dir) - - if File.file?(file) - @@mutex.synchronize do - tree = Marshal.restore(File.new(file, "rb")) - end - else - tree = new(data) - - if not tree.nil? - @@mutex.synchronize do - File.open(file, "wb") {|f| Marshal.dump(tree, f)} - end - end - end - - return tree - end - - def inspect - @objects.collect do |obj| - obj.inspect - end.join("\n") - end - - def buildobjects(string) - raise "Has to be defined in the subclass." - end - - def buildparents - level = 1 - levels = Hash.new - levels[0] = nil - parse do |type, obj| - case obj.upordown - when Down - obj.level = level - obj.parent = levels[level-1] - levels[level] = obj - level += 1 - when Up, Dummy - pl = level - 1.upto(level-1) do |l| - po = levels[l] - pl = l if po.subtype == obj.subtype - end - level = pl - obj.level = level - obj.parent = levels[level-1] - when Same - obj.level = level - obj.parent = levels[level-1] - end - end - end - - def buildchildren - @objects.each do |obj| - obj.children = [] - end - - parse do |type, obj| - if not obj.parent.nil? - po = obj.parent - po.children << obj - else - @children << obj - end - end - end - - def markclosed - ([self].concat @objects).each do |obj| - obj.children.each_index do |i| - co1 = obj.children[i] - co2 = obj.children[i+1] - - co1.closed = (not co2.nil? and co1.upordown == Down and (co2.upordown == Up or co2.upordown == Dummy) and co1.subtype == co2.subtype) - end - end - end - - def deletedummies - ([self].concat @objects).each do |obj| - obj.children.delete_if do |obj2| - obj2.upordown == Dummy - end - end - - @objects.delete_if do |obj| - obj.upordown == Dummy - end - end - - def parse(types=[], subtypes=[], once=false) - types = [types] if types.class == Class - subtypes = [subtypes] if subtypes.class == String - hidelevel = nil - - catch :once do - @objects.each do |obj| - if (@checkvisibility and hidelevel.nil? and (not obj.visible)) - hidelevel = obj.level - else - if (@checkvisibility and (not hidelevel.nil?) and obj.visible and obj.level <= hidelevel) - hidelevel = nil - end - end - - if hidelevel.nil? - ok = false - catch :stop do - if types.empty? - if subtypes.empty? - ok = true - throw :stop - else - subtypes.each do |st| - if obj.subtype == st - ok = true - throw :stop - end - end - end - else - if subtypes.empty? - types.each do |t| - if obj.kind_of?(t) - ok = true - throw :stop - end - end - else - types.each do |t| - subtypes.each do |st| - if obj.kind_of?(t) and obj.subtype == st - ok = true - throw :stop - end - end - end - end - end - end - - if ok - yield(obj.class.to_s, obj) - - throw :once if once - end - end - end - end - end - - def path(pad) - p1 = self - - unless pad.nil? - pad.split(/\//).each do |deel| - tag, voorkomen = deel.split(/:/) - - if (not tag.nil?) and (not p1.nil?) - voorkomen = 1 if voorkomen.nil? - voorkomen = voorkomen.to_i - - teller = 0 - p2 = nil - p1.children.each_index do |i| - #if p1.children[i].upordown == Down - unless p1.children[i].subtype.nil? - if p1.children[i].subtype.noquotes == tag.noquotes - teller += 1 - p2 = p1.children[i] if teller == voorkomen - end - end - #end - end - p1 = p2 - end - end - end - - p1 - end -end +require "ev/ruby" +require "ev/net" +require "md5" +require "thread" + +Same = 0 +Down = 1 +Up = 2 +Dummy = 3 + +module TextArray + def textarray + @children.collect do |obj| + [obj.text] << obj.textarray + end.flatten.compact + end +end + + +module ParseTree + def parsetree(premethod="prechildren", postmethod="postchildren", *args) + if @visible + method(premethod).call(*args) if respond_to?(premethod) + + @children.each do |obj| + obj.parsetree(premethod, postmethod, *args) + end + + method(postmethod).call(*args) if respond_to?(postmethod) + end + end + + #def parsetree(premethod="prechildren", postmethod="postchildren", *args) + # stack = [self] + # done = [] + # + # while not stack.empty? + # obj = stack.pop + # + # if not done.include?(obj) + # obj.method(premethod).call(*args) if obj.respond_to?(premethod) + # + # stack.push(obj) + # done.push(obj) + # + # stack.concat obj.children.reverse + # #obj.children.reverse.each do |cobj| + # #stack.push(cobj) + # #end + # else + # obj.method(postmethod).call(*args) if obj.respond_to?(postmethod) + # end + # end + #end +end + +class TreeObject + attr_reader :subtype + attr_writer :subtype + attr_reader :upordown + attr_writer :upordown + attr_reader :level + attr_writer :level + attr_reader :parent + attr_writer :parent + attr_reader :children + attr_writer :children + attr_reader :closed + attr_writer :closed + attr_reader :text + attr_writer :text + attr_reader :visible + attr_writer :visible + + include TextArray + include ParseTree + + def initialize(subtype=nil) + @subtype = subtype + @upordown = Same + @level = nil + @parent = nil + @children = [] + @closed = nil + @visible = true + end + + def inspect + parent, children = @parent, @children + + @parent, @children = parent.id, children.collect{|obj| obj.id} + + res = " " * (level-1) + "#{self.class}(#{@subtype}) #{super}" + + @parent, @children = parent, children + + res + end +end + +class Tree + @@versie = 1 + @@mutex = Mutex.new + + attr_reader :data + attr_writer :data + attr_reader :parent + attr_writer :parent + attr_reader :children + attr_writer :children + attr_reader :visible + attr_writer :visible + + include TextArray + include ParseTree + + def initialize(string) + string = string.join("") if string.kind_of?(Array) + + @data = string + @parent = nil + @children = [] + @objects = [] + @visible = true + @checkvisibility = false + + buildobjects(string) + buildparents + buildchildren + markclosed + deletedummies + + @checkvisibility = true + end + + def self.file(file) + new(File.new(file).readlines) + end + + def self.location(url, form=Hash.new) + s = HTTPClient.get(url, form) + s = "" if s.nil? + new(s) + end + + def self.new_from_cache2(data) + new(data) + end + + def self.new_from_cache(data) + hash = MD5.new("#{@@versie} #{data}") + + dir = "#{temp}/evcache.#{user}/tree.new" + file = "#{dir}/#{hash}" + + tree = nil + + Dir.mkdirrec(dir) + + if File.file?(file) + @@mutex.synchronize do + tree = Marshal.restore(File.new(file, "rb")) + end + else + tree = new(data) + + if not tree.nil? + @@mutex.synchronize do + File.open(file, "wb") {|f| Marshal.dump(tree, f)} + end + end + end + + return tree + end + + def inspect + @objects.collect do |obj| + obj.inspect + end.join("\n") + end + + def buildobjects(string) + raise "Has to be defined in the subclass." + end + + def buildparents + level = 1 + levels = Hash.new + levels[0] = nil + parse do |type, obj| + case obj.upordown + when Down + obj.level = level + obj.parent = levels[level-1] + levels[level] = obj + level += 1 + when Up, Dummy + pl = level + 1.upto(level-1) do |l| + po = levels[l] + pl = l if po.subtype == obj.subtype + end + level = pl + obj.level = level + obj.parent = levels[level-1] + when Same + obj.level = level + obj.parent = levels[level-1] + end + end + end + + def buildchildren + @objects.each do |obj| + obj.children = [] + end + + parse do |type, obj| + if not obj.parent.nil? + po = obj.parent + po.children << obj + else + @children << obj + end + end + end + + def markclosed + ([self].concat @objects).each do |obj| + obj.children.each_index do |i| + co1 = obj.children[i] + co2 = obj.children[i+1] + + co1.closed = (not co2.nil? and co1.upordown == Down and (co2.upordown == Up or co2.upordown == Dummy) and co1.subtype == co2.subtype) + end + end + end + + def deletedummies + ([self].concat @objects).each do |obj| + obj.children.delete_if do |obj2| + obj2.upordown == Dummy + end + end + + @objects.delete_if do |obj| + obj.upordown == Dummy + end + end + + def parse(types=[], subtypes=[], once=false) + types = [types] if types.class == Class + subtypes = [subtypes] if subtypes.class == String + hidelevel = nil + + catch :once do + @objects.each do |obj| + if (@checkvisibility and hidelevel.nil? and (not obj.visible)) + hidelevel = obj.level + else + if (@checkvisibility and (not hidelevel.nil?) and obj.visible and obj.level <= hidelevel) + hidelevel = nil + end + end + + if hidelevel.nil? + ok = false + catch :stop do + if types.empty? + if subtypes.empty? + ok = true + throw :stop + else + subtypes.each do |st| + if obj.subtype == st + ok = true + throw :stop + end + end + end + else + if subtypes.empty? + types.each do |t| + if obj.kind_of?(t) + ok = true + throw :stop + end + end + else + types.each do |t| + subtypes.each do |st| + if obj.kind_of?(t) and obj.subtype == st + ok = true + throw :stop + end + end + end + end + end + end + + if ok + yield(obj.class.to_s, obj) + + throw :once if once + end + end + end + end + end + + def path(pad) + p1 = self + + unless pad.nil? + pad.split(/\//).each do |deel| + tag, voorkomen = deel.split(/:/) + + if (not tag.nil?) and (not p1.nil?) + voorkomen = 1 if voorkomen.nil? + voorkomen = voorkomen.to_i + + teller = 0 + p2 = nil + p1.children.each_index do |i| + #if p1.children[i].upordown == Down + unless p1.children[i].subtype.nil? + if p1.children[i].subtype.noquotes == tag.noquotes + teller += 1 + p2 = p1.children[i] if teller == voorkomen + end + end + #end + end + p1 = p2 + end + end + end + + p1 + end +end