knjrbfw 0.0.23 → 0.0.24
Sign up to get free protection for your applications and to get access to all the features.
- data/VERSION +1 -1
- data/knjrbfw.gemspec +7 -4
- data/lib/knj/autoload.rb +1 -61
- data/lib/knj/datarow.rb +7 -10
- data/lib/knj/datarow_custom.rb +12 -2
- data/lib/knj/datet.rb +107 -0
- data/lib/knj/eruby.rb +21 -12
- data/lib/knj/gettext_threadded.rb +1 -1
- data/lib/knj/http2.rb +27 -9
- data/lib/knj/image.rb +10 -0
- data/lib/knj/includes/require_info.rb +3 -3
- data/lib/knj/knj.rb +16 -9
- data/lib/knj/knj_controller.rb +10 -1
- data/lib/knj/knjdb/drivers/mysql/knjdb_mysql.rb +26 -9
- data/lib/knj/knjdb/drivers/mysql/knjdb_mysql_columns.rb +11 -8
- data/lib/knj/knjdb/drivers/mysql/knjdb_mysql_indexes.rb +5 -0
- data/lib/knj/knjdb/drivers/mysql/knjdb_mysql_tables.rb +83 -26
- data/lib/knj/knjdb/drivers/sqlite3/knjdb_sqlite3_tables.rb +3 -3
- data/lib/knj/knjdb/libknjdb.rb +19 -20
- data/lib/knj/knjdb/revision.rb +9 -2
- data/lib/knj/kvm.rb +100 -0
- data/lib/knj/locale_strings.rb +32 -3
- data/lib/knj/locales.rb +1 -4
- data/lib/knj/memory_analyzer.rb +335 -0
- data/lib/knj/objects/objects_sqlhelper.rb +2 -2
- data/lib/knj/objects.rb +44 -11
- data/lib/knj/opts.rb +8 -8
- data/lib/knj/os.rb +13 -0
- data/lib/knj/php.rb +18 -33
- data/lib/knj/process.rb +3 -0
- data/lib/knj/process_meta.rb +1 -1
- data/lib/knj/rhodes/mutex.rb +2 -1
- data/lib/knj/rhodes/rhodes.js +5 -1
- data/lib/knj/rhodes/rhodes.rb +15 -15
- data/lib/knj/rhodes/youtube_embed.erb +12 -0
- data/lib/knj/rhodes/youtube_open.erb +45 -0
- data/lib/knj/strings.rb +2 -1
- data/lib/knj/translations.rb +3 -3
- data/lib/knj/unix_proc.rb +15 -4
- data/lib/knj/web.rb +17 -247
- data/lib/knj/webscripts/image.rhtml +9 -3
- data/lib/knj/wref.rb +109 -70
- data/spec/datet_spec.rb +30 -0
- data/spec/http2_spec.rb +23 -0
- data/spec/php_spec.rb +3 -0
- metadata +20 -17
- data/lib/knj/rhodes/delegate.rb +0 -414
- 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
|
-
|
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
|
-
@
|
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
|
-
@
|
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
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
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
|
-
|
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
|
-
|
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 =
|
16
|
-
value = db.select(
|
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 =
|
29
|
-
result = db.select(
|
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(
|
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(
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
|
data/lib/knj/process_meta.rb
CHANGED
data/lib/knj/rhodes/mutex.rb
CHANGED
data/lib/knj/rhodes/rhodes.js
CHANGED
@@ -1,3 +1,7 @@
|
|
1
1
|
function knj_rhodes_html_links(args){
|
2
|
-
$.ajax({type: "POST", data: {"url": args
|
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
|
}
|