knjrbfw 0.0.7 → 0.0.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (65) hide show
  1. data/Gemfile +3 -1
  2. data/VERSION +1 -1
  3. data/knjrbfw.gemspec +14 -4
  4. data/lib/knj/amixer.rb +148 -0
  5. data/lib/knj/arrayext.rb +14 -5
  6. data/lib/knj/autoload.rb +63 -57
  7. data/lib/knj/autoload/backups/facets_dictionary.rb +2 -2
  8. data/lib/knj/autoload/erubis.rb +2 -0
  9. data/lib/knj/cmd_gen.rb +71 -0
  10. data/lib/knj/compiler.rb +2 -2
  11. data/lib/knj/datarow.rb +138 -38
  12. data/lib/knj/datestamp.rb +2 -2
  13. data/lib/knj/datet.rb +72 -17
  14. data/lib/knj/erb/include.rb +5 -5
  15. data/lib/knj/errors.rb +4 -1
  16. data/lib/knj/eruby.rb +25 -11
  17. data/lib/knj/event_filemod.rb +27 -26
  18. data/lib/knj/event_handler.rb +8 -8
  19. data/lib/knj/exchangerates.rb +1 -1
  20. data/lib/knj/facebook_connect.rb +37 -0
  21. data/lib/knj/gettext_threadded.rb +4 -3
  22. data/lib/knj/google_sitemap.rb +1 -1
  23. data/lib/knj/hash_methods.rb +1 -1
  24. data/lib/knj/http.rb +35 -19
  25. data/lib/knj/http2.rb +249 -0
  26. data/lib/knj/image.rb +128 -0
  27. data/lib/knj/jruby-gtk2/gtk2.rb +1 -1
  28. data/lib/knj/knj.rb +1 -1
  29. data/lib/knj/knj_controller.rb +0 -2
  30. data/lib/knj/knjdb/drivers/mysql/knjdb_mysql.rb +3 -3
  31. data/lib/knj/knjdb/drivers/mysql/knjdb_mysql_columns.rb +11 -11
  32. data/lib/knj/knjdb/drivers/mysql/knjdb_mysql_tables.rb +2 -2
  33. data/lib/knj/knjdb/drivers/sqlite3/knjdb_sqlite3.rb +71 -14
  34. data/lib/knj/knjdb/drivers/sqlite3/knjdb_sqlite3_columns.rb +17 -14
  35. data/lib/knj/knjdb/drivers/sqlite3/knjdb_sqlite3_tables.rb +5 -5
  36. data/lib/knj/knjdb/libknjdb.rb +33 -16
  37. data/lib/knj/knjdb/libknjdb_row.rb +8 -8
  38. data/lib/knj/maemo/fremantle-calendar/fremantle-calendar.rb +1 -1
  39. data/lib/knj/mount.rb +6 -6
  40. data/lib/knj/mutexcl.rb +2 -2
  41. data/lib/knj/objects.rb +286 -73
  42. data/lib/knj/opts.rb +11 -4
  43. data/lib/knj/os.rb +16 -3
  44. data/lib/knj/php.rb +73 -26
  45. data/lib/knj/php_parser/php_parser.rb +1 -77
  46. data/lib/knj/retry.rb +4 -4
  47. data/lib/knj/rhodes/rhodes.rb +106 -0
  48. data/lib/knj/sshrobot/sshrobot.rb +1 -1
  49. data/lib/knj/strings.rb +72 -0
  50. data/lib/knj/sysuser.rb +1 -1
  51. data/lib/knj/tests/test_http2.rb +18 -0
  52. data/lib/knj/thread.rb +1 -5
  53. data/lib/knj/thread2.rb +3 -3
  54. data/lib/knj/threadhandler.rb +2 -2
  55. data/lib/knj/threadpool.rb +4 -4
  56. data/lib/knj/translations.rb +2 -17
  57. data/lib/knj/unix_proc.rb +3 -3
  58. data/lib/knj/web.rb +156 -77
  59. data/lib/knj/webscripts/image.rhtml +22 -3
  60. data/lib/knj/x11vnc.rb +3 -3
  61. data/spec/amixer_spec.rb +27 -0
  62. data/spec/knjrbfw_spec.rb +70 -12
  63. data/testfiles/image.jpg +0 -0
  64. metadata +32 -14
  65. data/Gemfile.lock +0 -32
