knjrbfw 0.0.23 → 0.0.24

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. data/VERSION +1 -1
  2. data/knjrbfw.gemspec +7 -4
  3. data/lib/knj/autoload.rb +1 -61
  4. data/lib/knj/datarow.rb +7 -10
  5. data/lib/knj/datarow_custom.rb +12 -2
  6. data/lib/knj/datet.rb +107 -0
  7. data/lib/knj/eruby.rb +21 -12
  8. data/lib/knj/gettext_threadded.rb +1 -1
  9. data/lib/knj/http2.rb +27 -9
  10. data/lib/knj/image.rb +10 -0
  11. data/lib/knj/includes/require_info.rb +3 -3
  12. data/lib/knj/knj.rb +16 -9
  13. data/lib/knj/knj_controller.rb +10 -1
  14. data/lib/knj/knjdb/drivers/mysql/knjdb_mysql.rb +26 -9
  15. data/lib/knj/knjdb/drivers/mysql/knjdb_mysql_columns.rb +11 -8
  16. data/lib/knj/knjdb/drivers/mysql/knjdb_mysql_indexes.rb +5 -0
  17. data/lib/knj/knjdb/drivers/mysql/knjdb_mysql_tables.rb +83 -26
  18. data/lib/knj/knjdb/drivers/sqlite3/knjdb_sqlite3_tables.rb +3 -3
  19. data/lib/knj/knjdb/libknjdb.rb +19 -20
  20. data/lib/knj/knjdb/revision.rb +9 -2
  21. data/lib/knj/kvm.rb +100 -0
  22. data/lib/knj/locale_strings.rb +32 -3
  23. data/lib/knj/locales.rb +1 -4
  24. data/lib/knj/memory_analyzer.rb +335 -0
  25. data/lib/knj/objects/objects_sqlhelper.rb +2 -2
  26. data/lib/knj/objects.rb +44 -11
  27. data/lib/knj/opts.rb +8 -8
  28. data/lib/knj/os.rb +13 -0
  29. data/lib/knj/php.rb +18 -33
  30. data/lib/knj/process.rb +3 -0
  31. data/lib/knj/process_meta.rb +1 -1
  32. data/lib/knj/rhodes/mutex.rb +2 -1
  33. data/lib/knj/rhodes/rhodes.js +5 -1
  34. data/lib/knj/rhodes/rhodes.rb +15 -15
  35. data/lib/knj/rhodes/youtube_embed.erb +12 -0
  36. data/lib/knj/rhodes/youtube_open.erb +45 -0
  37. data/lib/knj/strings.rb +2 -1
  38. data/lib/knj/translations.rb +3 -3
  39. data/lib/knj/unix_proc.rb +15 -4
  40. data/lib/knj/web.rb +17 -247
  41. data/lib/knj/webscripts/image.rhtml +9 -3
  42. data/lib/knj/wref.rb +109 -70
  43. data/spec/datet_spec.rb +30 -0
  44. data/spec/http2_spec.rb +23 -0
  45. data/spec/php_spec.rb +3 -0
  46. metadata +20 -17
  47. data/lib/knj/rhodes/delegate.rb +0 -414
  48. data/lib/knj/rhodes/weakref.rb +0 -80
data/lib/knj/locales.rb CHANGED
@@ -40,8 +40,7 @@ module Knj::Locales
40
40
  #Returns a float from the formatted string according to the current locale.
41
41
  def self.number_in(num_str)
42
42
  lc = Knj::Locales.localeconv
43
- num_str = num_str.to_s.gsub(lc["thousands_sep"], "").gsub(lc["decimal_point"], ".").to_f
44
- return num_str
43
+ return num_str.to_s.gsub(lc["thousands_sep"], "").gsub(lc["decimal_point"], ".").to_f
45
44
  end
46
45
 
47
46
  #Returns the given number as a formatted string according to the current locale.
@@ -60,8 +59,6 @@ module Knj::Locales
60
59
 
61
60
  if Thread.current[:locale]
62
61
  return Thread.current[:locale]
63
- elsif $locale
64
- return $locale
65
62
  elsif ENV["LANGUAGE"]
66
63
  return ENV["LANGUAGE"]
67
64
  end
