rack-mini-profiler 0.1.28 → 0.9.0
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.
Potentially problematic release.
This version of rack-mini-profiler might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/{Ruby/CHANGELOG → CHANGELOG} +27 -0
- data/{Ruby/README.md → README.md} +73 -31
- data/{Ruby/lib → lib}/html/includes.css +0 -0
- data/{Ruby/lib → lib}/html/includes.js +9 -8
- data/{Ruby/lib → lib}/html/includes.less +0 -0
- data/{Ruby/lib → lib}/html/includes.tmpl +3 -1
- data/{Ruby/lib → lib}/html/jquery.1.7.1.js +0 -0
- data/{Ruby/lib → lib}/html/jquery.tmpl.js +0 -0
- data/{Ruby/lib → lib}/html/list.css +2 -2
- data/{Ruby/lib → lib}/html/list.js +1 -1
- data/{Ruby/lib → lib}/html/list.tmpl +2 -2
- data/lib/html/profile_handler.js +1 -0
- data/{Ruby/lib → lib}/html/share.html +2 -2
- data/{Ruby/lib → lib}/mini_profiler/client_settings.rb +11 -11
- data/{Ruby/lib → lib}/mini_profiler/client_timer_struct.rb +0 -0
- data/{Ruby/lib → lib}/mini_profiler/config.rb +11 -4
- data/{Ruby/lib → lib}/mini_profiler/context.rb +1 -1
- data/{Ruby/lib → lib}/mini_profiler/custom_timer_struct.rb +0 -0
- data/lib/mini_profiler/gc_profiler.rb +181 -0
- data/{Ruby/lib → lib}/mini_profiler/page_timer_struct.rb +4 -4
- data/{Ruby/lib → lib}/mini_profiler/profiler.rb +165 -142
- data/{Ruby/lib → lib}/mini_profiler/profiling_methods.rb +31 -11
- data/{Ruby/lib → lib}/mini_profiler/request_timer_struct.rb +5 -5
- data/{Ruby/lib → lib}/mini_profiler/sql_timer_struct.rb +0 -0
- data/{Ruby/lib → lib}/mini_profiler/storage/abstract_store.rb +0 -0
- data/{Ruby/lib → lib}/mini_profiler/storage/file_store.rb +26 -4
- data/{Ruby/lib → lib}/mini_profiler/storage/memcache_store.rb +0 -0
- data/{Ruby/lib → lib}/mini_profiler/storage/memory_store.rb +25 -4
- data/{Ruby/lib → lib}/mini_profiler/storage/redis_store.rb +0 -0
- data/{Ruby/lib → lib}/mini_profiler/timer_struct.rb +0 -0
- data/lib/mini_profiler/version.rb +5 -0
- data/{Ruby/lib → lib}/mini_profiler_rails/railtie.rb +6 -2
- data/{Ruby/lib → lib}/patches/net_patches.rb +0 -0
- data/{Ruby/lib → lib}/patches/sql_patches.rb +3 -2
- data/{Ruby/lib → lib}/rack-mini-profiler.rb +0 -0
- data/rack-mini-profiler.gemspec +14 -6
- metadata +153 -43
- data/Ruby/lib/html/flamegraph.html +0 -351
- data/Ruby/lib/html/profile_handler.js +0 -1
- data/Ruby/lib/mini_profiler/flame_graph.rb +0 -54
- data/Ruby/lib/mini_profiler/gc_profiler.rb +0 -107
- data/Ruby/lib/mini_profiler/version.rb +0 -5
@@ -43,16 +43,16 @@ module Rack
|
|
43
43
|
def root
|
44
44
|
@attributes['Root']
|
45
45
|
end
|
46
|
-
|
46
|
+
|
47
47
|
def to_json(*a)
|
48
48
|
attribs = @attributes.merge(
|
49
|
-
"Started" => '/Date(%d)/' % @attributes['Started'],
|
49
|
+
"Started" => '/Date(%d)/' % @attributes['Started'],
|
50
50
|
"DurationMilliseconds" => @attributes['Root']['DurationMilliseconds'],
|
51
51
|
"CustomTimingNames" => @attributes['CustomTimingStats'].keys.sort
|
52
|
-
)
|
52
|
+
)
|
53
53
|
::JSON.generate(attribs, :max_nesting => 100)
|
54
54
|
end
|
55
55
|
end
|
56
|
-
|
56
|
+
|
57
57
|
end
|
58
58
|
end
|
@@ -18,7 +18,8 @@ require 'mini_profiler/profiling_methods'
|
|
18
18
|
require 'mini_profiler/context'
|
19
19
|
require 'mini_profiler/client_settings'
|
20
20
|
require 'mini_profiler/gc_profiler'
|
21
|
-
|
21
|
+
# TODO
|
22
|
+
# require 'mini_profiler/gc_profiler_ruby_head' if Gem::Version.new('2.1.0') <= Gem::Version.new(RUBY_VERSION)
|
22
23
|
|
23
24
|
module Rack
|
24
25
|
|
@@ -137,7 +138,9 @@ module Rack
|
|
137
138
|
|
138
139
|
def serve_html(env)
|
139
140
|
file_name = env['PATH_INFO'][(@config.base_url_path.length)..1000]
|
141
|
+
|
140
142
|
return serve_results(env) if file_name.eql?('results')
|
143
|
+
|
141
144
|
full_path = ::File.expand_path("../html/#{file_name}", ::File.dirname(__FILE__))
|
142
145
|
return [404, {}, ["Not found"]] unless ::File.exists? full_path
|
143
146
|
f = Rack::File.new nil
|
@@ -201,11 +204,12 @@ module Rack
|
|
201
204
|
skip_it = true
|
202
205
|
end
|
203
206
|
|
204
|
-
if query_string =~ /pp=enable/
|
207
|
+
if query_string =~ /pp=enable/ && (@config.authorization_mode != :whitelist || MiniProfiler.request_authorized?)
|
205
208
|
skip_it = false
|
209
|
+
config.enabled = true
|
206
210
|
end
|
207
211
|
|
208
|
-
if skip_it
|
212
|
+
if skip_it || !config.enabled
|
209
213
|
status,headers,body = @app.call(env)
|
210
214
|
client_settings.disable_profiling = true
|
211
215
|
client_settings.write!(headers)
|
@@ -215,8 +219,18 @@ module Rack
|
|
215
219
|
end
|
216
220
|
|
217
221
|
if query_string =~ /pp=profile-gc/
|
222
|
+
current.measure = false if current
|
223
|
+
|
218
224
|
if query_string =~ /pp=profile-gc-time/
|
219
225
|
return Rack::MiniProfiler::GCProfiler.new.profile_gc_time(@app, env)
|
226
|
+
elsif query_string =~ /pp=profile-gc-ruby-head/
|
227
|
+
result = StringIO.new
|
228
|
+
report = MemoryProfiler.report do
|
229
|
+
_,_,body = @app.call(env)
|
230
|
+
body.close if body.respond_to? :close
|
231
|
+
end
|
232
|
+
report.pretty_print(result)
|
233
|
+
return text_result(result.string)
|
220
234
|
else
|
221
235
|
return Rack::MiniProfiler::GCProfiler.new.profile_gc(@app, env)
|
222
236
|
end
|
@@ -237,38 +251,21 @@ module Rack
|
|
237
251
|
current.skip_backtrace = true
|
238
252
|
end
|
239
253
|
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
if query_string =~ /pp=sample/ || query_string =~ /pp=flamegraph/
|
245
|
-
current.measure = false
|
246
|
-
skip_frames = 0
|
247
|
-
backtraces = []
|
248
|
-
t = Thread.current
|
249
|
-
|
250
|
-
Thread.new {
|
251
|
-
# new in Ruby 2.0
|
252
|
-
has_backtrace_locations = t.respond_to?(:backtrace_locations)
|
253
|
-
begin
|
254
|
-
i = 10000 # for sanity never grab more than 10k samples
|
255
|
-
while i > 0
|
256
|
-
break if done_sampling
|
257
|
-
i -= 1
|
258
|
-
backtraces << (has_backtrace_locations ? t.backtrace_locations : t.backtrace)
|
259
|
-
|
260
|
-
# On my machine using Ruby 2.0 this give me excellent fidelity of stack trace per 1.2ms
|
261
|
-
# with this fidelity analysis becomes very powerful
|
262
|
-
sleep 0.0005
|
263
|
-
end
|
264
|
-
ensure
|
265
|
-
quit_sampler = true
|
266
|
-
end
|
267
|
-
}
|
268
|
-
end
|
254
|
+
flamegraph = nil
|
255
|
+
|
256
|
+
trace_exceptions = query_string =~ /pp=trace-exceptions/ && defined? TracePoint
|
257
|
+
status, headers, body, exceptions,trace = nil
|
269
258
|
|
270
|
-
status, headers, body = nil
|
271
259
|
start = Time.now
|
260
|
+
|
261
|
+
if trace_exceptions
|
262
|
+
exceptions = []
|
263
|
+
trace = TracePoint.new(:raise) do |tp|
|
264
|
+
exceptions << tp.raised_exception
|
265
|
+
end
|
266
|
+
trace.enable
|
267
|
+
end
|
268
|
+
|
272
269
|
begin
|
273
270
|
|
274
271
|
# Strip all the caching headers so we don't get 304s back
|
@@ -276,13 +273,33 @@ module Rack
|
|
276
273
|
env['HTTP_IF_MODIFIED_SINCE'] = ''
|
277
274
|
env['HTTP_IF_NONE_MATCH'] = ''
|
278
275
|
|
279
|
-
|
276
|
+
if query_string =~ /pp=flamegraph/
|
277
|
+
unless defined?(Flamegraph) && Flamegraph.respond_to?(:generate)
|
278
|
+
|
279
|
+
flamegraph = "Please install the flamegraph gem and require it: add gem 'flamegraph' to your Gemfile"
|
280
|
+
status,headers,body = @app.call(env)
|
281
|
+
else
|
282
|
+
# do not sully our profile with mini profiler timings
|
283
|
+
current.measure = false
|
284
|
+
match_data = query_string.match(/flamegraph_sample_rate=(?<rate>[\d\.]+)/)
|
285
|
+
|
286
|
+
mode = query_string =~ /mode=c/ ? :c : :ruby
|
287
|
+
|
288
|
+
if match_data && !match_data[:rate].to_f.zero?
|
289
|
+
sample_rate = match_data[:rate].to_f
|
290
|
+
else
|
291
|
+
sample_rate = config.flamegraph_sample_rate
|
292
|
+
end
|
293
|
+
flamegraph = Flamegraph.generate(nil, fidelity: sample_rate, embed_resources: query_string =~ /embed/, mode: mode) do
|
294
|
+
status,headers,body = @app.call(env)
|
295
|
+
end
|
296
|
+
end
|
297
|
+
else
|
298
|
+
status,headers,body = @app.call(env)
|
299
|
+
end
|
280
300
|
client_settings.write!(headers)
|
281
301
|
ensure
|
282
|
-
if
|
283
|
-
done_sampling = true
|
284
|
-
sleep 0.001 until quit_sampler
|
285
|
-
end
|
302
|
+
trace.disable if trace
|
286
303
|
end
|
287
304
|
|
288
305
|
skip_it = current.discard
|
@@ -299,6 +316,11 @@ module Rack
|
|
299
316
|
return [status,headers,body] if skip_it
|
300
317
|
|
301
318
|
# we must do this here, otherwise current[:discard] is not being properly treated
|
319
|
+
if trace_exceptions
|
320
|
+
body.close if body.respond_to? :close
|
321
|
+
return dump_exceptions exceptions
|
322
|
+
end
|
323
|
+
|
302
324
|
if query_string =~ /pp=env/
|
303
325
|
body.close if body.respond_to? :close
|
304
326
|
return dump_env env
|
@@ -313,56 +335,65 @@ module Rack
|
|
313
335
|
page_struct['User'] = user(env)
|
314
336
|
page_struct['Root'].record_time((Time.now - start) * 1000)
|
315
337
|
|
316
|
-
if
|
338
|
+
if flamegraph
|
317
339
|
body.close if body.respond_to? :close
|
318
|
-
|
319
|
-
return analyze(backtraces, page_struct)
|
320
|
-
else
|
321
|
-
return flame_graph(backtraces, page_struct)
|
322
|
-
end
|
340
|
+
return self.flamegraph(flamegraph)
|
323
341
|
end
|
324
342
|
|
325
343
|
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
content_type = headers['Content-Type']
|
331
|
-
# inject headers, script
|
332
|
-
if content_type && status == 200
|
333
|
-
|
334
|
-
client_settings.write!(headers)
|
335
|
-
|
336
|
-
# mini profiler is meddling with stuff, we can not cache cause we will get incorrect data
|
337
|
-
# Rack::ETag has already inserted some nonesense in the chain
|
338
|
-
headers.delete('ETag')
|
339
|
-
headers.delete('Date')
|
340
|
-
headers['Cache-Control'] = 'must-revalidate, private, max-age=0'
|
344
|
+
begin
|
345
|
+
# no matter what it is, it should be unviewed, otherwise we will miss POST
|
346
|
+
@storage.set_unviewed(page_struct['User'], page_struct['Id'])
|
347
|
+
@storage.save(page_struct)
|
341
348
|
|
342
|
-
# inject
|
343
|
-
if headers
|
344
|
-
headers
|
349
|
+
# inject headers, script
|
350
|
+
if headers['Content-Type'] && status == 200
|
351
|
+
client_settings.write!(headers)
|
352
|
+
result = inject_profiler(env,status,headers,body)
|
353
|
+
return result if result
|
345
354
|
end
|
346
|
-
|
347
|
-
if
|
348
|
-
|
349
|
-
script = self.get_profile_script(env)
|
350
|
-
|
351
|
-
if String === body
|
352
|
-
response.write inject(body,script)
|
353
|
-
else
|
354
|
-
body.each { |fragment| response.write inject(fragment, script) }
|
355
|
-
end
|
356
|
-
body.close if body.respond_to? :close
|
357
|
-
return response.finish
|
355
|
+
rescue Exception => e
|
356
|
+
if @config.storage_failure != nil
|
357
|
+
@config.storage_failure.call(e)
|
358
358
|
end
|
359
359
|
end
|
360
360
|
|
361
361
|
client_settings.write!(headers)
|
362
362
|
[status, headers, body]
|
363
|
+
|
363
364
|
ensure
|
364
365
|
# Make sure this always happens
|
365
|
-
current = nil
|
366
|
+
self.current = nil
|
367
|
+
end
|
368
|
+
|
369
|
+
def inject_profiler(env,status,headers,body)
|
370
|
+
# mini profiler is meddling with stuff, we can not cache cause we will get incorrect data
|
371
|
+
# Rack::ETag has already inserted some nonesense in the chain
|
372
|
+
content_type = headers['Content-Type']
|
373
|
+
|
374
|
+
headers.delete('ETag')
|
375
|
+
headers.delete('Date')
|
376
|
+
headers['Cache-Control'] = 'must-revalidate, private, max-age=0'
|
377
|
+
|
378
|
+
# inject header
|
379
|
+
if headers.is_a? Hash
|
380
|
+
headers['X-MiniProfiler-Ids'] = ids_json(env)
|
381
|
+
end
|
382
|
+
|
383
|
+
if current.inject_js && content_type =~ /text\/html/
|
384
|
+
response = Rack::Response.new([], status, headers)
|
385
|
+
script = self.get_profile_script(env)
|
386
|
+
|
387
|
+
if String === body
|
388
|
+
response.write inject(body,script)
|
389
|
+
else
|
390
|
+
body.each { |fragment| response.write inject(fragment, script) }
|
391
|
+
end
|
392
|
+
body.close if body.respond_to? :close
|
393
|
+
response.finish
|
394
|
+
else
|
395
|
+
nil
|
396
|
+
end
|
366
397
|
end
|
367
398
|
|
368
399
|
def inject(fragment, script)
|
@@ -377,9 +408,9 @@ module Rack
|
|
377
408
|
regex = /<\/html>/i
|
378
409
|
close_tag = '</html>'
|
379
410
|
else
|
380
|
-
# implicit </body> and </html>.
|
411
|
+
# implicit </body> and </html>. Don't do anything.
|
381
412
|
|
382
|
-
return fragment
|
413
|
+
return fragment
|
383
414
|
end
|
384
415
|
|
385
416
|
matches = fragment.scan(regex).length
|
@@ -402,8 +433,17 @@ module Rack
|
|
402
433
|
end
|
403
434
|
end
|
404
435
|
|
405
|
-
def
|
436
|
+
def dump_exceptions(exceptions)
|
406
437
|
headers = {'Content-Type' => 'text/plain'}
|
438
|
+
body = "Exceptions (#{exceptions.length} raised during request)\n\n"
|
439
|
+
exceptions.each do |e|
|
440
|
+
body << "#{e.class} #{e.message}\n#{e.backtrace.join("\n")}\n\n\n\n"
|
441
|
+
end
|
442
|
+
|
443
|
+
[200, headers, [body]]
|
444
|
+
end
|
445
|
+
|
446
|
+
def dump_env(env)
|
407
447
|
body = "Rack Environment\n---------------\n"
|
408
448
|
env.each do |k,v|
|
409
449
|
body << "#{k}: #{v}\n"
|
@@ -414,11 +454,19 @@ module Rack
|
|
414
454
|
body << "#{k}: #{v}\n"
|
415
455
|
end
|
416
456
|
|
457
|
+
body << "\n\nRuby Version\n---------------\n"
|
458
|
+
body << "#{RUBY_VERSION} p#{RUBY_PATCHLEVEL}\n"
|
459
|
+
|
417
460
|
body << "\n\nInternals\n---------------\n"
|
418
461
|
body << "Storage Provider #{config.storage_instance}\n"
|
419
462
|
body << "User #{user(env)}\n"
|
420
463
|
body << config.storage_instance.diagnostics(user(env)) rescue "no diagnostics implemented for storage"
|
421
464
|
|
465
|
+
text_result(body)
|
466
|
+
end
|
467
|
+
|
468
|
+
def text_result(body)
|
469
|
+
headers = {'Content-Type' => 'text/plain'}
|
422
470
|
[200, headers, [body]]
|
423
471
|
end
|
424
472
|
|
@@ -432,73 +480,37 @@ module Rack
|
|
432
480
|
pp=no-backtrace #{"(*) " if client_settings.backtrace_none?}: don't collect stack traces from all the SQL executed (sticky, use pp=normal-backtrace to enable)
|
433
481
|
pp=normal-backtrace #{"(*) " if client_settings.backtrace_default?}: collect stack traces from all the SQL executed and filter normally
|
434
482
|
pp=full-backtrace #{"(*) " if client_settings.backtrace_full?}: enable full backtraces for SQL executed (use pp=normal-backtrace to disable)
|
435
|
-
pp=sample : sample stack traces and return a report isolating heavy usage (works best on Ruby 2.0)
|
436
483
|
pp=disable : disable profiling for this session
|
437
484
|
pp=enable : enable profiling for this session (if previously disabled)
|
438
485
|
pp=profile-gc: perform gc profiling on this request, analyzes ObjectSpace generated by request (ruby 1.9.3 only)
|
439
486
|
pp=profile-gc-time: perform built-in gc profiling on this request (ruby 1.9.3 only)
|
440
|
-
pp=
|
487
|
+
pp=profile-gc-ruby-head: requires the memory_profiler gem, new location based report
|
488
|
+
pp=flamegraph: works best on Ruby 2.0, a graph representing sampled activity (requires the flamegraph gem).
|
489
|
+
pp=flamegraph&flamegraph_sample_rate=1: creates a flamegraph with the specified sample rate (in ms). Overrides value set in config
|
490
|
+
pp=flamegraph_embed: works best on Ruby 2.0, a graph representing sampled activity (requires the flamegraph gem), embedded resources for use on an intranet.
|
491
|
+
pp=trace-exceptions: requires Ruby 2.0, will return all the spots where your application raises execptions
|
441
492
|
"
|
442
493
|
|
443
494
|
client_settings.write!(headers)
|
444
495
|
[200, headers, [body]]
|
445
496
|
end
|
446
497
|
|
447
|
-
def
|
448
|
-
graph = FlameGraph.new(traces)
|
449
|
-
data = graph.graph_data
|
450
|
-
|
498
|
+
def flamegraph(graph)
|
451
499
|
headers = {'Content-Type' => 'text/html'}
|
452
|
-
|
453
|
-
body = IO.read(::File.expand_path('../html/flamegraph.html', ::File.dirname(__FILE__)))
|
454
|
-
body.gsub!("/*DATA*/", ::JSON.generate(data));
|
455
|
-
|
456
|
-
[200, headers, [body]]
|
500
|
+
[200, headers, [graph]]
|
457
501
|
end
|
458
502
|
|
459
|
-
def
|
460
|
-
|
461
|
-
|
462
|
-
|
463
|
-
seen = {}
|
464
|
-
fulldump = ""
|
465
|
-
traces.each do |trace|
|
466
|
-
fulldump << "\n\n"
|
467
|
-
distinct = {}
|
468
|
-
trace.each do |frame|
|
469
|
-
frame = frame.to_s unless String === frame
|
470
|
-
unless distinct[frame]
|
471
|
-
distinct[frame] = true
|
472
|
-
seen[frame] ||= 0
|
473
|
-
seen[frame] += 1
|
474
|
-
end
|
475
|
-
fulldump << frame << "\n"
|
476
|
-
end
|
477
|
-
end
|
478
|
-
|
479
|
-
body << "\n\nStack Trace Analysis\n"
|
480
|
-
seen.to_a.sort{|x,y| y[1] <=> x[1]}.each do |name, count|
|
481
|
-
if count > traces.count / 10
|
482
|
-
body << "#{name} x #{count}\n"
|
483
|
-
end
|
484
|
-
end
|
485
|
-
|
486
|
-
body << "\n\n\nRaw traces \n"
|
487
|
-
body << fulldump
|
488
|
-
|
489
|
-
[200, headers, [body]]
|
503
|
+
def ids(env)
|
504
|
+
# cap at 10 ids, otherwise there is a chance you can blow the header
|
505
|
+
([current.page_struct["Id"]] + (@storage.get_unviewed_ids(user(env)) || [])[0..8]).uniq
|
490
506
|
end
|
491
507
|
|
492
508
|
def ids_json(env)
|
493
|
-
|
494
|
-
ids = [current.page_struct["Id"]] + (@storage.get_unviewed_ids(user(env)) || [])[0..8]
|
495
|
-
::JSON.generate(ids.uniq)
|
509
|
+
::JSON.generate(ids(env))
|
496
510
|
end
|
497
511
|
|
498
512
|
def ids_comma_separated(env)
|
499
|
-
|
500
|
-
ids = [current.page_struct["Id"]] + (@storage.get_unviewed_ids(user(env)) || [])[0..8]
|
501
|
-
ids.join(",")
|
513
|
+
ids(env).join(",")
|
502
514
|
end
|
503
515
|
|
504
516
|
# get_profile_script returns script to be injected inside current html page
|
@@ -508,26 +520,37 @@ module Rack
|
|
508
520
|
# * you have disabled auto append behaviour throught :auto_inject => false flag
|
509
521
|
# * you do not want script to be automatically appended for the current page. You can also call cancel_auto_inject
|
510
522
|
def get_profile_script(env)
|
511
|
-
|
512
|
-
|
513
|
-
|
514
|
-
|
515
|
-
|
516
|
-
|
517
|
-
|
518
|
-
|
519
|
-
|
520
|
-
|
521
|
-
|
522
|
-
|
523
|
+
|
524
|
+
settings = {
|
525
|
+
:path => "#{env['SCRIPT_NAME']}#{@config.base_url_path}",
|
526
|
+
:version => MiniProfiler::VERSION,
|
527
|
+
:position => @config.position,
|
528
|
+
:showTrivial => false,
|
529
|
+
:showChildren => false,
|
530
|
+
:maxTracesToShow => 10,
|
531
|
+
:showControls => false,
|
532
|
+
:authorized => true,
|
533
|
+
:toggleShortcut => @config.toggle_shortcut,
|
534
|
+
:startHidden => @config.start_hidden
|
535
|
+
}
|
536
|
+
|
537
|
+
if current && current.page_struct
|
538
|
+
settings[:ids] = ids_comma_separated(env)
|
539
|
+
settings[:currentId] = current.page_struct["Id"]
|
540
|
+
else
|
541
|
+
settings[:ids] = []
|
542
|
+
settings[:currentId] = ""
|
543
|
+
end
|
544
|
+
|
523
545
|
# TODO : cache this snippet
|
524
546
|
script = IO.read(::File.expand_path('../html/profile_handler.js', ::File.dirname(__FILE__)))
|
525
547
|
# replace the variables
|
526
|
-
|
527
|
-
regex = Regexp.new("\\{#{
|
528
|
-
script.gsub!(regex,
|
548
|
+
settings.each do |k,v|
|
549
|
+
regex = Regexp.new("\\{#{k.to_s}\\}")
|
550
|
+
script.gsub!(regex, v.to_s)
|
529
551
|
end
|
530
|
-
|
552
|
+
|
553
|
+
current.inject_js = false if current
|
531
554
|
script
|
532
555
|
end
|
533
556
|
|