wagn 1.14.1 → 1.14.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.tm_properties +2 -1
- data/VERSION +1 -1
- data/app/controllers/card_controller.rb +4 -3
- data/db/bootstrap/card_acts.yml +1 -1
- data/db/bootstrap/cards.yml +1028 -1028
- data/db/migrate_core_cards/20140629222005_add_email_cards.rb +2 -25
- data/db/migrate_core_cards/20141204061304_watchers_to_following.rb +38 -0
- data/db/version_core_cards.txt +1 -1
- data/features/history.feature +21 -0
- data/features/step_definitions/history_steps.rb +3 -0
- data/features/step_definitions/wagn_steps.rb +10 -1
- data/lib/card/act.rb +2 -2
- data/lib/card/action.rb +9 -9
- data/lib/card/diff.rb +370 -211
- data/lib/card/exceptions.rb +2 -0
- data/lib/card/format.rb +5 -3
- data/lib/card/query.rb +4 -4
- data/lib/card/query/card_spec.rb +69 -51
- data/lib/card/set.rb +3 -2
- data/lib/wagn.rb +15 -3
- data/lib/wagn/all.rb +1 -3
- data/lib/wagn/application.rb +10 -1
- data/lib/wagn/generators/wagn/templates/Gemfile +6 -1
- data/lib/wagn/log.rb +69 -0
- data/lib/wagn/tasks/wagn.rake +1 -1
- data/mod/01_core/set/all/collection.rb +8 -5
- data/mod/01_core/set/all/content.rb +1 -1
- data/mod/01_core/set/all/fetch.rb +34 -32
- data/mod/01_core/set/all/notify.rb +2 -2
- data/mod/01_core/set/all/phases.rb +5 -0
- data/mod/01_core/set/all/trash.rb +1 -1
- data/mod/02_basic_types/set/type/pointer.rb +4 -0
- data/mod/03_machines/set/type/coffee_script.rb +10 -0
- data/mod/03_machines/set/type/css.rb +9 -0
- data/mod/03_machines/set/type/java_script.rb +5 -0
- data/mod/03_machines/set/type/scss.rb +8 -2
- data/mod/05_standard/set/all/history.rb +10 -1
- data/mod/05_standard/set/type/html.rb +4 -0
- data/mod/05_standard/spec/set/all/base_spec.rb +2 -0
- data/mod/05_standard/spec/set/all/history_spec.rb +12 -0
- data/mod/06_email/set/all/email_html.rb +0 -4
- data/mod/06_email/set/type/email_template.rb +6 -2
- data/spec/lib/card/diff_spec.rb +207 -107
- data/spec/lib/card/query_spec.rb +14 -13
- data/test/fixtures/card_actions.yml +21 -0
- data/test/fixtures/card_acts.yml +103 -85
- data/test/fixtures/card_changes.yml +53 -23
- data/test/fixtures/cards.yml +1349 -1331
- data/test/seed.rb +5 -1
- metadata +8 -3
- data/lib/wagn/config/initializers/airbrake.rb +0 -9
data/lib/card/exceptions.rb
CHANGED
data/lib/card/format.rb
CHANGED
@@ -183,7 +183,9 @@ class Card
|
|
183
183
|
@current_view = view = ok_view canonicalize_view( view ), args
|
184
184
|
args = default_render_args view, args
|
185
185
|
with_inclusion_mode view do
|
186
|
-
|
186
|
+
Wagn.with_logging card.name, :view, view, args do
|
187
|
+
send "_view_#{ view }", args
|
188
|
+
end
|
187
189
|
end
|
188
190
|
end
|
189
191
|
rescue => e
|
@@ -244,9 +246,9 @@ class Card
|
|
244
246
|
if Rails.env =~ /^cucumber|test$/
|
245
247
|
raise e
|
246
248
|
else
|
247
|
-
controller.send :notify_airbrake, e if Airbrake.configuration.api_key
|
248
249
|
Rails.logger.info "\nError rendering #{error_cardname} / #{view}: #{e.class} : #{e.message}"
|
249
|
-
|
250
|
+
Card::Error.current = e
|
251
|
+
card.notable_exception_raised
|
250
252
|
rendering_error e, view
|
251
253
|
end
|
252
254
|
end
|
data/lib/card/query.rb
CHANGED
@@ -27,6 +27,7 @@ class Card::Query
|
|
27
27
|
end
|
28
28
|
|
29
29
|
def run
|
30
|
+
# puts "~~~~~~~~~~~~~~\nCARD SPEC =\n#{@card_spec.rawspec}\n\n-----\n\nSQL=\n#{sql}"
|
30
31
|
rows = ActiveRecord::Base.connection.select_all( sql )
|
31
32
|
retrn = query[:return].present? ? query[:return].to_s : 'card'
|
32
33
|
case retrn
|
@@ -66,10 +67,9 @@ class Card::Query
|
|
66
67
|
end
|
67
68
|
|
68
69
|
def to_s
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
)"
|
70
|
+
select = fields.reject(&:blank?) * ', '
|
71
|
+
where = conditions.reject(&:blank?) * ' and '
|
72
|
+
['(SELECT', select, 'FROM', tables, joins, 'WHERE', where, group, order, limit, offset, ')'].compact * ' '
|
73
73
|
end
|
74
74
|
end
|
75
75
|
|
data/lib/card/query/card_spec.rb
CHANGED
@@ -17,7 +17,7 @@ class Card
|
|
17
17
|
CONJUNCTIONS = { :any=>:or, :in=>:or, :or=>:or, :all=>:and, :and=>:and }
|
18
18
|
|
19
19
|
attr_reader :sql, :query, :rawspec, :selfname
|
20
|
-
attr_accessor :joins
|
20
|
+
attr_accessor :joins, :join_count
|
21
21
|
|
22
22
|
class << self
|
23
23
|
def build query
|
@@ -185,7 +185,7 @@ class Card
|
|
185
185
|
#~~~~~~ RELATIONAL
|
186
186
|
|
187
187
|
def type val
|
188
|
-
|
188
|
+
restrict :type_id, val
|
189
189
|
end
|
190
190
|
|
191
191
|
def part val
|
@@ -193,12 +193,13 @@ class Card
|
|
193
193
|
subcondition :left=>val, :right=>right, :conj=>:or
|
194
194
|
end
|
195
195
|
|
196
|
+
|
196
197
|
def left val
|
197
|
-
|
198
|
+
restrict :left_id, val
|
198
199
|
end
|
199
200
|
|
200
201
|
def right val
|
201
|
-
|
202
|
+
restrict :right_id, val
|
202
203
|
end
|
203
204
|
|
204
205
|
def editor_of val
|
@@ -210,19 +211,19 @@ class Card
|
|
210
211
|
end
|
211
212
|
|
212
213
|
def last_editor_of val
|
213
|
-
|
214
|
+
restrict_by_join :id, val, :return=>'updater_id'
|
214
215
|
end
|
215
216
|
|
216
217
|
def last_edited_by val
|
217
|
-
|
218
|
+
restrict :updater_id, val
|
218
219
|
end
|
219
220
|
|
220
221
|
def creator_of val
|
221
|
-
|
222
|
+
restrict_by_join :id, val, :return=>'creator_id'
|
222
223
|
end
|
223
224
|
|
224
225
|
def created_by val
|
225
|
-
|
226
|
+
restrict :creator_id, val
|
226
227
|
end
|
227
228
|
|
228
229
|
def member_of val
|
@@ -236,18 +237,21 @@ class Card
|
|
236
237
|
|
237
238
|
#~~~~~~ PLUS RELATIONAL
|
238
239
|
|
239
|
-
def left_plus
|
240
|
-
|
241
|
-
merge( field(:id) => subspec(junc_spec, :return=>'right_id', :left =>part_spec))
|
240
|
+
def left_plus val
|
241
|
+
junction :left, val
|
242
242
|
end
|
243
243
|
|
244
|
-
def right_plus
|
245
|
-
|
246
|
-
merge( field(:id) => subspec(junc_spec, :return=>'left_id', :right=> part_spec ))
|
244
|
+
def right_plus val
|
245
|
+
junction :right, val
|
247
246
|
end
|
248
247
|
|
249
|
-
def plus
|
250
|
-
|
248
|
+
def plus val
|
249
|
+
any( { :left_plus=>val, :right_plus=>val.deep_clone } )
|
250
|
+
end
|
251
|
+
|
252
|
+
def junction side, val
|
253
|
+
part_spec, junction_spec = val.is_a?(Array) ? val : [ val, {} ]
|
254
|
+
restrict_by_join :id, junction_spec, side=>part_spec, :return=>"#{ side==:left ? :right : :left}_id"
|
251
255
|
end
|
252
256
|
|
253
257
|
|
@@ -280,23 +284,23 @@ class Card
|
|
280
284
|
unless c && [SearchTypeID,SetID].include?(c.type_id)
|
281
285
|
raise BadQuery, %{"found_by" value needs to be valid Search, but #{c.name} is a #{c.type_name}}
|
282
286
|
end
|
283
|
-
|
284
|
-
merge(field(:id) => subspec(found_by_spec))
|
287
|
+
restrict_by_join :id, CardSpec.new(c.get_spec).rawspec
|
285
288
|
end
|
286
289
|
end
|
287
290
|
|
288
291
|
def not val
|
289
|
-
|
292
|
+
subselect = CardSpec.build(:return=>:id, :_parent=>self).merge(val).to_sql
|
293
|
+
join_alias = add_join :not, subselect, :id, :id, :side=>'LEFT'
|
294
|
+
merge field(:cond) => SqlCond.new("#{join_alias}.id is null")
|
290
295
|
end
|
291
296
|
|
292
297
|
def sort val
|
293
298
|
return nil if @parent
|
294
299
|
val[:return] = val[:return] ? safe_sql(val[:return]) : 'db_content'
|
295
|
-
@mods[:sort] = "t_sort.#{val[:return]}"
|
296
300
|
item = val.delete(:item) || 'left'
|
297
301
|
|
298
302
|
if val[:return] == 'count'
|
299
|
-
cs_args = { :return=>'count', :group=>'sort_join_field' }
|
303
|
+
cs_args = { :return=>'count', :group=>'sort_join_field', :_parent=>self }
|
300
304
|
@mods[:sort] = "coalesce(#{@mods[:sort]},0)"
|
301
305
|
case item
|
302
306
|
when 'referred_to'
|
@@ -316,7 +320,9 @@ class Card
|
|
316
320
|
end
|
317
321
|
|
318
322
|
cs.sql.fields << "#{cs.table_alias}.#{join_field} as sort_join_field"
|
319
|
-
add_join :sort, cs.to_sql, :id, :sort_join_field, :side=>'LEFT'
|
323
|
+
join_table = add_join :sort, cs.to_sql, :id, :sort_join_field, :side=>'LEFT'
|
324
|
+
@mods[:sort] = "#{join_table}.#{val[:return]}"
|
325
|
+
|
320
326
|
end
|
321
327
|
|
322
328
|
def match(val)
|
@@ -345,8 +351,9 @@ class Card
|
|
345
351
|
end
|
346
352
|
|
347
353
|
def extension_type val
|
348
|
-
# DEPRECATED!!!
|
349
|
-
|
354
|
+
# DEPRECATED LONG AGO!!!
|
355
|
+
Rails.logger.info "using DEPRECATED extension_type in WQL"
|
356
|
+
merge field(:right_plus) => AccountID
|
350
357
|
end
|
351
358
|
|
352
359
|
|
@@ -367,8 +374,16 @@ class Card
|
|
367
374
|
end
|
368
375
|
|
369
376
|
def add_join(name, table, cardfield, otherfield, opts={})
|
370
|
-
|
371
|
-
|
377
|
+
root.join_count = root.join_count.to_i + 1
|
378
|
+
join_alias = "#{name}_#{root.join_count}"
|
379
|
+
on = "#{table_alias}.#{cardfield} = #{join_alias}.#{otherfield}"
|
380
|
+
is_subselect = !table.is_a?( Symbol )
|
381
|
+
|
382
|
+
if @mods[:conj] == 'or' and is_subselect
|
383
|
+
opts[:side] ||= 'LEFT'
|
384
|
+
merge field(:cond) => SqlCond.new(on)
|
385
|
+
end
|
386
|
+
@joins[join_alias] = ["\n ", opts[:side], 'JOIN', table, 'AS', join_alias, 'ON', on, "\n"].compact.join ' '
|
372
387
|
join_alias
|
373
388
|
end
|
374
389
|
|
@@ -376,11 +391,11 @@ class Card
|
|
376
391
|
@fields ||= {}
|
377
392
|
@fields[name] ||= 0
|
378
393
|
@fields[name] += 1
|
379
|
-
"#{ name }
|
394
|
+
"#{ name }_#{ @fields[name] }"
|
380
395
|
end
|
381
396
|
|
382
397
|
def field_root key
|
383
|
-
key.to_s.gsub
|
398
|
+
key.to_s.gsub /\_\d+/, ''
|
384
399
|
end
|
385
400
|
|
386
401
|
def subcondition(val, args={})
|
@@ -388,34 +403,34 @@ class Card
|
|
388
403
|
cardspec = CardSpec.build( args )
|
389
404
|
merge field(:cond) => cardspec.merge(val)
|
390
405
|
self.joins.merge! cardspec.joins
|
391
|
-
end
|
392
|
-
|
393
|
-
# def revision_spec(field, linkfield, val)
|
394
|
-
# card_select = CardSpec.build(:_parent=>self, :return=>'id').merge(val).to_sql
|
395
|
-
# add_join :ed, "(select distinct #{field} from card_revisions where #{linkfield} in #{card_select})", :id, field
|
396
|
-
# end
|
397
|
-
|
406
|
+
end
|
398
407
|
|
399
408
|
def action_spec(field, linkfield, val)
|
400
409
|
card_select = CardSpec.build(:_parent=>self, :return=>'id').merge(val).to_sql
|
401
410
|
sql = "(SELECT DISTINCT #{field} AS join_card_id FROM card_acts INNER JOIN card_actions ON card_acts.id = card_act_id "
|
402
|
-
sql += "
|
411
|
+
sql += " JOIN (#{card_select}) AS ss ON #{linkfield}=ss.id AND (draft is false OR draft is null))"
|
403
412
|
add_join :ac, sql, :id, :join_card_id
|
404
413
|
end
|
405
414
|
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
|
415
|
+
def id_from_spec spec
|
416
|
+
case spec
|
417
|
+
when Integer ; spec
|
418
|
+
when String ; Card.fetch_id(spec)
|
419
|
+
end
|
411
420
|
end
|
412
|
-
|
413
|
-
def
|
414
|
-
id =
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
|
421
|
+
|
422
|
+
def restrict id_field, val, opts={}
|
423
|
+
if id = id_from_spec(val)
|
424
|
+
merge field(id_field) => id
|
425
|
+
else
|
426
|
+
restrict_by_join id_field, val, opts
|
427
|
+
end
|
428
|
+
end
|
429
|
+
|
430
|
+
def restrict_by_join id_field, val, opts={}
|
431
|
+
opts.reverse_merge!(:return=>:id, :_parent=>self)
|
432
|
+
subselect = CardSpec.build(opts).merge(val).to_sql
|
433
|
+
add_join "card_#{id_field}", subselect, id_field, opts[:return]
|
419
434
|
end
|
420
435
|
|
421
436
|
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
@@ -425,8 +440,11 @@ class Card
|
|
425
440
|
|
426
441
|
def to_sql *args
|
427
442
|
sql.conditions << basic_conditions
|
428
|
-
|
429
|
-
|
443
|
+
|
444
|
+
if @mods[:return]=='condition'
|
445
|
+
conds = sql.conditions.last
|
446
|
+
return conds.blank? ? nil : "(#{conds})"
|
447
|
+
end
|
430
448
|
|
431
449
|
if pconds = permission_conditions
|
432
450
|
sql.conditions << pconds
|
@@ -451,7 +469,7 @@ class Card
|
|
451
469
|
end
|
452
470
|
|
453
471
|
def basic_conditions
|
454
|
-
@spec.map { |key, val| val.to_sql field_root(key) }.join " #{ current_conjunction } "
|
472
|
+
@spec.map { |key, val| val.to_sql field_root(key) }.compact.join " #{ current_conjunction } "
|
455
473
|
end
|
456
474
|
|
457
475
|
def current_conjunction
|
data/lib/card/set.rb
CHANGED
data/lib/wagn.rb
CHANGED
@@ -1,10 +1,9 @@
|
|
1
1
|
# should be able to move these to more appropriate places
|
2
|
-
|
3
2
|
WAGN_GEM_ROOT = File.expand_path('../..', __FILE__)
|
4
3
|
|
5
4
|
module Wagn
|
6
5
|
|
7
|
-
class << self
|
6
|
+
class << self
|
8
7
|
def root
|
9
8
|
Rails.root
|
10
9
|
end
|
@@ -25,9 +24,22 @@ module Wagn
|
|
25
24
|
WAGN_GEM_ROOT
|
26
25
|
end
|
27
26
|
|
27
|
+
def with_logging cardname, method, message, details, &block
|
28
|
+
if Wagn.config.performance_logger and
|
29
|
+
Wagn.config.performance_logger[:methods] and
|
30
|
+
Wagn.config.performance_logger[:methods].include? method
|
31
|
+
Wagn::Log.start_block :cardname=>cardname, :method=>method, :message=>message, :details=>details
|
32
|
+
result = block.call
|
33
|
+
Wagn::Log.finish_block
|
34
|
+
result
|
35
|
+
else
|
36
|
+
block.call
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
28
40
|
def future_stamp
|
29
41
|
## used in test data
|
30
42
|
@@future_stamp ||= Time.local 2020,1,1,0,0,0
|
31
43
|
end
|
32
44
|
end
|
33
|
-
end
|
45
|
+
end
|
data/lib/wagn/all.rb
CHANGED
@@ -1,16 +1,14 @@
|
|
1
1
|
require 'rails/all'
|
2
2
|
|
3
|
+
require 'builder'
|
3
4
|
require 'htmlentities'
|
4
5
|
require 'recaptcha'
|
5
|
-
require 'airbrake'
|
6
6
|
require 'RMagick'
|
7
7
|
require 'paperclip'
|
8
8
|
require 'coderay'
|
9
9
|
require 'haml'
|
10
10
|
require 'kaminari'
|
11
11
|
require 'diff/lcs'
|
12
|
-
require 'diffy'
|
13
|
-
#require 'scheduler_daemon'
|
14
12
|
|
15
13
|
require 'wagn/application'
|
16
14
|
|
data/lib/wagn/application.rb
CHANGED
@@ -9,6 +9,14 @@ if defined?(Bundler)
|
|
9
9
|
# Bundler.require(:default, :assets, Rails.env)
|
10
10
|
end
|
11
11
|
|
12
|
+
module ActiveSupport::BufferedLogger::Severity
|
13
|
+
WAGN = UNKNOWN + 1
|
14
|
+
|
15
|
+
def wagn progname, &block
|
16
|
+
add(WAGN, nil, progname, &block)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
12
20
|
|
13
21
|
module Wagn
|
14
22
|
class Application < Rails::Application
|
@@ -28,7 +36,7 @@ module Wagn
|
|
28
36
|
end
|
29
37
|
|
30
38
|
initializer :load_mod_initializers, :after => :load_wagn_config_initializers do
|
31
|
-
paths.add 'mod-initializers', :with=>'mod', :glob=>"
|
39
|
+
paths.add 'mod-initializers', :with=>'mod', :glob=>"**{,/*/**}/initializers/*.rb"
|
32
40
|
config.paths['mod-initializers'].existent.sort.each do |initializer|
|
33
41
|
load(initializer)
|
34
42
|
end
|
@@ -76,6 +84,7 @@ module Wagn
|
|
76
84
|
config.token_expiry = 2.days
|
77
85
|
config.revisions_per_page = 10
|
78
86
|
config.request_logger = false
|
87
|
+
config.performance_logger = false
|
79
88
|
|
80
89
|
config
|
81
90
|
end
|
@@ -65,7 +65,7 @@ group :test do
|
|
65
65
|
|
66
66
|
# CUKES see features dir
|
67
67
|
gem 'cucumber-rails', '~> 1.3', :require=>false # feature-driven-development suite
|
68
|
-
gem 'capybara', '~> 2.
|
68
|
+
gem 'capybara', '~> 2.4.4'
|
69
69
|
gem 'selenium-webdriver', '~> 2.39'
|
70
70
|
# gem 'capybara-webkit'
|
71
71
|
gem 'launchy' # lets cucumber launch browser windows
|
@@ -97,3 +97,8 @@ group :debug do
|
|
97
97
|
end
|
98
98
|
end
|
99
99
|
<% end %>
|
100
|
+
|
101
|
+
Dir.glob(File.join(File.dirname(__FILE__), '*','**{,/*/**}','Gemfile')).each do |gemfile|
|
102
|
+
instance_eval(File.read(gemfile))
|
103
|
+
end
|
104
|
+
|
data/lib/wagn/log.rb
ADDED
@@ -0,0 +1,69 @@
|
|
1
|
+
|
2
|
+
class Wagn::Log
|
3
|
+
TAB_SIZE = 2
|
4
|
+
@@log = []
|
5
|
+
@@last_toplevel_card = nil
|
6
|
+
|
7
|
+
class << self
|
8
|
+
|
9
|
+
# args:
|
10
|
+
# :method => :view|:event|:fetch|:search
|
11
|
+
# :cardname, :message, :details
|
12
|
+
def start_block args
|
13
|
+
level = @@log.last ? @@log.last[:level] + 1 : 1
|
14
|
+
@@log << args.merge( :start => Time.now, :level=>level, :subtree =>[] )
|
15
|
+
end
|
16
|
+
|
17
|
+
def finish_block
|
18
|
+
log = @@log.pop
|
19
|
+
duration = (Time.now - log[:start]) * 1000
|
20
|
+
return if limit = Wagn.config.performance_logger[:limit] and limit > 0 and duration < limit
|
21
|
+
|
22
|
+
log_msg = "#{ indent log[:level] }(%d.2ms) #{ log[:method] }: #{ log[:message] }" % duration
|
23
|
+
log_msg += details log if Wagn.config.performance_logger[:details]
|
24
|
+
log_msg += subtree log
|
25
|
+
|
26
|
+
if log_parent = @@log.last
|
27
|
+
if sibling = log_parent[:subtree].last and ( sibling[:card] == log[:cardname] or not log[:cardname] )
|
28
|
+
sibling[:lines] << log_msg
|
29
|
+
else
|
30
|
+
log_parent[:subtree] << {:card=>log[:cardname], :lines=>[log_msg]}
|
31
|
+
end
|
32
|
+
else
|
33
|
+
if log[:cardname] and @@last_toplevel_card != log[:cardname]
|
34
|
+
@@last_toplevel_card = log[:cardname]
|
35
|
+
Rails.logger.wagn log[:cardname]
|
36
|
+
end
|
37
|
+
Rails.logger.wagn log_msg
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
|
42
|
+
def indent level, args={}
|
43
|
+
res = (' '*TAB_SIZE + '|') * level
|
44
|
+
res += args[:no_link] ? ' ' : '--'
|
45
|
+
end
|
46
|
+
|
47
|
+
def details log
|
48
|
+
if log[:details]
|
49
|
+
", " + log[:details].to_s.gsub( "\n", "\n#{ indent( log[:level]+1, :no_link=>true) }" )
|
50
|
+
else
|
51
|
+
''
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def subtree log
|
56
|
+
if log[:subtree].present?
|
57
|
+
"\n" + log[:subtree].map do |subentry|
|
58
|
+
msg = subentry[:card] ? "#{ indent(log[:level]) }#{ subentry[:card] }\n" : ''
|
59
|
+
msg += subentry[:lines].join("\n")
|
60
|
+
end.join("\n")
|
61
|
+
else
|
62
|
+
''
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
69
|
+
|