@@ -0,0 +1,335 @@
1
+ class Knj::Memory_analyzer
2
+ def initialize
3
+ @printed = {}
4
+ end
5
+
6
+ def write(to = $stdout)
7
+ to.print "<div style=\"width: 600px;\">\n"
8
+
9
+ self.garbage_collector(to)
10
+ GC.start
11
+
12
+ self.arrays(to)
13
+ GC.start
14
+
15
+ self.hashes(to)
16
+ GC.start
17
+
18
+ self.constants(to)
19
+ GC.start
20
+
21
+ self.global_vars(to)
22
+ GC.start
23
+
24
+ to.print "</div>\n"
25
+ end
26
+
27
+ def garbage_collector(to = $stdout)
28
+ to.print "<h1>Garbage collector</h1>\n"
29
+
30
+ if GC.enable
31
+ to.print "<div>Garbage collector was not enabled! But it is again now!</div>\n"
32
+ else
33
+ to.print "<div>Garbage collector was already enabled.</div>\n"
34
+ end
35
+
36
+ GC.start
37
+ end
38
+
39
+ def hashes(to = $stdout)
40
+ hashes = {}
41
+
42
+ ObjectSpace.each_object(Hash) do |hash|
43
+ begin
44
+ keys_orig = hash.keys.sort
45
+ rescue ArgumentError
46
+ #When unable to sort regexps...
47
+ next
48
+ end
49
+
50
+ keys = []
51
+ keys_orig.each do |key|
52
+ keys << key.to_s
53
+ end
54
+
55
+ if keys.empty?
56
+ keystr = :empty
57
+ else
58
+ keystr = keys.join(":")
59
+ end
60
+
61
+ if !hashes.key?(keystr)
62
+ hashes[keystr] = 1
63
+ else
64
+ hashes[keystr] += 1
65
+ end
66
+ end
67
+
68
+ hashes.delete_if do |key, val|
69
+ val < 100
70
+ end
71
+
72
+ hashes = Knj::ArrayExt.hash_sort(hashes) do |h1, h2|
73
+ h2[1] <=> h1[1]
74
+ end
75
+
76
+ to.print "<h1>Hashes</h1>\n"
77
+ to.write "<table class=\"hashes list\">\n"
78
+ to.write "\t<thead>\n"
79
+ to.write "\t\t<tr>\n"
80
+ to.write "\t\t\t<th>Hash keys</th>\n"
81
+ to.write "\t\t\t<th>Instances</th>\n"
82
+ to.write "\t\t</tr>\n"
83
+ to.write "\t</thead>\n"
84
+ to.write"\t<tbody>\n"
85
+
86
+ hashes.each do |key, val|
87
+ to.write "\t\t<tr>\n"
88
+ to.write "\t\t\t<td>#{Knj::Web.html(key)}</td>\n"
89
+ to.write "\t\t\t<td>#{Knj::Locales.number_out(val, 0)}</td>\n"
90
+ to.write "\t\t</tr>\n"
91
+ end
92
+
93
+ to.write "\t</tbody>\n"
94
+ to.write "</table>\n"
95
+ end
96
+
97
+ def arrays(to = $stdout)
98
+ arrays = {}
99
+
100
+ ObjectSpace.each_object(Array) do |arr|
101
+ begin
102
+ arr = arr.sort
103
+ rescue ArgumentError
104
+ #When unable to sort regexps...
105
+ next
106
+ end
107
+
108
+ keys = []
109
+ arr.each do |key|
110
+ keys << key.class.name.to_s
111
+ end
112
+
113
+ if keys.empty?
114
+ keystr = :empty
115
+ else
116
+ keystr = keys.join(":")
117
+ end
118
+
119
+ if !arrays.key?(keystr)
120
+ arrays[keystr] = 1
121
+ else
122
+ arrays[keystr] += 1
123
+ end
124
+ end
125
+
126
+ arrays.delete_if do |key, val|
127
+ val < 100
128
+ end
129
+
130
+ arrays = Knj::ArrayExt.hash_sort(arrays) do |h1, h2|
131
+ h2[1] <=> h1[1]
132
+ end
133
+
134
+ to.write "<h1>Arrays</h1>\n"
135
+ to.write "<table class=\"arrays list\">\n"
136
+ to.write "\t<thead>\n"
137
+ to.write "\t\t<tr>\n"
138
+ to.write "\t\t\t<th>Array classes</th>\n"
139
+ to.write "\t\t\t<th>Instances</th>\n"
140
+ to.write "\t\t</tr>\n"
141
+ to.write "\t</thead>\n"
142
+ to.write"\t<tbody>\n"
143
+
144
+ arrays.each do |key, val|
145
+ to.write "\t\t<tr>\n"
146
+ to.write "\t\t\t<td>#{Knj::Web.html(key)}</td>\n"
147
+ to.write "\t\t\t<td>#{Knj::Locales.number_out(val, 0)}</td>\n"
148
+ to.write "\t\t</tr>\n"
149
+ end
150
+
151
+ to.write "\t</tbody>\n"
152
+ to.write "</table>\n"
153
+ end
154
+
155
+ def global_vars(to = $stdout)
156
+ to.print "<h1>Global variables</h1>\n"
157
+ to.print "<table class=\"global_variables list\">\n"
158
+ to.print "\t<thead>\n"
159
+ to.print "\t\t<tr>\n"
160
+ to.print "\t\t\t<th>Name</th>\n"
161
+ to.print "\t\t</tr>\n"
162
+ to.print "\t</thead>\n"
163
+ to.print "\t<tbody>\n"
164
+
165
+ count = 0
166
+ Kernel.global_variables.each do |name|
167
+ count += 1
168
+
169
+ #begin
170
+ # global_var_ref = eval(name.to_s)
171
+ #rescue => e
172
+ # to.print "\t\t<tr>\n"
173
+ # to.print "\t\t\t<td>Error: #{Knj::Web.html(e.message)}</td>\n"
174
+ # to.print "\t\t</tr>\n"
175
+ #
176
+ # next
177
+ #end
178
+
179
+ #size = 0
180
+ #size = Knj::Memory_analyzer::Object_size_counter.new(global_var_ref).calculate_size
181
+ #size = size.to_f / 1024.0
182
+
183
+ to.print "\t\t<tr>\n"
184
+ to.print "\t\t\t<td>#{Knj::Web.html(name)}</td>\n"
185
+ to.print "\t\t</tr>\n"
186
+ end
187
+
188
+ if count <= 0
189
+ to.print "\t\t<tr>\n"
190
+ to.print "\t\t\t<td colspan=\"2\" class=\"error\">No global variables has been defined.</td>\n"
191
+ to.print "\t\t</tr>\n"
192
+ end
193
+
194
+ to.print "\t</tbody>\n"
195
+ to.print "</table>\n"
196
+ end
197
+
198
+ def constants(to = $stdout)
199
+ to.print "<h1>Constants</h1>\n"
200
+ to.print "<table class=\"memory_analyzer list\">\n"
201
+ to.print "\t<thead>\n"
202
+ to.print "\t\t<tr>\n"
203
+ to.print "\t\t\t<th>Class</th>\n"
204
+ to.print "\t\t\t<th style=\"text-align: right;\">Instances</th>\n"
205
+ to.print "\t\t</tr>\n"
206
+ to.print "\t</thead>\n"
207
+ to.print "\t<tbody>\n"
208
+
209
+ constants_m = Module.constants
210
+ constants_o = Object.constants
211
+ constants_k = Kernel.constants
212
+ constants = constants_m + constants_o + constants_k
213
+
214
+ constants.sort.each do |mod|
215
+ self.write_constant(to, Kernel, mod)
216
+ end
217
+
218
+ to.print "\t</tbody>\n"
219
+ to.print "</table>\n"
220
+ end
221
+
222
+ def write_constant(to, mod, submod)
223
+ submod_s = submod.to_s
224
+
225
+ #return false if mod.name.to_s == "Object" or mod.name.to_s == "Module"
226
+ return false if @printed.key?(submod_s)
227
+ return false if mod.autoload?(submod)
228
+ return false if !mod.const_defined?(submod)
229
+
230
+ @printed[submod_s] = true
231
+
232
+ instances = 0
233
+
234
+ invalid_submod_size_names = ["BasicObject", "Kernel", "Object", "FALSE"]
235
+
236
+ if invalid_submod_size_names.index(submod_s) != nil
237
+ size = "-"
238
+ calc_size = false
239
+ else
240
+ size = 0
241
+ calc_size = true
242
+ end
243
+
244
+ classobj = mod.const_get(submod)
245
+
246
+ begin
247
+ ObjectSpace.each_object(classobj) do |obj|
248
+ instances += 1
249
+ end
250
+ rescue Exception => e
251
+ emsg = e.message.to_s
252
+ if emsg.index("no such file to load") != nil or emsg.index("class or module required") != nil or emsg.index("uninitialized constant") != nil
253
+ #return false
254
+ else
255
+ raise e
256
+ end
257
+ end
258
+
259
+ if mod.to_s == "Kernel" or mod.to_s == "Class" or mod.to_s == "Object"
260
+ mod_title = submod_s
261
+ else
262
+ mod_title = "#{mod.to_s}::#{submod_s}"
263
+ end
264
+
265
+ if instances > 0
266
+ to.print "\t\t<tr>\n"
267
+ to.print "\t\t\t<td>#{mod_title.html}</td>\n"
268
+ to.print "\t\t\t<td style=\"text-align: right;\">#{Knj::Locales.number_out(instances, 0)}</td>\n"
269
+ to.print "\t\t</tr>\n"
270
+ GC.start
271
+ end
272
+
273
+ if classobj.respond_to?("constants")
274
+ classobj.constants.sort.each do |subsubmod|
275
+ self.write_constant(to, classobj, subsubmod)
276
+ end
277
+ end
278
+ end
279
+ end
280
+
281
+ class Knj::Memory_analyzer::Object_size_counter
282
+ def initialize(obj)
283
+ @checked = {}
284
+ @object = obj
285
+ end
286
+
287
+ def calculate_size
288
+ ret = self.var_size(@object)
289
+ @checked = nil
290
+ @object = nil
291
+ return ret
292
+ end
293
+
294
+ def object_size(obj)
295
+ size = 0
296
+
297
+ obj.instance_variables.each do |var_name|
298
+ var = obj.instance_variable_get(var_name)
299
+ next if @checked.key?(var.__id__)
300
+ @checked[var.__id__] = true
301
+ size += self.var_size(var)
302
+ end
303
+
304
+ return size
305
+ end
306
+
307
+ def var_size(var)
308
+ size = 0
309
+
310
+ if var.is_a?(String)
311
+ size += var.length
312
+ elsif var.is_a?(Integer)
313
+ size += var.to_s.length
314
+ elsif var.is_a?(Symbol) or var.is_a?(Fixnum)
315
+ size += 4
316
+ elsif var.is_a?(Time)
317
+ size += var.to_f.to_s.length
318
+ elsif var.is_a?(Hash)
319
+ var.each do |key, val|
320
+ size += self.var_size(key)
321
+ size += self.var_size(val)
322
+ end
323
+ elsif var.is_a?(Array)
324
+ var.each do |val|
325
+ size += self.object_size(val)
326
+ end
327
+ elsif var.is_a?(TrueClass) or var.is_a?(FalseClass)
328
+ size += 1
329
+ else
330
+ size += self.object_size(var)
331
+ end
332
+
333
+ return size
334
+ end
335
+ end
@@ -347,9 +347,9 @@ class Knj::Objects
347
347
  found = true
