kanal 0.4.2 → 0.5.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: 3a651f7ffee3a091afafa59e96d5c4e90d3f15ebd8fe5c0991ef0f3d25559cb5
4
- data.tar.gz: 80a337f6047a542982f5167a1a15c73a9df90ffa95d6d24dc07bba881a4f575e
3
+ metadata.gz: 17fda67309b135e40e75787a8b2aba0908259bf25b55f3da4ad7170082090745
4
+ data.tar.gz: 0f751de312d93913c2f81e3b69eaee000359fa01327c873c64a128e46d88286c
5
5
  SHA512:
6
- metadata.gz: 69b67d9f7886722abe0cc0b8ba27e30daecde925a275e3147b38c5b80bb1b9d041d1acdd33151be97c8e4a668888fbcf1819192dceb763e52104bfaa97a56ce4
7
- data.tar.gz: fb12441c0c5797397cbc40e4517cc23c6a70c6604a0314961d4c9b203c02130464baefda7c6671cd31733112d4f131076de3d92482d695f10b7898c7b5c7b2c8
6
+ metadata.gz: 8523d9eeed98f12107d9550cdc6e823707df37a817ed055229fa7b4b45c12d99e2786e83e1fd3be74acf98e4c01d2312aab37fa86f52869b7583ad3885c1def2
7
+ data.tar.gz: aa2272b6afcbf4f1dc655c7ed91e57df4caa0e046e4e420c0ddb5985d6cc7b470d05aa3bf372b656004aa5519e1071307d9de84ac1c4e0d6dfb4fe43a70ac6b4
data/CHANGELOG.md CHANGED
@@ -1,5 +1,14 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [0.5.0] 2023-04-14
4
+ - 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
+ - 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)
6
+ - internal: output hook :output_before_returned is executed after it was enqueued into the output_input_pair_queue. Meaning hook executed not right after processing respond blocks and creating output, but after it was enqueued to the queue which purpose is to ship output further into the `.output_ready(&block)` consumer. It was done so router public method `.provide_output_with_input(output, input)` was possible (avoiding router but not end hook)
7
+
8
+ ## [0.4.3] 2023-03-30
9
+ - New condition for button pressed
10
+ - Input property button_pressed
11
+
3
12
  ## [0.4.2] 2023-03-22
4
13
  - Adding any number of loggers can be now done with core.add_logger(l) - where l is logger that have same methods as default ruby logger (debug, warn, fatal, etc)
5
14
  - To get logger into your class you can include Kanal::Core::Logging::Logger - this will give you method .logger to get logger
data/Gemfile.lock CHANGED
@@ -1,94 +1,94 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- kanal (0.4.2)
4
+ kanal (0.5.0)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
8
8
  specs:
9
9
  ast (2.4.2)
10
10
  backport (1.2.0)
11
- benchmark (0.2.0)
11
+ benchmark (0.2.1)
12
12
  diff-lcs (1.5.0)
13
13
  docile (1.4.0)
14
14
  e2mmap (0.1.0)
15
15
  jaro_winkler (1.5.4)
16
- json (2.6.2)
16
+ json (2.6.3)
17
17
  kramdown (2.4.0)
18
18
  rexml
19
19
  kramdown-parser-gfm (1.1.0)
20
20
  kramdown (~> 2.0)
21
- mini_portile2 (2.8.0)
22
- nokogiri (1.13.8)
21
+ mini_portile2 (2.8.1)
22
+ nokogiri (1.14.3)
23
23
  mini_portile2 (~> 2.8.0)
24
24
  racc (~> 1.4)
25
- nokogiri (1.13.8-x86_64-darwin)
25
+ nokogiri (1.14.3-x86_64-darwin)
26
26
  racc (~> 1.4)
27
27
  parallel (1.22.1)
28
- parser (3.1.2.0)
28
+ parser (3.2.2.0)
29
29
  ast (~> 2.4.1)
30
- racc (1.6.0)
30
+ racc (1.6.2)
31
31
  rainbow (3.1.1)
32
32
  rake (13.0.6)
