card 1.101.3 → 1.101.4

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.
Files changed (84) hide show
  1. checksums.yaml +4 -4
  2. data/VERSION +1 -1
  3. data/config/initializers/02_patches/active_record.rb +1 -1
  4. data/config/locales/en.yml +155 -378
  5. data/db/migrate_core_cards/20150202143810_import_bootstrap_layout.rb +1 -1
  6. data/lib/card.rb +15 -2
  7. data/lib/card/auth.rb +5 -2
  8. data/lib/card/auth/current.rb +39 -100
  9. data/lib/card/auth/proxy.rb +36 -16
  10. data/lib/card/auth/token.rb +6 -0
  11. data/lib/card/cache/all.rb +83 -0
  12. data/lib/card/cache/card_class.rb +41 -0
  13. data/lib/card/cache/persistent.rb +3 -34
  14. data/lib/card/cache/persistent_class.rb +28 -0
  15. data/lib/card/codename.rb +1 -1
  16. data/lib/card/content.rb +16 -2
  17. data/lib/card/content/all.rb +59 -0
  18. data/lib/card/director/act_direction.rb +4 -0
  19. data/lib/card/director/all.rb +61 -0
  20. data/lib/card/director/card_class.rb +18 -0
  21. data/lib/card/director/phases.rb +0 -1
  22. data/lib/card/dirty.rb +13 -3
  23. data/lib/card/env/success.rb +14 -14
  24. data/lib/card/env/success/target.rb +9 -11
  25. data/lib/card/error.rb +1 -1
  26. data/lib/card/fetch/all.rb +32 -0
  27. data/lib/card/fetch/card_class.rb +147 -0
  28. data/lib/card/format.rb +1 -1
  29. data/lib/card/format/error.rb +3 -3
  30. data/lib/card/format/nest.rb +1 -1
  31. data/lib/card/format/nest/fetch.rb +1 -1
  32. data/lib/card/lexicon.rb +2 -2
  33. data/lib/card/name/all.rb +8 -0
  34. data/lib/card/name/all/descendants.rb +6 -3
  35. data/lib/card/name/card_class.rb +26 -0
  36. data/lib/card/reference/all.rb +131 -0
  37. data/lib/card/rule/all.rb +75 -0
  38. data/lib/card/set/event/all.rb +95 -0
  39. data/lib/card/set/event/skip_and_trigger.rb +89 -0
  40. data/lib/card/set/pattern/all.rb +63 -0
  41. data/lib/card/subcards/all.rb +103 -0
  42. data/lib/cardio/migration/import.rb +1 -1
  43. data/lib/cardio/utils.rb +5 -3
  44. data/mod/admin/set/self/admin_info.rb +3 -5
  45. data/mod/admin/set/self/trash.rb +2 -2
  46. data/mod/core/set/all/autoname.rb +17 -0
  47. data/mod/core/set/all/codename.rb +2 -2
  48. data/mod/core/set/all/content.rb +52 -97
  49. data/mod/core/set/all/name_events.rb +69 -58
  50. data/mod/core/set/all/reference_events.rb +67 -0
  51. data/mod/core/set/all/states.rb +2 -2
  52. data/mod/core/set/all/subcards.rb +0 -100
  53. data/mod/core/set/all/trash.rb +11 -13
  54. data/mod/core/set/all/type.rb +7 -9
  55. data/mod/core/set/all/utils.rb +3 -0
  56. data/mod/core/set/type/cardtype.rb +3 -3
  57. data/mod/core/set_pattern/06_rule.rb +1 -1
  58. data/mod/core/spec/set/all/{rules2_spec.rb → clean_me_spec.rb} +0 -0
  59. data/mod/core/spec/set/all/name_events_spec.rb +204 -0
  60. metadata +30 -37
  61. data/lib/card/mod_inflector.rb +0 -16
  62. data/lib/card/name/all/class_methods.rb +0 -28
  63. data/mod/core/set/all/actify.rb +0 -68
  64. data/mod/core/set/all/cache.rb +0 -109
  65. data/mod/core/set/all/event_conditions.rb +0 -172
  66. data/mod/core/set/all/fetch.rb +0 -122
  67. data/mod/core/set/all/fetch_helper.rb +0 -35
  68. data/mod/core/set/all/i18n.rb +0 -9
  69. data/mod/core/set/all/pattern.rb +0 -54
  70. data/mod/core/set/all/references.rb +0 -191
  71. data/mod/core/set/all/rename.rb +0 -33
  72. data/mod/core/set/all/rules.rb +0 -81
  73. data/mod/core/spec/set/all/actify_spec.rb +0 -58
  74. data/mod/core/spec/set/all/content_spec.rb +0 -15
  75. data/mod/core/spec/set/all/event_conditions_spec.rb +0 -217
  76. data/mod/core/spec/set/all/fetch_helper_spec.rb +0 -65
  77. data/mod/core/spec/set/all/fetch_spec.rb +0 -338
  78. data/mod/core/spec/set/all/i18n_spec.rb +0 -17
  79. data/mod/core/spec/set/all/pattern_spec.rb +0 -101
  80. data/mod/core/spec/set/all/permissions/reader_rules_spec.rb +0 -166
  81. data/mod/core/spec/set/all/references_spec.rb +0 -62
  82. data/mod/core/spec/set/all/rename_spec.rb +0 -189
  83. data/mod/core/spec/set/all/rules_spec.rb +0 -100
  84. data/mod/core/spec/set/all/subcards_spec.rb +0 -102
