lib/knj/web.rb in knjrbfw-0.0.7 vs lib/knj/web.rb in knjrbfw-0.0.8

- old
+ new

@@ -173,20 +173,20 @@ if @data if @data[:user_agent] != @server["HTTP_USER_AGENT"] or @data[:ip] != @server["REMOTE_ADDR"] @data = nil else - @db.update(:sessions, {"last_url" => @server["REQUEST_URI"].to_s, "date_active" => Datestamp.dbstr}, {"id" => @data[:id]}) + @db.update(:sessions, {"last_url" => @server["REQUEST_URI"].to_s, "date_active" => Time.new}, {"id" => @data[:id]}) session_id = @args[:id] + "_" + @data[:id] end end end if !@data or !session_id @db.insert(:sessions, - :date_start => Knj::Datet.new.dbstr, - :date_active => Knj::Datet.new.dbstr, + :date_start => Time.new, + :date_active => Time.new, :user_agent => @server["HTTP_USER_AGENT"], :ip => @server["REMOTE_ADDR"], :last_url => @server["REQUEST_URI"].to_s ) @@ -209,28 +209,69 @@ end def self.parse_cookies(str) ret = {} - str.split("; ").each do |cookie_str| - splitted = cookie_str.split("=") - ret[Knj::Php.urldecode(splitted[0])] = Knj::Php.urldecode(splitted[1]) + str.split(/;\s*/).each do |cookie_str| + if !match = cookie_str.match(/^(.*?)=\"(.*)\"$/) + match = cookie_str.match(/^(.*?)=(.*)$/) + end + + ret[self.urldec(match[1])] = self.urldec(match[2]) end return ret end + def self.parse_set_cookies(str) + str = String.new(str.to_s) + return [] if str.length <= 0 + args = {} + cookie_start_regex = /^(.+?)=(.*?)(;\s*|$)/ + + match = str.match(cookie_start_regex) + raise "Could not match cookie: '#{str}'." if !match + str.gsub!(cookie_start_regex, "") + + args["name"] = self.urldec(match[1].to_s) + args["value"] = self.urldec(match[2].to_s) + + while match = str.match(/(.+?)=(.*?)(;\s*|$)/) + str = str.gsub(match[0], "") + args[match[1].to_s.downcase] = match[2].to_s + end + + return [args] + end + + def self.cookie_str(cookie_data) + raise "Not a hash: '#{cookie_data.class.name}', '#{cookie_data}'." unless cookie_data.is_a?(Hash) + cookiestr = "#{self.urlenc(cookie_data["name"])}=#{self.urlenc(cookie_data["value"])}" + + cookie_data.each do |key, val| + next if key == "name" or key == "value" + + if key.to_s.downcase == "expires" and val.is_a?(Time) + cookiestr += "; Expires=#{val.httpdate}" + else + cookiestr += "; #{key}=#{val}" + end + end + + return cookiestr + end + def self.parse_urlquery(querystr, args = {}) get = {} querystr.to_s.split("&").each do |value| pos = value.index("=") if pos != nil name = value[0..pos-1] name = name.to_sym if args[:syms] valuestr = value.slice(pos+1..-1) - Knj::Web.parse_name(get, Knj::Php.urldecode(name), valuestr, args) + Knj::Web.parse_name(get, self.urldec(name), valuestr, args) end end return get end @@ -240,11 +281,11 @@ if secname.length <= 0 secname_empty = true try = 0 loop do - if !seton.has_key?(try) + if !seton.key?(try) break else try += 1 end end @@ -262,28 +303,28 @@ def self.parse_name(seton, varname, value, args = {}) if value.respond_to?(:filename) and value.filename realvalue = value else realvalue = value.to_s + realvalue = self.urldec(realvalue) if args[:urldecode] + realvalue = realvalue.force_encoding("utf-8") if args[:force_utf8] if realvalue.respond_to?(:force_encoding) end - realvalue = Knj::Php.urldecode(realvalue) if args[:urldecode] and !value.respond_to?(:filename) - if varname and varname.index("[") != nil if match = varname.match(/\[(.*?)\]/) namepos = varname.index(match[0]) name = varname.slice(0..namepos - 1) name = name.to_sym if args[:syms] - seton[name] = {} if !seton.has_key?(name) + seton[name] = {} if !seton.key?(name) secname, secname_empty = Knj::Web.parse_secname(seton[name], match[1], args) valuefrom = namepos + secname.to_s.length + 2 restname = varname.slice(valuefrom..-1) if restname and restname.index("[") != nil - seton[name][secname] = {} if !seton[name].has_key?(secname) + seton[name][secname] = {} if !seton[name].key?(secname) Knj::Web.parse_name_second(seton[name][secname], restname, value, args) else seton[name][secname] = realvalue end else @@ -297,10 +338,11 @@ def self.parse_name_second(seton, varname, value, args = {}) if value.respond_to?(:filename) and value.filename realvalue = value else realvalue = value.to_s + realvalue = realvalue.force_encoding("utf-8") if args[:force_utf8] end match = varname.match(/^\[(.*?)\]/) if match namepos = varname.index(match[0]) @@ -309,11 +351,11 @@ valuefrom = namepos + match[1].length + 2 restname = varname.slice(valuefrom..-1) if restname and restname.index("[") != nil - seton[secname] = {} if !seton.has_key?(secname) + seton[secname] = {} if !seton.key?(secname) Knj::Web.parse_name_second(seton[secname], restname, value, args) else seton[secname] = realvalue end else @@ -395,14 +437,39 @@ end return html end + def self.style_html(css) + return "" if css.length <= 0 + + str = " style=\"" + + css.each do |key, val| + str += "#{key}: #{val};" + end + + str += "\"" + + return str + end + + def self.attr_html(attrs) + return "" if attrs.length <= 0 + + html = "" + attrs.each do |key, val| + html += " #{key}=\"#{val.to_s.html}\"" + end + + return html + end + def self.input(args) Knj::ArrayExt.hash_sym(args) - if args.has_key?(:value) + if args.key?(:value) if args[:value].is_a?(Array) and args[:value][0].is_a?(NilClass) value = nil elsif args[:value].is_a?(Array) if !args[:value][2] or args[:value][2] == :key value = args[:value][0][args[:value][1]] @@ -422,11 +489,11 @@ value = args[:value_default] elsif value.is_a?(NilClass) value = "" end - if value and args.has_key?(:value_func) and args[:value_func] + if value and args.key?(:value_func) and args[:value_func] cback = args[:value_func] if cback.is_a?(Method) value = cback.call(value) elsif cback.is_a?(Array) @@ -453,47 +520,55 @@ end else args[:type] = args[:type].to_sym end - if args.has_key?(:disabled) and args[:disabled] - disabled = "disabled " - else - disabled = "" - end + attr = { + "name" => args[:name], + "id" => args[:id], + "type" => args[:type], + "class" => "input_#{args[:type]}" + } + attr.merge!(args[:attr]) if args[:attr] + attr["disabled"] = "disabled" if args[:disabled] - raise "No name given to the Web::input()-method." if !args[:name] and args[:type] != :info and args[:type] != :textshow + raise "No name given to the Web::input()-method." if !args[:name] and args[:type] != :info and args[:type] != :textshow and args[:type] != :plain - checked = "" - checked += " value=\"#{args[:value_active]}\"" if args.has_key?(:value_active) - checked += " checked" if value.is_a?(String) and value == "1" or value.to_s == "1" - checked += " checked" if value.is_a?(TrueClass) + css = {} + css["text-align"] = args[:align] if args.key?(:align) + attr_keys = [:onchange] + attr_keys.each do |tag| + if args.key?(tag) + attr[tag] = args[tag] + end + end + html = "" if args[:type] == :checkbox + attr["value"] = args[:value_active] if args.key?(:value_active) + attr["checked"] = "checked" if value.is_a?(String) and value == "1" or value.to_s == "1" or value.to_s == "on" or value.to_s == "true" + attr["checked"] = "checked" if value.is_a?(TrueClass) + html += "<tr>" html += "<td colspan=\"2\" class=\"tdcheck\">" - html += "<input type=\"checkbox\" class=\"input_checkbox\" id=\"#{args[:id].html}\" name=\"#{args[:name].html}\"#{checked} />" + html += "<input#{self.attr_html(attr)} />" html += "<label for=\"#{args[:id].html}\">#{args[:title].html}</label>" html += "</td>" html += "</tr>" else html += "<tr>" html += "<td class=\"tdt\">" html += args[:title].to_s.html html += "</td>" - html += "<td class=\"tdc\">" + html += "<td#{self.style_html(css)} class=\"tdc\">" if args[:type] == :textarea - if args.has_key?(:height) - styleadd = " style=\"height: #{args[:height].html}px;\"" - else - styleadd = "" - end + css["height"] = "#{args[:height]}px" if args.key?(:height) - html += "<textarea#{styleadd} class=\"input_textarea\" name=\"#{args[:name].html}\" id=\"#{args[:id].html}\">#{value}</textarea>" + html += "<textarea#{self.style_html(css)} class=\"input_textarea\" name=\"#{args[:name].html}\" id=\"#{args[:id].html}\">#{value}</textarea>" html += "</td>" elsif args[:type] == :fckeditor args[:height] = 400 if !args[:height] require "/usr/share/fckeditor/fckeditor.rb" @@ -502,29 +577,28 @@ fck.Value = value html += fck.CreateHtml html += "</td>" elsif args[:type] == :select - html += "<select name=\"#{args[:name].html}\" id=\"#{args[:id].html}\" class=\"input_select\"" - html += " onchange=\"#{args[:onchange]}\"" if args[:onchange] - html += " multiple" if args[:multiple] - html += " size=\"#{args[:size].to_s}\"" if args[:size] - html += ">" + attr["multiple"] = "multiple" if args[:multiple] + attr["size"] = args["size"] if args[:size] + + html += "<select#{self.attr_html(attr)}>" html += Knj::Web.opts(args[:opts], value, args[:opts_args]) html += "</select>" html += "</td>" elsif args[:type] == :imageupload html += "<table class=\"designtable\"><tr><td style=\"width: 100%;\">" html += "<input type=\"file\" name=\"#{args[:name].html}\" class=\"input_file\" />" html += "</td><td style=\"padding-left: 5px;\">" - raise "No path given for imageupload-input." if !args.has_key?(:path) - raise "No value given in arguments for imageupload-input." if !args.has_key?(:value) + raise "No path given for imageupload-input." if !args.key?(:path) + raise "No value given in arguments for imageupload-input." if !args.key?(:value) path = args[:path].gsub("%value%", value.to_s).untaint if File.exists?(path) - html += "<img src=\"image.php?picture=#{Knj::Php.urlencode(path).html}&smartsize=100&edgesize=25&force=true&ts=#{Time.new.to_f}\" alt=\"Image\" />" + html += "<img src=\"image.rhtml?path=#{self.urlenc(path).html}&smartsize=100&rounded_corners=10&border_color=black&force=true&ts=#{Time.new.to_f}\" alt=\"Image\" />" if args[:dellink] dellink = args[:dellink].gsub("%value%", value.to_s) html += "<div style=\"text-align: center;\">(<a href=\"javascript: if (confirm('#{_("Do you want to delete the image?")}')){location.href='#{dellink}';}\">#{_("delete")}</a>)</div>" end @@ -534,43 +608,35 @@ html += "</td>" elsif args[:type] == :file html += "<input type=\"#{args[:type].to_s}\" class=\"input_#{args[:type].to_s}\" name=\"#{args[:name].html}\" /></td>" elsif args[:type] == :textshow or args[:type] == :info html += "#{value}</td>" + elsif args[:type] == :plain + html += "#{Knj::Web.html(value)}" elsif args[:type] == :editarea - css = { - "width" => "100%" - } - css["height"] = args[:height] if args.has_key?(:height) + css["width"] = "100%" + css["height"] = args[:height] if args.key?(:height) + html += "<textarea#{self.attr_html(attr)}#{self.style_html(css)} id=\"#{args[:id]}\" name=\"#{args[:name]}\">#{value}</textarea>" - styleadd = " style=\"" - css.each do |key, val| - styleadd += "#{key}: #{val};" - end - styleadd += "\"" - - styleadd += "width=\"100%\"" - styleadd += "height=\"#{args[:height]}\"" if args[:height] - html += "<textarea#{styleadd} id=\"#{args[:id]}\" name=\"#{args[:name]}\">#{value}</textarea>" - jshash = { "id" => args[:id], "start_highlight" => true } pos_keys = [:skip_init, :allow_toggle, :replace_tab_by_spaces, :toolbar, :syntax] pos_keys.each do |key| - jshash[key.to_s] = args[key] if args.has_key?(key) + jshash[key.to_s] = args[key] if args.key?(key) end html += "<script type=\"text/javascript\">" html += "function knj_web_init_#{args[:name]}(){" html += "editAreaLoader.init(#{Knj::Php.json_encode(jshash)});" html += "}" html += "</script>" else - html += "<input #{disabled}type=\"#{args[:type].to_s.html}\" class=\"input_#{args[:type].html}\" id=\"#{args[:id].html}\" name=\"#{args[:name].html}\" value=\"#{value.html}\" /></td>" + attr[:value] = value + html += "<input#{self.attr_html(attr)} /></td>" html += "</td>" end html += "</tr>" end @@ -605,10 +671,12 @@ if curvalue.is_a?(Array) and curvalue.index(key) != nil html += " selected=\"selected\"" elsif curvalue.to_s == key.to_s html += " selected=\"selected\"" + elsif curvalue and curvalue.respond_to?(:is_knj?) and curvalue.id.to_s == key.to_s + html += " selected=\"selected\"" end html += " value=\"#{key.html}\">#{value.html}</option>" end elsif opthash.is_a?(Array) @@ -725,10 +793,14 @@ version = "Googlebot" elsif agent.index("gidbot") != nil browser = "bot" title = "Bot" version = "GIDBot" + elsif match = agent.match(/android\s+([\d\.]+)/) + browser = "android" + title = "Android" + version = match[1] elsif match = agent.match(/safari\/(\d+)/) browser = "safari" title = "Safari" version = match[1] elsif agent.index("iPad") != nil @@ -781,10 +853,14 @@ version = match[1] elsif match = agent.match(/ezooms\/([\d\.]+)/) browser = "bot" title = "Ezooms" version = match[1] + elsif match = agent.match(/ahrefsbot\/([\d\.]+)/) + browser = "bot" + title = "AhrefsBot" + version = match[1] else browser = "unknown" title = "(unknown browser)" version = "(unknown version)" end @@ -879,45 +955,48 @@ end return html end + #Parses a string to be safe for use in <a href="">. def self.ahref_parse(str) return str.to_s.gsub("&", "&amp;") end + + #URL-encodes a string. + def self.urlenc(string) + #Thanks to CGI framework + string.to_s.gsub(/([^ a-zA-Z0-9_.-]+)/) do + '%' + $1.unpack('H2' * $1.bytesize).join('%').upcase + end.tr(' ', '+') + end + + #URL-decodes a string. + def self.urldec(string) + #Thanks to CGI framework + str = string.to_s.tr('+', ' ').gsub(/((?:%[0-9a-fA-F]{2})+)/) do + [$1.delete('%')].pack('H*') + end + end + + #Escapes HTML-characters in a string. + def self.html(string) + return string.to_s.gsub(/&/, "&amp;").gsub(/\"/, "&quot;").gsub(/>/, "&gt;").gsub(/</, "&lt;") + end end -def alert(string) - return Knj::Web.alert(string) -end - -def redirect(string) - return Knj::Web.redirect(string) -end - -def jsback(string) - return Knj::Web.back -end - class String def html - return self.to_s.gsub(/&/, "&amp;").gsub(/\"/, "&quot;").gsub(/>/, "&gt;").gsub(/</, "&lt;") + return Knj::Web.html(self) end def sql begin - return _httpsession.db.escape(self) - rescue NameError - #ignore - not in KnjAppServer HTTP-session. - end - - begin return _db.escape(self) rescue NameError #ignore - not i KnjAppServer HTTP-session. end - return $db.escape(self) if $db raise "Could not figure out where to find db object." end end class Symbol \ No newline at end of file