33
- regexp_parser (2.5.0)
33
+ rbs (2.8.4)
34
+ regexp_parser (2.7.0)
34
35
  reverse_markdown (2.1.1)
35
36
  nokogiri
36
37
  rexml (3.2.5)
37
- rspec (3.11.0)
38
- rspec-core (~> 3.11.0)
39
- rspec-expectations (~> 3.11.0)
40
- rspec-mocks (~> 3.11.0)
41
- rspec-core (3.11.0)
42
- rspec-support (~> 3.11.0)
43
- rspec-expectations (3.11.0)
38
+ rspec (3.12.0)
39
+ rspec-core (~> 3.12.0)
40
+ rspec-expectations (~> 3.12.0)
41
+ rspec-mocks (~> 3.12.0)
42
+ rspec-core (3.12.1)
43
+ rspec-support (~> 3.12.0)
44
+ rspec-expectations (3.12.2)
44
45
  diff-lcs (>= 1.2.0, < 2.0)
45
- rspec-support (~> 3.11.0)
46
- rspec-mocks (3.11.1)
46
+ rspec-support (~> 3.12.0)
47
+ rspec-mocks (3.12.5)
47
48
  diff-lcs (>= 1.2.0, < 2.0)
48
- rspec-support (~> 3.11.0)
49
- rspec-support (3.11.0)
50
- rubocop (1.33.0)
49
+ rspec-support (~> 3.12.0)
50
+ rspec-support (3.12.0)
51
+ rubocop (1.50.0)
51
52
  json (~> 2.3)
52
53
  parallel (~> 1.10)
53
- parser (>= 3.1.0.0)
54
+ parser (>= 3.2.0.0)
54
55
  rainbow (>= 2.2.2, < 4.0)
55
56
  regexp_parser (>= 1.8, < 3.0)
56
57
  rexml (>= 3.2.5, < 4.0)
57
- rubocop-ast (>= 1.19.1, < 2.0)
58
+ rubocop-ast (>= 1.28.0, < 2.0)
58
59
  ruby-progressbar (~> 1.7)
59
- unicode-display_width (>= 1.4.0, < 3.0)
60
- rubocop-ast (1.19.1)
61
- parser (>= 3.1.1.0)
60
+ unicode-display_width (>= 2.4.0, < 3.0)
61
+ rubocop-ast (1.28.0)
62
+ parser (>= 3.2.1.0)
62
63
  ruby-debug-ide (0.7.3)
63
64
  rake (>= 0.8.1)
64
- ruby-progressbar (1.11.0)
65
- simplecov (0.21.2)
65
+ ruby-progressbar (1.13.0)
66
+ simplecov (0.22.0)
66
67
  docile (~> 1.1)
67
68
  simplecov-html (~> 0.11)
68
69
  simplecov_json_formatter (~> 0.1)
69
70
  simplecov-html (0.12.3)
70
71
  simplecov_json_formatter (0.1.4)
71
- solargraph (0.45.0)
72
+ solargraph (0.49.0)
72
73
  backport (~> 1.2)
73
74
  benchmark
74
- bundler (>= 1.17.2)
75
+ bundler (~> 2.0)
75
76
  diff-lcs (~> 1.4)
76
77
  e2mmap
77
78
  jaro_winkler (~> 1.5)
78
79
  kramdown (~> 2.3)
79
80
  kramdown-parser-gfm (~> 1.1)
80
81
  parser (~> 3.0)
81
- reverse_markdown (>= 1.0.5, < 3)
82
- rubocop (>= 0.52)
82
+ rbs (~> 2.0)
83
+ reverse_markdown (~> 2.0)
84
+ rubocop (~> 1.38)
83
85
  thor (~> 1.0)
84
86
  tilt (~> 2.0)
85
87
  yard (~> 0.9, >= 0.9.24)
86
88
  thor (1.2.1)
87
- tilt (2.0.11)
88
- unicode-display_width (2.2.0)
89
- webrick (1.7.0)
90
- yard (0.9.28)
91
- webrick (~> 1.7.0)
89
+ tilt (2.1.0)
90
+ unicode-display_width (2.4.2)
91
+ yard (0.9.33)
92
92
 
93
93
  PLATFORMS
94
94
  ruby
