card 1.15.4 → 1.15.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (40) hide show
  1. checksums.yaml +4 -4
  2. data/VERSION +1 -1
  3. data/config/initializers/recaptcha.rb +1 -1
  4. data/db/migrate_core_cards/20141208162106_add_ace_script.rb +2 -4
  5. data/db/migrate_core_cards/20150508212032_menu_compatibility.rb +1 -2
  6. data/db/migrate_core_cards/20150605115802_add_performance_log_card.rb +7 -0
  7. data/lib/card/content.rb +6 -0
  8. data/lib/card/log.rb +110 -17
  9. data/lib/card/query.rb +31 -21
  10. data/lib/cardio.rb +1 -0
  11. data/mod/01_core/set/all/collection.rb +42 -8
  12. data/mod/01_core/set/all/permissions.rb +21 -21
  13. data/mod/01_core/set/all/templating.rb +18 -12
  14. data/mod/01_core/spec/set/all/collection_spec.rb +7 -1
  15. data/mod/01_history/set/all/content_history.rb +14 -12
  16. data/mod/02_basic_types/set/type/pointer.rb +54 -24
  17. data/mod/03_machines/lib/javascript/wagn_mod.js.coffee +1 -1
  18. data/mod/03_machines/lib/stylesheets/style_cards.scss +3 -0
  19. data/mod/03_machines/set/type/scss.rb +5 -5
  20. data/mod/05_email/set/right/follow.rb +3 -3
  21. data/mod/05_standard/set/all/rich_html/content.rb +17 -13
  22. data/mod/05_standard/set/self/performance_log.rb +92 -0
  23. data/mod/05_standard/set/type/search_type.rb +15 -17
  24. data/spec/lib/card/content_spec.rb +12 -0
  25. metadata +4 -17
  26. data/db/seed/README.md +0 -2
  27. data/db/seed/new/card_actions.yml +0 -4495
  28. data/db/seed/new/card_acts.yml +0 -7
  29. data/db/seed/new/card_changes.yml +0 -29416
  30. data/db/seed/new/card_references.yml +0 -4348
  31. data/db/seed/new/cards.yml +0 -28134
  32. data/db/seed/test/fixtures/.gitkeep +0 -0
  33. data/db/seed/test/fixtures/card_actions.yml +0 -6336
  34. data/db/seed/test/fixtures/card_acts.yml +0 -841
  35. data/db/seed/test/fixtures/card_changes.yml +0 -34632
  36. data/db/seed/test/fixtures/card_references.yml +0 -5783
  37. data/db/seed/test/fixtures/cards.yml +0 -32803
  38. data/db/seed/test/fixtures/mao2.jpg +0 -0
  39. data/db/seed/test/fixtures/rails.gif +0 -0
  40. data/db/seed/test/seed.rb +0 -201
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4dc15d9c2c0968a351432221cb47274d695515c9
4
- data.tar.gz: 006311ea9e42182b47adc6e3a1ed434e47239c54
3
+ metadata.gz: 6aac9bc9a4a0c51d23aa1a1618373dba3c070b5b
4
+ data.tar.gz: 9526abccf7afcc74f2b8663dc8b902af7e744efe
5
5
  SHA512:
6
- metadata.gz: 897cf06f078a5deef931ec1b38d70c1690b3f97943f58987789e33c1dbea8a9d46b89c53d123196b35cb00b8b05d7c92c2fa3c8b6d6718de1863ee7f2276f217
7
- data.tar.gz: a9e1cd1a88f3da9b79b9b3b011d48e5ea64650b4e5f35945e263cd5bdc8fc14563c6f463c5acaed93f30d03a46bd01b0345e8bb076f5423845b31cc8bfa538fa
6
+ metadata.gz: cf0f29ab1c1a45f3a3f5ae3e5d086ab07f90af258260d1294a9bcbd25ce9c28cef2fbd427863574e0d52f6ecfc3ded650f8720161da07a9aee0d977ccc8b7b3c
7
+ data.tar.gz: f8a18bf5ea522c43003bbf54b96ec59dc97f794c1ace83fa80002e0c55bc3fc49ce6e6ac2cce1cefe19903986181465d7541842b00ad94d755c3b0a2d037614a
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.15.4
1
+ 1.15.5
@@ -3,5 +3,5 @@ Recaptcha.configure do |config|
3
3
  config.public_key = Cardio.config.recaptcha_public_key || nil
4
4
  config.private_key = Cardio.config.recaptcha_private_key || nil
