card 1.16.4 → 1.16.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (70) hide show
  1. checksums.yaml +4 -4
  2. data/VERSION +1 -1
  3. data/db/migrate_core_cards/20150429090551_search_card_context.rb +34 -0
  4. data/db/migrate_core_cards/20150824135418_update_file_history.rb +10 -5
  5. data/db/migrate_core_cards/20150910085603_remove_performance_log_card.rb +10 -0
  6. data/db/seed/new/card_actions.yml +358 -366
  7. data/db/seed/new/card_acts.yml +1 -1
  8. data/db/seed/new/card_changes.yml +1379 -1399
  9. data/db/seed/new/card_references.yml +1109 -710
  10. data/db/seed/new/cards.yml +1436 -1454
  11. data/db/seed/test/fixtures/card_actions.yml +1031 -1039
  12. data/db/seed/test/fixtures/card_acts.yml +155 -155
  13. data/db/seed/test/fixtures/card_changes.yml +4148 -4168
  14. data/db/seed/test/fixtures/card_references.yml +1577 -1178
  15. data/db/seed/test/fixtures/cards.yml +2259 -2277
  16. data/db/version_core_cards.txt +1 -1
  17. data/lib/card.rb +3 -2
  18. data/lib/card/env.rb +66 -0
  19. data/lib/card/format.rb +3 -38
  20. data/lib/card/loader.rb +0 -4
  21. data/lib/card/location.rb +38 -0
  22. data/lib/card/set.rb +1 -3
  23. data/lib/card/success.rb +2 -3
  24. data/mod/01_core/format/html_format.rb +0 -48
  25. data/mod/01_core/set/all/collection.rb +9 -7
  26. data/mod/01_core/set/all/initialize.rb +5 -0
  27. data/mod/01_core/set/all/location_history.rb +10 -0
  28. data/mod/01_core/set/all/phases.rb +2 -1
  29. data/mod/01_core/set/all/rules.rb +0 -2
  30. data/mod/01_core/set/all/trash.rb +3 -2
  31. data/mod/01_core/set/all/utils.rb +12 -0
  32. data/mod/01_core/spec/set/all/permissions_spec.rb +8 -8
  33. data/mod/01_core/spec/set/all/type_spec.rb +14 -14
  34. data/mod/01_history/set/all/content_history.rb +7 -3
  35. data/mod/01_history/set/all/history.rb +3 -3
  36. data/mod/02_basic_types/set/type/pointer.rb +8 -1
  37. data/mod/03_machines/lib/javascript/wagn_mod.js.coffee +39 -0
  38. data/mod/03_machines/lib/stylesheets/style_cards.scss +12 -2
  39. data/mod/03_machines/set/right/machine_output.rb +4 -0
  40. data/mod/03_machines/set/type/css.rb +1 -1
  41. data/mod/04_settings/spec/set/right/structure_spec.rb +1 -1
  42. data/mod/05_email/set/all/observer.rb +5 -5
  43. data/mod/05_email/set/type_plus_right/user/follow.rb +1 -1
  44. data/mod/05_standard/file/favicon/image-icon.png +0 -0
  45. data/mod/05_standard/file/favicon/image-large.png +0 -0
  46. data/mod/05_standard/file/favicon/image-medium.png +0 -0
  47. data/mod/05_standard/file/favicon/image-original.png +0 -0
  48. data/mod/05_standard/file/favicon/image-small.png +0 -0
  49. data/mod/05_standard/lib/carrier_wave/cardmount.rb +8 -2
  50. data/mod/05_standard/lib/file_uploader.rb +47 -35
  51. data/mod/05_standard/set/abstract/attachment.rb +87 -35
  52. data/mod/05_standard/set/all/error.rb +1 -1
  53. data/mod/05_standard/set/all/links.rb +1 -0
  54. data/mod/05_standard/set/self/signin.rb +1 -1
  55. data/mod/05_standard/set/type/file.rb +16 -1
  56. data/mod/05_standard/set/type/image.rb +2 -0
  57. data/mod/05_standard/set/type/search_type.rb +2 -2
  58. data/mod/05_standard/spec/chunk/link_spec.rb +42 -32
  59. data/mod/05_standard/spec/set/all/links_spec.rb +15 -0
  60. data/mod/05_standard/spec/set/self/head_spec.rb +3 -3
  61. data/mod/05_standard/spec/set/type/email_template_spec.rb +39 -39
  62. data/mod/05_standard/spec/set/type/file_spec.rb +0 -12
  63. data/mod/05_standard/spec/set/type/image_spec.rb +26 -2
  64. data/spec/lib/card/content_spec.rb +169 -154
  65. data/spec/lib/card/format_spec.rb +7 -7
  66. data/spec/lib/card/success_spec.rb +1 -1
  67. metadata +7 -6
  68. data/lib/card/log.rb +0 -545
  69. data/mod/05_standard/set/self/performance_log.rb +0 -92
  70. data/spec/lib/card/log_spec.rb +0 -270
