diff -ur rubywebdialogs-none.tar.gz/rubywebdialogs/init.rb rubywebdialogs-0.0.1.tar.gz/rubywebdialogs/init.rb --- rubywebdialogs-none.tar.gz/rubywebdialogs/init.rb 2004-06-23 00:36:57.000000000 +0200 +++ rubywebdialogs-0.0.1.tar.gz/rubywebdialogs/init.rb 2004-04-21 23:29:38.000000000 +0200 @@ -0,0 +1,40 @@ +require "rbconfig" + +Reversed = (ARGV.include?("-r")) + +FromDirs = ENV["PATH"].split(/:/) + [".", "./lib", "./rubylib/lib"] +ToDir = Config::CONFIG["sitelibdir"] + "/ev" + +Dir.mkdir(ToDir) if not File.directory?(ToDir) + +FromDirs.each do |fromdir| + fromdir = Dir.pwd if fromdir == "." + if File.directory?(fromdir) + Dir.new(fromdir).each do |file| + if not file.scan(/\.lib\.rb$/).empty? + fromfile = fromdir + "/" + file + tofile = ToDir + "/" + file.sub(/\.lib\.rb/, ".rb") + + if not (File.directory?("c:/")) + printf "%s -> %s\n", fromfile, tofile + + File.unlink(tofile) if File.symlink?(tofile) + File.symlink(fromfile, tofile) + else + if Reversed + tofile, fromfile = fromfile, tofile + end + + if FileTest.file?(fromfile) + printf "%s -> %s\n", fromfile, tofile + + File.delete(tofile) if File.writable?(tofile) + File.open(tofile, "w") {|f| f.puts File.new(fromfile).readlines} + else + printf "%s -> %s (Skipped!)\n", fromfile, tofile + end + end + end + end + end +end diff -ur rubywebdialogs-none.tar.gz/rubywebdialogs/install.rb rubywebdialogs-0.0.1.tar.gz/rubywebdialogs/install.rb --- rubywebdialogs-none.tar.gz/rubywebdialogs/install.rb 2004-06-23 00:36:57.000000000 +0200 +++ rubywebdialogs-0.0.1.tar.gz/rubywebdialogs/install.rb 2004-04-18 14:20:31.000000000 +0200 @@ -0,0 +1,40 @@ +require "rbconfig" + +Reversed = (ARGV.include?("-r")) + +FromDirs = ENV["PATH"].split(/:/) + [".", "./lib", "./rubylib/lib"] +ToDir = Config::CONFIG["sitelibdir"] + "/ev" + +Dir.mkdir(ToDir) if not File.directory?(ToDir) + +FromDirs.each do |fromdir| + fromdir = Dir.pwd if fromdir == "." + if File.directory?(fromdir) + Dir.new(fromdir).each do |file| + if not file.scan(/\.lib\.rb$/).empty? + fromfile = fromdir + "/" + file + tofile = ToDir + "/" + file.sub(/\.lib\.rb/, ".rb") + + if not (File.directory?("c:/")) + printf "%s -> %s\n", fromfile, tofile + + File.unlink(tofile) if File.symlink?(tofile) + File.symlink(fromfile, tofile) + else + if Reversed + tofile, fromfile = fromfile, tofile + end + + if FileTest.file?(fromfile) + printf "%s -> %s\n", fromfile, tofile + + File.delete(tofile) if File.writable?(tofile) + File.open(tofile, "w") {|f| f.puts File.new(fromfile).readlines} + else + printf "%s -> %s (Skipped!)\n", fromfile, tofile + end + end + end + end + end +end diff -ur rubywebdialogs-none.tar.gz/rubywebdialogs/lib/net.lib.rb rubywebdialogs-0.0.1.tar.gz/rubywebdialogs/lib/net.lib.rb --- rubywebdialogs-none.tar.gz/rubywebdialogs/lib/net.lib.rb 2004-06-23 00:36:57.000000000 +0200 +++ rubywebdialogs-0.0.1.tar.gz/rubywebdialogs/lib/net.lib.rb 2004-04-18 14:20:31.000000000 +0200 @@ -0,0 +1,541 @@ +require "ev/ruby" +#alias old_timeout :timeout +require "net/http" +#alias timeout :old_timeout +require "socket" +require "uri" +require "cgi" +require "md5" +require "thread" + +file = "#{home}/.evnet" +if File.file?(file) + Hash.file(file).each do |k, v| + eval "$#{k} = ´#{v}´" unless k=~ /^\#/ + #$proxy_auth = [$proxy_auth].pack("m").chomp if k == "proxy_auth" + end +end + +def uri2txt(s) + i = s.index(/%[[:digit:]]{2}/) + while not i.nil? + s = s[0..(i-1)] + s[(i+1)..(i+2)].unpack(´H2´).shift.to_i.chr + s[(i+3)..-1] + i = s.index(/%[[:digit:]]{2}/) + end + s +end + +class EVURI + attr_reader :protocol + attr_writer :protocol + attr_reader :userpass + attr_writer :userpass + attr_reader :host + attr_writer :host + attr_reader :port + attr_writer :port + attr_reader :path + attr_writer :path + attr_reader :vars + attr_writer :vars + attr_reader :anchor + attr_writer :anchor + + def initialize(url) + begin + @protocol, @userpass, @host, @port, d1, @path, d2, @vars, @anchor = URI.split(url.to_s) + rescue + end + + @protocol = "" if @protocol.nil? + @userpass = "" if @userpass.nil? + @host = "" if @host.nil? + @port = 0 if @port.nil? + @path = "" if @path.nil? + @vars = "" if @vars.nil? + @anchor = "" if @anchor.nil? + + res = {} + @varsvolgorde = [] + @vars.split(/&/).each{|var| k, v = var.split(/=/) ; res[k] = v ; @varsvolgorde << k} + @vars = res + + @port = @port.to_i + end + + def + (url2) + url1 = self.to_s + url2 = url2.to_s if url2.kind_of?(self.class) + + return EVURI.new((URI::Generic.new(*URI.split(url1)) + URI::Generic.new(*URI.split(url2))).to_s) rescue nil + end + + def to_s + protocol = @protocol + userpass = @userpass + host = @host + port = @port.to_s + path = @path + vars = varstring + anchor = @anchor + + protocol = nil if @protocol.empty? + userpass = nil if @userpass.empty? + host = nil if @host.empty? + port = nil if @port.zero? + path = nil if @path.empty? + vars = nil if @vars.empty? + anchor = nil if @anchor.empty? + + res = URI::HTTP.new(@protocol, @userpass, @host, port, nil, @path, nil, vars, @anchor).to_s + + res.gsub!(/@/, "") if (@userpass.nil? or @userpass.empty?) + + res.gsub!(/\#$/, "") + + return res + end + + def varstring + res = [] + vars = @vars.dup + + @varsvolgorde.each do |k| + if vars.include?(k) + v = vars[k] + vars.delete(k) + + res << (v.nil? ? k : "#{k}=#{v}") + end + end + + res.concat(vars.collect{|k, v| v.nil? ? k : "#{k}=#{v}"}) + + return res.join("&") + end +end + +class HTTPClient + @@versie = 1 + @@mutex = Mutex.new + @@hosts = {} + + class Header + attr_reader :header + attr_reader :protocol + attr_reader :code + attr_reader :text + + def initialize(header) + @header = {} + + if not header.nil? + firstline, rest = header.split(/\r*\n/, 2) + + @protocol, @code, @text = firstline.split(/ */, 3) + + if not rest.nil? + rest.split(/\r*\n/).each do |line| + key, value = line.split(/ /, 2) + @header[key.sub(/:$/, "").downcase] = value + end + end + end + end + + def to_s + res = "" + + res << "%s %s %s\n" % [@protocol, @code, @text] + + @header.each do |k, v| + res << "%s=%s\n" % [k, v] + end + + return res + end + end + + class Chunk + def initialize(data) + @data = "" + line, data = data.split(/\r*\n/, 2) + size, ext = line.split(/;/, 2) + size = size.hex + while not size.zero? and not data.nil? + @data += data[0..(size-1)] + data = data[size..-1] + if not data.nil? + data.gsub!(/^\r*\n/, "") + line, data = data.split(/\r*\n/, 2) + size, ext = line.split(/;/, 2) + size = size.hex + end + end + end + + def to_s + @data + end + end + + def self.head(uri, form={}, recursive=true) + header = Header.new(nil) + + begin + while not uri.nil? + if $proxy.nil? or $proxy.empty? + uri = EVURI.new(uri) if uri.kind_of? String + host = uri.host + port = uri.port + io = nil + + @@mutex.synchronize do + @@hosts[host] = IPSocket.getaddress(host) if not @@hosts.include?(host) + io = TCPSocket.new(@@hosts[host], port.zero? ? 80 : port) + end + + io.write("HEAD #{uri.path or ´/´}#{uri.varstring.empty? ? ´´ : ´?´ + uri.varstring} HTTP/1.0\r\nHost: #{host}\r\n\r\n") + else + proxy = EVURI.new($proxy) + host = proxy.host + port = proxy.port + + io = TCPSocket.new(host, port.zero? ? 8080 : port) + + io.write("HEAD #{uri} HTTP/1.0\r\n#{"Proxy-Authorization: Basic "+$proxy_auth+"\r\n" if not $proxy_auth.nil?}\r\n\r\n") + end + + io.close_write + + res = io.read + header, data = nil, nil + header, data = res.split(/\r*\n\r*\n/, 2) if not res.nil? + header = Header.new(header) + + if recursive and header.header["location"] != uri.to_s + uri = EVURI.new(uri) + header.header["location"] + else + uri = nil + end + end + rescue + header = Header.new(nil) + end + + return header + end + + def self.get(uri, form={}) + res = Array.new + form.each_pair do |var, value| + res << "#{var.to_html}=#{value.to_html}" + end + post = res.join("?") + + data = nil + + begin + while not uri.nil? + if $proxy.nil? or $proxy.empty? + uri = EVURI.new(uri) if uri.kind_of? String + host = uri.host + port = uri.port + io = nil + + @@mutex.synchronize do + @@hosts[host] = IPSocket.getaddress(host) if not @@hosts.include?(host) + io = TCPSocket.new(@@hosts[host], port.zero? ? 80 : port) + end + + if post.empty? + io.write("GET #{uri.path or ´/´}#{uri.varstring.empty? ? ´´ : ´?´ + uri.varstring} HTTP/1.0\r\nHost: #{host}\r\n\r\n") + else + io.write("POST #{uri.path or ´/´}#{uri.varstring.empty? ? ´´ : ´?´ + uri.varstring} HTTP/1.0\r\nHost: #{host}\r\nContent-Type: application/x-www-form-urlencoded\r\nContent-Length: #{post.length}\r\n\r\n") + io.write(post) + end + else + proxy = EVURI.new($proxy) + host = proxy.host + port = proxy.port + io = nil + + io = TCPSocket.new(host, port.zero? ? 8080 : port) + + if post.empty? + io.write("GET #{uri} HTTP/1.0\r\n#{"Proxy-Authorization: Basic "+$proxy_auth+"\r\n" if not $proxy_auth.nil?}\r\n\r\n") + else + io.write("POST #{uri} HTTP/1.0\r\n#{"Proxy-Authorization: Basic "+$proxy_auth+"\r\n" if not $proxy_auth.nil?}Content-Type: application/x-www-form-urlencoded\r\nContent-Length: #{post.length}\r\n\r\n") + io.write(post) + end + end + + io.close_write + + res = io.read + header, data = nil, nil + header, data = res.split(/\r*\n\r*\n/, 2) if not res.nil? + + header = Header.new(header) + + if header.header["location"] != uri.to_s + uri = EVURI.new(uri) + header.header["location"] + else + uri = nil + end + + if header.header["transfer-encoding"] == "chunked" + data = Chunk.new(data).to_s if not data.nil? + end + end + rescue + data = nil + end + + return data + end + + def self.head_from_cache(uri, form={}) + from_cache("head", uri, form) + end + + def self.get_from_cache(uri, form={}) + from_cache("get", uri, form) + end + + def self.from_cache(action, uri, form) + loc = uri.to_s + form.sort.inspect + hash = MD5.new("#{@@versie} #{loc}") + + dir = "#{temp}/evcache.#{user}/httpclient.#{action}" + file = "#{dir}/#{hash}" + data = nil + + Dir.mkdirrec(dir) + + expire = 356*24*60*60 + + if FileTest.file?(file) and (Time.new.to_f - File.stat(file).mtime.to_f < expire) + @@mutex.synchronize do + File.open(file, "rb") {|f| data = f.read} + end + else + data = method(action).call(uri, form) + + if not data.nil? + @@mutex.synchronize do + File.open(file, "wb") {|f| f.write data} + end + end + end + + return data + end +end + +class RequestGet < Hash + def initialize(data) + CGI.parse(data).each do |k, v| + self[k] = v.join(" ") + end + end +end + +class RequestPost < Hash + def initialize(data) + CGI.parse(data).each do |k, v| + self[k] = v.join(" ") + end + end +end + +class RequestRequest + attr_reader :method + attr_reader :uri + attr_reader :path + attr_reader :data + attr_reader :protocol + + def initialize(firstline) + @method, @uri, @protocol = firstline.split(/ /) + @path, @data = @uri.split(/\?/) + @data = "" if @data.nil? # TODO + +# i = @path.index(/%[[:digit:]]{2}/) +# while not i.nil? +# @path = @path[0..(i-1)] + @path[(i+1)..(i+2)].unpack(´H2´).shift.to_i.chr + @path[(i+3)..-1] +# i = @path.index(/%[[:digit:]]{2}/) +# end + end + + def to_s + "#{@method} #{@uri} #{@protocol}\r\n" + end +end + +class Request < Hash + attr_reader :peeraddr + attr_reader :request + attr_reader :cookies + attr_reader :vars + + def initialize(io) + @io = io + + firstline = @io.gets + + return if firstline.nil? + + @request = RequestRequest.new(firstline.strip) + + line = @io.gets.strip + while not line.empty? do + key, value = line.split(" ", 2) + self[key.sub(/:$/, "").downcase] = value + + line = @io.gets.strip + end + + cookie = self["cookie"] + cookie = "" if cookie.nil? + @cookies = {} + cookie.split(/;/).each do |s| + k, v = s.strip.split(/=/, 2) + @cookies[k] = v + end + + if not @request.method.nil? + case @request.method + when "HEAD" + when "GET" + @vars = RequestGet.new(@request.data.nil? ? "" : @request.data) + when "POST" + data = @io.read(self["content-length"].to_i) + @vars = RequestPost.new((self["content-type"] == "application/x-www-form-urlencoded") ? data : "") + else + puts "Unknown request (´#{firstline}´)." + end + end + + @peeraddr = @io.peeraddr + + @io.close_read + end + + def to_s + res = @request.to_s + self.each do |k, v| + res << "#{k}: #{v}\r\n" + end + res + end +end + +class Response < Hash + attr_writer :response + + def initialize(io) + @io = io + @response = "HTTP/1.0 200 OK" + @data = "" + end + + def flush + @io.write("#{to_s}\r\n#{@data}") + @io.close + end + + def to_s + res = "#{@response}\r\n" + self.each do |k, v| + res << "#{k}: #{v}\r\n" + end + res + end + + def << (s) + @data << s + end +end + +class HTTPServer + @@times = {} + + def self.serve(port=80, remote=false, auth=nil, realm="ev/net") + begin + server = TCPServer.new(remote ? "0.0.0.0" : "localhost", port) + puts "Just point your browser to http://localhost:#{port}/ ..." + rescue + server = nil + puts "Port #{port} is in use." + end + + if not server.nil? + loop do + io = nil + + begin + io = server.accept + + req = Request.new(io) + resp = Response.new(io) + rescue + puts "Getting request from browser failed." + io = nil + end + + if not io.nil? and not req.peeraddr.nil? + #Thread.new(req, resp) do |req, resp| + com = req.request.to_s.strip + req.peeraddr[3] + + @@times[com]=Time.new.to_f if not @@times.include?(com) + + if (not remote) or (remote and (auth.nil? or authenticate(auth, realm, req, resp))) + #puts "#{Time.new.strftime("%H:%M:%S")}: #{req.peeraddr[3]}: #{((Time.new.to_f - @@times[com]).to_s + "0"*4)[0..4]}: > #{req.request}" + + yield(req, resp) + + puts "#{Time.new.strftime("%H:%M:%S")}: #{req.peeraddr[3]}: #{((Time.new.to_f - @@times[com]).to_s + "0"*4)[0..4]}: < #{req.request}" + + @@times.delete(com) + end + + begin + resp.flush + rescue + end + #end + end + end + end + end + + def self.authenticate(auth, realm, req, resp) + if auth.kind_of? String + file = "#{home}/#{auth}" + auths = {} + auths = Hash.file(file) if FileTest.file?(file) + else + auths = auth + end + + authuserpassword = req["authorization"] + if not authuserpassword.nil? + authtype, userpassword = authuserpassword.split(/ /) + if authtype == "Basic" and not userpassword.nil? + u, p = userpassword.unpack("m").shift.split(/:/) + end + end + + ok = (auths.include?(u) and auths[u] == p) + + if ok + + else + resp["WWW-Authenticate"] = "Basic realm=\"#{realm}\"" + resp.response = "HTTP/1.0 401 Unauthorized" + end + + return ok + end +end diff -ur rubywebdialogs-none.tar.gz/rubywebdialogs/lib/ruby.lib.rb rubywebdialogs-0.0.1.tar.gz/rubywebdialogs/lib/ruby.lib.rb --- rubywebdialogs-none.tar.gz/rubywebdialogs/lib/ruby.lib.rb 2004-06-23 00:36:57.000000000 +0200 +++ rubywebdialogs-0.0.1.tar.gz/rubywebdialogs/lib/ruby.lib.rb 2004-04-18 14:20:31.000000000 +0200 @@ -0,0 +1,648 @@ +require "cgi" +require "rbconfig" + +Thread.abort_on_exception = true + +module Enumerable + def deep_dup + Marshal::load(Marshal::dump(dup)) + end + + def deep_clone + Marshal::load(Marshal::dump(clone)) + end +end + +class Object + alias deep_dup :dup + alias deep_clone :clone + + def to_fs + to_s + end +end + +class Numeric + def to_fs + to_f + end +end + +class String + def chomp!(dummy=nil) + self.gsub!(/[\r\n]*\z/, "") + end + + def chomp(dummy=nil) + self.gsub(/[\r\n]*\z/, "") + end + + def crlf + self.gsub(/\r*\n/, "\r\n").gsub(/\r\n\z/, "") + "\r\n" + end + + def strip + self.stripbefore.stripafter + end + + def stripbefore + self.gsub(/\A[[:blank:]\r\n]*/, "") + end + + def stripafter + self.gsub(/[[:blank:]\r\n]*\z/, "") + end + + def compress + self.gsub(/[[:blank:]\r\n]+/, " ").strip + end + + def compressspaces + self.gsub(/[[:blank:]]+/, " ") + end + + def numeric? + d, a, n = [self].to_par + + not n.empty? + end + + def exec(input=nil, output=true) + res = [] + + IO.popen(self, "w+") do |f| + f.puts input if not input.nil? + f.close_write + + res = f.readlines if output + end + + res.join("") + end + + def eval + Kernel::eval(self) + end + + def speak + require "drb" + + DRb.start_service + DRbObject.new(nil, "druby://localhost:3100").speak(self) + end + + def splitblocks(begindelimiters, enddelimiter) + bd = begindelimiters.collect {|s| Regexp.escape(s)} + ed = enddelimiter.collect {|s| Regexp.escape(s)} + + be = bd.join("|") + ee = ed.join("|") + + res = [] + type = 0 + tmp = "" + es = "" + self.split(/(#{be}|#{ee})/).each do |s| + if type == 0 + if begindelimiters.include?(s) + type = begindelimiters.index(s)+1 + tmp = s + es = enddelimiter[begindelimiters.index(s)] + else + #res << [0, s] if not s.compress.empty? + res << [0, s] if not s.empty? + end + else + if s == es + res << [type, tmp + s] + type = 0 + tmp = "" + es = "" + else + tmp = tmp + s + end + end + end + res + end + + def splitwords(tokens=[], begindelimiters=["´", ´"´], enddelimiter=["´", ´"´]) + tokens = [tokens] if not tokens.kind_of?(Array) + res = [] + self.splitblocks(begindelimiters, enddelimiter).each do |type, s| + case type + when 0 + tokens.each do |token| + token2 = token + token2 = Regexp.escape(token2) if token2.kind_of?(String) + s.gsub!(/#{token2}/, " #{token} ") + end + s.split().each do |w| + res << w + end + when 1, 2 + res << s[1..-2] + end + end + res + end + + def uncomment + res = [] + self.splitblocks( ["´" , ´"´ , "/*" , "<!--" , "#" , ";" ], + ["´" , ´"´ , "*/" , "-->" , "\n", "\n"]).each do |type, s| + case type + when 0, 1, 2 then res << s + when 3, 4, 5 + end + end + res.join("") + end + + def noquotes + self.sub(/\A[´"]/, "").sub(/[´"]\z/, "") + end + + def to_html(eolconversion=true) + s = CGI.escapeHTML(self) + + s.gsub!(/\"/, "\"") + s.gsub!(/\´/, "\´") + + if eolconversion + s.gsub!(/\n/ , "<br>") + end + + s + end + + def from_html(eolconversion=true) + s = self + + s.gsub!(/"/ , "\"") + s.gsub!(/´/, "\´") + + s = CGI.unescapeHTML(self) + + if eolconversion + s.gsub!(/<br>/, "\n") + end + + s + end + + def to_fs + if numeric? + to_f + else + to_s + end + end +end + +class Array + def chomp! + self.collect!{|s| s.chomp} + end + + def chomp + self.collect{|s| s.chomp} + end + + def compress + self.collect{|s| s.compress} + end + + def uncomment + self.join("\0").uncomment.split("\0") + end + + def strip + self.collect{|s| s.strip} + end + + def sum + res = 0 + self.each do |n| + res += n + end + res + end + + def product + res = 1 + self.each do |n| + res *= n + end + res + end + + def joinwords(sep=" ", quote=´"´) + self.collect do |s| + s = quote + s + quote if s =~ /[[:blank:]]/ + s + end.join(sep) + end + + def domino(tabellen, kolom=nil, onlymatchinglines=false) + links = self + res = [] + res = self.dup unless onlymatchinglines + + tabellen.each do |rechts| + tmp = [] + + links.each do |l| + if kolom.nil? or l.length == kolom + rechts.each do |r| + tmp << l + r[1..-1] if l[-1] == r[0] + end + end + end + + links = tmp + res.concat(tmp) + end + + res = res.sort.uniq + end + + def dominoloop(tabellen) + lres = [] + res = self.dup + kolom = 2 + + while lres.length != res.length do + lres = res.dup + res = res.domino(tabellen, kolom) + + res.each do |line| + line << "*" if (line.length != line.uniq.length and line[-1] != "*") + end + + $stderr.print "#{100*(res.length)/(lres.length)}% " + + kolom += 1 + end + + $stderr.puts "" + + return res + end + + def buildtree + self.dominoloop([self]) + end + + def subset(fields, values, results, exact=true, emptyline=nil, joinwith=nil) + fields = [fields] if not fields.kind_of? Array + values = [values] if not values.kind_of? Array + results = [results] if not results.kind_of? Array + res = [] + + self.each do |l| + ok = true + + case l.class.to_s + when "String" + c = l.splitwords + correction = 1 + joinwith = " " if joinwith.nil? + when "Array" + c = l + correction = 0 + end + + 0.upto(c.length-1) do |n| + if fields.include?(n+correction) + v = values[fields.index(n+correction)] + if not emptyline.nil? and not v.downcase == emptyline.downcase + if exact + ok = false unless (v.nil? or c[n].downcase == v.downcase) + else + ok = false unless (v.nil? or c[n].downcase.include?(v.downcase)) + end + end + end + end + + if ok + res2 = [] + results.each do |n| + res2 << c[n-1] + end + res2 = res2.join(joinwith) if not joinwith.nil? + res << res2 + end + end + + return res + end + + def format(format) + res = [] + + [format.length, self.length].min.times do |n| + case format[n].chr + when "i" then res << self[n].to_i + when "s" then res << self[n].to_s + when "x" then res << self[n] + end + end + + res + end + + def to_i + collect{|c| c.to_i} + end + + def to_par + dash = self.dup + alpha = self.dup + numeric = self.dup + + dash.delete_if do |s| + not (s =~ /\A-/) or + (s =~ /\A-?[[:digit:]\.]+\z/) or + (s =~ /^-+$/) + end + + alpha.delete_if do |s| + ((s =~ /\A-/) or + (s =~ /\A-?[[:digit:]\.]+\z/)) and + not ((s =~ /^\.+$/) or (s =~ /^-+$/)) + end + + numeric.delete_if do |s| + not (s =~ /\A-?[[:digit:]\.]+\z/) or + (s =~ /^\.+$/) + end + + raise "Oops!" if dash.length + alpha.length + numeric.length != length + + return dash, alpha, numeric + end + + def self.file(file) + res = [] + + File.new(file).readlines.uncomment.chomp.each do |line| + res << line + end + + res + end + + def numsort + sort do |a, b| + a2 = a.to_fs + b2 = b.to_fs + + if a2.class != b2.class + a2 = a + b2 = b + end + + a2 <=> b2 + end + end + + def to_fs + collect{|s| s.to_fs} + end + + def chaos + res = self.dup + + (length^2).times do + a = rand(length) + b = rand(length) + + res[a], res[b] = res[b], res[a] + end + + res + end + + def minmax + min, value, max = self + [min, [value, max].min].max + end +end + +class Hash + def save(file, append=false) + org = {} + org = Hash.file(file) if (append and File.file?(file)) + + self.sort.each do |k, v| + org[k] = v + end + + File.open(file, "w") do |f| + org.sort.each do |k, v| + #f.puts "´%s´=´%s´" % [k, v] + f.puts "%s = %s" % [k, v] + end + end + end + + def subset(fields, values, results=nil, exact=true, emptyline=nil, joinwith=nil) + fields = [fields] if not fields.kind_of? Array + values = [values] if not values.kind_of? Array + results = [results] if not results.kind_of? Array + res = self.dup + res.delete_if {true} + + self.each do |k, l| + ok = true + + case l.class.to_s + when "String" + c = l.splitwords + correction = 1 + joinwith = " " if joinwith.nil? + when "Array" + c = l + correction = 0 + end + + 0.upto(c.length-1) do |n| + if fields.include?(n+correction) + v = values[fields.index(n+correction)] + if emptyline.nil? or (not emptyline.nil? and not v.downcase == emptyline.downcase) + if exact + ok = false unless (v.nil? or c[n].downcase == v.downcase) + else + ok = false unless (v.nil? or c[n].downcase.include?(v.downcase)) + end + end + end + end + + if ok + res2 = [] + if results == [nil] + res2 = c + else + results.each do |n| + res2 << c[n-correction] + end + end + res2 = res2.join(joinwith) if not joinwith.nil? + res[k] = res2 + end + end + + return res + end + + def to_i + collect{|k, v| v.to_i} + end + + def self.file(file) + res = {} + + File.new(file).readlines.chomp.each do |line| + if not line.compress.empty? + k, v = line.split(/\s*=\s*/, 2) + res[k] = v + end + end +# File.new(file).readlines.uncomment.chomp.each do |line| +# if not line.compress.empty? +# a = line.splitwords("=") +# +# if a.size == 3 and a[1] == "=" +# res[a[0]] = a[2] +# else +# puts "Error in #{file} (not ´var=\"value\"´)." +# end +# end +# end + + res + end +end + +class Dir + def Dir.mkdirrec(dir) + pdir = File.dirname(dir) + + if not pdir.empty? and not FileTest.directory?(pdir) + mkdirrec (pdir) + end + + Dir.mkdir(dir) rescue nil + end +end + +def id2ref(id) + ObjectSpace._id2ref(id) +end + +def after(seconds) + if not seconds.nil? and not seconds.zero? + Thread.new do + sleep seconds + yield + end + end +end + +def every(seconds) + if not seconds.nil? and not seconds.zero? + Thread.new do + loop do + sleep seconds + yield + end + end + end +end + +def evtimeout(seconds) + if not seconds.nil? and not seconds.zero? + t = Thread.current + threads = [] + res = nil + + threads[1] = Thread.new do + sleep seconds + begin + threads[2].kill + rescue NameError + end + res = false + t.wakeup + end + + threads[2] = Thread.new do + yield + begin + threads[1].kill + rescue NameError + end + res = true + t.wakeup + end + + threads[1].join + threads[2].join + + return res + else + yield + end +end + +def evtimeoutretry(seconds) + ok = false + + while not ok + evtimeout(seconds) do + yield + ok = true + end + end +end + +def trap(signal) + Kernel::trap(signal) do + yield + end + + # Seems pointless, but it´s for catching ^C under Windows... + + every(1) {} +end + +def linux? + not windows? and not cygwin? +end + +def windows? + not (target_os.downcase =~ /32/).nil? +end + +def cygwin? + not (target_os.downcase =~ /cyg/).nil? +end + +def target_os + Config::CONFIG["target_os"] or "" +end + +def user + ENV["USER"] or ENV["USERNAME"] +end + +def home + (ENV["HOME"] or ENV["USERPROFILE"] or (File.directory?("h:/") ? "h:" : "c:")).gsub(/\\/, "/") +end + +def temp + (ENV["TEMP"] or "/tmp").gsub(/\\/, "/") +end diff -ur rubywebdialogs-none.tar.gz/rubywebdialogs/lib/rwd.lib.rb rubywebdialogs-0.0.1.tar.gz/rubywebdialogs/lib/rwd.lib.rb --- rubywebdialogs-none.tar.gz/rubywebdialogs/lib/rwd.lib.rb 2004-06-23 00:36:57.000000000 +0200 +++ rubywebdialogs-0.0.1.tar.gz/rubywebdialogs/lib/rwd.lib.rb 2004-04-18 14:20:31.000000000 +0200 @@ -0,0 +1,1320 @@ +require "ev/xml" +require "ev/net" +require "md5" +require "rbconfig" +require "pstore" + +begin + require "win32ole" + require "win32/registry" +rescue LoadError + $".push "win32ole.rb" + $".push "win32/registry.rb" +end + +exit if ARGV.include?("--rwd-exit") + +Debug = false +Border = 0 +RWDEmptyline = "..." + +rcfile = nil +s = ENV["HOME"] ; s = s + "/.rwdrc" if not s.nil? ; rcfile = s if (not s.nil? and rcfile.nil? and FileTest.file?(s)) +s = ENV["USERPROFILE"] ; s = s + "/rwd.cfg" if not s.nil? ; rcfile = s if (not s.nil? and rcfile.nil? and FileTest.file?(s)) +s = ENV["windir"] ; s = s + "/rwd.cfg" if not s.nil? ; rcfile = s if (not s.nil? and rcfile.nil? and FileTest.file?(s)) + +AL = "align=´left´" +AC = "align=´center´" +AR = "align=´right´" +VA = "valign=´middle´" + +Format = "\n<!-- %-10s %-10s -->\t" + +if not rcfile.nil? + puts "Reading #{rcfile} ..." + + Hash.file(rcfile).each do |k, v| + ENV[k] = v + end +else + begin + puts "Looking for default browser..." + ENV["RWDBROWSER"] = Win32::Registry::HKEY_CLASSES_ROOT.open(´htmlfile\shell\open\command´)[0] + rescue + puts "Not found." + end + + if not ENV.include?("RWDBROWSER") and false # ??? + s = ENV["HOME"] ; s = s + "/.rwdrc" if not s.nil? ; rcfile = s if (not s.nil? and rcfile.nil?) + s = ENV["USERPROFILE"] ; s = s + "/rwd.cfg" if not s.nil? ; rcfile = s if (not s.nil? and rcfile.nil?) + s = ENV["windir"] ; s = s + "/rwd.cfg" if not s.nil? ; rcfile = s if (not s.nil? and rcfile.nil?) + + if not rcfile.nil? + puts "Creating #{rcfile} ..." + puts "" + puts "# This is the first time you start a RubyWebDialog application." + puts "# I have to know your favorite browser." + puts "# " + puts "# Put the full path to your favorite browser between the quotes" + puts "# (\"...\") after RWDBROWSER= and remove the hash (#) at the" + puts "# beginning of the line." + puts "# " + puts "# Restart your application." + puts "" + + File.open(rcfile, "a") do |f| + f.puts "# This is the first time you start a RubyWebDialog application." + f.puts "# I have to know your favorite browser." + f.puts "# " + f.puts "# Put the full path to your favorite browser between the quotes" + f.puts "# (\"...\") after RWDBROWSER= and remove the hash (#) at the" + f.puts "# beginning of the line." + f.puts "# " + f.puts "# Restart your application." + f.puts "" + f.puts "#RWDBROWSER=\"...\"" + end + end + + if windows? + system("notepad #{rcfile}") + + sleep 1 + else + puts "Please edit #{rcfile}." + end + + exit + end +end + +trap("INT") {puts "Terminating..." ; exit} + +$SAFE = 2 + +class IE + def initialize(url) + @ie = WIN32OLE.new("InternetExplorer.Application") + @ev = WIN32OLE_EVENT.new(@ie, "DWebBrowserEvents2") + + @ie.navigate(url) + + @ie.menubar = false + @ie.toolbar = false + @ie.addressbar = false + @ie.statusbar = false + + @ie.visible = true + + at_exit do + @ie.visible = false + end + + @ev.on_event("OnQuit") do + Thread.main.exit + end + + Thread.new do + loop do + WIN32OLE_EVENT.message_loop + end + end + end +end + +class Array + def rwd_options(emptyline=nil) + if emptyline.nil? + a = self + else + a = [emptyline].concat self + end + + a.numsort.collect{|s| "<option>#{s.to_html}</option>" }.join("\n") + end + + def rwd_method(method) + res = "" + + self.each do |s| + s = s.join("/") if s.kind_of?(Array) + s2 = s.dup + s2[0..0] = s2[0..0].upcase + res = res + "<p align=´left´><a action=´#{method}/#{s.to_html}´>#{s2.to_html}</a></p>" + end + + return res + end + + def rwd_row(key=nil, value=nil) + res = "" + + res = res + "<row valign=´top´>" + res = res + "<radio name=´#{key.to_html}´ value=´#{value.to_html}´/>" if not key.nil? + res = res + self.collect{|s| "<p align=´left´>#{s.to_html}</p>"}.join("") + res = res + "</row>" + + return res + end + + def rwd_headers(emptyfield=false) + res = "" + + res = res + "<row>" + res = res + "<p/>" if emptyfield + res = res + self.collect{|s| "<p align=´left´><b>#{s.to_html}</b></p>" }.join("") + res = res + "</row>" + + return res + end + + def rwd_form(prefix, values, twoparts=0, options={}) + res = [] + + res << "<table>" + self.each_index do |n| + name = "#{prefix.to_html}#{self[n].downcase.to_html}" + + res << "<row>" + res << "<p align=´right´>" + res << "#{self[n].to_html}:" + res << "</p>" + + if options.keys.include?(self[n]) + res << "<select name=´#{name}´>" + res << options[self[n]].rwd_options(RWDEmptyline) + res << "</select>" + else + s = "" + + s << "<text name=´#{name}´" + s << " value=´#{values[n].to_html}´" if n < values.length + s << "/>" + + res << s + end + + res << "</row>" + + if twoparts > 0 and n == twoparts-1 + res << "<row><empty/></row>" + end + end + res << "</table>" + + return res.join("\n") + end +end + +class Hash + def rwd_table(field, joinwith=@sep, headers=nil) + res = [] + + res << "<table>" + res << headers.rwd_headers(true) if not headers.nil? + self.keys.numsort.each do |key| + key2 = key + value2 = self[key] + + key2 = key2.join(joinwith) if key2.kind_of?(Array) + value2 = [value2] if value2.kind_of?(String) + + res << value2.rwd_row(field, key2) + end + res << "</table>" + + res.join("\n") + end +end + +class EVTable + def rwd_table(key, joinwith) + super(key, joinwith, @headers) + end + + def rwd_form(prefix="", key=nil, twoparts=false) + values = self[key] if not key.nil? + values = [] if values.nil? + options = {} + + if File.file?(oldlocation("constraints.csv")) + table = File.basename(@file).gsub(/\.csv$/, "") + + CSVFile.new(oldlocation("constraints.csv")).subset(["Table", "Constraint"], [table, "key"], ["Column", "Value"]).values.each do |column, table2| + options[column] = CSVFile.new(oldlocation("#{table2}.csv")).keys.collect{|a| a.join("\t")} + end + end + + @headers.rwd_form(prefix, values, twoparts ? @key : 0, options) + end + + def rwd_metadata + res = [] + + res << "<table>" + res << "<row>" + res << " <empty/>" + res << " <text name=´header_new´ value=´´/>" + res << "</row>" + @headers.each_index do |n| + res << "<row>" + res << " <text name=´header_#{n}_old´ value=´#{@headers[n]}´/>" + res << " <text name=´header_#{n}_new´ value=´´/>" + res << "</row>" + end + res << "</table>" + + return res.join("\n") + end +end + +class OpenTag + def prechildren(res, before, after, vars, switches, help, firstaction, tabs, tab) + bef = before[-1] + res.concat Format % ["Before", @subtype] if (Debug and not bef.nil?) + res.concat bef if not bef.nil? + + res.concat Format % ["Pre", @subtype] if Debug + + align = AC + align = "align=´#{@args["align"]}´" if @args.include?("align") + + valign = VA + valign = "valign=´#{@args["valign"]}´" if @args.include?("valign") + + value = "" + value = vars[@args["name"]] if vars.include?(@args["name"]) + value = @args["value"] if @args.include?("value") + + case @subtype + when "application" + when "window", "helpwindow" + args = @args.deep_dup + + args["nohelpbutton"] = (not help) + + res.concat(template(RWD_HTML1, args)) + when "p" then res.concat "<p #{align}>" + when "pre" then res.concat "<pre>" + when "big" then res.concat "<p #{align}><big>" + when "small" then res.concat "<p #{align}><small>" + when "list" then res.concat "<ul #{align}>" + when "item" then res.concat "<li #{align}>" + when "empty" then res.concat "<p><br>" + when "image" then res.concat "<img src=´#{@args["src"]}´>" + when "br" then res.concat "<br>" + when "hr" then res.concat "<hr>" + when "b" then res.concat "<b>" + when "i" then res.concat "<i>" + when "a" + if @args.include?("href") + res.concat "<a href=´#{@args["href"]}´ target=´#{@args["target"] or "new"}´>" + else + res.concat "<a href=´javascript:document.bodyform.rwd_action.value=\"#{@args["action"]}\";document.bodyform.submit();´>" + end + when "vertical" then res.concat "<table #{AC} border=´#{Border}´ cellspacing=´3´ cellpadding=´0´>" + when "horizontal" then res.concat "<table #{AC} border=´#{Border}´ cellspacing=´3´ cellpadding=´0´><tr #{align} #{valign}>" + when "table" then res.concat "<table #{AC} border=´#{Border}´ cellspacing=´3´ cellpadding=´0´>" + when "row" then res.concat "<tr #{align} #{valign}>" + when "hidden" then res.concat "<p #{align}><input name=´#{@args["name"]}´ value=´#{value}´ type=´hidden´>" + when "text" then res.concat "<p #{align}><input name=´#{@args["name"]}´ value=´#{value}´ type=´text´>" + when "textarea" then res.concat "<p #{align}><textarea name=´#{@args["name"]}´>#{value}</textarea>" + when "password" then res.concat "<p #{align}><input name=´#{@args["name"]}´ value=´#{value}´ type=´password´>" + when "checkbox" + if vars[@args["name"]] == "on" + switches[@args["name"]] = true + res.concat "<p #{align}><input name=´#{@args["name"]}´ checked=´on´ type=´checkbox´>" + else + switches[@args["name"]] = false + res.concat "<p #{align}><input name=´#{@args["name"]}´ type=´checkbox´>" + end + when "radio" + if vars[@args["name"]] == value + res.concat "<p #{align}><input name=´#{@args["name"]}´ checked=´on´ value=´#{value}´ type=´radio´>" + else + res.concat "<p #{align}><input name=´#{@args["name"]}´ value=´#{value}´ type=´radio´>" + end + when "select" + res.concat "<select #{align} name=´#{@args["name"]}´ width=´#{@args["width"]}´>" + name = @args["name"] + $select = vars[name] + when "option" + if $select == @children[0].text + res.concat "<option selected=´true´>" + else + res.concat "<option>" + end + when "button" + res.concat "<input type=´submit´ value=´#{@args["caption"]}´ onclick=´document.bodyform.rwd_action.value=\"#{@args["action"]}\";´>" + firstaction << @args["action"] if (firstaction.empty? and @args.include?("action")) + when "back" + res.concat "<input type=´submit´ value=´Back´ onclick=´document.bodyform.rwd_action.value=\"rwd_back\";´>" + firstaction << "rwd_back" if firstaction.empty? + when "help" + res.concat "<input type=´submit´ value=´Help´ onclick=´document.bodyform.rwd_action.value=\"rwd_help\";´>" + firstaction << "rwd_help" if firstaction.empty? + when "quit" + res.concat "<input type=´submit´ value=´Quit´ onclick=´document.bodyform.rwd_action.value=\"rwd_quit\";´>" + firstaction << "rwd_quit" if firstaction.empty? + when "close" + res.concat "<input type=´submit´ value=´Close´ onclick=´window.close();´>" + firstaction << "rwd_quit" if firstaction.empty? + when "reset" + res.concat "<input type=´reset´ value=´Reset´>" + firstaction << "rwd_quit" if firstaction.empty? + when "closewindow" + #res.concat "<script type=´text/javascript´>\n" + #res.concat "<!--\n" + #res.concat " window.close();\n" + #res.concat "//-->\n" + #res.concat "</script>" + when "tabs" + res.concat "<table #{AC} border=´#{Border}´ cellspacing=´3´ cellpadding=´0´>" + res.concat " <tr #{AC}>" + res.concat " <td #{AC}>" + res.concat " <table #{AC} border=´#{Border}´ cellspacing=´3´ cellpadding=´0´>" + res.concat " <tr #{AC}>" + tabs.each do |obj| + caption = obj.args["caption"] + if caption == tab + res.concat "<td #{AC}><div class=´box´><tt><b> #{caption} </b></tt></div></td>" + else + res.concat "<td #{AC}><div class=´box´><a href=´javascript:document.bodyform.rwd_action.value=\"rwd_tab_#{caption}\";document.bodyform.submit();´><tt> #{caption} </tt></a></div></td>" + end + end + res.concat " </tr>" + res.concat " </table>" + res.concat " </td>" + res.concat " </tr>" + when "tab" + res.concat "<tr #{align} #{valign}><td #{align}><div class=´box2´>" + else + puts "<#{@subtype}>" + res.concat "<#{@subtype}>" + end + + bef = nil + aft = nil + + case @subtype + when "vertical", "window", "helpwindow" + res.concat Format % ["AftPre", @subtype] if Debug + if @args.include?("spacing") + s = "<tr><td> </td></tr>" * (@args["spacing"].to_i) + else + s = "" + end + bef = "#{s}<tr #{align} #{valign}><td #{align}>" + aft = "</td></tr>" + when "horizontal", "row" + res.concat Format % ["AftPre", @subtype] if Debug + bef = "<td #{align}>" + aft = "</td>" + end + + before.push(bef) + after.push(aft) + end + + def postchildren(res, before, after, vars, switches, help, firstaction, tabs, tab) + case @subtype + when "vertical", "window", "helpwindow" + res.concat Format % ["BefPost", @subtype] if Debug + if @args.include?("spacing") + res.concat "<tr><td> </td></tr>" * (@args["spacing"].to_i) + end + when "horizontal", "row" + res.concat Format % ["BefPost", @subtype] if Debug + end + + res.concat Format % ["Post", @subtype] if Debug + + case @subtype + when "application" + when "window", "helpwindow" + args = @args.deep_dup + + args["nohelpbutton"] = (not help) + + res.concat(template(RWD_HTML2, args)) + when "p" then res.concat "</p>" + when "pre" then res.concat "</pre>" + when "big" then res.concat "</big></p>" + when "small" then res.concat "</small></p>" + when "list" then res.concat "</ul>" + when "item" then res.concat "</li>" + when "empty" then res.concat "</p>" + when "image" then res.concat "" + when "br" then res.concat "" + when "hr" then res.concat "" + when "b" then res.concat "</b>" + when "i" then res.concat "</i>" + when "a" then res.concat "</a>" + when "vertical" then res.concat "</table>" + when "horizontal" then res.concat "</tr></table>" + when "table" then res.concat "</table>" + when "row" then res.concat "</tr>" + when "hidden" then res.concat "</p>" + when "text" then res.concat "</p>" + when "textarea" then res.concat "</p>" + when "password" then res.concat "</p>" + when "checkbox" then res.concat "</p>" + when "radio" then res.concat "</p>" + when "select" + res.concat "</select>" + $select = nil + when "option" then res.concat "</option>" + when "button" then res.concat "" + when "back" then res.concat "" + when "help" then res.concat "" + when "quit" then res.concat "" + when "close" then res.concat "" + when "reset" then res.concat "" + when "closewindow" then res.concat "" + when "tabs" then res.concat "</table>" + when "tab" then res.concat "</div></td></tr>" + else + puts "</#{@subtype}>" + res.concat "</#{@subtype}>" + end + + before.pop + after.pop + + aft = after[-1] + res.concat Format % ["After", @subtype] if (Debug and not aft.nil?) + res.concat aft if not aft.nil? + end + + def template(html, vars) + res = [] + + a = {} + + vars.each do |k, v| + a[k.upcase] = v + end + + a["LOGO"] = "" unless ((not vars["logo"].nil?) and FileTest.file?(vars["logo"])) + + a["HELPBUTTON"] = (not (vars["nohelpbutton"])) + a["BACKBUTTONS"] = (not (vars["nobackbuttons"])) + a["BACKBUTTONS"] = (not (vars["nobackbuttons"])) + a["CLOSEBUTTON"] = (not (vars["noclosebutton"])) + + html.split(/\r*\n/).each do |line| + if line =~ /%[A-Z]+%/ + a.each do |k, v| + v = false if (v.kind_of?(String) and v.empty?) + + if line.include?("%#{k}%") + line.gsub!("%#{k}%", "#{v}") if v + end + end + + line = "<!-- #{line.scan(/%[A-Z]+%/).join(" ")} -->" if line =~ /%[A-Z]+%/ + end + + res << line + end + + res.join("\n") + end +end + +class Text + def prechildren(res, before, after, vars, switches, help, firstaction, tabs, tab) + if not @text.scan(/[^ \t\r\n]/).empty? + res.concat Format % ["Text", ""] if Debug + res.concat "#{@text}" + end + end +end + +class RWDTree < XML +end + +class RWDWindow + @@windows = {} # Kind of caching. + @@helpwindows = {} # Kind of caching. + + def initialize(rwd, window=nil) + rwd = rwd.join("\n") if rwd.kind_of?(Array) + + if @@windows[rwd].nil? + @@windows[rwd] = {} + @@helpwindows[rwd] = {} + + tree = XML.new(rwd) + + tree.parse(OpenTag, "window") do |type, obj| + @@windows[rwd][obj.args["name"]] = obj.to_h + end + + tree.parse(OpenTag, "helpwindow") do |type, obj| + @@helpwindows[rwd][obj.args["name"]] = obj.to_h + end + end + + @rwd = (@@windows[rwd][window] or "").dup + @helprwd = (@@helpwindows[rwd][window] or "").dup + end + + def render(vars=Hash.new, switches=Hash.new, help=false, tab="") + vars2 = Hash.new + firstaction = "" + html = "" + + vars.each do |key, value| + if not key.empty? + if value.respond_to? "to_s" + @rwd.gsub!(/%%#{key}%%/, value.to_s) + @rwd.gsub!(/%#{key}%/, value.to_s.to_html) + + @helprwd.gsub!(/%%#{key}%%/, value.to_s) + @helprwd.gsub!(/%#{key}%/, value.to_s.to_html) + + vars2[key] = value.to_s.to_html + end + end + end + + windowobject = RWDTree.new(@rwd).children.dup.delete_if{|obj| obj.subtype != "window"}[0] + helpobject = RWDTree.new(@helprwd).children.dup.delete_if{|obj| obj.subtype != "helpwindow"}[0] + + tabsobj = windowobject.children.dup.delete_if{|obj| obj.subtype != "tabs"}[0] + + if not tabsobj.nil? + tabs = tabsobj.children.dup.delete_if{|obj| (not obj.kind_of?(OpenTag)) or (obj.subtype != "tab")} + + if tab.empty? + tab = tabs[0].args["caption"] + end + + tabsobj.children.delete_if{|obj| (obj.kind_of?(OpenTag)) and (obj.subtype == "tab") and obj.args["caption"] != tab} + end + + if help + helpobject.parsetree("prechildren", "postchildren", html, [""], [""], vars2, switches, false, firstaction, tabs, tab) + else + windowobject.parsetree("prechildren", "postchildren", html, [""], [""], vars2, switches, (not @helprwd.empty?), firstaction, tabs, tab) + end + + html.gsub!(/%%*[[:alnum:]_\-]+%%*/, "") if not Debug + html.gsub!(/%%/, "%") + html.gsub!(/\n\n*/, "\n") + + if firstaction.empty? + focus = "" + else + focus = "document.bodyform.elements[0].focus();" + end + + html.gsub!(/\$RWD_FIRSTACTION\$/ , firstaction) + html.gsub!(/\$RWD_FOCUS\$/ , focus) + + html + end +end + +class RWDMessage < RWDWindow + def initialize(msg) + super("<window title=´RWD Message´ nobackbuttons><vertical><p><b>Message:</b> #{msg}</p><back/></vertical></window>") + end +end + +class RWDError < RWDWindow + def initialize(msg) + super("<window title=´RWD Error´ nobackbuttons><vertical><p><b>Error:</b> #{msg}</p><back/></vertical></window>") + end +end + +class RWDDone < RWDWindow + def initialize(exitbrowser) + super("<window title=´RWD Message´ nobackbuttons noclosebutton><p>Done.</p><horizontal><close/>#{exitbrowser ? "" : "<button caption=´Login´/>"}</horizontal>#{exitbrowser ? "<closewindow/>" : ""}</window>") + end +end + +class RWDialog + def initialize(xml) + @rwd_xml = xml + @rwd_exitbrowser = false + @rwd_history = [] + @rwd_clone_vars = ["@rwd_history"] + @rwd_ignore_vars = ["@rwd_server"] + end + + def self.file(rwdfile, *args) + new(File.new(rwdfile).readlines, *args) + end + + def serve(port=1234, auth=nil, realm=self.class.to_s) + raise "RWD is not initialized." if @rwd_xml.nil? + + @rwd_server = RWDServer.new(self, port, auth, realm) + end + + def render(res, path, post, sessionid) + + # Initialize some vars. + + vars = Hash.new if vars.nil? + @rwd_switches = Hash.new if @rwd_switches.nil? + + done = false + help = false + back = false + tab = "" + @rwd_msg = nil + + # Switches are used for checkboxes. + + @rwd_switches.each do |key, value| + vars[key] = "off" + end + + @rwd_switches = Hash.new + + # Copy the vars from the window to vars. vars wil later on be copied to instance variables. + + post.sort.each do |key, value| + puts "Post: #{key} -> #{value.from_html.inspect}" if Debug + + vars[key] = value.from_html + end + + # Stack handling for rwd_action and rwd_window. + + @rwd_action = vars["rwd_action"] + @rwd_action, @rwd_args = @rwd_action.split(/\//, 2) unless @rwd_action.nil? + + if @rwd_action =~ /^rwd_tab_/ + tab = @rwd_action.sub(/^rwd_tab_/, "") + else + case @rwd_action + when "rwd_back" + @rwd_history.pop + @rwd_action = (@rwd_history[-1] or [nil, nil])[0] + @rwd_window = (@rwd_history[-1] or [nil, nil])[1] + back = true + when "rwd_help" + help = true + when "rwd_main" + @rwd_window = "main" + @rwd_action = "main" + @rwd_history = [] + when "rwd_quit" + done = true + end + + # History stuff + + @rwd_history = @rwd_history[-100..-1] if @rwd_history.length >= 100 + @rwd_action = "main" if @rwd_action.nil? + @rwd_action = "main" if @rwd_action.empty? + @rwd_args = [] if @rwd_args.nil? + @rwd_window = "main" if @rwd_window.nil? + + vars["rwd_action"] = @rwd_action + vars["rwd_window"] = @rwd_window + + # Copy vars from window to instance. + + vars.each do |k, v| + instance_eval "@#{k} = vars[´#{k}´]" if ((not k.empty?) and k.scan(/^rwd_/).empty? and not @rwd_ignore_vars.include?("@#{k}")) + end + + # Callback. + + if not back + begin + puts "Method: #{@rwd_action}(#{@rwdargs.join(", ")})" if Debug + method(@rwd_action).call(*@rwd_args) + rescue NameError + end + + # History stuff + + @rwd_history = [["main", "main"]] if @rwd_action == "main" + @rwd_history = [["main", "main"]] if @rwd_history.empty? + @rwd_history.push [@rwd_action, @rwd_window] if (@rwd_history[-1] != [@rwd_action, @rwd_window] or not @rwd_msg.nil?) + end + end + + # Copy vars from instance to window. + + instance_variables.each do |k| + k.sub!(/^@/, "") + instance_eval "vars[´#{k}´] = @#{k}.to_s" if (k.scan(/^rwd_/).empty? and not @rwd_ignore_vars.include?("@#{k}")) + end + + # just ignore. + + vars.sort.each do |key, value| + puts "Pre: #{key} -> #{value.inspect}" if Debug + end + + # Answer to browser. + + if done + res << RWDDone.new(@rwd_exitbrowser).render + else + if not @rwd_msg.nil? + res << RWDMessage.new(@rwd_msg).render if @rwd_msgtype == "message" + res << RWDError.new(@rwd_msg).render if @rwd_msgtype == "error" + else + puts "Window: #{@rwd_window}" if Debug + res << RWDWindow.new(@rwd_xml, @rwd_window).render(vars, @rwd_switches, help, tab) + end + end + + return done + end + + def samewindow? + @rwd_history[-1][1] == @rwd_window + end + + def message(msg) + @rwd_msg = msg + @rwd_msgtype = "message" + end + + def error(msg) + @rwd_msg = msg + @rwd_msgtype = "error" + end + + def clone + @rwd_history = [] + + @rwd_clone_vars.each do |var| + instance_eval "#{var} = #{var}.clone" + end + + super + end + + def exitbrowser + @rwd_exitbrowser = true + end +end + +class RWDLogin < RWDialog + def initialize(realm) + super("<window name=´main´ title=´RWD Login for #{realm}´ nobackbuttons noclosebutton><table><row><p align=´right´>Username:</p><text name=´rwd_a´/></row><row><p align=´right´>Password:</p><password name=´rwd_b´/></row></table><button caption=´Login´/></window>") + end +end + +class RWDTimeOut < RWDialog + def initialize + super("<window name=´main´ title=´RWD Error´ nobackbuttons noclosebutton><p><b>Error:</b> Session has expired.</p><button caption=´New session´/></window>") + end +end + +class SessionCleanup + def initialize(sessions, interval, timeout) + every(interval) do + sessions.delete_if do |id, session| + time = Time.now.to_i - session.lastaccess.to_i + + puts "Session %s deleted" % id if time > timeout + + time > timeout + end + end + end +end + +class Sessions + def initialize(rack, cleanup) + @rack = rack.to_s + @cleanup = SessionCleanup.new(self, 3600, 24*3600) if cleanup + @sessions = {} + #@store = PStore.new("#{temp}/store.#{@rack}.#{user}") + + #@store.transaction do + #@store[@rack] = {} if not @store.root?(@rack) + #@sessions = @store[@rack] + #end + + #at_exit do + #@store.transaction do + #@store[@rack] = @sessions + #end + #end + end + + def [](sessionid) + @sessions[sessionid] + end + + def []=(sessionid, value) + @sessions[sessionid] = value + end + + def delete(sessionid) + @sessions.delete(sessionid) + end + + def delete_if(&block) + @sessions.delete_if{|k, v| block.call(k, v)} + end +end + +class Session < Hash + attr_reader :sessionid + attr_reader :lastaccess + attr_reader :authenticated + attr_writer :authenticated + + def initialize(sessionid=nil) + @sessionid = sessionid + @lastaccess = Time.now + @authenticated = false + end + + def touch + @lastaccess = Time.now + end +end + +class RWDSession < Session + def render(res, path, post) + done = self["object"].render(res, path, post, @sessionid) + + if done + res.gsub!(/\$RWD_SESSION\$/, "") + else + res.gsub!(/\$RWD_SESSION\$/, "#{@sessionid}") + end + + done + end +end + +class RWDServer + def initialize(obj, port, auth, realm) + @object = obj + @localbrowsing = false + @browserstarted = false + @sessions = Sessions.new(obj.class, (not auth.nil?)) + + if auth.nil? + @localbrowsing = true + + if ENV.include?("RWDBROWSER") + @browserstarted = true + @object.exitbrowser + + # Start browser. + + @browserthread = Thread.new do + puts "Starting the browser..." + + #if ENV["RWDBROWSER"].downcase =~ /iexplore/ + #@ie = IE.new("http://localhost:#{port}/") + #else + if windows? + system("#{ENV["RWDBROWSER"]} \"http://localhost:#{port}/\"") + elsif cygwin? + system("#{ENV["RWDBROWSER"].gsub(/\\/, "/").gsub(/ /, "\ ")} \"http://localhost:#{port}/\"") + else + system("#{ENV["RWDBROWSER"]} \"http://localhost:#{port}/\"") + end + #end + + puts "The browser has terminated." + end + end + end + + # Start server. + + catch :exit do + HTTPServer.serve(port, (not auth.nil?)) do |req, resp| + vars = req.vars.dup + + if auth.kind_of? String + file = "#{home}/#{auth}" + auths = {} + auths = Hash.file(file) if FileTest.file?(file) + else + auths = auth + end + + oldsessionid = vars["rwd_session"] + + # Retrieve session. + + session = @sessions[oldsessionid] + + # Eventually create new session. + + if session.nil? + if auth.nil? + session = RWDSession.new(MD5.new(req.peeraddr[3].to_s + @object.inspect.to_s).to_s) + session["object"] = @object + else + session = RWDSession.new(MD5.new(Time.new.to_s + req.peeraddr[3].to_s + @object.inspect.to_s).to_s) + session["object"] = @object.clone + end + + if oldsessionid.nil? or oldsessionid.empty? + if not auth.nil? and not session.authenticated + + # Check authentication + + us = vars["rwd_a"] + pa = vars["rwd_b"] + + if us.nil? or pa.nil? or auths[us] != pa + session = RWDSession.new + session["object"] = RWDLogin.new(realm) + else + session.authenticated = true + @sessions[session.sessionid] = session + end + else + @sessions[session.sessionid] = session + end + else + session = RWDSession.new + session["object"] = RWDTimeOut.new + end + + vars = {} + end + + # Avoid timeout. + + session.touch + + if req.request.path == "/" + + # Serve methods/callbacks. + + # Build new page. + + res = "" + + done = session.render(res, req.request.path, vars) + + begin + resp["Content-Type"] = "text/html" + + resp << res + rescue + puts "Sending response to browser failed." + + @sessions.delete(session.sessionid) + end + + # Eventually delete this session. + + if done + @sessions.delete(session.sessionid) + + if @localbrowsing + resp.flush + + if @browserstarted and @browserthread.alive? + puts "Waiting for the browser to terminate..." + + @browserthread.join + end + + throw :exit + end + end + + else + + # Serve files. + + if req.request.path == "/pixel.gif" + resp << RWD_Pixel + else + if (FileTest.file?(req.request.path.sub(/^\/*/, ""))) + resp << File.new(req.request.path.sub(/^\/*/, ""), "rb").read rescue nil + else + resp.response = "HTTP/1.0 404 NOT FOUND" + end + end + + end + end + end + end +end + +RWD_HTML = " +<!-- Generated by RubyWebDialog. --> +<!-- For more information, please contact Erik Veenstra <rwd@erikveen.dds.nl>. --> +<html> + <head> + <title>%TITLE%</title> + + <meta http-equiv=´Content-Type´ content=´text/html; charset=ISO-8859-15´> + <meta http-equiv=´Content-Style-Type´ content=´text/css´> + + <link rel=´shortcut icon´ href=´%LOGO%´> + + <style type=´text/css´> + <!-- + a { text-decoration : none } + div.box { border : thin solid #AAAAAA } + div.box2 { border-top : thin solid #AAAAAA } + //--> + </style> + + <script type=´text/javascript´> + <!-- + function BodyGo() { + $RWD_FOCUS$ + } + //--> + </script> + </head> + + <body onload=´BodyGo()´ link=´#000000´ vlink=´#000000´ alink=´#000000´> + <table align=´center´ border=´0´ cellspacing=´0´ cellpadding=´0´ width=´100%´ height=´100%´> + <tr align=´center´ valign=´middle´> + <td align=´center´> + + <table align=´center´ border=´0´ cellspacing=´0´ cellpadding=´0´> + + <tr align=´center´> + <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td> + <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td> + <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td> + <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td> + <td align=´center´ bgcolor=´black´><img src=´pixel.gif´ height=´1´ width=´1´></td> + <td align=´center´ bgcolor=´black´><img src=´pixel.gif´ height=´1´ width=´1´></td> + <td align=´center´ bgcolor=´black´><img src=´pixel.gif´ height=´1´ width=´1´></td> + <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td> + <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td> + <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td> + <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td> + </tr> + + <tr align=´center´> + <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td> + <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td> + <td align=´center´ bgcolor=´black´><img src=´pixel.gif´ height=´1´ width=´1´></td> + <td align=´center´ bgcolor=´black´><img src=´pixel.gif´ height=´1´ width=´1´></td> + <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td> + <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td> + <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td> + <td align=´center´ bgcolor=´black´><img src=´pixel.gif´ height=´1´ width=´1´></td> + <td align=´center´ bgcolor=´black´><img src=´pixel.gif´ height=´1´ width=´1´></td> + <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td> + <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td> + </tr> + + <tr align=´center´> + <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td> + <td align=´center´ bgcolor=´black´><img src=´pixel.gif´ height=´1´ width=´1´></td> + <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td> + <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td> + <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td> + <td align=´center´ bgcolor=´#EEEEEE´><img src=´pixel.gif´ height=´1´ width=´1´></td> + <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td> + <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td> + <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td> + <td align=´center´ bgcolor=´black´><img src=´pixel.gif´ height=´1´ width=´1´></td> + <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td> + </tr> + + <tr align=´center´> + <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td> + <td align=´center´ bgcolor=´black´><img src=´pixel.gif´ height=´1´ width=´1´></td> + <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td> + <td align=´center´ bgcolor=´#EEEEEE´><img src=´pixel.gif´ height=´1´ width=´1´></td> + <td align=´center´ bgcolor=´#EEEEEE´><img src=´pixel.gif´ height=´1´ width=´1´></td> + <td align=´center´ bgcolor=´#EEEEEE´><img src=´pixel.gif´ height=´1´ width=´1´></td> + <td align=´center´ bgcolor=´#EEEEEE´><img src=´pixel.gif´ height=´1´ width=´1´></td> + <td align=´center´ bgcolor=´#EEEEEE´><img src=´pixel.gif´ height=´1´ width=´1´></td> + <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td> + <td align=´center´ bgcolor=´black´><img src=´pixel.gif´ height=´1´ width=´1´></td> + <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td> + </tr> + + <tr align=´center´> + <td align=´center´ bgcolor=´black´><img src=´pixel.gif´ height=´1´ width=´1´></td> + <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td> + <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td> + <td align=´center´ bgcolor=´#EEEEEE´><img src=´pixel.gif´ height=´1´ width=´1´></td> + <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td> + <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td> + <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td> + <td align=´center´ bgcolor=´#EEEEEE´><img src=´pixel.gif´ height=´1´ width=´1´></td> + <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td> + <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td> + <td align=´center´ bgcolor=´black´><img src=´pixel.gif´ height=´1´ width=´1´></td> + </tr> + + <tr align=´center´> + <td align=´center´ bgcolor=´black´><img src=´pixel.gif´ height=´1´ width=´1´></td> + <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td> + <td align=´center´ bgcolor=´#EEEEEE´><img src=´pixel.gif´ height=´1´ width=´1´></td> + <td align=´center´ bgcolor=´#EEEEEE´><img src=´pixel.gif´ height=´1´ width=´1´></td> + <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td> + + <td align=´center´> + + <table align=´center´ border=´0´ cellspacing=´0´ cellpadding=´0´> + <tr align=´center´> + <td align=´center´ bgcolor=´#444488´> + + <table align=´left´ border=´0´ cellspacing=´1´ cellpadding=´0´> + <tr align=´center´> + <td align=´border´><img src=´%LOGO%´ width=´14´ height=´14´></td> + <td align=´center´><b><small><font color=´#FFFFFF´> %TITLE% </font></small></b></td> + </tr> + </table> + + <table align=´right´ border=´0´ cellspacing=´1´ cellpadding=´0´> + <tr align=´center´> + <!-- %HELPBUTTON% --><td align=´center´ bgcolor=´#EEEEEE´><b><small><a href=´javascript:document.bodyform.rwd_action.value=\"rwd_help\";document.bodyform.submit();´> ? </a></small></b></td> + <!-- %BACKBUTTONS% --><td align=´center´ bgcolor=´#EEEEEE´><b><small><a href=´javascript:document.bodyform.rwd_action.value=\"rwd_main\";document.bodyform.submit();´> << </a></small></b></td> + <!-- %BACKBUTTONS% --><td align=´center´ bgcolor=´#EEEEEE´><b><small><a href=´javascript:document.bodyform.rwd_action.value=\"rwd_back\";document.bodyform.submit();´> < </a></small></b></td> + <!-- %CLOSEBUTTON% --><td align=´center´ bgcolor=´#EEEEEE´><b><small><a href=´javascript:document.bodyform.rwd_action.value=\"rwd_quit\";document.bodyform.submit();´> X </a></small></b></td> + </tr> + </table> + + </td> + </tr> + + <tr align=´center´> + <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td> + </tr> + + <tr align=´center´> + <td align=´center´ bgcolor=´#CCCCCC´> + <form name=´bodyform´ action=´/´ method=´post´> + + <table align=´center´ border=´0´ cellspacing=´3´ cellpadding=´0´> + + %BODY% + + </table> + + <input name=´rwd_action´ value=´$RWD_FIRSTACTION$´ type=´hidden´> + <input name=´rwd_session´ value=´$RWD_SESSION$´ type=´hidden´> + </form> + </td> + </tr> + </table> + + </td> + + <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td> + <td align=´center´ bgcolor=´#EEEEEE´><img src=´pixel.gif´ height=´1´ width=´1´></td> + <td align=´center´ bgcolor=´#EEEEEE´><img src=´pixel.gif´ height=´1´ width=´1´></td> + <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td> + <td align=´center´ bgcolor=´black´><img src=´pixel.gif´ height=´1´ width=´1´></td> + </tr> + + <tr align=´center´> + <td align=´center´ bgcolor=´black´><img src=´pixel.gif´ height=´1´ width=´1´></td> + <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td> + <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td> + <td align=´center´ bgcolor=´#EEEEEE´><img src=´pixel.gif´ height=´1´ width=´1´></td> + <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td> + <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td> + <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td> + <td align=´center´ bgcolor=´#EEEEEE´><img src=´pixel.gif´ height=´1´ width=´1´></td> + <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td> + <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td> + <td align=´center´ bgcolor=´black´><img src=´pixel.gif´ height=´1´ width=´1´></td> + </tr> + + <tr align=´center´> + <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td> + <td align=´center´ bgcolor=´black´><img src=´pixel.gif´ height=´1´ width=´1´></td> + <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td> + <td align=´center´ bgcolor=´#EEEEEE´><img src=´pixel.gif´ height=´1´ width=´1´></td> + <td align=´center´ bgcolor=´#EEEEEE´><img src=´pixel.gif´ height=´1´ width=´1´></td> + <td align=´center´ bgcolor=´#EEEEEE´><img src=´pixel.gif´ height=´1´ width=´1´></td> + <td align=´center´ bgcolor=´#EEEEEE´><img src=´pixel.gif´ height=´1´ width=´1´></td> + <td align=´center´ bgcolor=´#EEEEEE´><img src=´pixel.gif´ height=´1´ width=´1´></td> + <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td> + <td align=´center´ bgcolor=´black´><img src=´pixel.gif´ height=´1´ width=´1´></td> + <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td> + </tr> + + <tr align=´center´> + <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td> + <td align=´center´ bgcolor=´black´><img src=´pixel.gif´ height=´1´ width=´1´></td> + <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td> + <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td> + <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td> + <td align=´center´ bgcolor=´#EEEEEE´><img src=´pixel.gif´ height=´1´ width=´1´></td> + <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td> + <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td> + <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td> + <td align=´center´ bgcolor=´black´><img src=´pixel.gif´ height=´1´ width=´1´></td> + <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td> + </tr> + + <tr align=´center´> + <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td> + <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td> + <td align=´center´ bgcolor=´black´><img src=´pixel.gif´ height=´1´ width=´1´></td> + <td align=´center´ bgcolor=´black´><img src=´pixel.gif´ height=´1´ width=´1´></td> + <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td> + <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td> + <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td> + <td align=´center´ bgcolor=´black´><img src=´pixel.gif´ height=´1´ width=´1´></td> + <td align=´center´ bgcolor=´black´><img src=´pixel.gif´ height=´1´ width=´1´></td> + <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td> + <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td> + </tr> + + <tr align=´center´> + <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td> + <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td> + <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td> + <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td> + <td align=´center´ bgcolor=´black´><img src=´pixel.gif´ height=´1´ width=´1´></td> + <td align=´center´ bgcolor=´black´><img src=´pixel.gif´ height=´1´ width=´1´></td> + <td align=´center´ bgcolor=´black´><img src=´pixel.gif´ height=´1´ width=´1´></td> + <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td> + <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td> + <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td> + <td align=´center´ bgcolor=´white´><img src=´pixel.gif´ height=´1´ width=´1´></td> + </tr> + + </table> + + </td> + </tr> + </table> + </body> +</html> +" + +RWD_Pixel = " +R0lGODlhAQABAOcAAAAAAAEBAQICAgMDAwQEBAUFBQYGBgcHBwgICAkJCQoK +CgsLCwwMDA0NDQ4ODg8PDxAQEBERERISEhMTExQUFBUVFRYWFhcXFxgYGBkZ +GRoaGhsbGxwcHB0dHR4eHh8fHyAgICEhISIiIiMjIyQkJCUlJSYmJicnJygo +KCkpKSoqKisrKywsLC0tLS4uLi8vLzAwMDExMTIyMjMzMzQ0NDU1NTY2Njc3 +Nzg4ODk5OTo6Ojs7Ozw8PD09PT4+Pj8/P0BAQEFBQUJCQkNDQ0REREVFRUZG +RkdHR0hISElJSUpKSktLS0xMTE1NTU5OTk9PT1BQUFFRUVJSUlNTU1RUVFVV +VVZWVldXV1hYWFlZWVpaWltbW1xcXF1dXV5eXl9fX2BgYGFhYWJiYmNjY2Rk +ZGVlZWZmZmdnZ2hoaGlpaWpqamtra2xsbG1tbW5ubm9vb3BwcHFxcXJycnNz +c3R0dHV1dXZ2dnd3d3h4eHl5eXp6ent7e3x8fH19fX5+fn9/f4CAgIGBgYKC +goODg4SEhIWFhYaGhoeHh4iIiImJiYqKiouLi4yMjI2NjY6Ojo+Pj5CQkJGR +kZKSkpOTk5SUlJWVlZaWlpeXl5iYmJmZmZqampubm5ycnJ2dnZ6enp+fn6Cg +oKGhoaKioqOjo6SkpKWlpaampqenp6ioqKmpqaqqqqurq6ysrK2tra6urq+v +r7CwsLGxsbKysrOzs7S0tLW1tba2tre3t7i4uLm5ubq6uru7u7y8vL29vb6+ +vr+/v8DAwMHBwcLCwsPDw8TExMXFxcbGxsfHx8jIyMnJycrKysvLy8zMzM3N +zc7Ozs/Pz9DQ0NHR0dLS0tPT09TU1NXV1dbW1tfX19jY2NnZ2dra2tvb29zc +3N3d3d7e3t/f3+Dg4OHh4eLi4uPj4+Tk5OXl5ebm5ufn5+jo6Onp6erq6uvr +6+zs7O3t7e7u7u/v7/Dw8PHx8fLy8vPz8/T09PX19fb29vf39/j4+Pn5+fr6 ++vv7+/z8/P39/f7+/v///yH+FUNyZWF0ZWQgd2l0aCBUaGUgR0lNUAAh+QQB +CgD/ACwAAAAAAQABAAAIBAD/BQQAOw== +".unpack("m").shift + +RWD_HTML1, RWD_HTML2 = RWD_HTML.split(/^\s*%BODY%\s*\r*$/) diff -ur rubywebdialogs-none.tar.gz/rubywebdialogs/lib/sgml.lib.rb rubywebdialogs-0.0.1.tar.gz/rubywebdialogs/lib/sgml.lib.rb --- rubywebdialogs-none.tar.gz/rubywebdialogs/lib/sgml.lib.rb 2004-06-23 00:36:57.000000000 +0200 +++ rubywebdialogs-0.0.1.tar.gz/rubywebdialogs/lib/sgml.lib.rb 2004-04-18 14:20:31.000000000 +0200 @@ -0,0 +1,234 @@ +require "ev/tree" + +class SGMLObject < TreeObject + def to_s + res = "" + + parsetree("prechildren_to_s", "postchildren_to_s", res) + + res + end + + def to_h + res = "" + + parsetree("prechildren_to_sgml", "postchildren_to_sgml", res) + + res + end +end + +class Text < SGMLObject + def initialize(text) + super() + @text = text + end + + def prechildren_to_s(res) + res << "#{@text}" + end + + def prechildren_to_sgml(res) + res << "#{@text}" + end +end + +class Comment < SGMLObject + def initialize(text) + super() + @text = text + end + + def prechildren_to_sgml(res) + res << "#{@text}" + end +end + +class Special < SGMLObject + def initialize(text) + super() + @text = text + end + + def prechildren_to_sgml(res) + res << "#{@text}" + end +end + +class Instruction < SGMLObject + def initialize(text) + super() + @text = text + end + + def prechildren_to_sgml(res) + res << "#{@text}" + end +end + +class Tag < SGMLObject + attr_reader :args + attr_writer :args + + def initialize(subtype, args={}) + super(subtype) + @args = args + end +end + +class OpenTag < Tag + def initialize(*args) + super + @upordown = Down + end + + def prechildren_to_sgml(res) + a = [@subtype] + + @args.each do |k, v| + if not v.include?("´") + a << "#{k}=´#{v}´" + else + if not v.include?(´"´) + a << "#{k}=\"#{v}\"" + else + a << "#{k}=´#{v.gsub(/\´/, ´"´)}´" + end + end + end + + res << "<#{a.join(" ")}>" + end + + def postchildren_to_sgml(res) + res << "</#{@subtype}>" if @closed + end +end + +class CloseTag < Tag + def initialize(*args) + super + @upordown = Dummy + end +end + +class SGML < Tree + def initialize(*args) + @tagcache = {} + + super + end + + def buildobjects(string) + @objects = [] + + string.splitblocks(["<!--", "<!", "<?", "<"], ["-->", ">", "?>", ">"]).each do |type, s| + case type + when 0 then @objects << Text.new(s) + when 1 then @objects << Comment.new(s) + when 2 then @objects << Special.new(s) + when 3 then @objects << Instruction.new(s) + when 4 + + tag, args, open, close = verwerktag1(s) + + @objects << OpenTag.new(tag.dup, args.dup) if open + @objects << CloseTag.new(tag.dup, args.dup) if close + end + end + end + + def verwerktag1(string) + res = nil + + if @tagcache.include? string + res = @tagcache[string] + + else + res = verwerktag2(string) + + @tagcache[string] = res + end + + return res + end + + def verwerktag2(string) + a = [] + + string.splitblocks(["´", ´"´], ["´", ´"´]).collect do |type, s| + case type + when 0 + if self.class.to_s == "HTML" + s.splitwords(["<", ">"]).each do |w| + d = w.split("=", 2) + + if d.length == 1 + a << d[0] + else + a << d[0] if not d[0].nil? and not d[0].empty? + a << "=" + a << d[1] if not d[1].nil? and not d[1].empty? + end + end + else + a.concat s.splitwords(["<", "/", "=", ">"]) + end + when 1, 2 then a << s + end + end + + a = a[1..-2] + open = false + close = false + + if not a.nil? + a = a[0].splitwords("/") + a[1..-1] + + if a[0] == "/" + close = true + a.shift + else + open = true + end + + if a[-1] == "/" + close = true + a.pop + end + + tag = a.shift.downcase + args = {} + + while not a.length.zero? + if a.length >= 3 and a[1] == "=" + key = a.shift.downcase + dummy = a.shift + value = a.shift.noquotes + args[key] = value + else + key = a.shift.downcase + args[key] = "" + end + end + end + + return [tag, args, open, close] + end + + def to_s + res = "" + + parsetree("prechildren_to_s", "postchildren_to_s", res) + + res + end + + def to_h + res = "" + + parsetree("prechildren_to_sgml", "postchildren_to_sgml", res) + + res + end +end diff -ur rubywebdialogs-none.tar.gz/rubywebdialogs/lib/tree.lib.rb rubywebdialogs-0.0.1.tar.gz/rubywebdialogs/lib/tree.lib.rb --- rubywebdialogs-none.tar.gz/rubywebdialogs/lib/tree.lib.rb 2004-06-23 00:36:57.000000000 +0200 +++ rubywebdialogs-0.0.1.tar.gz/rubywebdialogs/lib/tree.lib.rb 2004-04-18 14:20:31.000000000 +0200 @@ -0,0 +1,316 @@ +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_writer :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 FileTest.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=[]) + types = [types] if types.class == Class + subtypes = [subtypes] if subtypes.class == String + hidelevel = nil + + @objects.each do |obj| + hidelevel = obj.level if (@checkvisibility and hidelevel.nil? and (not obj.visible)) + hidelevel = nil if (@checkvisibility and (not hidelevel.nil?) and obj.visible and obj.level <= hidelevel) + + if hidelevel.nil? + ok = false + if types.empty? + if subtypes.empty? + ok = true + else + subtypes.each do |st| + ok = true if obj.subtype == st + end + end + else + if subtypes.empty? + types.each do |t| + ok = true if obj.kind_of?(t) + end + else + types.each do |t| + subtypes.each do |st| + ok = true if obj.kind_of?(t) if obj.subtype == st + end + end + end + end + + yield(obj.class.to_s, obj) if ok + end + end + end + + def path(pad) + p = self + + pad.split(/\//).each do |deel| + tag, voorkomen = deel.split(/:/) + + if (not tag.nil?) and (not p.nil?) + voorkomen = 1 if voorkomen.nil? + voorkomen = voorkomen.to_i + + teller = 0 + p2 = nil + p.children.each_index do |i| + if p.children[i].upordown == Down + if p.children[i].subtype.noquotes == tag.noquotes + teller += 1 + p2 = p.children[i] if teller == voorkomen + end + end + end + p = p2 + end + end + + p + end +end diff -ur rubywebdialogs-none.tar.gz/rubywebdialogs/lib/xml.lib.rb rubywebdialogs-0.0.1.tar.gz/rubywebdialogs/lib/xml.lib.rb --- rubywebdialogs-none.tar.gz/rubywebdialogs/lib/xml.lib.rb 2004-06-23 00:36:57.000000000 +0200 +++ rubywebdialogs-0.0.1.tar.gz/rubywebdialogs/lib/xml.lib.rb 2004-04-18 14:20:31.000000000 +0200 @@ -0,0 +1,4 @@ +require "ev/sgml" + +class XML < SGML +end