5
5
  config.proxy = Cardio.config.recaptcha_proxy || nil
6
- config.api_version = 'v1'
6
+ config.api_version = 'v1' if config.respond_to?(:api_version=)
7
7
  end
@@ -2,10 +2,8 @@
2
2
 
3
3
  class AddAceScript < Card::CoreMigration
4
4
  def up
5
- all_script = Card[:all].fetch :trait=>:script
6
- all_script.add_item "script: ace"
7
- all_script.save!
8
-
5
+ Card[:all].fetch(:trait=>:script).add_item! "script: ace"
6
+
9
7
  Card.create! :name=>"script: ace",:codename=>"script_ace",:type=>"JavaScript"
10
8
 
11
9
  end
@@ -7,8 +7,7 @@ class MenuCompatibility < Card::CoreMigration
7
7
  bootswatch_shared = Card[:bootswatch_shared]
8
8
  Card.search(:type_id=>Card::SkinID) do |skin|
9
9
  if skin.item_cards.find { |item_card| item_card.codename.to_s == 'style_bootstrap_compatible'}
10
- skin.add_item bootswatch_shared.name
11
- skin.save!
10
+ skin.add_item! bootswatch_shared.name
12
11
  end
13
12
  end
14
13
 
@@ -0,0 +1,7 @@
1
+ # -*- encoding : utf-8 -*-
2
+
3
+ class AddPerformanceLogCard < Card::CoreMigration
4
+ def up
5
+ Card.create! :name=>'*performance log', :type_code=>:pointer, :codename=>:performance_log
6
+ end
7
+ end
@@ -179,6 +179,12 @@ class Card
179
179
  end.gsub(/<\!--.*?-->/, '')
180
180
  end
181
181
 
182
+ if Card.config.space_last_in_multispace
183
+ def clean_with_space_last! string, tags = ALLOWED_TAGS
184
+ clean_without_space_last!(string, tags).gsub(/(?:^|\b) ((?:&nbsp;)+)/, '\1 ')
185
+ end
186
+ alias_method_chain :clean!, :space_last
187
+ end
182
188
  def truncatewords_with_closing_tags(input, words = 25, truncate_string = "...")
183
189
  if input.nil? then return end
184
190
  wordlist = input.to_s.split
@@ -45,7 +45,7 @@ class Card::Log
45
45
  # config.performance_logger = {
46
46
  # :min_time => 100, # show only method calls that are slower than 100ms
47
47
  # :max_depth => 3, # show nested method calls only up to depth 3
48
- # :details=> true # show method arguments and sql
48
+ # :details=> true, # show method arguments and sql
49
49
  # :methods => [:event, :search, :fetch, :view], # choose methods to log
50
50
  # }
51
51
  #
@@ -79,7 +79,7 @@ class Card::Log
79
79
  }
80
80
 
81
81
  SPECIAL_METHODS = [:search, :view, :event] # these methods have already a Wagn.with_logging block
82
- # we don't have to monkey patch them, only turn the logging on with adding the symbol to the methods hash
82
+ # we don't have to monkey patch them, only turn the logging on with adding the symbol to the methods hash
83
83
 
84
84
 
85
85
 
@@ -91,14 +91,31 @@ class Card::Log
91
91
 
92
92
 
93
93
  class << self
94
+ def params_to_config args
95
+ args[:details] = args[:details] == 'true' ? true : false
96
+ args[:max_depth] &&= args[:max_depth].to_i
97
+ args[:min_time] &&= args[:min_time].to_i
98
+ args[:output] &&= args[:output].to_sym
99
+ if args[:methods]
100
+ if args[:methods].kind_of?(String) && args[:methods].match(/^\[.+\]$/)
101
+ args[:methods] = JSON.parse(args[:methods]).map(&:to_sym)
102
+ elsif args[:methods].kind_of?(Array)
103
+ args[:methods].map!(&:to_sym)
104
+ end
105
+ end
106
+ args
107
+ end
108
+
94
109
  def load_config args
110
+ args = params_to_config args
95
111
  @details = args[:details] || false
96
112
  @max_depth = args[:max_depth] || false
97
113
  @min_time = args[:min_time] || false
114
+ @output = args[:output] || :text
98
115
  @enabled_methods = ::Set.new
99
116
  prepare_methods_for_logging args[:methods] if args[:methods]
100
117
  end
101
-
118
+
102
119
  def start args={}