348
348
  elsif args.key?(:cols_num) and match = key.match(/^(.+)_(from|to|above|below)$/) and args[:cols_num].index(match[1]) != nil
349
349
  if match[2] == "from"
350
- sql_where << " AND #{table}`#{db.esc_col(match[1])}` <= '#{db.esc(val)}'"
351
- elsif match[2] == "to"
352
350
  sql_where << " AND #{table}`#{db.esc_col(match[1])}` >= '#{db.esc(val)}'"
351
+ elsif match[2] == "to"
352
+ sql_where << " AND #{table}`#{db.esc_col(match[1])}` <= '#{db.esc(val)}'"
353
353
  elsif match[2] == "above"
354
354
  sql_where << " AND #{table}`#{db.esc_col(match[1])}` > '#{db.esc(val)}'"
355
355
  elsif match[2] == "below"
data/lib/knj/objects.rb CHANGED
@@ -15,11 +15,9 @@ class Knj::Objects
15
15
  @objects = {}
16
16
  @locks = {}
17
17
  @data = {}
18
- @mutex_require = Mutex.new
18
+ @lock_require = Monitor.new
19
19
 
20
- if @args[:cache] == :weak
21
- require "#{$knjpath}wref"
22
- end
20
+ require "#{$knjpath}wref" if @args[:cache] == :weak
23
21
 