@@ -2,7 +2,7 @@ class Knj::SSHRobot
2
2
  def initialize(args)
3
3
  @forwards = []
4
4
  @args = Knj::ArrayExt.hash_sym(args)
5
- @args[:port] = 22 if !@args.has_key?(:port)
5
+ @args[:port] = 22 if !@args.key?(:port)
6
6
  end
7
7
 
8
8
  def session
@@ -62,4 +62,76 @@ module Knj::Strings
62
62
  str = str.slice(0..(maxlength - 1)).strip + "..." if str.length > maxlength
63
63
  return str
64
64
  end
65
+
66
+ def self.html_links(str, args = {})
67
+ str.to_s.html.scan(/(http:\/\/([A-z]+)\S*\.([A-z]{2,4})(\S+))/) do |match|
68
+ if block_given?
69
+ str = yield(:str => str, :args => args, :match => match)
70
+ else
71
+ if args["target"]
72
+ html = "<a target=\"#{args["target"]}\""
73
+ else
74
+ html = "<a"
75
+ end
76
+
77
+ html += " href=\"#{match[0]}\">#{match[0]}</a>"
78
+ str = str.gsub(match[0], html)
79
+ end
80
+ end
81
+
82
+ return str
83
+ end
84
+
85
+ def self.strip(origstr, args)
86
+ newstr = "#{origstr}<br>"
87
+
88
+ if !args.key?(:right) or args[:right]
89
+ loop do
90
+ changed = false
91
+ args[:strips].each do |str|
92
+ len = str.length
93
+ endstr = newstr.slice(-len, len)
94
+ next if !endstr
95
+
96
+ if endstr == str
97
+ changed = true
98
+ newstr = newstr.slice(0..newstr.length-len-1)
99
+ end
100
+ end
101
+
102
+ break if !changed
103
+ end
104
+ end
105
+
106
+ if !args.key?(:left) or args[:left]
107
+ loop do
108
+ changed = false
109
+ args[:strips].each do |str|
110
+ len = str.length
111
+ endstr = newstr.slice(0, len)
112
+ next if !endstr
113
+
114
+ if endstr == str
115
+ changed = true
116
+ newstr = newstr.slice(len..-1)
117
+ end
118
+ end
119
+
120
+ break if !changed
121
+ end
122
+ end
123
+
124
+ return newstr
125
+ end
126
+
127
+ #Returns the module from the given string - even if formed as SomeClass::SomeNewClass.
128
+ def self.const_get_full(str)
129
+ module_use = Kernel
130
+
131
+ str.scan(/(.+?)(::|$)/) do |match|
132
+ module_use = module_use.const_get(match[0])
133
+ end
134
+
135
+ return module_use
136
+ end
65
137
  end
@@ -21,7 +21,7 @@ class Knj::Sysuser
21
21
  end
22
22
 
23
23
  def [](key)
24
- raise "No such key: " + key if !@data.has_key?(key)
24
+ raise "No such key: " + key if !@data.key?(key)
25
25
  return @data[key]
26
26
  end
27
27
  end
@@ -0,0 +1,18 @@
1
+ #!/usr/bin/env ruby1.9.1
2
+
3
+ Dir.chdir(File.dirname(__FILE__))
4
+ require "../../knjrbfw.rb"
5
+
6
+ require "../autoload"
7
+
8
+ http = Knj::Http2.new(:host => "www.partyworm.dk", :port => 80, :ssl => false)
9
+ resp = http.get("/?show=frontpage")
10
+ resp = http.get("/?show=login")
11
+
12
+ #print "Wee!\n"
13
+ #exit
14
+
15
+ http = Knj::Http2.new(:host => "mexico.balance4u.com", :port => 443, :ssl => true)
16
+ resp = http.get("/")
17
+
18
+ Knj::Php.print_r(http.cookies)
@@ -13,11 +13,7 @@ class Knj::Thread < Thread
13
13
  rescue SystemExit
14
14
  exit
15
15
  rescue Exception => e
16
- print "Error: "
17
- puts e.inspect
18
- print "\n"
19
- puts e.backtrace
20
- print "\n\n"
16
+ print Knj::Errors.error_str(e)
21
17
  end