@@ -105,4 +105,4 @@ DEPENDENCIES
105
105
  yard
106
106
 
107
107
  BUNDLED WITH
108
- 2.3.19
108
+ 2.4.5
data/README.md CHANGED
@@ -1,18 +1,142 @@
1
- # Kanal
2
1
 
3
- Welcome to kanal!
2
+ # Kanal
4
3
 
5
- TODO: Delete this and the text above, and describe your gem
4
+ Welcome to Kanal!
5
+
6
+ Kanal is a platform to create chat-bots with it's own DSL. As a key feature Kanal provides router which is configured by you, the developer. Configuration of router implies setting specific responses to specific inputs. Router can consume input (text, images, audio, files) and prepare response (or several responses) to it to be processed further. Configured router defines chat-bot's communication logic that can be used by different types of chat-platforms (Telegram, Discord, etc.)
7
+
8
+ Core functionality of Kanal can be extended with plugins. For example, plugins can provide database to store data; user system that allows storing and working with data of end-users of chat-bot; integration with telegram or discord to receive messages from end-users and responses to be sent to them. Kanal has Batteries plugin that allows input and output to have text and also image, audio or file attached.
9
+
10
+ ## Overview of Kanal components
11
+ #### Core
12
+ Core is is a key Kanal component. To create the Kanal app is to create Core.
13
+ ```
14
+ core = Kanal::Core::Core.new
15
+ ```
16
+ #### Input and Output
17
+ Input is an object representing information received from end-user. To store data inside Input and access it later you need to register parameter for it. Then you can pass your data to it.
18
+ ```
19
+ core.register_input_parameter :test_parameter
20
+ input = core.create_input
21
+ input.test_parameter = "test_value"
22
+ ```
23
+ Batteries plugin provides pre-made parameters, such as body and source.
24
+ ```
25
+ input.body = <Your string>
26
+ # Source should be of Symbol type
27
+ input.source = :telegram
28
+ input.audio =
29
+ input.image =
30
+ input.file =
31
+ ```
32
+ TODO: Describe image, audio and file parameters. Are they supposed to contain url strings?
33
+
34
+ Output is an object representing information ready to be sent to end-user. As with Input, you can register your own parameters. Batteries provides same parameters for Output as for Input.
35
+ #### Conditions
36
+ Condition is a true/false blocks that will tell the router if particular route should be used. Conditions are registered within the `condition pack` that has specific name.
37
+ ```
38
+ core.add_condition_pack :contains_day_of_week do
39
+ add_condition :friday
40
+ met? do |input, core, argument|
41
+ # Rememer how you registered .body parameter of input? It will be accessible in condition here!
42
+ input.body.include? "friday"
43
+ end
44
+ end
45
+
46
+ add_condition :monday
47
+ met? do |input, core, argument|
48
+ input.body.include? "monday"
49
+ end
50
+ end
51
+ end
52
+ ```
53
+ #### Router
54
+ Router is a collection of responses to specific conditions defined by user. Upon meeting the condition router will create output (or outputs). Using previously made conditions we can specify what operation will be performed and what the output (outputs) will contain.
55
+ ```
56
+ core.router.configure do
57
+ on :contains_day_of_week :friday do
58
+ respond do
59
+ body "What, already?"
60
+ end
61
+ end
62
+
63
+ on :contains_day_of_week :tuesday do
64
+ respond do
65
+ body "Start of the week huh"
66
+ end
67
+
68
+ respond_async do
69
+ <http request or database call here>
70
+ body "I will work tirelessly!"
71
+ end
72
+ end
73
+ end
74
+ ```
75
+ In respond block you can do anything besides setting output parameters.
76
+
77
+ _It is advised to make database calls, http requests or other time-consuming operations in respond_async block._
78
+
79
+ Router has built-in default response for when none of the conditions are met. You can set your own default response.
80
+ ```
81
+ core.router.default_response do
82
+ body "Custom default message here"
83
+ end
84
+ ```
85
+
86
+ Router has built-in error response for when there is an error during constructing of output. You can set your own error response.
87
+ ```
88
+ core.router.error_response do
89
+ body "Custom error message here"
90
+ end
91
+ ```
92
+
93
+ #### Hooks
94
+ Hooks can be used to intercept the execution flow in specific places in your code and do something with data provided to it. Hooks are registered in the Core. You can attach to hook, specifying arguments and block of code to be executed. When the hook will be called, the argument will be passed to provided block and it will be executed.
95
+ ```
96
+ core.hook_storage.register :on_something
97
+ val = nil
98
+ hooks.attach :on_something do |value|
99
+ val = value
100
+ end
101
+ hooks.call :on_something, "testy"
102
+ puts val # "testy"
103
+ ```
104
+
105
+ By default core has 3 hooks.
106
+ ```
107
+ :input_just_created # input
108
+ :input_before_router # input
109
+ :output_before_returned # input, output
110
+ ```
111
+
112
+ #### Attachments
113
+ Batteries plugin provides Attachments functionality.
114
+ ```
115
+ attachment = ::Attachment.new "https://website.com/filename.jpg"
116
+ # Get the url value
117
+ attachment.url # "https://website.com/filename.jpg"
118
+ # Get url file extension
119
+ attachment.extension # "jpg"
120
+ # Different helper methods for different multimedia types.
121
+ attachment.jpg? # True
122
+ attachment.image? # True
123
+ attachment.mp3? # False
124
+ attachment.audio? # False
125
+ ```
126
+ #### Interfaces
127
+ #### Plugins
128
+ #### Interfaces
129
+ #### Plugins
6
130
 
