kanal 0.6.0 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: af8a33084b0e457be1bd9538405b4c885d624d71c67581dc1393474037e9c09b
4
- data.tar.gz: 2ffae451a04fb4cd5c13079b8bbabcf14b2298fe3bbce681710409fc8da74c5f
3
+ metadata.gz: a3fa557dde04dae9b2a64daefc5b05e083331240c38701248bc3d8e2f02f136f
4
+ data.tar.gz: 2602843cdb547c6633322520e25b158def2d110952466cd8d80de9ab15ea8377
5
5
  SHA512:
6
- metadata.gz: '0844b50cab451ba9eb5fd2632d2cdab50e8b8260e1a120697a637772be613fbc5cb9504e60c42acf131cc9ad9e84b167e768363b53255bd1b9a4ff172616b9d2'
7
- data.tar.gz: 3efa7140827918ebc21c954bec87f57bd7dd57d2b3475d8be8ad065660af73cb7d7651cc0d7715f39a07a66accf8f4671707716c98e744eec50bfef9340396e6
6
+ metadata.gz: b87922aa8cdaaf257ed89b6a6eea547a22181ed7dd60c3284b8bb7f8cb68ed048de256f38fa50ddedc83cd758ed4b35172692513c0aa5773401433833ee82732
7
+ data.tar.gz: c882a6864449692ae4ce1dd63450b9ed61d12dc3d469468c355ec28b862a6f103ccaffe0eeab87e6993d7ad761d1111adf2f7d80e1d5f603acaa0b0e05a86d55
data/CHANGELOG.md CHANGED
@@ -1,5 +1,12 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [0.8.0] 2023-05-02
4
+ - after_respond, after_respond_async to store blocks of code to be executed after responses. They do not spawn outputs
5
+ - respond do; cancel end - now we can use cancel DSL keyword in response block if response should not be processed further to spawn an output
6
+
7
+ ## [0.7.0] 2023-04-25
8
+ - new output property for batteries: specifics. You can now add specific properties for whatever purpose like specifics.add, specifics.get. specifics.has?
9
+
3
10
  ## [0.6.0] 2023-04-24
4
11
  - .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
12
  - you can now get beautified router info in string format for debug purpose via router.routes_info_string method
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- kanal (0.6.0)
4
+ kanal (0.8.0)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
@@ -22,21 +22,19 @@ GEM
22
22
  kramdown-parser-gfm (1.1.0)
23
23
  kramdown (~> 2.0)
24
24
  mini_mime (1.1.2)
25
- mini_portile2 (2.8.1)
26
25
  multi_xml (0.6.0)
27
- nokogiri (1.14.3)
28
- mini_portile2 (~> 2.8.0)
29
- racc (~> 1.4)
30
26
  nokogiri (1.14.3-x86_64-darwin)
31
27
  racc (~> 1.4)
32
- parallel (1.22.1)
33
- parser (3.2.2.0)
28
+ nokogiri (1.14.3-x86_64-linux)
29
+ racc (~> 1.4)
30
+ parallel (1.23.0)
31
+ parser (3.2.2.1)
34
32
  ast (~> 2.4.1)
35
33
  racc (1.6.2)
36
34
  rainbow (3.1.1)
37
35
  rake (13.0.6)
38
36
  rbs (2.8.4)
39
- regexp_parser (2.7.0)
37
+ regexp_parser (2.8.0)
40
38
  reverse_markdown (2.1.1)
41
39
  nokogiri
42
40
  rexml (3.2.5)
@@ -44,16 +42,16 @@ GEM
44
42
  rspec-core (~> 3.12.0)
45
43
  rspec-expectations (~> 3.12.0)
46
44
  rspec-mocks (~> 3.12.0)
47
- rspec-core (3.12.1)
45
+ rspec-core (3.12.2)
48
46
  rspec-support (~> 3.12.0)
49
- rspec-expectations (3.12.2)
47
+ rspec-expectations (3.12.3)
50
48
  diff-lcs (>= 1.2.0, < 2.0)
51
49
  rspec-support (~> 3.12.0)
52
50
  rspec-mocks (3.12.5)
53
51
  diff-lcs (>= 1.2.0, < 2.0)