22
18
  end
23
19
  end
@@ -6,12 +6,12 @@ class Knj::Thread2
6
6
  end
7
7
 
8
8
  def connect(signal, &block)
9
- @callbacks[signal] = [] if !@callbacks.has_key?(signal)
9
+ @callbacks[signal] = [] if !@callbacks.key?(signal)
10
10
  @callbacks[signal] << block
11
11
  end
12
12
 
13
13
  def call(signal, *args)
14
- return false if !@callbacks.has_key?(signal)
14
+ return false if !@callbacks.key?(signal)
15
15
  @callbacks[signal].each do |block|
16
16
  block.call(*args)
17
17
  end
@@ -32,7 +32,7 @@ class Knj::Thread2
32
32
  rescue Exception => e
33
33
  call(:on_error, e)
34
34
 
35
- if !@args.has_key?(:print_error) or @args[:print_error]
35
+ if !@args.key?(:print_error) or @args[:print_error]
36
36
  print "Error: "
37
37
  puts e.inspect
38
38
  print "\n"
@@ -111,9 +111,9 @@ class Knj::Threadhandler
111
111
  end
112
112
 
113
113
  def free(obj)
114
- raise "Destroyed Knj::Threadhandler." if !@mutex
115
-
116
114
  @mutex.synchronize do
115
+ return false if !@mutex or !@objects #something is trying to free and object, but the handler is destroyed. Dont crash but return false.
116
+
117
117
  freedata = false
118
118
  @objects.each do |data|
119
119
  if data[:object] == obj
@@ -3,7 +3,7 @@ class Knj::Threadpool
3
3
 
4
4
  def initialize(args = {})
5
5
  @args = args
6
- @args[:sleep] = 0.01 if !@args.has_key?(:sleep)
6
+ @args[:sleep] = 0.01 if !@args.key?(:sleep)
7
7
  @workers = []
8
8
  @blocks = []
9
9
  @mutex = Mutex.new
@@ -49,7 +49,7 @@ class Knj::Threadpool
49
49
  if blockdata[:runned]
50
50
  begin
51
51
  res = blockdata[:result]
52
- raise blockdata[:error] if blockdata.has_key?(:error)
52
+ raise blockdata[:error] if blockdata.key?(:error)
53
53
  ensure
54
54
  @mutex.synchronize do
55
55
  blockdata.clear
@@ -76,7 +76,7 @@ class Knj::Threadpool
76
76
 
77
77
  @mutex.synchronize do
78
78
  @blocks.each do |blockdata|
79
- if !blockdata[:running] and !blockdata[:runned]
79
+ if blockdata and !blockdata[:running] and !blockdata[:runned]
80
80
  blockdata[:running] = true
81
81
  return blockdata
82
82
  end
@@ -109,7 +109,7 @@ class Knj::Threadpool::Worker
109
109
  res = nil
110
110
  raise "No block in blockdata?" if !@blockdata[:block]
111
111
 
112
- if @blockdata.has_key?(:result)
112
+ if @blockdata.key?(:result)
113
113
  begin
114
114
  @running = true
115
115
  res = @blockdata[:block].call(*@blockdata[:args])
@@ -43,7 +43,7 @@ class Knj::Translations
43
43
  return "" if trans.empty?
44
44
 
45
45
  trans.each do |tran|