7
131
  ## Installation
8
132
 
9
133
  Install the gem and add to the application's Gemfile by executing:
10
134
 
11
- $ bundle add kanal
135
+ $ bundle add kanal
12
136
 
13
137
  If bundler is not being used to manage dependencies, install the gem by executing:
14
138
 
15
- $ gem install kanal
139
+ $ gem install kanal
16
140
 
17
141
  ## Usage
18
142
 
@@ -20,13 +144,13 @@ TODO: Write usage instructions here
20
144
 
21
145
  ## TODO
22
146
 
23
- - [DONE] ~provide default response for branch with subbranches because default response could be handy~
24
- Provided with the :flow condition pack with condition :any
147
+ - [DONE] ~provide default response for branch with subbranches because default response could be handy~
148
+ Provided with the :flow condition pack with condition :any
25
149
  - [DONE] ~rework hooks storage, make hooks without arguments validation~
26
- - provide default logger with base class. this logger service should be used by every other service/plugin etc
27
- - provide default response on error, when router node fails with error
28
- - [DONE] ~provide :source condition for :source~
29
- Created :source condition pack
150
+ - ~provide default logger with base class. this logger service should be used by every other service/plugin etc~
151
+ - ~provide default response on error, when router node fails with error~
152
+ - [DONE] ~provide :source condition for :source~
153
+ Created :source condition pack
30
154
  - Allow to "append" conditions to condition packs
31
155
 
32
156
 
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kanal
4
+ module Core
5
+ module Helpers
6
+ #
7
+ # Objects of this class are constructed by router to be put into #router.input_output_pair_queue
8
+ # It is needed so we don't keep input directly in output as a parameter
9
+ # Upon queueing these objects processed in item_added hook, for which input might be needed
10
+ #
11
+ class InputOutputPair
12
+ attr_reader :input, :output
13
+
14
+ def initialize(input, output)
15
+ @input = input
16
+ @output = output
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative "../logging/composite_logger"
4
+
3
5
  module Kanal
4
6
  module Core
5
7
  module Helpers
@@ -8,22 +10,32 @@ module Kanal
8
10
  # get(name)
9
11
  # transforms unknown methods to setters/getters for parameters
10
12
  module ParameterFinderWithMethodMissingMixin
11
- def method_missing(symbol, *args)
13
+ include Logging::Logger
14
+
15
+ def method_missing(symbol, *args, &block)
16
+ if block && !args.first.nil?
17
+ logger.error "Block and arg given simultaneously. Parameter name: '#{symbol.to_s}, arg: #{args.first}'"
18
+
19
+ raise "Block and arg given simultaneously for parameter #{symbol.to_s}"
20
+ end
21
+
12
22
  parameter_name = symbol.to_s