54
52
  rspec-support (~> 3.12.0)
55
53
  rspec-support (3.12.0)
56
- rubocop (1.50.0)
54
+ rubocop (1.50.2)
57
55
  json (~> 2.3)
58
56
  parallel (~> 1.10)
59
57
  parser (>= 3.2.0.0)
@@ -63,7 +61,7 @@ GEM
63
61
  rubocop-ast (>= 1.28.0, < 2.0)
64
62
  ruby-progressbar (~> 1.7)
65
63
  unicode-display_width (>= 2.4.0, < 3.0)
66
- rubocop-ast (1.28.0)
64
+ rubocop-ast (1.28.1)
67
65
  parser (>= 3.2.1.0)
68
66
  ruby-debug-ide (0.7.3)
69
67
  rake (>= 0.8.1)
@@ -93,11 +91,11 @@ GEM
93
91
  thor (1.2.1)
94
92
  tilt (2.1.0)
95
93
  unicode-display_width (2.4.2)
96
- yard (0.9.33)
94
+ yard (0.9.34)
97
95
 
98
96
  PLATFORMS
99
- ruby
100
- x86_64-darwin-21
97
+ x86_64-darwin-22
98
+ x86_64-linux
101
99
 
102
100
  DEPENDENCIES
103
101
  httparty (= 0.21.0)
@@ -111,4 +109,4 @@ DEPENDENCIES
111
109
  yard
112
110
 
113
111
  BUNDLED WITH
114
- 2.4.5
112
+ 2.4.9
@@ -3,14 +3,42 @@
3
3
  module Kanal
4
4
  module Core
5
5
  module Helpers
6
+ #
7
+ # Response block stores block of code
8
+ # to be executed at runtime and output to be created
9
+ #
6
10
  class ResponseBlock
7
11
  attr_reader :block
8
12
 
9
- def initialize(block, async: false)
13
+ #
14
+ # Creates response block that stores block for evaluation
15
+ # at runtime, when output is constructed
16
+ #
17
+ # @param block [Proc] block of code to be evaluated at runtime and output to be constructed with it
18
+ # @param async [Boolean] block should be executed in thread
19
+ # @param functional [Boolean] block should be executed but not shipped as outpu
20
+ #
21
+ def initialize(block, async: false, functional: false)
10
22
  @block = block
11
23
  @async = async
24
+ @functional = functional
12
25
  end
13
26
 
27
+ #
28
+ # Whether response block is functional, means no output should
29
+ # be processed after execution of block
30
+ #
31
+ # @return [Boolean] <description>
32
+ #
33
+ def functional?
34
+ @functional
35
+ end
36
+
37
+ #
38
+ # Should execution of block be async?
39
+ #
40
+ # @return [Boolean] <description>
41
+ #
14
42
  def async?
15
43
  @async
16
44
  end
@@ -7,12 +7,25 @@ require_relative "../helpers/input_output_pair"
7
7
  module Kanal
8
8
  module Core
9
9
  module Helpers
10
+ #
11
+ # This class executes response block and constructs output
12
+ # It is also can execute response block and disable moving it forward to the
13
+ # queue
14
+ #
10
15
  class ResponseExecutionBlock
11
16
  include Output
12
17
  include Logging::Logger
13
18
 
14
19
  attr_reader :response_block, :input
15
20
 
21
+ #
22
+ # Creating response execution block with all needed parameters
23
+ #
24
+ # @param response_block [Kanal::Core::Helpers::ResponseBlock] response block
25
+ # @param input [Kanal::Core::Input::Input] input provided by router
26
+ # @param default_error_node [Kanal::Core::Router::RouterNode] default error node if no user defined error node available
27
+ # @param error_node [Kanal::Core::Router::RouterNode] user (developer of bot) defined error node with information about error
28
+ #
16
29
  def initialize(response_block, input, default_error_node, error_node)
17
30
  @response_block = response_block
18
31
  @input = input
@@ -20,31 +33,61 @@ module Kanal
20
33
  @error_node = error_node
21
34
  end
22
35
 