24
22
  @events = Knj::Event_handler.new
25
23
  @events.add_event(
@@ -34,6 +32,10 @@ class Knj::Objects
34
32
  :name => :missing_class,
35
33
  :connections_max => 1
36
34
  )
35
+ @events.add_event(
36
+ :name => :require_class,
37
+ :connections_max => 1
38
+ )
37
39
 
38
40
  raise "No DB given." if !@args[:db] and !@args[:custom]
39
41
  raise "No class path given." if !@args[:class_path] and (@args[:require] or !@args.key?(:require))
@@ -72,6 +74,11 @@ class Knj::Objects
72
74
  @locks[classname] = Mutex.new
73
75
  end
74
76
 
77
+ def uninit_class(classname)
78
+ @objects.delete(classname)
79
+ @locks.delete(classname)
80
+ end
81
+
75
82
  #Returns a cloned version of the @objects variable. Cloned because iteration on it may crash some of the other methods in Ruby 1.9+
76
83
  def objects
77
84
  objs_cloned = {}
@@ -149,15 +156,31 @@ class Knj::Objects
149
156
  classname = classname.to_sym
150
157
  return false if @objects.key?(classname)
151
158
 
152
- @mutex_require.synchronize do
159
+ @lock_require.synchronize do
153
160
  #Maybe the classname got required meanwhile the synchronized wait - check again.