13
23
  parameter_name.sub! "=", ""
14
24
 
15
25
  parameter_name = parameter_name.to_sym
16
26
 
27
+ value = block_given? ? block : args.first
28
+
17
29
  # standard workflow with settings properties with
18
30
  # input.prop = 123
19
31
  if symbol.to_s.include? "="
20
- @parameter_bag.set parameter_name, args.first
21
- elsif !args.empty?
32
+ @parameter_bag.set parameter_name, value
33
+ elsif !args.empty? || block_given?
22
34
  # this approach can be used also in dsl
23
35
  # like that
24
36
  # setters: prop value
25
37
  # getters: prop
26
- @parameter_bag.set parameter_name, args.first
38
+ @parameter_bag.set parameter_name, value
27
39
  # means it is used as setter in dsl,
28
40
  # method call with argument
29
41
  else
@@ -2,6 +2,7 @@
2
2
 
3
3
  require_relative "../output/output"
4
4
  require_relative "../logging/logger"
5
+ require_relative "../helpers/input_output_pair"
5
6
 
6
7
  module Kanal
7
8
  module Core
@@ -19,16 +20,16 @@ module Kanal
19
20
  @error_node = error_node
20
21
  end
21
22
 
22
- def execute(core, output_queue)
23
+ def execute(core, input_output_pair_queue)
23
24
  if response_block.async?
24
- # NOTE: Thread doesnt just die here - it's execution is continued in output_queue.enqueue in router
25
+ # NOTE: Thread doesnt just die here - it's execution is continued in input_output_pair_queue.enqueue in router
25
26
  # then :item_queued hook is called inside and subsequently output_ready_block gets called in this thread
26
27
  # TODO: be aware that this can cause unexpected behaviour. Maybe think how to rework it.
27
28
  Thread.new do
28
- output_queue.enqueue construct_output(core)
29
+ input_output_pair_queue.enqueue InputOutputPair.new(@input, construct_output(core))
29
30
  end
30
31
  else
31
- output_queue.enqueue construct_output(core)
32
+ input_output_pair_queue.enqueue InputOutputPair.new(@input, construct_output(core))
32
33
  end
33
34
  end
34
35
 
@@ -37,18 +38,16 @@ module Kanal
37
38
  def construct_output(core)
38
39
  logger.info "Constructing output for input ##{input.__id__}"
39
40
 
40
- output = Output::Output.new core.output_parameter_registrator, input, core
41
+ output = Output::Output.new core.output_parameter_registrator, core
41
42
 
42
43
  begin
43
44
  core.hooks.call :output_just_created, input, output
44
45
 
45
46
  output.instance_eval(&@response_block.block)
46
-
47
- core.hooks.call :output_before_returned, input, output
48
47
  rescue => e
49
48
  logger.error "Failed to construct output for input ##{input.__id__}. Error: '#{e}'"
50
49
 
51
- output = Output::Output.new core.output_parameter_registrator, input, core
50
+ output = Output::Output.new core.output_parameter_registrator, core
52
51
 
53
52
  error_node = @error_node || @default_error_node
54
53
 
@@ -56,16 +55,12 @@ module Kanal
56
55
 
57
56
  begin
58
57
  output.instance_eval(&error_node.response_blocks.first.block)
59
-
60
- core.hooks.call :output_before_returned, input, output
61
58
  rescue => e
62
59
  logger.error "Failed to construct error response for input ##{input.__id__}. Error: '#{e}'"
63
60
 
64
61
  logger.info "Trying to construct default error response for input ##{input.__id__}"
65
62
 
66
63
  output.instance_eval(&@default_error_node.response_blocks.first.block)
67
-
68
- core.hooks.call :output_before_returned, input, output
69
64
  end
70
65
  end
71
66
 
@@ -12,10 +12,9 @@ module Kanal
12
12
  include Helpers
13
13
  include Helpers::ParameterFinderWithMethodMissingMixin
14
14
 
15
- attr_reader :input, :core
15
+ attr_reader :core
16
16
 
