ae_easy-core 0.2.0 → 0.2.1

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 (76) hide show
  1. checksums.yaml +4 -4
  2. data/CODE_OF_CONDUCT.md +1 -1
  3. data/Gemfile +1 -1
  4. data/LICENSE +1 -1
  5. data/README.md +8 -4
  6. data/Rakefile +0 -10
  7. data/ae_easy-core.gemspec +6 -13
  8. data/lib/ae_easy/core.rb +4 -256
  9. metadata +18 -125
  10. data/doc/AeEasy.html +0 -117
  11. data/doc/AeEasy/Core.html +0 -1590
  12. data/doc/AeEasy/Core/Config.html +0 -311
  13. data/doc/AeEasy/Core/Exception.html +0 -117
  14. data/doc/AeEasy/Core/Exception/OutdatedError.html +0 -135
  15. data/doc/AeEasy/Core/Helper.html +0 -117
  16. data/doc/AeEasy/Core/Helper/Cookie.html +0 -1070
  17. data/doc/AeEasy/Core/Mock.html +0 -282
  18. data/doc/AeEasy/Core/Mock/FakeDb.html +0 -3779
  19. data/doc/AeEasy/Core/Mock/FakeExecutor.html +0 -3289
  20. data/doc/AeEasy/Core/Mock/FakeFinisher.html +0 -160
  21. data/doc/AeEasy/Core/Mock/FakeParser.html +0 -160
  22. data/doc/AeEasy/Core/Mock/FakeSeeder.html +0 -160
  23. data/doc/AeEasy/Core/Plugin.html +0 -117
  24. data/doc/AeEasy/Core/Plugin/CollectionVault.html +0 -299
  25. data/doc/AeEasy/Core/Plugin/ConfigBehavior.html +0 -541
  26. data/doc/AeEasy/Core/Plugin/ContextIntegrator.html +0 -445
  27. data/doc/AeEasy/Core/Plugin/Executor.html +0 -259
  28. data/doc/AeEasy/Core/Plugin/ExecutorBehavior.html +0 -344
  29. data/doc/AeEasy/Core/Plugin/Finisher.html +0 -265
  30. data/doc/AeEasy/Core/Plugin/FinisherBehavior.html +0 -142
  31. data/doc/AeEasy/Core/Plugin/InitializeHook.html +0 -220
  32. data/doc/AeEasy/Core/Plugin/Parser.html +0 -270
  33. data/doc/AeEasy/Core/Plugin/ParserBehavior.html +0 -235
  34. data/doc/AeEasy/Core/Plugin/Seeder.html +0 -674
  35. data/doc/AeEasy/Core/Plugin/SeederBehavior.html +0 -142
  36. data/doc/AeEasy/Core/SmartCollection.html +0 -1087
  37. data/doc/_index.html +0 -364
  38. data/doc/class_list.html +0 -51
  39. data/doc/css/common.css +0 -1
  40. data/doc/css/full_list.css +0 -58
  41. data/doc/css/style.css +0 -496
  42. data/doc/file.README.html +0 -91
  43. data/doc/file_list.html +0 -56
  44. data/doc/frames.html +0 -17
  45. data/doc/index.html +0 -91
  46. data/doc/js/app.js +0 -303
  47. data/doc/js/full_list.js +0 -216
  48. data/doc/js/jquery.js +0 -4
  49. data/doc/method_list.html +0 -939
  50. data/doc/top-level-namespace.html +0 -110
  51. data/lib/ae_easy/core/config.rb +0 -27
  52. data/lib/ae_easy/core/exception.rb +0 -8
  53. data/lib/ae_easy/core/exception/outdated_error.rb +0 -9
  54. data/lib/ae_easy/core/helper.rb +0 -8
  55. data/lib/ae_easy/core/helper/cookie.rb +0 -209
  56. data/lib/ae_easy/core/mock.rb +0 -45
  57. data/lib/ae_easy/core/mock/fake_db.rb +0 -561
  58. data/lib/ae_easy/core/mock/fake_executor.rb +0 -373
  59. data/lib/ae_easy/core/mock/fake_finisher.rb +0 -28
  60. data/lib/ae_easy/core/mock/fake_parser.rb +0 -33
  61. data/lib/ae_easy/core/mock/fake_seeder.rb +0 -28
  62. data/lib/ae_easy/core/plugin.rb +0 -19
  63. data/lib/ae_easy/core/plugin/collection_vault.rb +0 -23
  64. data/lib/ae_easy/core/plugin/config_behavior.rb +0 -43
  65. data/lib/ae_easy/core/plugin/context_integrator.rb +0 -60
  66. data/lib/ae_easy/core/plugin/executor.rb +0 -19
  67. data/lib/ae_easy/core/plugin/executor_behavior.rb +0 -32
  68. data/lib/ae_easy/core/plugin/finisher.rb +0 -19
  69. data/lib/ae_easy/core/plugin/finisher_behavior.rb +0 -9
  70. data/lib/ae_easy/core/plugin/initialize_hook.rb +0 -17
  71. data/lib/ae_easy/core/plugin/parser.rb +0 -19
  72. data/lib/ae_easy/core/plugin/parser_behavior.rb +0 -17
  73. data/lib/ae_easy/core/plugin/seeder.rb +0 -44
  74. data/lib/ae_easy/core/plugin/seeder_behavior.rb +0 -9
  75. data/lib/ae_easy/core/smart_collection.rb +0 -236
  76. data/lib/ae_easy/core/version.rb +0 -6