@@ -10,24 +10,24 @@ describe Card::Format do
10
10
  expect(format.show_view?( :menu, :default_visibility=>:hide )).to be_falsey
11
11
  expect(format.show_view?( :menu, {} )).to be_truthy
12
12
  end
13
-
13
+
14
14
  it "should respect developer default overrides" do
15
15
  expect(format.show_view?( :menu, :optional_menu=>:show, :default_visibility=>:hide )).to be_truthy
16
16
  expect(format.show_view?( :menu, :optional_menu=>:hide, :default_visibility=>:show )).to be_falsey
17
17
  expect(format.show_view?( :menu, :optional_menu=>:hide )).to be_falsey
18
18
  end
19
-
19
+
20
20
  it "should handle args from inclusions" do
21
21
  expect(format.show_view?( :menu, :show=>'menu', :default_visibility=>:hide )).to be_truthy
22
22
  expect(format.show_view?( :menu, :hide=>'menu, paging', :default_visibility=>:show )).to be_falsey
23
- expect(format.show_view?( :menu, :show=>'menu', :optional_menu=>:hide )).to be_truthy
23
+ expect(format.show_view?( :menu, :show=>'menu', :optional_menu=>:hide )).to be_truthy
24
24
  end
25
-
25
+
26
26
  it "should handle hard developer overrides" do
27
27
  expect(format.show_view?( :menu, :optional_menu=>:always, :hide=>'menu' )).to be_truthy
28
28
  expect(format.show_view?( :menu, :optional_menu=>:never, :show=>'menu' )).to be_falsey
29
29
  end
30
-
30
+
31
31
  end
32
32
 
33
33
  describe 'format helpers and link building' do
@@ -61,11 +61,11 @@ describe Card::Format do
61
61
 
62
62
  it "should format html links" do
63
63
  cobj = Card::Content.new url_text1, html_format
64
- expect(cobj.to_s).to eq "with external free link <a class=\"external-link\" href=\"http://localhost:2020/path?cgi=foo&amp;bar=baz\">http://localhost:2020/path?cgi=foo&bar=baz</a>"
64
+ expect(cobj.to_s).to eq "with external free link <a target=\"_blank\" class=\"external-link\" href=\"http://localhost:2020/path?cgi=foo&amp;bar=baz\">http://localhost:2020/path?cgi=foo&bar=baz</a>"
65
65
  cobj = Card::Content.new url_text2+url_text3+url_text4, html_format
66
66
  expect(cobj.to_s).to eq url_text2+url_text3+url_text4
67
67
  cobj = Card::Content.new url_text5, html_format
68
- expect(cobj.to_s).to eq "external with port: <a class=\"external-link\" href=\"http://localhost:2020/path?cgi=foo+bar=baz\">http://localhost:2020/path?cgi=foo+bar=baz</a> after "
68
+ expect(cobj.to_s).to eq "external with port: <a target=\"_blank\" class=\"external-link\" href=\"http://localhost:2020/path?cgi=foo+bar=baz\">http://localhost:2020/path?cgi=foo+bar=baz</a> after "
69
69
  end
70
70
 
71
71
  it "formats page_path" do
@@ -5,8 +5,8 @@ describe Card::Success do
5
5
  let(:previous) { '/B' }
6
6
  let(:home) { Card['Home'] }
7
7
  def success_params params
8
+ Card::Env.save_location Card['B']
8
9
  @success = Card::Success.new(context, params)
9
- @success.stub(:previous_location) { previous }
10
10
  end
11
11
  describe '#target' do
12
12
  subject { @success.target }
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: card
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.16.4
4
+ version: 1.16.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ethan McCutchen
@@ -11,7 +11,7 @@ authors:
11
11
  autorequire:
12
12
  bindir: bin
13
13
  cert_chain: []
14
- date: 2015-09-07 00:00:00.000000000 Z
14
+ date: 2015-09-19 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: smartname
@@ -291,6 +291,7 @@ files:
291
291
  - db/migrate_core_cards/20150317162412_bootstrap_themes.rb
292
292
  - db/migrate_core_cards/20150326205655_bootswatch_themes.rb
293
293
  - db/migrate_core_cards/20150331135745_new_card_menu.rb
294
+ - db/migrate_core_cards/20150429090551_search_card_context.rb
294
295
  - db/migrate_core_cards/20150508212032_menu_compatibility.rb
295
296
  - db/migrate_core_cards/20150510031118_fix_skin_images.rb
296
297
  - db/migrate_core_cards/20150528084659_add_session_cardtype.rb
@@ -304,6 +305,7 @@ files:
304
305
  - db/migrate_core_cards/20150807205221_create_references_for_search_cards.rb
305
306
  - db/migrate_core_cards/20150824135418_update_file_history.rb
306
307
  - db/migrate_core_cards/20150903130006_attachment_upload_cards.rb
308
+ - db/migrate_core_cards/20150910085603_remove_performance_log_card.rb
307
309
  - db/migrate_core_cards/data/1.11_help_text.json
308
310
  - db/migrate_core_cards/data/1.12_stylesheets/classic_cards.scss
309
311
  - db/migrate_core_cards/data/1.12_stylesheets/common.scss
@@ -390,7 +392,7 @@ files:
390
392
  - lib/card/exceptions.rb
391
393
  - lib/card/format.rb
392
394
  - lib/card/loader.rb
393
- - lib/card/log.rb
395
+ - lib/card/location.rb
394
396
  - lib/card/mailer.rb
395
397
  - lib/card/migration.rb
396
398
  - lib/card/name.rb
@@ -443,6 +445,7 @@ files:
443
445
  - mod/01_core/set/all/fetch.rb
444
446
  - mod/01_core/set/all/haml.rb
445
447
  - mod/01_core/set/all/initialize.rb
448
+ - mod/01_core/set/all/location_history.rb
446
449
  - mod/01_core/set/all/name.rb
447
450
  - mod/01_core/set/all/pattern.rb
448
451
  - mod/01_core/set/all/permissions.rb
@@ -702,7 +705,6 @@ files:
702
705
  - mod/05_standard/set/self/head.rb
703
706
  - mod/05_standard/set/self/navbox.rb
704
707
  - mod/05_standard/set/self/now.rb
705
- - mod/05_standard/set/self/performance_log.rb
706
708
  - mod/05_standard/set/self/recent.rb
707
709
  - mod/05_standard/set/self/search.rb
708
710
  - mod/05_standard/set/self/signin.rb
@@ -740,6 +742,7 @@ files:
740
742
  - mod/05_standard/spec/set/all/error_spec.rb
741
743
  - mod/05_standard/spec/set/all/event_viz_spec.rb
742
744
  - mod/05_standard/spec/set/all/history_spec.rb
745
+ - mod/05_standard/spec/set/all/links_spec.rb
743
746
  - mod/05_standard/spec/set/all/rich_html/editing_spec.rb
744
747
  - mod/05_standard/spec/set/all/rich_html/form_spec.rb
745
748
  - mod/05_standard/spec/set/all/rich_html/wrapper_spec.rb
@@ -955,7 +958,6 @@ files:
955
958
  - spec/lib/card/diff_spec.rb
956
959
  - spec/lib/card/format_spec.rb
957
960
  - spec/lib/card/loader_spec.rb
958
- - spec/lib/card/log_spec.rb
959
961
  - spec/lib/card/name_spec.rb
960
962
  - spec/lib/card/query_spec.rb
961
963
  - spec/lib/card/reference_spec.rb
@@ -1184,7 +1186,6 @@ test_files:
1184
1186
  - spec/lib/card/diff_spec.rb
1185
1187
  - spec/lib/card/format_spec.rb
1186
1188
  - spec/lib/card/loader_spec.rb
1187
- - spec/lib/card/log_spec.rb
1188
1189
  - spec/lib/card/name_spec.rb
1189
1190
  - spec/lib/card/query_spec.rb