154
161
  return false if @objects.key?(classname)
155
162
 
156
- if (@args[:require] or !@args.key?(:require)) and (!args.key?(:require) or args[:require])
157
- filename = "#{@args[:class_path]}/#{@args[:class_pre]}#{classname.to_s.downcase}.rb"
158
- filename_req = "#{@args[:class_path]}/#{@args[:class_pre]}#{classname.to_s.downcase}"
159
- raise "Class file could not be found: #{filename}." if !File.exists?(filename)
160
- require filename_req
163
+ if @events.connected?(:require_class)
164
+ @events.call(:require_class, {
165
+ :class => classname
166
+ })
167
+ else
168
+ doreq = false
169
+
170
+ if args[:require]
171
+ doreq = true
172
+ elsif args.key?(:require) and !args[:require]
173
+ doreq = false
174
+ elsif @args[:require] or !@args.key?(:require)
175
+ doreq = true
176
+ end
177
+
178
+ if doreq
179
+ filename = "#{@args[:class_path]}/#{@args[:class_pre]}#{classname.to_s.downcase}.rb"
180
+ filename_req = "#{@args[:class_path]}/#{@args[:class_pre]}#{classname.to_s.downcase}"
181
+ raise "Class file could not be found: #{filename}." if !File.exists?(filename)
182
+ require filename_req
183
+ end
161
184
  end
162
185
 
163
186
  if args[:class]
@@ -227,7 +250,7 @@ class Knj::Objects
227
250
 
228
251
  @locks[classname].synchronize do
229
252
  #Maybe the object got spawned while we waited for the lock? If so we shouldnt spawn another instance.
230
- if obj = @objects[classname].get!(id) and obj.id.to_i == id
253
+ if @args[:cache] == :weak and obj = @objects[classname].get!(id) and obj.id.to_i == id
231
254
  return obj
232
255
  end
233
256
 
@@ -261,6 +284,7 @@ class Knj::Objects
261
284
  end
262
285
  end
263
286
 
287
+ #Returns the first object found from the given arguments. Also automatically limits the results to 1.
264
288
  def get_by(classname, args = {})
265
289
  classname = classname.to_sym
266
290
  self.requireclass(classname)
@@ -344,6 +368,10 @@ class Knj::Objects
344
368
  html << "<option"
345
369
  html << " selected=\"selected\"" if !args[:selected]
346
370
  html << " value=\"\">#{_("Add new")}</option>"
371
+ elsif args[:none]
372
+ html << "<option"
373
+ html << " selected=\"selected\"" if !args[:selected]
374
+ html << " value=\"\">#{_("None")}</option>"
347
375
  end
348
376
 
349
377
  self.list(classname, args[:list_args]) do |object|
@@ -461,6 +489,7 @@ class Knj::Objects
461
489
 
462
490
  #Add a new object to the database and to the cache.
463
491
  def add(classname, data = {})
492
+ raise "data-variable was not a hash: '#{data.class.name}'." if !data.is_a?(Hash)
464
493
  classname = classname.to_sym
465
494
  self.requireclass(classname)
466
495
 
@@ -594,6 +623,9 @@ class Knj::Objects
594
623
 