@@ -1,19 +0,0 @@
1
- require 'ae_easy/core/plugin/initialize_hook'
2
- require 'ae_easy/core/plugin/context_integrator'
3
- require 'ae_easy/core/plugin/collection_vault'
4
- require 'ae_easy/core/plugin/config_behavior'
5
- require 'ae_easy/core/plugin/executor_behavior'
6
- require 'ae_easy/core/plugin/executor'
7
- require 'ae_easy/core/plugin/parser_behavior'
8
- require 'ae_easy/core/plugin/parser'
9
- require 'ae_easy/core/plugin/seeder_behavior'
10
- require 'ae_easy/core/plugin/seeder'
11
- require 'ae_easy/core/plugin/finisher_behavior'
12
- require 'ae_easy/core/plugin/finisher'
13
-
14
- module AeEasy
15
- module Core
16
- module Plugin
17
- end
18
- end
19
- end
@@ -1,23 +0,0 @@
1
- module AeEasy
2
- module Core
3
- module Plugin
4
- module CollectionVault
5
- # Stored collections info as hash.
6
- def collections
7
- @collections ||= {}
8
- end
9
-
10
- # Add a new collection
11
- #
12
- # @param [Symbol] key Collection key used to lookup for collection name.
13
- # @param [String] name Collection name used on outputs.
14
- def add_collection key, name
15
- if collections.has_key? key
16
- raise "Can't add \"#{key}\" collection, it already exists!"
17
- end
18
- collections[key] = name
19
- end
20
- end
21
- end
22
- end
23
- end
@@ -1,43 +0,0 @@
1
- module AeEasy
2
- module Core
3
- module Plugin
4
- module ConfigBehavior
5
- include AeEasy::Core::Plugin::ContextIntegrator
6
- include AeEasy::Core::Plugin::CollectionVault
7
-
8
- attr_reader :config_collection_key
9
-
10
- # Hook to map config behavior on self
11
- #
12
- # @param [Hash] opts ({}) Configuration options.
13
- # @option opts [Array] :config_collection ([:config, 'config']) Key value pair array to se a custom collection.
14
- #
15
- # @example
16
- # initialize_hook_core_config_behavior config_collection: [:my_config, 'abc']
17
- # config_collection
18
- # # => 'abc'
19
- def initialize_hook_core_config_behavior opts = {}
20
- @config_collection_key, collection = opts[:config_collection] || [:config, 'config']
21
- add_collection config_collection_key, collection
22
- end
23
-
24
- # Get config collection name.
25
- # @return [String]
26
- def config_collection
27
- collections[config_collection_key]
28
- end
29
-
30
- # Find a configuration value by item key.
31
- #
32
- # @param [Symbol] key Item key to find.
33
- #
34
- # @note Instance must implement:
35
- # * `find_output(collection, query)`
36
- def find_config key
37
- value = find_output config_collection, '_id' => key
38
- value ||= {'_collection' => config_collection, '_id' => key}
39
- end
40
- end
41
- end
42
- end
43
- end
@@ -1,60 +0,0 @@
1
- module AeEasy
2
- module Core
3
- module Plugin
4
- module ContextIntegrator
5
- # Last mocked ontext object.
6
- attr_reader :context
7
-
8
- # Mock a context methods into self.
9
- #
10
- # @param origin Object that represents the context to mock.
11
- #
12
- # @example
13
- # class MyContext
14
- # attr_accessor :message
15
- # def initialize
16
- # message = 'Hello world!'
17
- # end
18
- #
19
- # def hello_world
20
- # message
21
- # end
22
- # end
23
- #
24
- # class Foo
25
- # include ContextIntegrator
26
- #
27
- # def hello_person
28
- # 'Hello person!'
29
- # end
30
- # end
31
- #
32
- # context = MyContext.new
33
- # my_object = Foo.new
34
- # my_object.mock_context context
35
- #
36
- # puts my_object.hello_world
37
- # # => 'Hello world!'
38
- # puts my_object.hello_person
39
- # # => 'Hello person!'
40
- #
41
- # context.message = 'Hello world again!'
42
- # puts my_object.hello_world
43
- # # => 'Hello world again!
44
- def mock_context origin
45
- @context = origin
46
- AeEasy::Core.mock_instance_methods context, self
47
- end
48
-
49
- # Hook to mock context on initialize.
50
- #
51
- # @param [Hash] opts ({}) Configuration options.
52
- # @option opts :context Object that represents the context to mock.
53
- def initialize_hook_core_context_integrator opts = [{}]
54
- raise ':context object is required.' if opts[:context].nil?
55
- mock_context opts[:context]
56
- end
57
- end
58
- end
59
- end
60
- end
@@ -1,19 +0,0 @@
1
- module AeEasy
2
- module Core
3
- module Plugin
4
- module Executor
5
- include AeEasy::Core::Plugin::InitializeHook
6
- include AeEasy::Core::Plugin::ExecutorBehavior
7
-
8
- # Initialize hooks.
9
- #
10
- # @param [Hash] opts ({}) Configuration options.
11
- #
12
- # @see AeEasy::Core::Plugin::ContextIntegrator#initialize_hook_core_context_integrator
13
- def initialize opts = {}
14
- initialize_hooks opts
15
- end
16
- end
17
- end
18
- end
19
- end
@@ -1,32 +0,0 @@
1
- module AeEasy
2
- module Core
3
- module Plugin
4
- module ExecutorBehavior
5
- include AeEasy::Core::Plugin::ContextIntegrator
6
-
7
- # Enqueue a single/multiple pages for fetch. Analog to `save_pages`.
8
- #
9
- # @param [Array,Hash] object Pages to save being Hash when single and
10
- # Array when many.
11
- #
12
- # @note Instance must implement:
13
- # * `save_pages(pages)`
14
- def enqueue object
15
- object = [object] unless object.is_a? Array
16
- save_pages object
17
- end
18
-
19
- # Save a single/multiple outputs. Analog to `save_outputs`.
20
- #
21
- # @param [Array,Hash] object Outputs to save being Hash when single and Array when many.
22
- #
23
- # @note Instance must implement:
24
- # * `save_outputs(outputs)`
25
- def save object
26
- object = [object] unless object.is_a? Array
27
- save_outputs object
28
- end
29
- end
30
- end
31
- end
32
- end
@@ -1,19 +0,0 @@
1
- module AeEasy
2
- module Core
3
- module Plugin
4
- module Finisher
5
- include AeEasy::Core::Plugin::InitializeHook
6
- include AeEasy::Core::Plugin::FinisherBehavior
7
-
8
- # Initialize finisher and hooks.
9
- #
10
- # @param [Hash] opts ({}) Configuration options.
11
- #
12
- # @see AeEasy::Core::Plugin::ContextIntegrator#initialize_hook_core_context_integrator
13
- def initialize opts = {}
14
- initialize_hooks opts
15
- end
16
- end
17
- end
18
- end
19
- end
@@ -1,9 +0,0 @@
1
- module AeEasy
2
- module Core
3
- module Plugin
4
- module FinisherBehavior
5
- include AeEasy::Core::Plugin::ExecutorBehavior
6
- end
7
- end
8
- end
9
- end
@@ -1,17 +0,0 @@
1
- module AeEasy
2
- module Core
3
- module Plugin
4
- module InitializeHook
5
- # Execute all methods with `initilaize_hook_` prefix (hooks).
6
- #
7
- # @param [Hash] opts ({}) Configuration options sent to all hooks.
8
- def initialize_hooks opts = {}
9
- initializers = self.methods.select{|i|i.to_s =~ /^initialize_hook_/}
10
- initializers.each do |method|
11
- self.send method, opts
12
- end
13
- end
14
- end
15
- end
16
- end
17
- end
@@ -1,19 +0,0 @@
1
- module AeEasy
2
- module Core
3
- module Plugin
4
- module Parser
5
- include AeEasy::Core::Plugin::InitializeHook
6
- include AeEasy::Core::Plugin::ParserBehavior
7
-
8
- # Initialize parser and hooks.
9
- #
10
- # @param [Hash] opts ({}) Configuration options.
11
- #
12
- # @see AeEasy::Core::Plugin::ContextIntegrator#initialize_hook_core_context_integrator
13
- def initialize opts = {}
14
- initialize_hooks opts
15
- end
16
- end
17
- end
18
- end
19
- end
@@ -1,17 +0,0 @@
1
- module AeEasy
2
- module Core
3
- module Plugin
4
- module ParserBehavior
5
- include AeEasy::Core::Plugin::ExecutorBehavior
6
-
7
- # Alias to `page['vars']`.
8
- #
9
- # @note Instance must implement:
10
- # * `page`
11
- def vars
12
- page['vars']
13
- end
14
- end
15
- end
16
- end
17
- end
@@ -1,44 +0,0 @@
1
- module AeEasy
2
- module Core
3
- module Plugin
4
- module Seeder
5
- include AeEasy::Core::Plugin::InitializeHook
6
- include AeEasy::Core::Plugin::SeederBehavior
7
-
8
- # Root input directory path.
9
- # @return [String]
10
- attr_accessor :root_input_dir
11
-
12
- # Referer to use on page seeding.
13
- # @return [String]
14
- attr_accessor :referer
15
-
16
- # Cookie to use on page seeing.
17
- # @return [String]
18
- attr_accessor :cookie
19
-
20
- # Hook to initialize seeder object.
21
- #
22
- # @param [Hash] opts ({}) Configuration options.
23
- # @option opts [String] :root_input_dir (nil) Root directory for inputs.
24
- # @option opts [String] :referer (nil) New pages referer, useful to dynamic setups.
25
- # @option opts [String] :cookie (nil) Cookie to use on seeded pages fetchs.
26
- def initialize_hook_core_seeder opts = {}
27
- @root_input_dir = opts[:root_input_dir]
28
- @referer = opts[:referer]
29
- @cookie = opts[:cookie]
30
- end
31
-
32
- # Initialize seeder and hooks.
33
- #
34
- # @param [Hash] opts ({}) Configuration options.
35
- #
36
- # @see AeEasy::Core::Plugin::ContextIntegrator#initialize_hook_core_context_integrator
37
- # @see #initialize_hook_core_seeder
38
- def initialize opts = {}
39
- initialize_hooks opts
40
- end
41
- end
42
- end
43
- end
44
- end
@@ -1,9 +0,0 @@
1
- module AeEasy
2
- module Core
3
- module Plugin
4
- module SeederBehavior
5
- include AeEasy::Core::Plugin::ExecutorBehavior
6
- end
7
- end
8
- end
9
- end
@@ -1,236 +0,0 @@
1
- module AeEasy
2
- module Core
3
- # Smart collection capable to avoid duplicates on insert by matching id
4
- # defined fields along events.
5
- class SmartCollection < Array
6
- # Implemented event list.
7
- EVENTS = [
8
- :before_defaults,
9
- :before_match,
10
- :before_insert,
11
- :after_insert
12
- ]
13
-
14
- # Key fields, analog to primary keys.
15
- attr_reader :key_fields
16
- # Default fields values. Apply to missing fields and null values.
17
- attr_reader :defaults
18
-
19
- # Initialize collection
20
- #
21
- # @param [Array] key_fields Key fields, analog to primary keys.
22
- # @param [Hash] opts ({}) Configuration options.
23
- # @option opts [Array] :values ([]) Initial values; will avoid duplicates on insert.
24
- # @option opts [Hash] :defaults ({}) Default values. `proc` values will be executed to get default value.
25
- #
26
- # @example With default values.
27
- # count = 0
28
- # defaults = {
29
- # 'id' => lambda{|item| count += 1},
30
- # 'aaa' => 111,
31
- # 'bbb' => proc{|item| item['ccc'].nil? ? 'No ccc' : 'Has ccc'}
32
- # }
33
- # values = [
34
- # {'aaa' => 'Defaults apply on nil values only', 'bbb' => nil},
35
- # {'ccc' => 'ddd'},
36
- # {'id' => 'abc123'}
37
- # ]
38
- # new_item = {'bbb' => 'Look mom! no ccc'}
39
- # collection = SmartCollection.new ['id'], defaults: defaults
40
- # collection << new_item
41
- # collection
42
- # # => [
43
- # # {'id' => 1, 'aaa' => 'Defaults apply on nil values only', 'bbb' => 'No ccc'},
44
- # # {'id' => 2, 'aaa' => 111, 'bbb' => 'Has ccc', 'ccc' => 'ddd'},
45
- # # {'id' => 'abc123', 'aaa' => 111, 'bbb' => 'No ccc'},
46
- # # {'id' => 3, 'aaa' => 111, 'bbb' => 'Look mom! no ccc'}
47
- # # ]
48
- #
49
- # @note Defaults will apply to missing fields and null values only.
50
- def initialize key_fields, opts = {}
51
- @key_fields = key_fields || []
52
- @defaults = opts[:defaults] || {}
53
- super 0
54
- (opts[:values] || []).each{|item| self << item}
55
- end
56
-
57
- # Asigned events.
58
- # @private
59
- def events
60
- @events ||= {}
61
- end
62
-
63
- # Add event binding by key and block.
64
- #
65
- # @param [Symbol] key Event name.
66
- #
67
- # @raise [ArgumentError] When unknown event key.
68
- #
69
- # @example before_defaults
70
- # defaults = {'aaa' => 111}
71
- # collection = SmartCollection.new [],
72
- # defaults: defaults
73
- # collection.bind_event(:before_defaults) do |collection, item|
74
- # puts collection
75
- # # => []
76
- # puts item
77
- # # => {'bbb' => 222}
78
- #
79
- # # Sending the item back is required, or a new one
80
- # # in case you want to replace item to insert.
81
- # item
82
- # end
83
- # data << {'bbb' => 222}
84
- # data
85
- # # => [{'aaa' => 111, 'bbb' => 222}]
86
- #
87
- # @example before_match
88
- # keys = ['id']
89
- # defaults = {'aaa' => 111}
90
- # values = [
91
- # {'id' => 1, 'ccc' => 333}
92
- # ]
93
- # collection = SmartCollection.new keys,
94
- # defaults: defaults
95
- # values: values
96
- # collection.bind_event(:before_match) do |collection, item|
97
- # puts collection
98
- # # => [{'id' => 1, 'aaa' => 111, 'ccc' => 333}]
99
- # puts item
100
- # # => {'id' => 1, 'aaa' => 111, 'bbb' => 222}
101
- #
102
- # # Sending the item back is required, or a new one
103
- # # in case you want to replace item to insert.
104
- # item
105
- # end
106
- # data << {'id' => 1, 'bbb' => 222}
107
- # data
108
- # # => [{'id' => 1, 'aaa' => 111, 'bbb' => 222}]
109
- #
110
- # @example before_insert
111
- # keys = ['id']
112
- # defaults = {'aaa' => 111}
113
- # values = [
114
- # {'id' => 1, 'ccc' => 333}
115
- # ]
116
- # collection = SmartCollection.new keys,
117
- # defaults: defaults
118
- # values: values
119
- # collection.bind_event(:before_insert) do |collection, item, match|
120
- # puts collection
121
- # # => [{'id' => 1, 'aaa' => 111, 'ccc' => 333}]
122
- # puts item
123
- # # => {'id' => 1, 'aaa' => 111, 'bbb' => 222}
124
- # puts match
125
- # # => {'id' => 1, 'aaa' => 111, 'ccc' => 333}
126
- #
127
- # # Sending the item back is required, or a new one
128
- # # in case you want to replace item to insert.
129
- # item
130
- # end
131
- # data << {'id' => 1, 'bbb' => 222}
132
- # data
133
- # # => [{'id' => 1, 'aaa' => 111, 'bbb' => 222}]
134
- #
135
- # @example after_insert
136
- # keys = ['id']
137
- # defaults = {'aaa' => 111}
138
- # values = [
139
- # {'id' => 1, 'ccc' => 333}
140
- # ]
141
- # collection = SmartCollection.new keys,
142
- # defaults: defaults
143
- # values: values
144
- # collection.bind_event(:after_insert) do |collection, item, match|
145
- # puts collection
146
- # # => [{'id' => 1, 'aaa' => 111, 'bbb' => 222}]
147
- # puts item
148
- # # => {'id' => 1, 'aaa' => 111, 'bbb' => 222}
149
- # puts match
150
- # # => {'id' => 1, 'aaa' => 111, 'ccc' => 333}
151
- # # No need to send item back since it is already inserted
152
- # end
153
- # data << {'id' => 1, 'bbb' => 222}
154
- # data
155
- # # => [{'id' => 1, 'aaa' => 111, 'bbb' => 222}]
156
- #
157
- # @note Some events will expect a return value to replace item on insertion:
158
- # * `before_match`
159
- # * `before_defaults`
160
- # * `before_insert`
161
- def bind_event key, &block
162
- unless EVENTS.include? key
163
- raise ArgumentError.new("Unknown event '#{key}'")
164
- end
165
- (events[key] ||= []) << block
166
- end
167
-
168
- # Call an event
169
- # @private
170
- #
171
- # @param [Symbol] key Event name.
172
- # @param default Detault return value when event's return nil.
173
- # @param args event arguments.
174
- def call_event key, default = nil, *args
175
- return default if events[key].nil?
176
- result = nil
177
- events[key].each{|event| result = event.call self, *args}
178
- result.nil? ? default : result
179
- end
180
-
181
- # Check whenever two items keys match.
182
- #
183
- # @param [Hash] item_a Item to match.
184
- # @param [Hash] item_b Item to match.
185
- #
186
- # @return [Boolean]
187
- def match_keys? item_a, item_b
188
- return false if key_fields.nil? || key_fields.count < 1
189
- return true if item_a.nil? && item_b.nil?
190
- return false if item_a.nil? || item_b.nil?
191
- key_fields.each do |key|
192
- return false if item_a[key] != item_b[key]
193
- end
194
- true
195
- end
196
-
197
- # Apply default values into item.
198
- # @private
199
- #
200
- # @param [Hash] item Item to apply defaults.
201
- #
202
- # @return [Hash] Item
203
- def apply_defaults item
204
- defaults.each do |key, value|
205
- next unless item[key].nil?
206
- item[key] = value.respond_to?(:call) ? value.call(item) : value
207
- end
208
- end
209
-
210
- # Find an item by matching filter keys
211
- #
212
- # @param [Hash] filter
213
- #
214
- # @return [Hash,nil] First existing item match or nil when no match.
215
- #
216
- # @note _Warning:_ It uses table scan to filter and will be slow.
217
- def find_match filter
218
- self.find do |item|
219
- match_keys? item, filter
220
- end
221
- end
222
-
223
- # Add/remplace an item avoiding duplicates
224
- def << item
225
- item = call_event :before_defaults, item, item
226
- apply_defaults item
227
- item = call_event :before_match, item, item
228
- match = find_match item
229
- item = call_event :before_insert, item, item, match
230
- delete match unless match.nil?
231
- result = super(item)
232
- call_event :after_insert, result, item, match
233
- end
234
- end
235
- end
236
- end