1190
1191
  - spec/lib/card/reference_spec.rb
@@ -1,545 +0,0 @@
1
- require 'csv'
2
-
3
- class Card::Log
4
-
5
- class Request
6
-
7
- def self.path
8
- path = (Card.paths['request_log'] && Card.paths['request_log'].first) || File.dirname(Card.paths['log'].first)
9
- filename = "#{Date.today}_#{Rails.env}.csv"
10
- File.join path, filename
11
- end
12
-
13
- def self.write_log_entry controller
14
- return if controller.env["REQUEST_URI"] =~ %r{^/files?/}
15
-
16
- controller.instance_eval do
17
- log = []
18
- log << (Card::Env.ajax? ? "YES" : "NO")
19
- log << env["REMOTE_ADDR"]
20
- log << Card::Auth.current_id
21
- log << card.name
22
- log << action_name
23
- log << params['view'] || (s = params['success'] and s['view'])
24
- log << env["REQUEST_METHOD"]
25
- log << status
26
- log << env["REQUEST_URI"]
27
- log << DateTime.now.to_s
28
- log << env['HTTP_ACCEPT_LANGUAGE'].to_s.scan(/^[a-z]{2}/).first
29
- log << env["HTTP_REFERER"]
30
-
31
- File.open(Card::Log::Request.path, "a") do |f|
32
- f.write CSV.generate_line(log)
33
- end
34
- end
35
- end
36
-
37
- end
38
-
39
-
40
- class Performance
41
- # To enable logging add a performance_logger hash to your configuration
42
- #
43
- # Example:
44
- # config.performance_logger = {
45
- # :min_time => 100, # show only method calls that are slower than 100ms
46
- # :max_depth => 3, # show nested method calls only up to depth 3
47
- # :details=> true, # show method arguments and sql
48
- # :methods => [:event, :search, :fetch, :view], # choose methods to log
49
- # :log_level => :info
50
- # }
51
- #
52
- # If you give :methods a hash you can log arbitrary methods. The syntax is as follows:
53
- # class => method type => method name => log options
54
- #
55
- # Example:
56
- # Card => {
57
- # :instance => [ :fetch, :search ],
58
- # :singleton => { :fetch => { :title => 'Card.fetch' } },
59
- # :all => {
60
- # :fetch => {
61
- # :message => 2 # use second argument passed to fetch
62
- # :details => :to_s # use return value of to_s in method context
63
- # :title => proc { |method_context| method_context.name }
64
- # },
65
- # },
66
- # },
67
- #
68
- # class, method type and log options are optional.
69
- # Default values are 'Card', ':all' and { :title => method name, :message => first argument, :details=> remaining arguments }.
70
- # For example [:fetch] is equivalent to Card => { :all => { :fetch => { :message=>1, :details=>1..-1 } }
71
-
72
- DEFAULT_CLASS = Card
73
- DEFAULT_METHOD_TYPE = :all
74
- DEFAULT_LOG_LEVEL = :info
75
- DEFAULT_METHOD_OPTIONS = {
76
- :title => :method_name,
77
- :message => 1,
78
- :details => 1..-1,
79
- :context => nil
80
- }
81
-
82
- SPECIAL_METHODS = [:search, :view, :event] # these methods have already a Wagn.with_logging block
83
- # we don't have to monkey patch them, only turn the logging on with adding the symbol to the methods hash
84
-
85
-
86
-
87
- TAB_SIZE = 3
88
- @@log = []
89
- @@context_entries = []
90
- @@active_entries = []
91
- @@current_level = 0
92
-
93
-
94
- class << self
95
- def params_to_config args
96
- args[:details] = args[:details] == 'true' ? true : false
97
- args[:max_depth] &&= args[:max_depth].to_i
98
- args[:min_time] &&= args[:min_time].to_i
99
- args[:output] &&= args[:output].to_sym
100
- if args[:methods]
101
- if args[:methods].kind_of?(String) && args[:methods].match(/^\[.+\]$/)
102
- args[:methods] = JSON.parse(args[:methods]).map(&:to_sym)
103
- elsif args[:methods].kind_of?(Array)
104
- args[:methods].map!(&:to_sym)
105
- end
106
- end
107
- args
108
- end
109
-
110
- def load_config args
111
- args = params_to_config args
112
- @details = args[:details] || false
113
- @max_depth = args[:max_depth] || false
114
- @min_time = args[:min_time] || false
115
- @log_level = args[:log_level] || DEFAULT_LOG_LEVEL
116
- @output = args[:output] || :text
117
- @enabled_methods = ::Set.new
118
- prepare_methods_for_logging args[:methods] if args[:methods]
119
- end
120
-
121
- def start args={}
122
- @@current_level = 0
123
- @@log = []
124
- @@context_entries = []
125
- @@active_entries = []
126
- @@first_entry = new_entry(args)
127
- end
128
-
129
- def stop
130
- while (entry = @@context_entries.pop) do
131
- finish_entry entry
132
- end
133
- if @@first_entry
134
- @@first_entry.save_duration
135
- finish_entry @@first_entry
136
- end
137
- print_log
138
- end
139
-
140
-
141
- def with_timer method, args, &block
142
- if args[:context]
143
-
144
- # if the previous context was created by an entry on the same level
145
- # then finish the current context if it's a different context
146
- if @@context_entries.last && @@current_level == @@context_entries.last.level+1 &&
147
- args[:context] != @@context_entries.last.context
148
- finish_entry @@context_entries.pop
149
- end
150
-
151
- # start new context if it's different from the parent context
152
- if @@context_entries.empty? || args[:context] != @@context_entries.last.context
153
- @@context_entries << new_entry( :title=>'process', :message=>args[:context], :context=>args[:context] )
154
- end
155
- end
156
-
157
- timer = new_entry args.merge(:method=>method )
158
- begin
159
- result = block.call
160
- ensure
161
- timer.save_duration
162
- finish_entry timer
163
-
164
- # finish all deeper nested contexts
165
- while @@context_entries.last && @@context_entries.last.level >= @@current_level
166
- finish_entry @@context_entries.pop
167
- end
168
- # we don't know whether the next entry will belong to the same context or will start a new one
169
- # so we save the time
170
- @@context_entries.last.save_duration if @@context_entries.last
171
- end
172
- result
173
- end
174
-
175
-
176
- def enable_method method_name
177
- @enabled_methods ||= ::Set.new
178
- @enabled_methods << method_name
179
- end
180
-
181
- def enabled_method? method_name
182
- @enabled_methods && @enabled_methods.include?(method_name)
183
- end
184
-
185
- private
186
-
187
- def print_log
188
- if @output == :card && Card[:performance_log]
189
- Card[:performance_log].add_log_entry @@log.first.message, html_log
190
- elsif @output == :html
191
- html_log
192
- else
193
- text_log
194
- end
195
- end
196
-
197
- def text_log
198
- @@log.each do |entry|
199
- Rails.logger.send @log_level, entry.to_s! if entry.valid
200
- end
201
- end
202
-
203
- def html_log
204
- @html_log ||= begin
205
- list = @@log.inject([]) do |tree, entry|
206
- if entry.parent
207
- #entry.parent.children << entry
208
- else
209
- tree << entry
210
- end
211
- tree
212
- end
213
-
214
- list_to_accordion list
215
- end
216
- end
217
-
218
- def list_to_accordion list
219
- list.map do |entry|
220
- if entry.children && entry.children.present?
221
- accordion_entry entry
222
- else
223
- "<li class='list-group-item'>#{simple_entry entry}</li>"
224
- end
225
- end.join "\n"
226
- end
227
-
228
- def simple_entry entry
229
- entry.to_html
230
- end
231
-
232
- def accordion_entry entry
233
- panel_body = list_to_accordion entry.children
234
- collapse_id = entry.hash.to_s
235
- %{
236
- <div class="panel-group" id="accordion-#{collapse_id}" role="tablist" aria-multiselectable="true">
237
- <div class="panel panel-default #{'panel-danger' if entry.duration > 100 }">
238
- <div class="panel-heading" role="tab" id="heading-#{collapse_id}">
239
- <h4 class="panel-title">
240
- <a data-toggle="collapse" data-parent="#accordion-#{collapse_id}" href="##{collapse_id}" aria-expanded="true" aria-controls="#{collapse_id}">
241
- #{ simple_entry entry }
242
- </a>
243
- </h4>
244
- </div>
245
- <div id="#{collapse_id}" class="panel-collapse collapse #{'in' if entry.duration > 100}" role="tabpanel" aria-labelledby="heading-#{collapse_id}">
246
- <div class="panel-body">
247
- #{ panel_body }
248
- </div>
249
- </div>
250
- </div>
251
- </div>
252
- }
253
- end
254
-
255
-
256
- def new_entry args
257
- args.delete(:details) unless @details
258
- level = @@current_level
259
-
260
- last_entry = @@active_entries.last
261
- parent = if last_entry
262
- last_entry.level == level ? last_entry.parent : last_entry
263
- end
264
-
265
- @@log << Card::Log::Performance::Entry.new(parent, level, args )
266
- @@current_level += 1
267
- @@active_entries << @@log.last
268
-
269
- @@log.last
270
- end
271
-
272
- def finish_entry entry
273
- if (@max_depth && entry.level > @max_depth) || (@min_time && entry.duration < @min_time)
274
- entry.delete
275
- end
276
- @@active_entries.pop
277
- @@current_level -= 1
278
- end
279
-
280
- def prepare_methods_for_logging args
281
- classes = hashify_and_verify_keys( args, DEFAULT_CLASS ) do |key|
282
- key.kind_of?(Class) || key.kind_of?(Module)
283
- end
284
-
285
- classes.each do |klass, method_types|
286
- klass.extend BigBrother # add watch methods
287
-
288
- method_types = hashify_and_verify_keys( method_types, DEFAULT_METHOD_TYPE ) do |key|
289
- [:all, :instance, :singleton].include? key
290
- end
291
-
292
- method_types.each do |method_type, methods|
293
- methods = hashify_and_verify_keys methods
294
- methods.each do |method_name, options|
295
- klass.watch_method method_name, method_type, DEFAULT_METHOD_OPTIONS.merge(options)
296
- end
297
- end
298
-
299
- end
300
- end
301
-
302
-
303
- def hashify_and_verify_keys args, default_key=nil
304
- if default_key
305
- case args
306
- when Symbol
307
- { default_key => [ args ] }
308
- when Array
309
- { default_key => args }
310
- when Hash
311
- if block_given?
312
- args.keys.select{ |key| !(yield(key)) }.each do |key|
313
- args[default_key] = { key => args[key] }
314
- args.delete key
315
- end
316
- end
317
- args
318
- end
319
- else
320
- case args
321
- when Symbol
322
- { args => {} }
323
- when Array
324
- args.inject({}) do |h, key|
325
- h[key] = {}
326
- h
327
- end
328
- else
329
- args
330
- end
331
- end
332
- end
333
-
334
- end
335
-
336
-
337
- class Entry
338
- attr_accessor :level, :valid, :context, :parent, :children_cnt, :duration, :children
339
- attr_reader :message
340
-
341
- def initialize( parent, level, args )
342
- @start = Time.new
343
- @message = "#{ args[:title] || args[:method] || '' }"
344
- @message += ": #{ args[:message] }" if args[:message]
345
- @details = args[:details]
346
- @context = args[:context]
347
- @level = level
348
- @duration = nil
349
- @valid = true
350
- @parent = parent
351
- @children_cnt = 0
352
- @children = []
353
- if @parent
354
- @parent.add_children self
355
- #@sibling_nr = @parent.children_cnt
356
- end
357
- end
358
-
359
- def add_children child=false
360
- @children_cnt += 1
361
- @children << child if child
362
- end
363
-
364
- def delete_children child=false
365
- @children_cnt -= 1
366
- @children.delete child if child
367
-
368
- end
369
-
370
- def has_younger_siblings?
371
- @parent && @parent.children_cnt > 0 #@sibling_nr
372
- end
373
-
374
- def save_duration
375
- @duration = (Time.now - @start) * 1000
376
- end
377
-
378
- def delete
379
- @valid = false
380
- @parent.delete_children(self) if @parent
381
- end
382
-
383
-
384
- # deletes the children counts in order to print the tree;
385
- # must be called in the right order
386
- #
387
- # More robuts but more expensive approach: use @sibling_nr instead of counting @children_cnt down,
388
- # but @sibling_nr has to be updated for all siblings of an entry if the entry gets deleted due to
389
- # min_time or max_depth restrictions in the config, so we have to save all children relations for that
390
- def to_s!
391
- @to_s ||= begin
392
- msg = indent
393
- msg += "(%d.2ms) " % @duration if @duration
394
- msg += @message if @message
395
-
396
- if @details
397
- msg += ", " + @details.to_s.gsub( "\n", "\n#{ indent(false) }#{' '* TAB_SIZE}" )
398
- end
399
- @parent.delete_children if @parent
400
- msg
401
- end
402
- end
403
- def to_html
404
- @to_html ||= begin
405
- msg = "<span title='#{@details}'>"
406
- msg += @message if @message
407
- msg += "<span class='badge #{"badge-danger" if @duration > 100}'> %d.2ms </span>" % @duration if @duration
408
- msg += '</span>'
409
- end
410
- end
411
-
412
- private
413
-
414
- def indent link=true
415
- @indent ||= begin
416
- if @level == 0
417
- "\n"
418
- else
419
- res = ' '
420
- res += (1..level-1).inject('') do |msg, index|
421
- if younger_siblings[index]
422
- msg << '|' + ' ' * (TAB_SIZE-1)
423
- else
424
- msg << ' ' * TAB_SIZE
425
- end
426
- end
427
-
428
- res += link ? '|--' : ' '
429
- end
430
- end
431
- end
432
-
433
- def younger_siblings
434
- res = []
435
- next_parent = self
436
- while (next_parent)
437
- res << next_parent.has_younger_siblings?
438
- next_parent = next_parent.parent
439
- end
440
- res.reverse
441
- end
442
-
443
- end
444
-
445
-
446
- module BigBrother
447
-
448
- def watch_method method_name, method_type=:all, options={}
449
- Card::Log::Performance.enable_method method_name
450
-
451
- if !SPECIAL_METHODS.include? method_name
452
- if method_type == :all || method_type == :singleton
453
- add_singleton_logging method_name, options
454
- end
455
- if method_type == :all || method_type == :instance
456
- add_instance_logging method_name, options
457
- end
458
- end
459
- end
460
-
461
- def watch_instance_method *names
462
- names.each do |name|
463
- watch_method name, :instance
464
- end
465
- end
466
-
467
- def watch_singleton_method *names
468
- names.each do |name|
469
- watch_method name, :singleton
470
- end
471
- end
472
-
473
- def watch_all_instance_methods
474
- watch_instance_method *instance_methods
475
- end
476
-
477
- def watch_all_singleton_methods
478
- fragile_methods = [:default_scope, :default_scopes, :default_scopes=] # if I touch these methods ActiveRecord breaks
479
- watch_singleton_method *(singleton_methods - fragile_methods)
480
- end
481
-
482
- def watch_all_methods
483
- watch_all_instance_methods
484
- watch_all_singleton_methods
485
- end
486
-
487
- private
488
-
489
- def add_singleton_logging method_name, options
490
- return unless singleton_class.method_defined? method_name
491
- m = method(method_name)
492
- add_logging method_name, :define_singleton_method, options do |bind_object, args, &block|
493
- m.call(*args, &block)
494
- end
495
- end
496
-
497
- def add_instance_logging method_name, options
498
- return unless method_defined? method_name
499
- m = instance_method(method_name)
500
- add_logging method_name, :define_method, options do |bind_object, args, &block|
501
- m.bind(bind_object).(*args, &block)
502
- end
503
- end
504
-
505
- def add_logging method_name, define_method, options, &bind_block
506
- send(define_method, method_name) do |*args, &block|
507
- log_args = {}
508
- options.each do |key,value|
509
- log_args[key] = case value
510
- when Integer then args[value-1]
511
- when Range then args[value]
512
- when Symbol then eval(value.to_s)
513
- when Proc then value.call(self)
514
- else value
515
- end
516
- end
517
- Card::Log::Performance.with_timer(method_name, log_args) do
518
- bind_block.call(self, args, &block)
519
- end
520
- end
521
- end
522
-
523
- def log_options_variable_name method_name, define_method
524
- "@_#{self.class.name}_#{method_name.hash.to_s.sub(/^-/,'_')}_#{define_method}_logging_options".to_sym
525
- end
526
-
527
- end
528
-
529
-
530
- end
531
-
532
- end
533
-
534
- class Card
535
- def self.with_logging method, opts, &block
536
- if Card::Log::Performance.enabled_method? method
537
- Card::Log::Performance.with_timer(method, opts) do
538
- block.call
539
- end
540
- else
541
- block.call
542
- end
543
- end
544
- end
545
-