595
624
  #Delete an object. Both from the database and from the cache.
596
625
  def delete(object)
626
+ #Return false if the object has already been deleted.
627
+ return false if object.deleted?
628
+
597
629
  self.call("object" => object, "signal" => "delete_before")
598
630
  self.unset(object)
599
631
  obj_id = object.id
@@ -637,6 +669,7 @@ class Knj::Objects
637
669
  arr_ids = []
638
670
  ids = []
639
671
  objs.each do |obj|
672
+ next if obj.deleted?
640
673
  ids << obj.id
641
674
  if ids.length >= 1000
642
675
  arr_ids << ids
data/lib/knj/opts.rb CHANGED
@@ -1,19 +1,19 @@
1
1
  module Knj::Opts
2
- $knjoptions = {
2
+ CONFIG = {
3
3
  "table" => "options"
4
4
  }
5
5
 
6
6
  def self.init(arr_opts)
7
7
  arr_opts.each do |pair|
8
8
  if pair[0] == "knjdb" or pair[0] == "table"
9
- $knjoptions[pair[0]] = pair[1]
9
+ Knj::Opts::CONFIG[pair[0]] = pair[1]
10
10
  end
11
11
  end
12
12
  end
13
13
 
14
14
  def self.get(title)
15
- db = $knjoptions["knjdb"]
16
- value = db.select($knjoptions["table"], {"title" => title}, {"limit" => 1}).fetch
15
+ db = Knj::Opts::CONFIG["knjdb"]
16
+ value = db.select(Knj::Opts::CONFIG["table"], {"title" => title}, {"limit" => 1}).fetch
17
17
 
18
18
  if !value
19
19
  return ""
@@ -25,11 +25,11 @@ module Knj::Opts
25
25
  end
26
26
 
27
27
  def self.set(title, value)
28
- db = $knjoptions["knjdb"]
29
- result = db.select($knjoptions["table"], {"title" => title}, {"limit" => 1}).fetch
28
+ db = Knj::Opts::CONFIG["knjdb"]
29
+ result = db.select(Knj::Opts::CONFIG["table"], {"title" => title}, {"limit" => 1}).fetch
30
30
 
31
31
  if !result
32
- db.insert($knjoptions["table"], {
32
+ db.insert(Knj::Opts::CONFIG["table"], {
33
33
  "title" => title,
34
34
  "value" => value
35
35
  })
@@ -39,7 +39,7 @@ module Knj::Opts
39
39
  id = result[:id] if result.key?(:id)
40
40
  raise "Could not figure out of ID." if !id
41
41
 
42
- db.update($knjoptions["table"], {"value" => value}, {"id" => id})
42
+ db.update(Knj::Opts::CONFIG["table"], {"value" => value}, {"id" => id})
43
43
  end
44
44
  end
45
45
  end
data/lib/knj/os.rb CHANGED
@@ -13,6 +13,19 @@ module Knj::Os
13
13
  return homedir
14
14
  end
15
15
 
16
+ #This method was created to make up for the fact that Dir.tmpdir sometimes returns empty strings??
17
+ def self.tmpdir
18
+ require "tmpdir"
19
+ tmpdir = Dir.tmpdir.to_s.strip
20
+
21
+ return tmpdir if tmpdir.length >= 3 and File.exists?(tmpdir)
22
+ return ENV["TEMP"] if ENV["TEMP"].to_s.strip.length > 0 and File.exists?(ENV["TMP"])
23
+ return ENV["TMP"] if ENV["TMP"].to_s.strip.length > 0 and File.exists?(ENV["TMP"])
24
+ return "/tmp" if File.exists?("/tmp")
25
+
26
+ raise "Could not figure out temp-dir."
27
+ end
28
+
16
29
  def self.whoami
17
30
  if ENV["USERNAME"]
18
31
  whoami = ENV["USERNAME"]
data/lib/knj/php.rb CHANGED
@@ -294,16 +294,25 @@ module Knj::Php
294
294
  end
295
295
 
296
296
  def substr(string, from, to = nil)
297
+ #If 'to' is not given it should be the total length of the string.
297
298
  if to == nil
298
299
  to = string.length
299
300
  end
300
301
 
302
+ #The behaviour with a negative 'to' is not the same as in PHP. Hack it!
303
+ if to < 0
304
+ to = string.length + to
305
+ end
306
+
307
+ #Cut the string.
301
308
  string = "#{string[from.to_i, to.to_i]}"
302
309
 
310
+ #Sometimes the encoding will no longer be valid. Fix that if that is the case.
303
311
  if !string.valid_encoding? and Knj::Php.class_exists("Iconv")
304
312
  string = Iconv.conv("UTF-8//IGNORE", "UTF-8", "#{string} ")[0..-2]
305
313
  end
306
314
 
315
+ #Return the cut string.
307
316
  return string
308
317
  end
309
318
 
@@ -329,30 +338,8 @@ module Knj::Php
329
338
  end
330
339
  end
331
340
 
332
- sent = false
333
-
334
- if Knj::Php.class_exists("Apache")
335
- Apache.request.headers_out[key] = value
336
- sent = true
337
- end
338
-
339
- begin
340
- _kas.header(key, value) #This is for knjAppServer - knj.
341
- sent = true
342
- rescue NameError => e
343
- if $knj_eruby
344
- $knj_eruby.header(key, value)
345
- sent = true
346
- elsif $cgi.class.name == "CGI"
347
- sent = true
348
- $cgi.header(key => value)
349
- elsif $_CGI.class.name == "CGI"
350
- sent = true
351
- $_CGI.header(key => value)
352
- end
353
- end
354
-
355
- return sent
341
+ _kas.header(key, value) #This is for knjAppServer - knj.
342
+ return true
356
343
  end
357
344
 
358
345
  def nl2br(string)
@@ -631,14 +618,7 @@ module Knj::Php
631
618
  args["expires"] = Time.at(expire) if expire
632
619
  args["domain"] = domain if domain
633
620
 
634
- begin
635
- _kas.cookie(args)
636
- rescue NameError
637
- cookie = CGI::Cookie.new(args)
638
- status = Knj::Php.header("Set-Cookie: #{cookie.to_s}")
639
- $_COOKIE[cname] = cvalue if $_COOKIE
640
- end
641
-
621
+ _kas.cookie(args)
642
622
  return status
643
623
  end
644
624
 
@@ -757,7 +737,12 @@ module Knj::Php
757
737
  end
758
738
 
759
739
  def base64_encode(str)
760
- return Base64.encode64(str.to_s)
740
+ #The strict-encode wont do corrupt newlines...
741
+ if Base64.respond_to?("strict_encode64")
742
+ return Base64.strict_encode64(str.to_s)
743
+ else
744
+ return Base64.encode64(str.to_s)
745
+ end
761
746
  end
762
747
 
763
748
  def base64_decode(str)
data/lib/knj/process.rb CHANGED
@@ -376,6 +376,8 @@ class Knj::Process
376
376
  $stderr.print "Answer is block for #{id} #{block_res}\n" if @debug and block_res
377
377
 
378
378
  loop do
379
+ raise "Process destroyed." if !@out_answers
380
+
379
381
  if block_res
380
382
  self.exec_block_results(id)
381
383
  break if block_res and block_res[:finished]
@@ -418,6 +420,7 @@ class Knj::Process
418
420
  def destroy
419
421
  self.kill_listen
420
422
  @err_thread.kill if @err_thread
423
+ @out_answers = nil
421
424
  end
422
425
  end
423
426
 
@@ -367,7 +367,7 @@ class Knj::Process_meta
367
367
  begin
368
368
  Process.kill(9, pid) if process_exists
369
369
  rescue Errno::ESRCH => e
370
- raise e if e.message != "No such process"
370
+ raise e if e.message.index("No such process") == nil
371
371
  end
372
372
 
373
373
  retry
@@ -1,7 +1,8 @@
1
1
  class Mutex
2
2
  def synchronize
3
- sleep 0.1 if @working
3
+ sleep 0.05 while @working
4
4
  @working = true
5
+
5
6
  begin
6
7
  yield
7
8
  ensure
@@ -1,3 +1,7 @@
1
1
  function knj_rhodes_html_links(args){
2
- $.ajax({type: "POST", data: {"url": args["url"]}, url: "/app/Knj/html_links"});
2
+ $.ajax({type: "POST", data: {"url": args.url}, url: "/app/Knj/html_links"})
3
+ }
4
+
5
+ function knj_rhodes_youtube_open_in_app(args){
6
+ $.ajax({type: "POST", data: {"youtube_id": args.youtube_id}, url: "/app/Knj/youtube_open_in_app"})
3
7
  }