@@ -1,16 +0,0 @@
1
- class ModInflector < Zeitwerk::Inflector
2
- def camelize basename, abspath
3
- ActiveSupport::Dependencies::ZeitwerkIntegration::Inflector.camelize(basename, abspath)
4
-
5
- # if basename =~ /\Ahtml_(.*)/
6
- # ActiveSupport::Dependencies::ZeitwerkIntegration::Inflector.camelize(basename, abspath)
7
- # # "HTML" + super($1, abspath)
8
- # else
9
- # super
10
- # end
11
- end
12
-
13
- def inflect overrides
14
- ActiveSupport::Dependencies::ZeitwerkIntegration::Inflector.inflect(overrides)
15
- end
16
- end
@@ -1,28 +0,0 @@
1
- class Card
2
- class Name
3
- module All
4
- # Name-related Card class methods
5
- module ClassMethods
6
- def rename! oldname, newname
7
- Card[oldname].update! name: newname, update_referers: true
8
- end
9
-
10
- def uniquify_name name, rename=:new
11
- return name unless Card.exists? name
12
- uniq_name = generate_alternative_name name
13
- return uniq_name unless rename == :old
14
- rename!(name, uniq_name)
15
- name
16
- end
17
-
18
- private
19
-
20
- def generate_alternative_name name
21
- uniq_name = "#{name} 1"
22
- uniq_name.next! while Card.exists?(uniq_name)
23
- uniq_name
24
- end
25
- end
26
- end
27
- end
28
- end
@@ -1,68 +0,0 @@
1
- def act options={}, &block
2
- if act_card
3
- add_to_act options, &block
4
- else
5
- start_new_act &block
6
- end
7
- end
8
-
9
- def act_card
10
- Card::Director.act_card
11
- end
12
-
13
- def act_card?
14
- self == act_card
15
- end
16
-
17
- module ClassMethods
18
- def create! opts
19
- card = Card.new opts
20
- card.save!
21
- card
22
- end
23
-
24
- def create opts
25
- card = Card.new opts
26
- card.save
27
- card
28
- end
29
- end
30
-
31
- def save! *args
32
- as_subcard = args.first&.delete :as_subcard
33
- act(as_subcard: as_subcard) { super }
34
- end
35
-
36
- def save(*)
37
- act { super }
38
- end
39
-
40
- def valid?(*)
41
- act(validating: true) { super }
42
- end
43
-
44
- def update *args
45
- act { super }
46
- end
47
-
48
- def update! *args
49
- act { super }
50
- end
51
-
52
- alias_method :update_attributes, :update
53
- alias_method :update_attributes!, :update!
54
-
55
- private
56
-
57
- def start_new_act
58
- self.director = nil
59
- Director.run_act(self) do
60
- run_callbacks(:act) { yield }
61
- end
62
- end
63
-
64
- def add_to_act options={}
65
- director.appoint self unless @director
66
- director.head = true unless options[:validating] || options[:as_subcard]
67
- yield
68
- end
@@ -1,109 +0,0 @@
1
- module ClassMethods
2
- def retrieve_from_cache cache_key, local_only=false
3
- return unless cache
4
- local_only ? cache.soft.read(cache_key) : cache.read(cache_key)
5
- end
6
-
7
- def retrieve_from_cache_by_id id, local_only=false
8
- key = Card::Lexicon.name(id)&.key
9
- return unless key.present?
10
-
11
- retrieve_from_cache key, local_only if key
12
- end
13
-
14
- def retrieve_from_cache_by_key key, local_only=false
15
- retrieve_from_cache key, local_only
16
- end
17
-
18
- def write_to_cache card, local_only=false
19
- if local_only
20
- write_to_soft_cache card
21
- elsif cache
22
- cache.write card.key, card
23
- end
24
- end
25
-
26
- def write_to_soft_cache card
27
- return unless cache
28
- cache.soft.write card.key, card
29
- end
30
-
31
- def expire name
32
- key = name.to_name.key
33
- return unless (card = Card.cache.read key)
34
- card.expire
35
- end
36
- end
37
-
38
- def update_soft_cache
39
- Card.write_to_soft_cache self
40
- end
41
-
42
- def expire_pieces
43
- name.piece_names.each do |piece|
44
- Card.expire piece
45
- end
46
- end
47
-
48
- def expire cache_type=nil
49
- return unless (cache_class = cache_class_from_type cache_type)
50
- expire_views
51
- expire_names cache_class
52
- expire_id cache_class
53
- end
54
-
55
- def cache_class_from_type cache_type
56
- cache_type ? Card.cache.send(cache_type) : Card.cache
57
- end
58
-
59
- def view_cache_clean?
60
- !db_content_changed?
61
- end
62
-
63
- def view_cache_keys
64
- @view_cache_keys ||= hard_read_view_cache_keys || []
65
- end
66
-
67
- def ensure_view_cache_key cache_key
68
- return if view_cache_keys.include? cache_key
69
-
70
- @view_cache_keys << cache_key
71
- hard_write_view_cache_keys
72
- end
73
-
74
- def hard_read_view_cache_keys
75
- Card.cache.hard&.read_attribute key, :view_cache_keys
76
- end
77
-
78
- def hard_write_view_cache_keys
79
- # puts "WRITE VIEW CACHE KEYS (#{name}): #{view_cache_keys}"
80
- Card.cache.hard&.write_attribute key, :view_cache_keys, view_cache_keys
81
- end
82
-
83
- def expire_views
84
- # puts "EXPIRE VIEW CACHE (#{name}): #{view_cache_keys}"
85
- return unless view_cache_keys.present?
86
- Array.wrap(view_cache_keys).each do |view_cache_key|
87
- Card::View.cache.delete view_cache_key
88
- end
89
- @view_cache_keys = []
90
- hard_write_view_cache_keys
91
- end
92
-
93
- def expire_names cache
94
- [name, name_before_act].uniq.each do |name_version|
95
- expire_name name_version, cache
96
- end
97
- end
98
-
99
- def expire_name name_version, cache
100
- return unless name_version.present?
101
- key_version = name_version.to_name.key
102
- return unless key_version.present?
103
- cache.delete key_version
104
- end
105
-
106
- def expire_id cache
107
- return unless id.present?
108
- cache.delete "~#{id}"
109
- end
@@ -1,172 +0,0 @@
1
- Card.action_specific_attributes +=
2
- %i[skip_hash full_skip_hash trigger_hash full_trigger_hash]
3
-
4
- def event_applies? event
5
- return unless set_condition_applies? event.set_module, event.opts[:changing]
6
-
7
- Card::Set::Event::CONDITIONS.all? do |key|
8
- send "#{key}_condition_applies?", event, event.opts[key]
9
- end
10
- end
11
-
12
- # force skipping this event for all cards in act
13
- def skip_event! *events
14
- @full_skip_hash = nil
15
- events.each do |event|
16
- act_skip_hash[event.to_s] = :force
17
- end
18
- end
19
-
20
- # force skipping this event for this card only
21
- def skip_event_in_action! *events
22
- events.each do |event|
23
- full_skip_hash[event.to_s] = :force
24
- end
25
- end
26
-
27
- # force triggering this event (when it comes up) for all cards in act
28
- def trigger_event! *events
29
- @full_trigger_hash = nil
30
- events.each do |event|
31
- act_trigger_hash[event.to_s] = :force
32
- end
33
- end
34
-
35
- # force triggering this event (when it comes up) for this card only
36
- def trigger_event_in_action! *events
37
- events.each do |event|
38
- full_trigger_hash[event.to_s] = :force
39
- end
40
- end
41
-
42
- # hash form of raw skip setting, eg { "my_event" => true }
43
- def skip_hash
44
- @skip_hash ||= hash_with_value skip, true
45
- end
46
-
47
- def trigger_hash
48
- @trigger_hash ||= hash_with_value trigger, true
49
- end
50
-
51
- private
52
-
53
- def set_condition_applies? set_module, old_sets
54
- return true if set_module == Card
55
-
56
- set_condition_card(old_sets).singleton_class.include? set_module
57
- end
58
-
59
- def on_condition_applies? _event, actions
60
- actions = Array(actions).compact
61
- actions.empty? ? true : actions.include?(action)
62
- end
63
-
64
- # if changing name/type, the old card has no-longer-applicable set modules, so we create
65
- # a new card to determine whether events apply.
66
- # (note: cached condition card would ideally be cleared after all
67
- # conditions are reviewed)
68
- # @param old_sets [True/False] whether to use the old_sets
69
- def set_condition_card old_sets
70
- return self if old_sets || no_current_action?
71
- @set_condition_card ||=
72
- updating_sets? ? set_condition_card_with_new_set_modules : self
73
- end
74
-
75
- # existing card is being changed in a way that alters its sets
76
- def updating_sets?
77
- action == :update && real? && (type_id_is_changing? || name_is_changing?)
78
- end
79
-
80
- # prevents locking in set_condition_card
81
- def no_current_action?
82
- return false if @current_action
83
-
84
- @set_condition_card = nil
85
- true
86
- end
87
-
88
- def set_condition_card_with_new_set_modules
89
- cc = Card.find id
90
- cc.name = name
91
- cc.type_id = type_id
92
- cc.include_set_modules
93
- end
94
-
95
- def changed_condition_applies? _event, db_columns
96
- return true unless action == :update
97
- db_columns = Array(db_columns).compact
98
- return true if db_columns.empty?
99
- db_columns.any? { |col| single_changed_condition_applies? col }
100
- end
101
- alias_method :changing_condition_applies?, :changed_condition_applies?
102
-
103
- def when_condition_applies? _event, block
104
- case block
105
- when Proc then block.call(self)
106
- when Symbol then send block
107
- else true
108
- end
109
- end
110
-
111
- # "applies always means event can run
112
- # so if skip_condition_applies?, we do NOT skip
113
- def skip_condition_applies? event, allowed
114
- return true unless (val = full_skip_hash[event.name.to_s])
115
-
116
- allowed ? val.blank? : (val != :force)
117
- end
118
-
119
- def trigger_condition_applies? event, required
120
- return true unless required
121
-
122
- full_trigger_hash[event.name.to_s].present?
123
- end
124
-
125
- def single_changed_condition_applies? db_column
126
- return true unless db_column
127
- send "#{db_column}_is_changing?"
128
- end
129
-
130
- def wrong_stage opts
131
- return false if director.stage_ok? opts
132
- if !stage
133
- "phase method #{method} called outside of event phases"
134
- else
135
- "#{opts.inspect} method #{method} called in stage #{stage}"
136
- end
137
- end
138
-
139
- def wrong_action actn
140
- return false if on_condition_applies?(nil, actn)
141
- "on: #{actn} method #{method} called on #{action}"
142
- end
143
-
144
- def full_skip_hash
145
- @full_skip_hash ||= act_skip_hash.merge skip_in_action_hash
146
- end
147
-
148
- def act_skip_hash
149
- (act_card || self).skip_hash
150
- end
151
-
152
- def skip_in_action_hash
153
- hash_with_value skip_in_action, true
154
- end
155
-
156
- def full_trigger_hash
157
- @full_trigger_hash ||= act_trigger_hash.merge trigger_in_action_hash
158
- end
159
-
160
- def trigger_in_action_hash
161
- hash_with_value trigger_in_action, true
162
- end
163
-
164
- def act_trigger_hash
165
- (act_card || self).trigger_hash
166
- end
167
-
168
- def hash_with_value array, value
169
- Array.wrap(array).each_with_object({}) do |event, hash|
170
- hash[event.to_s] = value
171
- end
172
- end
@@ -1,122 +0,0 @@
1
- # = Card#fetch
2
- #
3
- # A multipurpose retrieval operator that integrates caching, database lookups,
4
- # and "virtual" card construction
5
- module ClassMethods
6
- # Look for cards in
7
- # * cache
8
- # * database
9
- # * virtual cards
10
- #
11
- # @param args [Integer, String, Card::Name, Symbol, Array]
12
- # one or more of the three unique identifiers
13
- # 1. a numeric id (Integer)
14
- # 2. a name/key (String or Card::Name)
15
- # 3. a codename (Symbol)
16
- # If you pass more then one mark or an array of marks they get joined with a '+'.
17
- # The final argument can be a hash to set the following options
18
- # :skip_virtual Real cards only
19
- # :skip_modules Don't load Set modules
20
- # :look_in_trash Return trashed card objects
21
- # :local_only Use only local cache for lookup and storing
22
- # new: { opts for Card#new } Return a new card when not found
23
- # @return [Card]
24
- def fetch *args
25
- Card::Fetch.new(*args)&.retrieve_or_new
26
- rescue ActiveModel::RangeError => _e
27
- return Card.new name: "card id out of range: #{f.mark}"
28
- end
29
-
30
- # fetch only real (no virtual) cards
31
- #
32
- # @param mark - see #fetch
33
- # @return [Card]
34
- def [] *mark
35
- fetch(*mark, skip_virtual: true)
36
- end
37
-
38
- # fetch real cards without set modules loaded. Should only be used for simple attributes
39
- # @example
40
- # quick_fetch "A", :self, :structure
41
- #
42
- # @param mark - see #fetch
43
- # @return [Card]
44
- def quick_fetch *mark
45
- fetch(*mark, skip_virtual: true, skip_modules: true)
46
- end
47
-
48
- # @return [Card]
49
- def fetch_from_cast cast
50
- fetch_args = cast[:id] ? [cast[:id].to_i] : [cast[:name], { new: cast }]
51
- fetch *fetch_args
52
- end
53
-
54
- #----------------------------------------------------------------------
55
- # ATTRIBUTE FETCHING
56
- # The following methods optimize fetching of specific attributes
57
-
58
- def id cardish
59
- case cardish
60
- when Integer then cardish
61
- when Card then cardish.id
62
- when Symbol then Card::Codename.id cardish
63
- else fetch_id cardish
64
- end
65
- end
66
-
67
- # @param mark_parts - see #fetch
68
- # @return [Integer]
69
- def fetch_id *mark_parts
70
- mark = Card::Fetch.new(*mark_parts)&.mark
71
- mark.is_a?(Integer) ? mark : quick_fetch(mark.to_s)&.id
72
- end
73
-
74
- # @param mark - see #fetch
75
- # @return [Card::Name]
76
- def fetch_name *mark
77
- if (card = quick_fetch(*mark))
78
- card.name
79
- elsif block_given?
80
- yield.to_name
81
- end
82
- rescue ActiveModel::RangeError => _e
83
- block_given? ? yield.to_name : nil
84
- rescue Card::Error::CodenameNotFound => e
85
- block_given? ? yield.to_name : raise(e)
86
- end
87
-
88
- # @param mark - see #fetch
89
- # @return [Integer]
90
- def fetch_type_id mark
91
- quick_fetch(mark)&.type_id
92
- end
93
- end
94
-
95
- #----------------------------------------------------------------------
96
- # INSTANCE METHODS
97
- # fetching from the context of a card
98
-
99
- def fetch traits, opts={}
100
- opts[:new][:supercard] = self if opts[:new]
101
- Array.wrap(traits).inject(self) do |card, trait|
102
- Card.fetch card.name.trait(trait), opts
103
- end
104
- end
105
-
106
- def newish opts
107
- reset_patterns
108
- Card.with_normalized_new_args opts do |norm_opts|
109
- handle_type norm_opts do
110
- assign_attributes norm_opts
111
- self.name = name # trigger superize_name
112
- end
113
- end
114
- end
115
-
116
- def refresh force=false
117
- return self unless force || frozen? || readonly?
118
- return unless id
119
- fresh_card = self.class.find id
120
- fresh_card.include_set_modules
121
- fresh_card
122
- end