17
- def initialize(parameter_registrator, input, core)
18
- @input = input
17
+ def initialize(parameter_registrator, core)
19
18
  @core = core
20
19
  @parameter_bag = ParameterBagWithRegistrator.new parameter_registrator
21
20
  end
@@ -3,6 +3,7 @@
3
3
  require_relative "./router_node"
4
4
  require_relative "../helpers/queue"
5
5
  require_relative "../helpers/response_execution_block"
6
+ require_relative "../helpers/input_output_pair"
6
7
  require_relative "../logging/composite_logger"
7
8
 
8
9
  module Kanal
@@ -35,20 +36,30 @@ module Kanal
35
36
  end
36
37
  @error_node = nil
37
38
  @response_execution_queue = Queue.new
38
- @output_queue = Queue.new
39
+ @input_output_pair_queue = Queue.new
39
40
  @output_ready_block = nil
40
41
  @core.hooks.register(:output_ready) # arg
41
42
 
42
43
  _this = self
43
- _output_queue = @output_queue
44
- @output_queue.hooks.attach :item_queued do |output|
45
- _this.logger.info "Calling output_ready block for input ##{output.input.__id__} and output #{output.__id__}. Output body is: '#{output.body}'"
44
+ _input_output_pair_queue = @input_output_pair_queue
45
+ # Attaching to the queue hook to capture enqueued output and move it
46
+ # forward in the workflow: apply hooks in :output_before_ready and pass it to
47
+ # the end consumer which uses .output_ready(&block)
48
+ @input_output_pair_queue.hooks.attach :item_queued do |input_output_pair|
49
+ _this.logger.info "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}'"
46
50
 
47
51
  begin
48
- _this.output_ready_block.call output
49
- _output_queue.remove(output)
52
+ _this.core.hooks.call :output_before_returned, input_output_pair.input, input_output_pair.output
53
+ rescue => e
54
+ logger.error "Error during output_before_returned call: #{e}"
55
+ return
56
+ end
57
+
58
+ begin
59
+ _this.output_ready_block.call input_output_pair.output
60
+ _input_output_pair_queue.remove(input_output_pair)
50
61
  rescue
51
- _output_queue.remove(output)
62
+ _input_output_pair_queue.remove(input_output_pair)
52
63
  raise "Error in output_ready block!"
53
64
  end
54
65
  end
@@ -85,6 +96,45 @@ module Kanal
85
96
  @error_node.respond(&block)
86
97
  end
87
98
 
99
+ # Method allows to pass output with input directly to the end step,
100
+ # when outputs are processed after router. Meaning it will not go
101
+ # through router, but will have all hooks in :output_before_returned executed for it.
102
+ # Input is needed for hooks to work properly.
103
+ #
104
+ # WARNING: this method AVOIDS router whatsoever
105
+ # Why use this method? If you want router to give out (through output_ready(&block) method) output without
106
+ # passing through router but with hooks called (many plugins use hooks to alter the output) - you
107
+ # use this method.
108
+ #
109
+ # This method adds input-output pair into input_output_pair_queue for it to be processed in item_queued hook
110
+ #
111
+ # param [Kanal::Core::Output::Output] output <description>
112
+ # param [Kanal::Core::Input::Input] input <description>
113
+ #
114
+ def provide_output_with_input(output, input)
115
+ @input_output_pair_queue.enqueue InputOutputPair.new input, output
116
+ end
117
+
118
+ #
119
+ # Method allows to pass output directly to the end output
120
+ # consumer (code which uses .output_ready(&block). Without passing router and
121
+ # without passing hooks attached to :output_before_ready
122
+ #
123
+ # WARNING: output provided via this method will avoid any alteration by the
124
+ # router inner machinery and will go directly to the output consumer
125
+ #
126
+ # Why use this method? If you want to pass output with your manually defined
127
+ # properties to the output consumer (which uses .output_ready(&block))
128
+ # without any alternations by the router system.
129
+ #
130
+ # This method calls output_ready_block on pre-formed output right away
131
+ #
132
+ # param [Kanal::Core::Output] output <description>
133
+ #
134
+ def provide_output(output)
135
+ @output_ready_block.call output
136
+ end
137
+
88
138
  # Main method for creating output(s) if it is found or going to default output