36
+ #
37
+ # Execute response block and ship created output into the queue
38
+ #
39
+ # @param core [Kanal::Core::Core] core to access parameter registrators and stuff TODO: remove core here and provide registrator as dependency
40
+ # @param input_output_pair_queue [Kanal::Core::Helpers::Queue] queue where Kanal::Core::Helpers::InputOutputPair will be stored
41
+ #
42
+ # @return [void] <description>
43
+ #
23
44
  def execute(core, input_output_pair_queue)
24
45
  if response_block.async?
25
46
  # NOTE: Thread doesnt just die here - it's execution is continued in input_output_pair_queue.enqueue in router
26
47
  # then :item_queued hook is called inside and subsequently output_ready_block gets called in this thread
27
48
  # TODO: be aware that this can cause unexpected behaviour. Maybe think how to rework it.
28
49
  Thread.new do
29
- input_output_pair_queue.enqueue InputOutputPair.new(@input, construct_output(core))
50
+ output = construct_output core
51
+ unless output.canceled?
52
+ input_output_pair_queue.enqueue InputOutputPair.new(@input, output)
53
+ end
30
54
  end
31
55
  else
32
- input_output_pair_queue.enqueue InputOutputPair.new(@input, construct_output(core))
56
+ output = construct_output core
57
+ unless output.canceled?
58
+ input_output_pair_queue.enqueue InputOutputPair.new(@input, output)
59
+ end
33
60
  end
34
61
  end
35
62
 
36
63
  private
37
64
 
65
+ #
66
+ # Construct output from response block
67
+ #
68
+ # @param core [Kanal::Core::Core] core to access registrator
69
+ #
70
+ # @return [Kanal::Core::Output::Output] output created
71
+ #
38
72
  def construct_output(core)
39
73
  logger.debug "Constructing output for input ##{input.__id__}"
40
74
 
41
75
  output = Output::Output.new core.output_parameter_registrator, @input, core
42
76
 
77
+ # Canceling output to be processed further if response block is functional.
78
+ # Whole .functional thing is done to allow after_respond and after_respond_async blocks
79
+ # that should not spawn outputs
80
+ output.cancel if @response_block.functional?
81
+
43
82
  begin
44
83
  core.hooks.call :output_just_created, input, output
45
84
 
85
+ # Evaluating response block
46
86
  output.instance_eval(&@response_block.block)
47
87
  rescue => e
88
+ # Something wrong happened
89
+ # we try and construct error response provided by the user (dev created bot)
90
+ # if there is no any - we use default user response block
48
91
  logger.error "Failed to construct output for input ##{input.__id__}. Error: '#{e}'"
49
92
 
50
93
  output = Output::Output.new core.output_parameter_registrator, @input, core
@@ -56,6 +99,9 @@ module Kanal
56
99
  begin
57
100
  output.instance_eval(&error_node.response_blocks.first.block)
58
101
  rescue => e
102
+ # Something wrong happened in user defined error response or
103
+ # for some reason even default error response block failed
104
+ # Logging error and trying default error block
59
105
  logger.error "Failed to construct error response for input ##{input.__id__}. Error: '#{e}'"
60
106
 
61
107
  logger.debug "Trying to construct default error response for input ##{input.__id__}"
@@ -12,23 +12,41 @@ module Kanal
12
12
  include Helpers
13
13
  include Helpers::ParameterFinderWithMethodMissingMixin
14
14
 
15
- attr_reader :input, :core
15
+ attr_reader :input, :core, :canceled
16
16
 
17
17
  #
18
- # @param parameter_registrator [Kanal::Core::Helpers::ParameterRegistrator]
18
+ # Creates new output with input, core and registered output parameters
19
+ #
20
+ # @param parameter_registrator [Kanal::Core::Helpers::ParameterRegistrator]
19
21
  # @param input [Kanal::Core::Input::Input] input required for dsl in respond blocks to have access to input
20
22
  # @param core [Kanal::Core::Core] core required also for dsl to access services or other information about core
21
23
  def initialize(parameter_registrator, input, core)
22
24
  @core = core
23
25
  @input = input
24
26
  @parameter_bag = ParameterBagWithRegistrator.new parameter_registrator
27
+ @canceled = false
25
28
  end
26
29
 