103
120
  @@current_level = 0
104
121
  @@log = []
@@ -118,7 +135,7 @@ class Card::Log
118
135
  print_log
119
136
  end
120
137
 
121
-
138
+
122
139
  def with_timer method, args, &block
123
140
  if args[:context]
124
141
 
@@ -152,7 +169,7 @@ class Card::Log
152
169
  end
153
170
  result
154
171
  end
155
-
172
+
156
173
 
157
174
  def enable_method method_name
158
175
  @enabled_methods ||= ::Set.new
@@ -166,11 +183,74 @@ class Card::Log
166
183
  private
167
184
 
168
185
  def print_log
186
+ if @output == :card && Card[:performance_log]
187
+ Card[:performance_log].add_log_entry @@log.first.message, html_log
188
+ elsif @output == :html
189
+ html_log
190
+ else
191
+ text_log
192
+ end
193
+ end
194
+
195
+ def text_log
169
196
  @@log.each do |entry|
170
197
  Rails.logger.wagn entry.to_s! if entry.valid
171
198
  end
172
199
  end
173
200
 
201
+ def html_log
202
+ @html_log ||= begin
203
+ list = @@log.inject([]) do |tree, entry|
204
+ if entry.parent
205
+ #entry.parent.children << entry
206
+ else
207
+ tree << entry
208
+ end
209
+ tree
210
+ end
211
+
212
+ list_to_accordion list
213
+ end
214
+ end
215
+
216
+ def list_to_accordion list
217
+ list.map do |entry|
218
+ if entry.children && entry.children.present?
219
+ accordion_entry entry
220
+ else
221
+ "<li class='list-group-item'>#{simple_entry entry}</li>"
222
+ end
223
+ end.join "\n"
224
+ end
225
+
226
+ def simple_entry entry
227
+ entry.to_html
228
+ end
229
+
230
+ def accordion_entry entry
231
+ panel_body = list_to_accordion entry.children
232
+ collapse_id = entry.hash.to_s
233
+ %{
234
+ <div class="panel-group" id="accordion-#{collapse_id}" role="tablist" aria-multiselectable="true">
235
+ <div class="panel panel-default #{'panel-danger' if entry.duration > 100 }">
236
+ <div class="panel-heading" role="tab" id="heading-#{collapse_id}">
237
+ <h4 class="panel-title">
238
+ <a data-toggle="collapse" data-parent="#accordion-#{collapse_id}" href="##{collapse_id}" aria-expanded="true" aria-controls="#{collapse_id}">
239
+ #{ simple_entry entry }
240
+ </a>
241
+ </h4>
242
+ </div>
243
+ <div id="#{collapse_id}" class="panel-collapse collapse #{'in' if entry.duration > 100}" role="tabpanel" aria-labelledby="heading-#{collapse_id}">
244
+ <div class="panel-body">
245
+ #{ panel_body }
246
+ </div>
247
+ </div>
248
+ </div>
249
+ </div>
250
+ }
251
+ end
252
+
253
+
174
254
  def new_entry args
175
255
  args.delete(:details) unless @details
176
256
  level = @@current_level
@@ -194,7 +274,7 @@ class Card::Log
194
274
  @@active_entries.pop
195
275
  @@current_level -= 1
196
276
  end
197
-
277
+
198
278
  def prepare_methods_for_logging args
199
279
  classes = hashify_and_verify_keys( args, DEFAULT_CLASS ) do |key|
200
280
  key.kind_of?(Class) || key.kind_of?(Module)
@@ -250,10 +330,11 @@ class Card::Log
250
330
  end
251
331
 
252
332
  end
253
-
254
-
333
+
334
+
255
335
  class Entry
256
- attr_accessor :level, :valid, :context, :parent, :children_cnt, :duration
336
+ attr_accessor :level, :valid, :context, :parent, :children_cnt, :duration, :children
337
+ attr_reader :message
257
338
 
258
339
  def initialize( parent, level, args )
259
340
  @start = Time.new
@@ -266,18 +347,22 @@ class Card::Log
266
347
  @valid = true
267
348
  @parent = parent
268
349
  @children_cnt = 0
350
+ @children = []
269
351
  if @parent
270
- @parent.add_children
352
+ @parent.add_children self
271
353
  #@sibling_nr = @parent.children_cnt
272
354
  end
273
355
  end
274
356
 
275
- def add_children
357
+ def add_children child=false
276
358
  @children_cnt += 1
359
+ @children << child if child
277
360
  end
