kanal 0.5.1 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +6 -0
- data/Gemfile +1 -0
- data/Gemfile.lock +8 -2
- data/lib/kanal/core/conditions/condition_creator.rb +2 -2
- data/lib/kanal/core/conditions/condition_pack.rb +2 -2
- data/lib/kanal/core/conditions/condition_pack_creator.rb +1 -1
- data/lib/kanal/core/conditions/condition_storage.rb +1 -1
- data/lib/kanal/core/core.rb +15 -3
- data/lib/kanal/core/helpers/parameter_registrator.rb +1 -1
- data/lib/kanal/core/helpers/response_execution_block.rb +4 -4
- data/lib/kanal/core/hooks/hook_storage.rb +2 -2
- data/lib/kanal/core/logging/composite_logger.rb +40 -12
- data/lib/kanal/core/router/router.rb +50 -5
- data/lib/kanal/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: af8a33084b0e457be1bd9538405b4c885d624d71c67581dc1393474037e9c09b
|
4
|
+
data.tar.gz: 2ffae451a04fb4cd5c13079b8bbabcf14b2298fe3bbce681710409fc8da74c5f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: '0844b50cab451ba9eb5fd2632d2cdab50e8b8260e1a120697a637772be613fbc5cb9504e60c42acf131cc9ad9e84b167e768363b53255bd1b9a4ff172616b9d2'
|
7
|
+
data.tar.gz: 3efa7140827918ebc21c954bec87f57bd7dd57d2b3475d8be8ad065660af73cb7d7651cc0d7715f39a07a66accf8f4671707716c98e744eec50bfef9340396e6
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,11 @@
|
|
1
1
|
## [Unreleased]
|
2
2
|
|
3
|
+
## [0.6.0] 2023-04-24
|
4
|
+
- .composite_logger method for core now gives possibility to take that logger and provide it as ruby logger somewhere in the other library (usually to flow some libraries used in your kanal app logs into the kanal logs to have logs in the same place)
|
5
|
+
- you can now get beautified router info in string format for debug purpose via router.routes_info_string method
|
6
|
+
- better error handling in block specified for .output_ready
|
7
|
+
- moved many logs from level INFO level to DEBUG to stop logs overflow of inner machinery when you just want to know some info
|
8
|
+
|
3
9
|
## [0.5.0] 2023-04-14
|
4
10
|
- new router method: `provide_output(output)` for providing output directly to consumer of `.output_ready(&block)` avoiding router and final output hook `:output_before_returned`
|
5
11
|
- new router method: `provide_output_with_input(output, input)` for providing output to consumer of `.output_ready(&block)` avoiding router but applying all hooks attached to the `:output_before_returned` (usually plugins attach to this hook to convert/transform output properties)
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
kanal (0.
|
4
|
+
kanal (0.6.0)
|
5
5
|
|
6
6
|
GEM
|
7
7
|
remote: https://rubygems.org/
|
@@ -12,13 +12,18 @@ GEM
|
|
12
12
|
diff-lcs (1.5.0)
|
13
13
|
docile (1.4.0)
|
14
14
|
e2mmap (0.1.0)
|
15
|
+
httparty (0.21.0)
|
16
|
+
mini_mime (>= 1.0.0)
|
17
|
+
multi_xml (>= 0.5.2)
|
15
18
|
jaro_winkler (1.5.4)
|
16
19
|
json (2.6.3)
|
17
20
|
kramdown (2.4.0)
|
18
21
|
rexml
|
19
22
|
kramdown-parser-gfm (1.1.0)
|
20
23
|
kramdown (~> 2.0)
|
24
|
+
mini_mime (1.1.2)
|
21
25
|
mini_portile2 (2.8.1)
|
26
|
+
multi_xml (0.6.0)
|
22
27
|
nokogiri (1.14.3)
|
23
28
|
mini_portile2 (~> 2.8.0)
|
24
29
|
racc (~> 1.4)
|
@@ -95,6 +100,7 @@ PLATFORMS
|
|
95
100
|
x86_64-darwin-21
|
96
101
|
|
97
102
|
DEPENDENCIES
|
103
|
+
httparty (= 0.21.0)
|
98
104
|
kanal!
|
99
105
|
rake (~> 13.0)
|
100
106
|
rspec (~> 3.0)
|
@@ -105,4 +111,4 @@ DEPENDENCIES
|
|
105
111
|
yard
|
106
112
|
|
107
113
|
BUNDLED WITH
|
108
|
-
2.4.
|
114
|
+
2.4.5
|
@@ -17,7 +17,7 @@ module Kanal
|
|
17
17
|
end
|
18
18
|
|
19
19
|
def create(&block)
|
20
|
-
logger.
|
20
|
+
logger.debug "Attempting to create condition '#{@name}'"
|
21
21
|
|
22
22
|
instance_eval(&block)
|
23
23
|
|
@@ -33,7 +33,7 @@ module Kanal
|
|
33
33
|
raise "Please provide met? block for condition #{@name}"
|
34
34
|
end
|
35
35
|
|
36
|
-
logger.
|
36
|
+
logger.debug "Creating condition '#{@name}'"
|
37
37
|
|
38
38
|
Condition.new @name, with_argument: @with_argument, &@met_block
|
39
39
|
end
|
@@ -37,7 +37,7 @@ module Kanal
|
|
37
37
|
end
|
38
38
|
|
39
39
|
def register_condition(condition)
|
40
|
-
logger.
|
40
|
+
logger.debug "Attempting to register condition '#{condition.name}'"
|
41
41
|
|
42
42
|
unless condition.is_a? Condition
|
43
43
|
logger.fatal "Attempted to register condition which isn't of Condition class"
|
@@ -50,7 +50,7 @@ module Kanal
|
|
50
50
|
return self
|
51
51
|
end
|
52
52
|
|
53
|
-
logger.
|
53
|
+
logger.debug "Registering condition '#{condition.name}'"
|
54
54
|
|
55
55
|
@conditions.append condition
|
56
56
|
|
data/lib/kanal/core/core.rb
CHANGED
@@ -67,6 +67,18 @@ module Kanal
|
|
67
67
|
@services = ServiceContainer.new
|
68
68
|
end
|
69
69
|
|
70
|
+
#
|
71
|
+
# This method provides access to composite logger in core.
|
72
|
+
# You can use it as a regular logger in your app to feed logs from external libraries into log rotation of Kanal.
|
73
|
+
# Example:
|
74
|
+
# HTTParty.get 'http://google.com', logger: core.composite_logger
|
75
|
+
#
|
76
|
+
# @return [Kanal::Core::Logging::CompositeLogger] <description>
|
77
|
+
#
|
78
|
+
def composite_logger
|
79
|
+
logger
|
80
|
+
end
|
81
|
+
|
70
82
|
#
|
71
83
|
# Method for registering plugins. Plugins should be of type
|
72
84
|
# Kanal::Core::Plugins::Plugin. Meaning that any dervied types
|
@@ -167,7 +179,7 @@ module Kanal
|
|
167
179
|
# @return [void] <description>
|
168
180
|
#
|
169
181
|
def register_input_parameter(name, readonly: false)
|
170
|
-
logger.
|
182
|
+
logger.debug "Registering input parameter: '#{name}', readonly: '#{readonly}'"
|
171
183
|
|
172
184
|
@input_parameter_registrator.register_parameter name, readonly: readonly
|
173
185
|
end
|
@@ -181,7 +193,7 @@ module Kanal
|
|
181
193
|
# @return [void] <description>
|
182
194
|
#
|
183
195
|
def register_output_parameter(name, readonly: false)
|
184
|
-
logger.
|
196
|
+
logger.debug "Registering output parameter: '#{name}', readonly: '#{readonly}'"
|
185
197
|
@output_parameter_registrator.register_parameter name, readonly: readonly
|
186
198
|
end
|
187
199
|
|
@@ -196,7 +208,7 @@ module Kanal
|
|
196
208
|
# @return [void] <description>
|
197
209
|
#
|
198
210
|
def add_condition_pack(name, &block)
|
199
|
-
logger.
|
211
|
+
logger.debug "Starting to create condition pack '#{name}'"
|
200
212
|
|
201
213
|
creator = ConditionPackCreator.new name
|
202
214
|
|
@@ -36,7 +36,7 @@ module Kanal
|
|
36
36
|
private
|
37
37
|
|
38
38
|
def construct_output(core)
|
39
|
-
logger.
|
39
|
+
logger.debug "Constructing output for input ##{input.__id__}"
|
40
40
|
|
41
41
|
output = Output::Output.new core.output_parameter_registrator, @input, core
|
42
42
|
|
@@ -51,20 +51,20 @@ module Kanal
|
|
51
51
|
|
52
52
|
error_node = @error_node || @default_error_node
|
53
53
|
|
54
|
-
logger.
|
54
|
+
logger.debug "Trying to construct error response for input ##{input.__id__}. Error response is default: #{@error_node.nil?}"
|
55
55
|
|
56
56
|
begin
|
57
57
|
output.instance_eval(&error_node.response_blocks.first.block)
|
58
58
|
rescue => e
|
59
59
|
logger.error "Failed to construct error response for input ##{input.__id__}. Error: '#{e}'"
|
60
60
|
|
61
|
-
logger.
|
61
|
+
logger.debug "Trying to construct default error response for input ##{input.__id__}"
|
62
62
|
|
63
63
|
output.instance_eval(&@default_error_node.response_blocks.first.block)
|
64
64
|
end
|
65
65
|
end
|
66
66
|
|
67
|
-
logger.
|
67
|
+
logger.debug "Output ##{output.__id__} for input ##{input.__id__} constructed"
|
68
68
|
|
69
69
|
output
|
70
70
|
end
|
@@ -38,7 +38,7 @@ module Kanal
|
|
38
38
|
return
|
39
39
|
end
|
40
40
|
|
41
|
-
logger.
|
41
|
+
logger.debug "Registering hook '#{name}'"
|
42
42
|
|
43
43
|
@listeners[name] = []
|
44
44
|
end
|
@@ -67,7 +67,7 @@ module Kanal
|
|
67
67
|
l.method(:hook_block).call(*args)
|
68
68
|
end
|
69
69
|
rescue RuntimeError => e
|
70
|
-
raise "There was a problem with calling
|
70
|
+
raise "There was a problem with calling hook #{name}. More info: #{e.full_message}"
|
71
71
|
end
|
72
72
|
|
73
73
|
#
|
@@ -1,40 +1,68 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "logger"
|
4
|
+
|
3
5
|
module Kanal
|
4
6
|
module Core
|
5
7
|
module Logging
|
6
|
-
|
8
|
+
#
|
9
|
+
# Object of this class us used to store and use several loggers.
|
10
|
+
# It inherits from standard Logger and overrides it's methods for accepting messages for every possible log level.
|
11
|
+
# Calling #debug (or any other loglevel) on this object results in calling #debug for every logger that it stores.
|
12
|
+
#
|
13
|
+
class CompositeLogger < ::Logger
|
7
14
|
# Property allowed_methods defines which methods can be called.
|
8
15
|
# These methods mirror standard Logger methods.
|
9
16
|
def initialize
|
10
17
|
@loggers = []
|
11
|
-
@allowed_methods = [:debug, :info, :warn, :error, :fatal, :unknown]
|
12
18
|
end
|
13
19
|
|
14
20
|
def add_logger(logger)
|
15
21
|
@loggers << logger
|
16
22
|
end
|
17
23
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
24
|
+
def debug(message)
|
25
|
+
feed_message_to_loggers :debug, caller_class_name(caller.first), message
|
26
|
+
end
|
27
|
+
|
28
|
+
def info(message)
|
29
|
+
feed_message_to_loggers :info, caller_class_name(caller.first), message
|
30
|
+
end
|
31
|
+
|
32
|
+
def warn(message)
|
33
|
+
feed_message_to_loggers :warn, caller_class_name(caller.first), message
|
34
|
+
end
|
35
|
+
|
36
|
+
def error(message)
|
37
|
+
feed_message_to_loggers :error, caller_class_name(caller.first), message
|
38
|
+
end
|
39
|
+
|
40
|
+
def fatal(message)
|
41
|
+
feed_message_to_loggers :fatal, caller_class_name(caller.first), message
|
42
|
+
end
|
43
|
+
|
44
|
+
def unknown(message)
|
45
|
+
feed_message_to_loggers :unknown, caller_class_name(caller.first), message
|
46
|
+
end
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
def caller_class_name(caller)
|
25
51
|
begin
|
26
|
-
caller_class_name = "[" + caller
|
52
|
+
caller_class_name = "[" + caller.split(".rb").first.split("/").last.split('_').collect(&:capitalize).join + "]"
|
27
53
|
rescue
|
28
54
|
caller_class_name = "[ErrorGettingClassName]"
|
29
55
|
end
|
30
56
|
|
31
|
-
|
57
|
+
caller_class_name
|
58
|
+
end
|
32
59
|
|
60
|
+
def feed_message_to_loggers(method_name, caller_class_name, message)
|
33
61
|
@loggers.each do |logger|
|
34
62
|
# progname is a property of standard Logger. It is a prefix for log message.
|
35
63
|
# In our case progname is used to store class name of class which calls for CompositeLogger methods.
|
36
64
|
logger.progname = caller_class_name
|
37
|
-
logger.send
|
65
|
+
logger.send method_name, message
|
38
66
|
end
|
39
67
|
end
|
40
68
|
end
|
@@ -46,21 +46,21 @@ module Kanal
|
|
46
46
|
# forward in the workflow: apply hooks in :output_before_ready and pass it to
|
47
47
|
# the end consumer which uses .output_ready(&block)
|
48
48
|
@input_output_pair_queue.hooks.attach :item_queued do |input_output_pair|
|
49
|
-
_this.logger.
|
49
|
+
_this.logger.debug "Calling output_ready block for input ##{input_output_pair.input.__id__} and output #{input_output_pair.output.__id__}. Output body is: '#{input_output_pair.output.body}'"
|
50
50
|
|
51
51
|
begin
|
52
52
|
_this.core.hooks.call :output_before_returned, input_output_pair.input, input_output_pair.output
|
53
53
|
rescue => e
|
54
|
-
logger.error "
|
54
|
+
_this.logger.error "Problem with some hooks inside :output_before_returned. More info: #{e.full_message}"
|
55
55
|
return
|
56
56
|
end
|
57
57
|
|
58
58
|
begin
|
59
59
|
_this.output_ready_block.call input_output_pair.output
|
60
60
|
_input_output_pair_queue.remove(input_output_pair)
|
61
|
-
rescue
|
61
|
+
rescue => e
|
62
62
|
_input_output_pair_queue.remove(input_output_pair)
|
63
|
-
|
63
|
+
_this.logger.error "Problem occurred in block provided in .output_ready(&block), here is more info: #{e.full_message}"
|
64
64
|
end
|
65
65
|
end
|
66
66
|
end
|
@@ -137,7 +137,7 @@ module Kanal
|
|
137
137
|
|
138
138
|
# Main method for creating output(s) if it is found or going to default output
|
139
139
|
def consume_input(input)
|
140
|
-
logger.
|
140
|
+
logger.debug "Consuming input #{input.__id__}."
|
141
141
|
|
142
142
|
# Checking if default node with output exists throw error if not
|
143
143
|
unless @default_node
|
@@ -228,6 +228,19 @@ module Kanal
|
|
228
228
|
end
|
229
229
|
end
|
230
230
|
|
231
|
+
def routes_info_string
|
232
|
+
error_and_default_response_data = "Router Debug Info:
|
233
|
+
|
234
|
+
Default response: #{variable_defined @default_node}
|
235
|
+
Error response: #{variable_defined @error_node}
|
236
|
+
|
237
|
+
Routes:
|
238
|
+
"
|
239
|
+
router_data = get_data @root_node
|
240
|
+
|
241
|
+
error_and_default_response_data + router_data
|
242
|
+
end
|
243
|
+
|
231
244
|
private :test_input_against_router_node
|
232
245
|
|
233
246
|
def default_error_response(&block)
|
@@ -235,6 +248,38 @@ module Kanal
|
|
235
248
|
|
236
249
|
@default_error_node.respond(&block)
|
237
250
|
end
|
251
|
+
|
252
|
+
def get_data(node, depth = 0)
|
253
|
+
if node != @root_node
|
254
|
+
data = get_node_data_string node
|
255
|
+
else
|
256
|
+
data = ""
|
257
|
+
end
|
258
|
+
|
259
|
+
if node.children?
|
260
|
+
node.children.each do |c|
|
261
|
+
c.children? ? symbol = "↳ " : symbol = "⏺ "
|
262
|
+
|
263
|
+
data = data + (" " * depth) + symbol + get_data(c, depth + 1)
|
264
|
+
end
|
265
|
+
end
|
266
|
+
|
267
|
+
data
|
268
|
+
end
|
269
|
+
|
270
|
+
def variable_defined(variable)
|
271
|
+
variable.nil? ? "not defined" : "defined"
|
272
|
+
end
|
273
|
+
|
274
|
+
def get_node_data_string(node)
|
275
|
+
data = "on :#{node.instance_variable_get(:@condition_pack_name)}, #{node.instance_variable_get(:@condition_name)}: #{node.instance_variable_get(:@condition_argument)}"
|
276
|
+
|
277
|
+
data = data + ", responses_total: #{node.instance_variable_get(:@response_blocks).count}" if node.instance_variable_get(:@response_blocks).count > 0
|
278
|
+
|
279
|
+
data = data + "
|
280
|
+
"
|
281
|
+
data
|
282
|
+
end
|
238
283
|
end
|
239
284
|
end
|
240
285
|
end
|
data/lib/kanal/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: kanal
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- idchlife
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-04-
|
11
|
+
date: 2023-04-24 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: Thanks to the core library, ecosystem of Kanal tools can be extendted
|
14
14
|
to use with input-output bot-like behaviour, with routing
|