27
30
  def configure_dsl(&block)
28
31
  instance_eval(&block)
29
32
  end
30
33
 
34
+ def canceled?
35
+ @canceled == true
36
+ end
37
+
38
+ #
39
+ # Canceles this output.
40
+ # It won't be processed further and given out from router
41
+ #
42
+ # @return [void] <description>
43
+ #
44
+ def cancel
45
+ @canceled = true
46
+ end
47
+
31
48
  private :core
49
+
32
50
  end
33
51
  end
34
52
  end
@@ -176,7 +176,9 @@ module Kanal
176
176
 
177
177
  error_node = @error_node || @default_error_node
178
178
 
179
- response_execution_blocks = response_blocks.map { |rb| ResponseExecutionBlock.new rb, input, @default_error_node, @error_node }
179
+ response_execution_blocks = response_blocks.map do |rb|
180
+ ResponseExecutionBlock.new rb, input, @default_error_node, @error_node
181
+ end
180
182
 
181
183
  response_execution_blocks.each do |reb|
182
184
  @response_execution_queue.enqueue reb
@@ -72,6 +72,18 @@ module Kanal
72
72
  @response_blocks.append ResponseBlock.new(block, async: true)
73
73
  end
74
74
 
75
+ def after_respond(&block)
76
+ raise "Router node with children cannot have response" unless @children.empty?
77
+
78
+ @response_blocks.append ResponseBlock.new(block, functional: true)
79
+ end
80
+
81
+ def after_respond_async(&block)
82
+ raise "Router node with children cannot have response" unless @children.empty?
83
+
84
+ @response_blocks.append ResponseBlock.new(block, functional: true, async: true)
85
+ end
86
+
75
87
  def response?
76
88
  !@response_blocks.empty?
77
89
  end
@@ -2,6 +2,7 @@
2
2
 
3
3
  require "kanal/core/plugins/plugin"
4
4
  require_relative "keyboard"
5
+ require_relative "specifics"
5
6
 
6
7
  module Kanal
7
8
  module Plugins
@@ -23,6 +24,7 @@ module Kanal
23
24
  keyboard_batteries core
24
25
  username_batteries core
25
26
  button_batteries core
27
+ specifics_batteries core
26
28
  end
27
29
 
28
30
  def flow_batteries(core)
@@ -237,6 +239,14 @@ module Kanal
237
239
  end
238
240
  end
239
241
  end
242
+
243
+ def specifics_batteries(core)
244
+ core.register_output_parameter :specifics
245
+
246
+ core.hooks.attach :output_just_created do |input, output|
247
+ output.specifics = Specifics.new
248
+ end
249
+ end
240
250
  end
241
251
  end
242
252
  end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "kanal/core/logging/composite_logger"
4
+
5
+ module Kanal
6
+ module Plugins
7
+ module Batteries
8
+ #
9
+ # This class provides possibility to store custom key-value pairs in outputs
10
+ #
11
+ class Specifics
12
+ include Kanal::Core::Logging
13
+
14
+ def initialize
15
+ @specifics = {}
16
+ end
17
+
18
+ def add(specific_name, specific_value)
19
+ @specifics[specific_name] = specific_value
20
+ end
21
+
22
+ def get(specific_name)
23
+ return nil unless has? specific_name
24
+
25
+ @specifics[specific_name]
26
+ end
27
+
28
+ def has?(specific_name)
29
+ @specifics.key? specific_name
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
data/lib/kanal/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Kanal
4
- VERSION = "0.6.0"
4
+ VERSION = "0.8.0"
5
5
  end
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.6.0
4
+ version: 0.8.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-24 00:00:00.000000000 Z
11
+ date: 2023-05-02 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
@@ -63,6 +63,7 @@ files:
63
63
  - lib/kanal/plugins/batteries/attachments/attachment.rb
64
64
  - lib/kanal/plugins/batteries/batteries_plugin.rb
65
65
  - lib/kanal/plugins/batteries/keyboard.rb
66
+ - lib/kanal/plugins/batteries/specifics.rb
66
67
  - lib/kanal/version.rb
67
68
  - lib/shortcuts.rb
68
69
  - sig/kanal.rbs