278
361
 
279
- def delete_children
362
+ def delete_children child=false
280
363
  @children_cnt -= 1
364
+ @children.delete child if child
365
+
281
366
  end
282
367
 
283
368
  def has_younger_siblings?
@@ -290,7 +375,7 @@ class Card::Log
290
375
 
291
376
  def delete
292
377
  @valid = false
293
- @parent.delete_children if @parent
378
+ @parent.delete_children(self) if @parent
294
379
  end
295
380
 
296
381
 
@@ -313,6 +398,14 @@ class Card::Log
313
398
  msg
314
399
  end
315
400
  end
401
+ def to_html
402
+ @to_html ||= begin
403
+ msg = "<span title='#{@details}'>"
404
+ msg += @message if @message
405
+ msg += "<span class='badge #{"badge-danger" if @duration > 100}'> %d.2ms </span>" % @duration if @duration
406
+ msg += '</span>'
407
+ end
408
+ end
316
409
 
317
410
  private
318
411
 
@@ -346,8 +439,8 @@ class Card::Log
346
439
  end
347
440
 
348
441
  end
349
-
350
-
442
+
443
+
351
444
  module BigBrother
352
445
 
353
446
  def watch_method method_name, method_type=:all, options={}
@@ -430,8 +523,8 @@ class Card::Log
430
523
  end
431
524
 
432
525
  end
433
-
434
-
526
+
527
+
435
528
  end
436
529
 
437
530
  end
@@ -3,7 +3,7 @@
3
3
  class Card::Query
4
4
  require_dependency 'card/query/clause'
5
5
  require_dependency 'card/query/card_clause'
6
- require_dependency 'card/query/value_clause'
6
+ require_dependency 'card/query/value_clause'
7
7
  require_dependency 'card/query/ref_clause'
8
8
 
9
9
  MODIFIERS = {}; %w{ conj return sort sort_as group dir limit offset }.each{|key| MODIFIERS[key.to_sym] = nil }
@@ -16,43 +16,53 @@ class Card::Query
16
16
  def initialize query
17
17
  @card_clause = CardClause.build query
18
18
  end
19
-
19
+
20
20
  def query
21
21
  @card_clause.query
22
22
  end
23
-
23
+
24
24
  def sql
25
25
  @sql ||= @card_clause.to_sql
26
26
  end
27
27
 
28
28
  def run
29
- # puts "~~~~~~~~~~~~~~\nCARD SPEC =\n#{@card_clause.rawclause}\n\n-----\n\nSQL=\n#{sql}"
30
- rows = ActiveRecord::Base.connection.select_all( sql )
31
29
  retrn = query[:return].present? ? query[:return].to_s : 'card'
32
- case retrn
33
- when 'card'
34
- rows.map do |row|
35
- card=
36
- if query[:prepend] || query[:append]
37
- cardname = [query[:prepend], row['name'], query[:append]].compact.join('+')
38
- Card.fetch cardname, :new=>{}
39
- else
40
- Card[ row['name'] ]
41
- end
42
- card.nil? ? Card.find_by_name_and_trash(row['name'],false).repair_key : card
30
+ if retrn == 'card'
31
+ simple_run('name').map do |name|
32
+ Card.fetch name, :new=>{}
33
+ end
34
+ else
35
+ simple_run retrn
36
+ end
37
+ end
38
+
39
+
40
+ def simple_run retrn
41
+ rows = run_sql
42
+
43
+ case retrn
44
+ when 'name' #common case
45
+ if query[:prepend] || query[:append]
46
+ rows.map do |row|
47
+ [ query[:prepend], row['name'], query[:append] ].compact * '+'
48
+ end
49
+ else
50
+ rows.map { |row| row['name'] }
43
51
  end
44
52
  when 'count'
45
53
  rows.first['count'].to_i
46
54
  when 'raw'
47
55
  rows
56
+ when /id$/
57
+ rows.map { |row| row[retrn].to_i }
48
58
  else
49
- integer = ( retrn =~ /id$/ )
50
- rows.map do |row|
51
- integer ? row[retrn].to_i : row[retrn]
52
- end
59
+ rows.map { |row| row[retrn] }
53
60
  end
54
61
  end
55
62
 
63
+ def run_sql
64
+ ActiveRecord::Base.connection.select_all( sql )
65
+ end
56
66
 
57
67
 
58
68
  class SqlCond < String
@@ -71,7 +81,7 @@ class Card::Query
71
81
  def to_s