46
- if !@cache.has_key?(classn)
46
+ if !@cache.key?(classn)
47
47
  @cache[classn] = {
48
48
  objid => {
49
49
  key => {
@@ -109,7 +109,7 @@ class Knj::Translations
109
109
  @ob.delete(tran)
110
110
  end
111
111
 
112
- @cache[classn].delete(objid) if @cache.has_key?(classn) and @cache.has_key?(objid)
112
+ @cache[classn].delete(objid) if @cache.key?(classn) and @cache.key?(objid)
113
113
  end
114
114
  end
115
115
 
@@ -121,19 +121,4 @@ class Knj::Translations::Translation < Knj::Datarow
121
121
  d.data.delete(:object)
122
122
  end
123
123
  end
124
-
125
- def self.list(d)
126
- sql = "SELECT * FROM #{d.db.escape_col}#{d.db.esc_col(table)}#{d.db.escape_col} WHERE 1=1"
127
- ret = list_helper(d)
128
-
129
- d.args.each do |key, val|
130
- raise "No such key: #{key}."
131
- end
132
-
133
- sql += ret[:sql_where]
134
- sql += ret[:sql_order]
135
- sql += ret[:sql_limit]
136
-
137
- return d.ob.list_bysql(:Translation, sql)
138
- end
139
124
  end
@@ -38,9 +38,9 @@ class Knj::Unix_proc
38
38
  "app" => File.basename(match[4])
39
39
  }
40
40
 
41
- next if (!args.has_key?("ignore_self") or args["ignore_self"]) and match[1].to_i == $$.to_i
41
+ next if (!args.key?("ignore_self") or args["ignore_self"]) and match[1].to_i == $$.to_i
42
42
  next if grepstr.length > 0 and match[4].index(grepstr) != nil #dont return current process.
43
- next if args.has_key?("pids") and args["pids"].index(pid) == nil
43
+ next if args.key?("pids") and args["pids"].index(pid) == nil
44
44
 
45
45
  ret << Knj::Unix_proc.spawn(data)
46
46
  end
@@ -72,7 +72,7 @@ class Knj::Unix_proc
72
72
  end
73
73
 
74
74
  def [](key)
75
- raise "No such data: #{key}" if !@data.has_key?(key)
75
+ raise "No such data: #{key}" if !@data.key?(key)
76
76
  return @data[key]
77
77
  end
78
78
 
@@ -175,7 +175,7 @@ class Knj::Web
175
175
  if @data[:user_agent] != @server["HTTP_USER_AGENT"] or @data[:ip] != @server["REMOTE_ADDR"]
176
176
  @data = nil
177
177
  else
178
- @db.update(:sessions, {"last_url" => @server["REQUEST_URI"].to_s, "date_active" => Datestamp.dbstr}, {"id" => @data[:id]})
178
+ @db.update(:sessions, {"last_url" => @server["REQUEST_URI"].to_s, "date_active" => Time.new}, {"id" => @data[:id]})
179
179
  session_id = @args[:id] + "_" + @data[:id]
180
180
  end
181
181
  end
@@ -183,8 +183,8 @@ class Knj::Web
183
183
 
184
184
  if !@data or !session_id
185
185
  @db.insert(:sessions,
186
- :date_start => Knj::Datet.new.dbstr,
187
- :date_active => Knj::Datet.new.dbstr,
186
+ :date_start => Time.new,
187
+ :date_active => Time.new,
188
188
  :user_agent => @server["HTTP_USER_AGENT"],
189
189
  :ip => @server["REMOTE_ADDR"],
190
190
  :last_url => @server["REQUEST_URI"].to_s
@@ -211,14 +211,55 @@ class Knj::Web
211
211
  def self.parse_cookies(str)
212
212
  ret = {}
213
213
 
214
- str.split("; ").each do |cookie_str|
215
- splitted = cookie_str.split("=")
216
- ret[Knj::Php.urldecode(splitted[0])] = Knj::Php.urldecode(splitted[1])
214
+ str.split(/;\s*/).each do |cookie_str|
215
+ if !match = cookie_str.match(/^(.*?)=\"(.*)\"$/)
216
+ match = cookie_str.match(/^(.*?)=(.*)$/)
217
+ end
218
+
219
+ ret[self.urldec(match[1])] = self.urldec(match[2])
217
220
  end
218
221
 
219
222
  return ret
220
223
  end
221
224
 
225
+ def self.parse_set_cookies(str)
226
+ str = String.new(str.to_s)
227
+ return [] if str.length <= 0
228
+ args = {}
229
+ cookie_start_regex = /^(.+?)=(.*?)(;\s*|$)/
230
+
231
+ match = str.match(cookie_start_regex)
232
+ raise "Could not match cookie: '#{str}'." if !match
233
+ str.gsub!(cookie_start_regex, "")
234
+
235
+ args["name"] = self.urldec(match[1].to_s)
236
+ args["value"] = self.urldec(match[2].to_s)
237
+
238
+ while match = str.match(/(.+?)=(.*?)(;\s*|$)/)
239
+ str = str.gsub(match[0], "")
240
+ args[match[1].to_s.downcase] = match[2].to_s
241
+ end
242
+
243
+ return [args]
244
+ end
245
+
246
+ def self.cookie_str(cookie_data)
247
+ raise "Not a hash: '#{cookie_data.class.name}', '#{cookie_data}'." unless cookie_data.is_a?(Hash)
248
+ cookiestr = "#{self.urlenc(cookie_data["name"])}=#{self.urlenc(cookie_data["value"])}"
249
+
250
+ cookie_data.each do |key, val|
251
+ next if key == "name" or key == "value"
252
+
253
+ if key.to_s.downcase == "expires" and val.is_a?(Time)
254
+ cookiestr += "; Expires=#{val.httpdate}"
255
+ else
256
+ cookiestr += "; #{key}=#{val}"
257
+ end
258
+ end
259
+
260
+ return cookiestr
261
+ end
262
+
222
263
  def self.parse_urlquery(querystr, args = {})
223
264
  get = {}
224
265
  querystr.to_s.split("&").each do |value|
@@ -228,7 +269,7 @@ class Knj::Web
228
269
  name = value[0..pos-1]
229
270
  name = name.to_sym if args[:syms]
230
271
  valuestr = value.slice(pos+1..-1)
231
- Knj::Web.parse_name(get, Knj::Php.urldecode(name), valuestr, args)
272
+ Knj::Web.parse_name(get, self.urldec(name), valuestr, args)
232
273
  end
233
274
  end
234
275
 
@@ -242,7 +283,7 @@ class Knj::Web
242
283
  try = 0
243
284
 
244
285
  loop do
245
- if !seton.has_key?(try)
286
+ if !seton.key?(try)
246
287
  break
247
288
  else
248
289
  try += 1
@@ -264,16 +305,16 @@ class Knj::Web
264
305
  realvalue = value
265
306
  else
266
307
  realvalue = value.to_s
308
+ realvalue = self.urldec(realvalue) if args[:urldecode]
309
+ realvalue = realvalue.force_encoding("utf-8") if args[:force_utf8] if realvalue.respond_to?(:force_encoding)
267
310
  end
268
311
 
269
- realvalue = Knj::Php.urldecode(realvalue) if args[:urldecode] and !value.respond_to?(:filename)
270
-
271
312
  if varname and varname.index("[") != nil
272
313
  if match = varname.match(/\[(.*?)\]/)
273
314
  namepos = varname.index(match[0])
274
315
  name = varname.slice(0..namepos - 1)
275
316
  name = name.to_sym if args[:syms]
276
- seton[name] = {} if !seton.has_key?(name)
317
+ seton[name] = {} if !seton.key?(name)
277
318
 
278
319
  secname, secname_empty = Knj::Web.parse_secname(seton[name], match[1], args)
279
320
 
@@ -281,7 +322,7 @@ class Knj::Web
281
322
  restname = varname.slice(valuefrom..-1)
282
323
 
283
324
  if restname and restname.index("[") != nil
284
- seton[name][secname] = {} if !seton[name].has_key?(secname)
325
+ seton[name][secname] = {} if !seton[name].key?(secname)
285
326
  Knj::Web.parse_name_second(seton[name][secname], restname, value, args)
286
327
  else
287
328
  seton[name][secname] = realvalue
@@ -299,6 +340,7 @@ class Knj::Web
299
340
  realvalue = value
300
341
  else
301
342
  realvalue = value.to_s
343
+ realvalue = realvalue.force_encoding("utf-8") if args[:force_utf8]
302
344
  end
303
345
 
304
346
  match = varname.match(/^\[(.*?)\]/)
@@ -311,7 +353,7 @@ class Knj::Web
311
353
  restname = varname.slice(valuefrom..-1)
312
354
 
313
355
  if restname and restname.index("[") != nil
314
- seton[secname] = {} if !seton.has_key?(secname)
356
+ seton[secname] = {} if !seton.key?(secname)
315
357
  Knj::Web.parse_name_second(seton[secname], restname, value, args)
316
358
  else
317
359
  seton[secname] = realvalue
@@ -397,10 +439,35 @@ class Knj::Web
397
439
  return html
398
440
  end
399
441
 
442
+ def self.style_html(css)
443
+ return "" if css.length <= 0
444
+
445
+ str = " style=\""
446
+
447
+ css.each do |key, val|
448
+ str += "#{key}: #{val};"
449
+ end
450
+
451
+ str += "\""
452
+
453
+ return str
454
+ end
455
+
456
+ def self.attr_html(attrs)
457
+ return "" if attrs.length <= 0
458
+
459
+ html = ""
460
+ attrs.each do |key, val|
461
+ html += " #{key}=\"#{val.to_s.html}\""
462
+ end
463
+
464
+ return html
465
+ end
466
+
400
467
  def self.input(args)
401
468
  Knj::ArrayExt.hash_sym(args)
402
469
 
403
- if args.has_key?(:value)
470
+ if args.key?(:value)
404
471
  if args[:value].is_a?(Array) and args[:value][0].is_a?(NilClass)
405
472
  value = nil
406
473
  elsif args[:value].is_a?(Array)
@@ -424,7 +491,7 @@ class Knj::Web
424
491
  value = ""
425
492
  end
426
493
 
427
- if value and args.has_key?(:value_func) and args[:value_func]
494
+ if value and args.key?(:value_func) and args[:value_func]
428
495
  cback = args[:value_func]
429
496
 
430
497
  if cback.is_a?(Method)
@@ -455,25 +522,37 @@ class Knj::Web
455
522
  args[:type] = args[:type].to_sym
456
523
  end
457
524
 
458
- if args.has_key?(:disabled) and args[:disabled]
459
- disabled = "disabled "
460
- else
461
- disabled = ""
462
- end
525
+ attr = {
526
+ "name" => args[:name],
527
+ "id" => args[:id],
528
+ "type" => args[:type],
529
+ "class" => "input_#{args[:type]}"
530
+ }
531
+ attr.merge!(args[:attr]) if args[:attr]
532
+ attr["disabled"] = "disabled" if args[:disabled]
533
+
534
+ raise "No name given to the Web::input()-method." if !args[:name] and args[:type] != :info and args[:type] != :textshow and args[:type] != :plain
463
535
 
464
- raise "No name given to the Web::input()-method." if !args[:name] and args[:type] != :info and args[:type] != :textshow
536
+ css = {}
537
+ css["text-align"] = args[:align] if args.key?(:align)
465
538
 
466
- checked = ""
467
- checked += " value=\"#{args[:value_active]}\"" if args.has_key?(:value_active)
468
- checked += " checked" if value.is_a?(String) and value == "1" or value.to_s == "1"
469
- checked += " checked" if value.is_a?(TrueClass)
539
+ attr_keys = [:onchange]
540
+ attr_keys.each do |tag|
541
+ if args.key?(tag)
542
+ attr[tag] = args[tag]
543
+ end
544
+ end
470
545
 
471
546
  html = ""
472
547
 
473
548
  if args[:type] == :checkbox
549
+ attr["value"] = args[:value_active] if args.key?(:value_active)
550
+ 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"
551
+ attr["checked"] = "checked" if value.is_a?(TrueClass)
552
+
474
553
  html += "<tr>"
475
554
  html += "<td colspan=\"2\" class=\"tdcheck\">"
476
- html += "<input type=\"checkbox\" class=\"input_checkbox\" id=\"#{args[:id].html}\" name=\"#{args[:name].html}\"#{checked} />"
555
+ html += "<input#{self.attr_html(attr)} />"
477
556
  html += "<label for=\"#{args[:id].html}\">#{args[:title].html}</label>"
478
557
  html += "</td>"
479
558
  html += "</tr>"
@@ -482,16 +561,12 @@ class Knj::Web
482
561
  html += "<td class=\"tdt\">"
483
562
  html += args[:title].to_s.html
484
563
  html += "</td>"
485
- html += "<td class=\"tdc\">"
564
+ html += "<td#{self.style_html(css)} class=\"tdc\">"
486
565
 
487
566
  if args[:type] == :textarea
488
- if args.has_key?(:height)
489
- styleadd = " style=\"height: #{args[:height].html}px;\""
490
- else
491
- styleadd = ""
492
- end
567
+ css["height"] = "#{args[:height]}px" if args.key?(:height)
493
568
 
494
- html += "<textarea#{styleadd} class=\"input_textarea\" name=\"#{args[:name].html}\" id=\"#{args[:id].html}\">#{value}</textarea>"
569
+ html += "<textarea#{self.style_html(css)} class=\"input_textarea\" name=\"#{args[:name].html}\" id=\"#{args[:id].html}\">#{value}</textarea>"
495
570
  html += "</td>"
496
571
  elsif args[:type] == :fckeditor
497
572
  args[:height] = 400 if !args[:height]
@@ -504,11 +579,10 @@ class Knj::Web
504
579
 
505
580
  html += "</td>"
506
581
  elsif args[:type] == :select
507
- html += "<select name=\"#{args[:name].html}\" id=\"#{args[:id].html}\" class=\"input_select\""
508
- html += " onchange=\"#{args[:onchange]}\"" if args[:onchange]
509
- html += " multiple" if args[:multiple]
510
- html += " size=\"#{args[:size].to_s}\"" if args[:size]
511
- html += ">"
582
+ attr["multiple"] = "multiple" if args[:multiple]
583
+ attr["size"] = args["size"] if args[:size]
584
+
585
+ html += "<select#{self.attr_html(attr)}>"
512
586
  html += Knj::Web.opts(args[:opts], value, args[:opts_args])
513
587
  html += "</select>"
514
588
  html += "</td>"
@@ -517,12 +591,12 @@ class Knj::Web
517
591
  html += "<input type=\"file\" name=\"#{args[:name].html}\" class=\"input_file\" />"
518
592
  html += "</td><td style=\"padding-left: 5px;\">"
519
593
 
520
- raise "No path given for imageupload-input." if !args.has_key?(:path)
521
- raise "No value given in arguments for imageupload-input." if !args.has_key?(:value)
594
+ raise "No path given for imageupload-input." if !args.key?(:path)
595
+ raise "No value given in arguments for imageupload-input." if !args.key?(:value)
522
596
 
523
597
  path = args[:path].gsub("%value%", value.to_s).untaint
524
598
  if File.exists?(path)
525
- html += "<img src=\"image.php?picture=#{Knj::Php.urlencode(path).html}&smartsize=100&edgesize=25&force=true&ts=#{Time.new.to_f}\" alt=\"Image\" />"
599
+ 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\" />"
526
600
 
527
601
  if args[:dellink]
528
602
  dellink = args[:dellink].gsub("%value%", value.to_s)
@@ -536,21 +610,12 @@ class Knj::Web
536
610
  html += "<input type=\"#{args[:type].to_s}\" class=\"input_#{args[:type].to_s}\" name=\"#{args[:name].html}\" /></td>"
537
611
  elsif args[:type] == :textshow or args[:type] == :info
538
612
  html += "#{value}</td>"
613
+ elsif args[:type] == :plain
614
+ html += "#{Knj::Web.html(value)}"
539
615
  elsif args[:type] == :editarea
540
- css = {
541
- "width" => "100%"
542
- }
543
- css["height"] = args[:height] if args.has_key?(:height)
544
-
545
- styleadd = " style=\""
546
- css.each do |key, val|
547
- styleadd += "#{key}: #{val};"
548
- end
549
- styleadd += "\""
550
-
551
- styleadd += "width=\"100%\""
552
- styleadd += "height=\"#{args[:height]}\"" if args[:height]
553
- html += "<textarea#{styleadd} id=\"#{args[:id]}\" name=\"#{args[:name]}\">#{value}</textarea>"
616
+ css["width"] = "100%"
617
+ css["height"] = args[:height] if args.key?(:height)
618
+ html += "<textarea#{self.attr_html(attr)}#{self.style_html(css)} id=\"#{args[:id]}\" name=\"#{args[:name]}\">#{value}</textarea>"
554
619
 
555
620
  jshash = {
556
621
  "id" => args[:id],
@@ -559,7 +624,7 @@ class Knj::Web
559
624
 
560
625
  pos_keys = [:skip_init, :allow_toggle, :replace_tab_by_spaces, :toolbar, :syntax]
561
626
  pos_keys.each do |key|
562
- jshash[key.to_s] = args[key] if args.has_key?(key)
627
+ jshash[key.to_s] = args[key] if args.key?(key)
563
628
  end
564
629
 
565
630
  html += "<script type=\"text/javascript\">"
@@ -568,7 +633,8 @@ class Knj::Web
568
633
  html += "}"
569
634
  html += "</script>"
570
635
  else
571
- 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>"
636
+ attr[:value] = value
637
+ html += "<input#{self.attr_html(attr)} /></td>"
572
638
  html += "</td>"
573
639
  end
574
640
 
@@ -607,6 +673,8 @@ class Knj::Web
607
673
  html += " selected=\"selected\""
608
674
  elsif curvalue.to_s == key.to_s
609
675
  html += " selected=\"selected\""
676
+ elsif curvalue and curvalue.respond_to?(:is_knj?) and curvalue.id.to_s == key.to_s
677
+ html += " selected=\"selected\""
610
678
  end
611
679
 
612
680
  html += " value=\"#{key.html}\">#{value.html}</option>"
@@ -727,6 +795,10 @@ class Knj::Web
727
795
  browser = "bot"
728
796
  title = "Bot"
729
797
  version = "GIDBot"
798
+ elsif match = agent.match(/android\s+([\d\.]+)/)
799
+ browser = "android"
800
+ title = "Android"
801
+ version = match[1]
730
802
  elsif match = agent.match(/safari\/(\d+)/)
731
803
  browser = "safari"
732
804
  title = "Safari"
@@ -783,6 +855,10 @@ class Knj::Web
783
855
  browser = "bot"
784
856
  title = "Ezooms"
785
857
  version = match[1]
858
+ elsif match = agent.match(/ahrefsbot\/([\d\.]+)/)
859
+ browser = "bot"
860
+ title = "AhrefsBot"
861
+ version = match[1]
786
862
  else
787
863
  browser = "unknown"
788
864
  title = "(unknown browser)"
@@ -881,42 +957,45 @@ class Knj::Web
881
957
  return html
882
958
  end
883
959
 
960
+ #Parses a string to be safe for use in <a href="">.
884
961
  def self.ahref_parse(str)
885
962
  return str.to_s.gsub("&", "&amp;")
886
963
  end
887
- end
888
-
889
- def alert(string)
890
- return Knj::Web.alert(string)
891
- end
892
-
893
- def redirect(string)
894
- return Knj::Web.redirect(string)
895
- end
896
-
897
- def jsback(string)
898
- return Knj::Web.back
964
+
965
+ #URL-encodes a string.
966
+ def self.urlenc(string)
967
+ #Thanks to CGI framework
968
+ string.to_s.gsub(/([^ a-zA-Z0-9_.-]+)/) do
969
+ '%' + $1.unpack('H2' * $1.bytesize).join('%').upcase
970
+ end.tr(' ', '+')
971
+ end
972
+
973
+ #URL-decodes a string.
974
+ def self.urldec(string)
975
+ #Thanks to CGI framework
976
+ str = string.to_s.tr('+', ' ').gsub(/((?:%[0-9a-fA-F]{2})+)/) do
977
+ [$1.delete('%')].pack('H*')
978
+ end
979
+ end
980
+
981
+ #Escapes HTML-characters in a string.
982
+ def self.html(string)
983
+ return string.to_s.gsub(/&/, "&amp;").gsub(/\"/, "&quot;").gsub(/>/, "&gt;").gsub(/</, "&lt;")
984
+ end
899
985
  end
900
986
 
901
987
  class String
902
988
  def html
903
- return self.to_s.gsub(/&/, "&amp;").gsub(/\"/, "&quot;").gsub(/>/, "&gt;").gsub(/</, "&lt;")
989
+ return Knj::Web.html(self)
904
990
  end
905
991
 
906
992
  def sql
907
993
  begin
908
- return _httpsession.db.escape(self)
909
- rescue NameError
910
- #ignore - not in KnjAppServer HTTP-session.
911
- end
912
-
913
- begin
914
994
  return _db.escape(self)
915
995
  rescue NameError
916
996
  #ignore - not i KnjAppServer HTTP-session.
917
997
  end
918
998
 
919
- return $db.escape(self) if $db
920
999
  raise "Could not figure out where to find db object."
921
1000
  end
922
1001
  end