89
139
  def consume_input(input)
90
140
  logger.info "Consuming input #{input.__id__}."
@@ -139,7 +189,7 @@ module Kanal
139
189
  until @response_execution_queue.empty?
140
190
  response_execution = @response_execution_queue.dequeue
141
191
 
142
- response_execution.execute core, @output_queue
192
+ response_execution.execute core, @input_output_pair_queue
143
193
  end
144
194
  end
145
195
 
@@ -15,76 +15,25 @@ module Kanal
15
15
  @url = url
16
16
  end
17
17
 
18
- def audio?
19
- mp3? || wav? || ogg?
20
- end
21
-
22
- def mp3?
23
- extension == "mp3"
24
- end
25
-
26
- def wav?
27
- extension == "wav"
28
- end
29
-
30
- def ogg?
31
- extension == "ogg"
32
- end
33
-
34
- def document?
35
- doc? || docx? || odf?
36
- end
37
-
38
- def doc?
39
- extension == "doc"
40
- end
41
-
42
- def docx?
43
- extension == "docx"
44
- end
45
-
46
- def odf?
47
- extension == "odf"
18
+ # Extension checks like jpg?, mp3?, mp4?, doc? etc. fall here
19
+ def method_missing(method)
20
+ extension == method.to_s.delete("?")
48
21
  end
49
22
 
50
23
  def image?
51
- jpg? || jpeg? || png? || bpm? || gif?
52
- end
53
-
54
- def jpg?
55
- extension == "jpg"
56
- end
57
-
58
- def jpeg?
59
- extension == "jpeg"
60
- end
61
-
62
- def png?
63
- extension == "png"
24
+ [jpg?, jpeg?, png?, bmp?, gif?].any?
64
25
  end
65
26
 
66
- def bpm?
67
- extension == "bpm"
68
- end
69
-
70
- def gif?
71
- extension == "gif"
27
+ def audio?
28
+ [mp3?, wav?, ogg?].any?
72
29
  end
73
30
 
74
31
  def video?
75
- mp4? || mov? || mkv?
76
- end
77
-
78
- def mp4?
79
- extension == "mp4"
32
+ [mp4?, mov?, mkv?].any?
80
33
  end
81
34
 
82
- def mov?
83
- extension == "mov"
84
- end
85
-
86
- def mkv?
87
- extension == "mkv"
35
+ def document?
36
+ [doc?, docx?, odf?].any?
88
37
  end
89
38
 
90
39
  #
@@ -9,6 +9,8 @@ module Kanal
9
9
  module Batteries
10
10
  # Plugin with some batteries like .body property etc
11
11
  class BatteriesPlugin < Core::Plugins::Plugin
12
+
13
+
12
14
  def name
13
15
  :batteries
14
16
  end
@@ -19,6 +21,8 @@ module Kanal
19
21
  flow_batteries core
20
22
  attachments_batteries core
21
23
  keyboard_batteries core
24
+ username_batteries core
25
+ button_batteries core
22
26
  end
23
27
 
24
28
  def flow_batteries(core)
@@ -117,11 +121,95 @@ module Kanal
117
121
  def attachments_batteries(core)
118
122
  core.register_input_parameter :image
119
123
  core.register_input_parameter :audio
120
- core.register_input_parameter :file
124
+ core.register_input_parameter :video
125
+ core.register_input_parameter :document
121
126
 
122
127
  core.register_output_parameter :image
123
128
  core.register_output_parameter :audio