72
82
  select = fields.reject(&:blank?) * ', '
73
83
  where = conditions.reject(&:blank?) * ' and '
74
-
84
+
75
85
  ['(SELECT', distinct, select, 'FROM', tables, joins, 'WHERE', where, group, order, limit, offset, ')'].compact * ' '
76
86
  end
77
87
  end
@@ -48,6 +48,7 @@ module Cardio
48
48
 
49
49
  config.token_expiry = 2.days
50
50
  config.revisions_per_page = 10
51
+ config.space_last_in_multispace = true
51
52
  config.closed_search_limit = 50
52
53
  end
53
54
 
@@ -57,6 +57,27 @@ def include_item? item
57
57
  item_names.map{|name| name.to_name.key}.member? key
58
58
  end
59
59
 
60
+ def add_item item
61
+ unless include_item? item
62
+ self.content="#{self.content}\n#{name}"
63
+ end
64
+ end
65
+
66
+ def drop_item item
67
+ if include_item? item
68
+ new_names = item_names.reject{ |i| i == item }
69
+ self.content = new_names.empty? ? '' : new_names.join("\n")
70
+ end
71
+ end
72
+
73
+ def insert_item index, name
74
+ new_names = item_names
75
+ new_names.delete(name)
76
+ new_names.insert(index,name)
77
+ self.content = new_names.join "\n"
78
+ end
79
+
80
+
60
81
  def extended_item_cards context = nil
61
82
  context = (context ? context.cardname : self.cardname)
62
83
  args={ :limit=>'' }
@@ -160,18 +181,31 @@ format :html do
160
181
  view :tabs do |args|
161
182
  tab_buttons = ''
162
183
  tab_panes = ''
163
- card.item_names.each_with_index do |item, index|
184
+ Card::Content.new(card.content, card).find_chunks( Card::Chunk::Reference ).each_with_index do |item, index|
164
185
  active_tab = (index == 0)
165
- id = "#{card.cardname.safe_key}-#{item.to_name.safe_key}"
186
+ id = "#{card.cardname.safe_key}-#{item.referee_name.safe_key}"
166
187
  i_args = item_args(args)
167
188
  if @inclusion_opts
168
189
  slot_args = @inclusion_opts.clone
169
190
  slot_args.delete(:view)
191
+ if item.kind_of? Card::Chunk::Include
192
+ slot_args.merge!(item.options)
193
+ end
170
194
  i_args.merge!(:slot=>slot_args)
171
195
  end
172
- url = page_path(item.to_name, i_args)
173
- tab_buttons += tab_button( "##{id}", item, active_tab, 'data-url'=>url.html_safe, :class=>(active_tab ? nil : 'load'))
174
- tab_content = active_tab ? nest(Card.fetch(item, :new=>{}), item_args(args)) : ''
196
+ url = page_path(item.referee_name, i_args)
197
+ tab_name = (item.respond_to?(:options) && item.options[:title]) || item.name
198
+ tab_buttons += tab_button( "##{id}", tab_name, active_tab, 'data-url'=>url.html_safe, :class=>(active_tab ? nil : 'load'))
199
+ tab_content =
200
+ if active_tab
201
+ if item.kind_of? Card::Chunk::Include
202
+ item.process_chunk { |options| prepare_nest options }
203
+ else
204
+ nest(Card.fetch(item, :new=>{}), i_args)
205
+ end
206
+ else
207
+ ''
208
+ end
175
209
  tab_panes += tab_pane( id, tab_content, active_tab )
176
210
  end
177
211
  tab_panel tab_buttons, tab_panes, args[:tab_type]
@@ -181,7 +215,7 @@ format :html do
181
215
  end
182
216
 
183
217
  view :pills, :view=>:tabs
184
- def default_pill_args args
218
+ def default_pills_args args
185
219
  args[:tab_type] ||= 'pills'
186
220
  end
187
221
 
@@ -196,12 +230,12 @@ format :html do
196
230
  end
197
231
  tab_panel tab_buttons, tab_panes, args[:tab_type]
198
232
  end
199
- def default_tab_static_args args
233
+ def default_tabs_static_args args
200
234
  args[:tab_type] ||= 'tabs'
201
235
  end
202
236
 
203
237
  view :pills_static, :view=>:tabs
204
- def default_tab_static_args args
238
+ def default_tabs_static_args args
205
239
  args[:tab_type] ||= 'pills'
206
240
  end
207
241