124
- core.register_output_parameter :file
129
+ core.register_output_parameter :video
130
+ core.register_output_parameter :document
131
+
132
+ _this = self
133
+
134
+ core.add_condition_pack :image do
135
+ add_condition :exists do
136
+ met? do |input, _core, _argument|
137
+ !input.image.nil?
138
+ end
139
+ end
140
+
141
+ add_condition :is do
142
+ with_argument
143
+
144
+ met? do |input, _, argument|
145
+ if input.image.image? && input.image.send((argument.to_s + "?").to_sym)
146
+ true
147
+ else
148
+ false
149
+ end
150
+ end
151
+ end
152
+ end
153
+
154
+ core.add_condition_pack :audio do
155
+ add_condition :exists do
156
+ met? do |input, _core, _argument|
157
+ !input.audio.nil?
158
+ end
159
+ end
160
+
161
+ add_condition :is do
162
+ with_argument
163
+
164
+ met? do |input, _, argument|
165
+ if input.audio.audio? && input.audio.send((argument.to_s + "?").to_sym)
166
+ true
167
+ else
168
+ false
169
+ end
170
+ end
171
+ end
172
+ end
173
+
174
+ core.add_condition_pack :video do
175
+ add_condition :exists do
176
+ met? do |input, _core, _argument|
177
+ !input.video.nil?
178
+ end
179
+ end
180
+
181
+ add_condition :is do
182
+ with_argument
183
+
184
+ met? do |input, _, argument|
185
+ if input.video.video? && input.video.send((argument.to_s + "?").to_sym)
186
+ true
187
+ else
188
+ false
189
+ end
190
+ end
191
+ end
192
+ end
193
+
194
+ core.add_condition_pack :document do
195
+ add_condition :exists do
196
+ met? do |input, _core, _argument|
197
+ !input.document.nil?
198
+ end
199
+ end
200
+
201
+ add_condition :is do
202
+ with_argument
203
+
204
+ met? do |input, _, argument|
205
+ if input.document.document? && input.document.send((argument.to_s + "?").to_sym)
206
+ true
207
+ else
208
+ false
209
+ end
210
+ end
211
+ end
212
+ end
125
213
  end
126
214
 
127
215
  def keyboard_batteries(core)
@@ -131,6 +219,24 @@ module Kanal
131
219
  output.keyboard = Keyboard.new
132
220
  end
133
221
  end
222
+
223
+ def username_batteries(core)
224
+ core.register_input_parameter :username
225
+ end
226
+
227
+ def button_batteries(core)
228
+ core.register_input_parameter :button_pressed
229
+
230
+ core.add_condition_pack :button do
231
+ add_condition :pressed do
232
+ with_argument
233
+
234
+ met? do |input, _, argument|
235
+ input.button_pressed == argument
236
+ end
237
+ end
238
+ end
239
+ end
134
240
  end
135
241
  end
136
242
  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.4.2"
4
+ VERSION = "0.5.0"
5
5
  end
data/lib/kanal.rb CHANGED
@@ -3,6 +3,7 @@
3
3
  require_relative "kanal/version"
4
4
  require_relative "kanal/core/core"
5
5
  require_relative "kanal/core/plugins/plugin"
6
+ require_relative "shortcuts"
6
7
 
7
8
  # This module used as a main entry point into kanal-core library
8
9
  module Kanal
data/lib/shortcuts.rb ADDED
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "./kanal/core/logging/logger"
4
+
5
+ module Kanal
6
+ module Logger
7
+ include Kanal::Core::Logging::Logger
8
+ end
9
+ 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.4.2
4
+ version: 0.5.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-03-22 00:00:00.000000000 Z
11
+ date: 2023-04-14 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
@@ -37,6 +37,7 @@ files:
37
37
  - lib/kanal/core/conditions/condition_storage.rb
38
38
  - lib/kanal/core/core.rb
39
39
  - lib/kanal/core/helpers/condition_finder.rb
40
+ - lib/kanal/core/helpers/input_output_pair.rb
40
41
  - lib/kanal/core/helpers/parameter_bag.rb
41
42
  - lib/kanal/core/helpers/parameter_bag_with_registrator.rb
42
43
  - lib/kanal/core/helpers/parameter_finder_with_method_missing_mixin.rb
@@ -63,6 +64,7 @@ files:
63
64
  - lib/kanal/plugins/batteries/batteries_plugin.rb
64
65
  - lib/kanal/plugins/batteries/keyboard.rb
65
66
  - lib/kanal/version.rb
67
+ - lib/shortcuts.rb
66
68
  - sig/kanal.rbs
67
69
  - sig/kanal/core/conditions/condition_pack.rbs
68
70
  - sig/kanal/core/conditions/condition_storage.rbs