charyf 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/Gemfile +6 -0
- data/Gemfile.lock +154 -0
- data/LICENSE.txt +21 -0
- data/README.md +18 -0
- data/Rakefile +6 -0
- data/bin/charyf-debug +7 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/charyf.gemspec +48 -0
- data/exe/charyf +4 -0
- data/lib/charyf/deps.rb +9 -0
- data/lib/charyf/engine/all.rb +22 -0
- data/lib/charyf/engine/charyf.rb +5 -0
- data/lib/charyf/engine/context.rb +61 -0
- data/lib/charyf/engine/controller/actions.rb +29 -0
- data/lib/charyf/engine/controller/controller.rb +62 -0
- data/lib/charyf/engine/controller/conversation.rb +58 -0
- data/lib/charyf/engine/controller/helpers.rb +38 -0
- data/lib/charyf/engine/controller/renderers.rb +103 -0
- data/lib/charyf/engine/dispatcher/base.rb +121 -0
- data/lib/charyf/engine/dispatcher/default.rb +60 -0
- data/lib/charyf/engine/intent/intent.rb +54 -0
- data/lib/charyf/engine/intent/processors/dummy.rb +30 -0
- data/lib/charyf/engine/intent/processors/helpers.rb +32 -0
- data/lib/charyf/engine/intent/processors/processor.rb +56 -0
- data/lib/charyf/engine/interface/interface.rb +35 -0
- data/lib/charyf/engine/interface/program.rb +59 -0
- data/lib/charyf/engine/request.rb +32 -0
- data/lib/charyf/engine/response.rb +41 -0
- data/lib/charyf/engine/session/processors/default.rb +42 -0
- data/lib/charyf/engine/session/processors/processor.rb +39 -0
- data/lib/charyf/engine/session/session.rb +68 -0
- data/lib/charyf/engine/skill/info.rb +24 -0
- data/lib/charyf/engine/skill/routing.rb +57 -0
- data/lib/charyf/engine/skill/skill.rb +40 -0
- data/lib/charyf/engine.rb +3 -0
- data/lib/charyf/support/all.rb +4 -0
- data/lib/charyf/support/hash.rb +43 -0
- data/lib/charyf/support/object.rb +7 -0
- data/lib/charyf/support/string.rb +94 -0
- data/lib/charyf/support/string_inquirer.rb +17 -0
- data/lib/charyf/support.rb +1 -0
- data/lib/charyf/utils/all.rb +13 -0
- data/lib/charyf/utils/app_engine/extensions.rb +21 -0
- data/lib/charyf/utils/app_engine.rb +24 -0
- data/lib/charyf/utils/app_loader.rb +38 -0
- data/lib/charyf/utils/application/bootstrap.rb +176 -0
- data/lib/charyf/utils/application/configuration.rb +51 -0
- data/lib/charyf/utils/application.rb +131 -0
- data/lib/charyf/utils/charyf.rb +44 -0
- data/lib/charyf/utils/cli.rb +14 -0
- data/lib/charyf/utils/command/actions.rb +24 -0
- data/lib/charyf/utils/command/base.rb +138 -0
- data/lib/charyf/utils/command/behavior.rb +81 -0
- data/lib/charyf/utils/command/environment_argument.rb +40 -0
- data/lib/charyf/utils/command.rb +106 -0
- data/lib/charyf/utils/commands/all.rb +6 -0
- data/lib/charyf/utils/commands/application/application_command.rb +21 -0
- data/lib/charyf/utils/commands/cli/cli_command.rb +115 -0
- data/lib/charyf/utils/commands/console/console_command.rb +77 -0
- data/lib/charyf/utils/commands/destroy/destroy_command.rb +26 -0
- data/lib/charyf/utils/commands/generate/generate_command.rb +31 -0
- data/lib/charyf/utils/commands/help/USAGE +9 -0
- data/lib/charyf/utils/commands/help/help.rb +20 -0
- data/lib/charyf/utils/commands.rb +15 -0
- data/lib/charyf/utils/configuration.rb +36 -0
- data/lib/charyf/utils/error_handler.rb +26 -0
- data/lib/charyf/utils/extension/configurable.rb +41 -0
- data/lib/charyf/utils/extension/configuration.rb +63 -0
- data/lib/charyf/utils/extension.rb +129 -0
- data/lib/charyf/utils/generator/actions.rb +281 -0
- data/lib/charyf/utils/generator/base.rb +288 -0
- data/lib/charyf/utils/generators/app/USAGE +8 -0
- data/lib/charyf/utils/generators/app/app_generator.rb +274 -0
- data/lib/charyf/utils/generators/app/templates/Gemfile.erb +20 -0
- data/lib/charyf/utils/generators/app/templates/README.md +24 -0
- data/lib/charyf/utils/generators/app/templates/app/skill_controller.rb.tt +8 -0
- data/lib/charyf/utils/generators/app/templates/bin/charyf +5 -0
- data/lib/charyf/utils/generators/app/templates/config/application.rb.tt +32 -0
- data/lib/charyf/utils/generators/app/templates/config/boot.rb.tt +4 -0
- data/lib/charyf/utils/generators/app/templates/config/chapp.rb.tt +5 -0
- data/lib/charyf/utils/generators/app/templates/config/environments/development.rb.tt +2 -0
- data/lib/charyf/utils/generators/app/templates/config/environments/production.rb.tt +2 -0
- data/lib/charyf/utils/generators/app/templates/config/environments/test.rb.tt +2 -0
- data/lib/charyf/utils/generators/app/templates/config/load.rb.tt +17 -0
- data/lib/charyf/utils/generators/app/templates/gitignore +18 -0
- data/lib/charyf/utils/generators/app_base.rb +277 -0
- data/lib/charyf/utils/generators/defaults.rb +75 -0
- data/lib/charyf/utils/generators/intents/intents_generator.rb +41 -0
- data/lib/charyf/utils/generators/named_base.rb +73 -0
- data/lib/charyf/utils/generators/skill/skill_generator.rb +47 -0
- data/lib/charyf/utils/generators/skill/templates/controllers/skill_controller.rb.tt +10 -0
- data/lib/charyf/utils/generators/skill/templates/module.rb.tt +6 -0
- data/lib/charyf/utils/generators/skill/templates/skill.rb.tt +3 -0
- data/lib/charyf/utils/generators.rb +187 -0
- data/lib/charyf/utils/initializable.rb +95 -0
- data/lib/charyf/utils/logger.rb +26 -0
- data/lib/charyf/utils/machine.rb +129 -0
- data/lib/charyf/utils/parser/en_parser.rb +97 -0
- data/lib/charyf/utils/parser/parser.rb +37 -0
- data/lib/charyf/utils/ruby_version_check.rb +15 -0
- data/lib/charyf/utils/storage/provider.rb +44 -0
- data/lib/charyf/utils/strategy.rb +44 -0
- data/lib/charyf/utils/utils.rb +64 -0
- data/lib/charyf/utils.rb +2 -0
- data/lib/charyf/version.rb +19 -0
- data/lib/charyf.rb +18 -0
- data/lib/locale/en.yml +206 -0
- data/todo.md +3 -0
- metadata +272 -0
@@ -0,0 +1,68 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
3
|
+
module Charyf
|
4
|
+
module Engine
|
5
|
+
class Session
|
6
|
+
|
7
|
+
attr_reader :uuid, :skill, :controller, :action, :timestamp
|
8
|
+
|
9
|
+
# TODO - mention it could return nil
|
10
|
+
# TODO sig
|
11
|
+
def self.get(uuid)
|
12
|
+
yaml = _storage.get(uuid)
|
13
|
+
yaml ? YAML.load(yaml) : nil
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.init(uuid, skill_name)
|
17
|
+
session = self.new(uuid, skill_name)
|
18
|
+
|
19
|
+
_storage.store(uuid, YAML.dump(session))
|
20
|
+
|
21
|
+
session
|
22
|
+
end
|
23
|
+
|
24
|
+
def route_to(controller, action)
|
25
|
+
@controller = controller
|
26
|
+
@action = action
|
27
|
+
end
|
28
|
+
|
29
|
+
def storage
|
30
|
+
@storage ||= Charyf.application.storage_provider.get_for("#{self.class}_#{@uuid}")
|
31
|
+
end
|
32
|
+
|
33
|
+
def keep!
|
34
|
+
@active = true
|
35
|
+
store!
|
36
|
+
end
|
37
|
+
|
38
|
+
def invalidate!
|
39
|
+
@active = false
|
40
|
+
self.class._storage.remove(@uuid)
|
41
|
+
end
|
42
|
+
|
43
|
+
def store!
|
44
|
+
@timestamp = Time.now
|
45
|
+
self.class._storage.store(@uuid, YAML.dump(self))
|
46
|
+
end
|
47
|
+
|
48
|
+
sig [], ['Symbol', 'String', 'NilClass'],
|
49
|
+
def full_controller_name
|
50
|
+
@controller.blank? ? nil : @skill.camelize + '::' + @controller.camelize
|
51
|
+
end
|
52
|
+
|
53
|
+
private
|
54
|
+
|
55
|
+
def initialize(uuid, skill)
|
56
|
+
@uuid = uuid
|
57
|
+
@skill = skill
|
58
|
+
@active = true
|
59
|
+
@timestamp = Time.now
|
60
|
+
end
|
61
|
+
|
62
|
+
def self._storage
|
63
|
+
@storage ||= Charyf.application.storage_provider.get_for(self)
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Charyf
|
2
|
+
module Skill
|
3
|
+
module Info
|
4
|
+
|
5
|
+
def self.included(base)
|
6
|
+
base.extend(ClassMethods)
|
7
|
+
end
|
8
|
+
|
9
|
+
module ClassMethods
|
10
|
+
|
11
|
+
sig ['String', 'Symbol', 'NilClass'], ['Symbol'],
|
12
|
+
def skill_name(name = nil)
|
13
|
+
if name
|
14
|
+
@_name = name.to_sym
|
15
|
+
end
|
16
|
+
|
17
|
+
@_name || self.name.gsub('::', ' ')
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
module Charyf
|
2
|
+
module Skill
|
3
|
+
module Routing
|
4
|
+
|
5
|
+
def self.included(base)
|
6
|
+
base.extend(ClassMethods)
|
7
|
+
end
|
8
|
+
|
9
|
+
module ClassMethods
|
10
|
+
|
11
|
+
sig ['Pathname'], ['Pathname'],
|
12
|
+
def routing_source_dir(abs_path = nil)
|
13
|
+
if abs_path
|
14
|
+
@_routing_source_dir = abs_path
|
15
|
+
end
|
16
|
+
|
17
|
+
@_routing_source_dir || skill_root.join('intents')
|
18
|
+
end
|
19
|
+
|
20
|
+
def public_routing_for(processor_name)
|
21
|
+
_public_routing(processor_name) << Proc.new
|
22
|
+
|
23
|
+
nil
|
24
|
+
end
|
25
|
+
|
26
|
+
def private_routing_for(processor_name)
|
27
|
+
_private_routing(processor_name) << Proc.new
|
28
|
+
|
29
|
+
nil
|
30
|
+
end
|
31
|
+
|
32
|
+
|
33
|
+
def _public_routing(processor)
|
34
|
+
processor = processor.to_sym
|
35
|
+
|
36
|
+
@_public_routing ||= Hash.new
|
37
|
+
|
38
|
+
@_public_routing[processor] ||= []
|
39
|
+
|
40
|
+
@_public_routing[processor]
|
41
|
+
end
|
42
|
+
|
43
|
+
def _private_routing(processor)
|
44
|
+
processor = processor.to_sym
|
45
|
+
|
46
|
+
@_public_routing ||= Hash.new
|
47
|
+
|
48
|
+
@_public_routing[processor] ||= []
|
49
|
+
|
50
|
+
@_public_routing[processor]
|
51
|
+
end
|
52
|
+
|
53
|
+
end # End of ClassMethods
|
54
|
+
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require_relative 'routing'
|
2
|
+
require_relative 'info'
|
3
|
+
|
4
|
+
module Charyf
|
5
|
+
module Skill
|
6
|
+
class Base
|
7
|
+
|
8
|
+
include Charyf::Skill::Routing
|
9
|
+
include Charyf::Skill::Info
|
10
|
+
|
11
|
+
class << self
|
12
|
+
attr_accessor :_file_path, :_file_name
|
13
|
+
|
14
|
+
def inherited(subclass)
|
15
|
+
Base._subclasses[subclass.name.demodulize] = subclass
|
16
|
+
|
17
|
+
# TODO this should be tested
|
18
|
+
subclass._file_path = Pathname.new(caller.first[/^[^:]+/]).dirname
|
19
|
+
subclass._file_name = Pathname.new(caller.first[/^[^:]+/]).basename
|
20
|
+
end
|
21
|
+
|
22
|
+
def _subclasses
|
23
|
+
@_subclasses ||= Hash.new
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.skill_root
|
29
|
+
self._file_path.join(self._file_name.sub_ext(''))
|
30
|
+
end
|
31
|
+
|
32
|
+
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.list
|
36
|
+
Base._subclasses.values
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
class Hash
|
2
|
+
# Returns a new hash with +self+ and +other_hash+ merged recursively.
|
3
|
+
#
|
4
|
+
# h1 = { a: true, b: { c: [1, 2, 3] } }
|
5
|
+
# h2 = { a: false, b: { x: [3, 4, 5] } }
|
6
|
+
#
|
7
|
+
# h1.deep_merge(h2) # => { a: false, b: { c: [1, 2, 3], x: [3, 4, 5] } }
|
8
|
+
#
|
9
|
+
# Like with Hash#merge in the standard library, a block can be provided
|
10
|
+
# to merge values:
|
11
|
+
#
|
12
|
+
# h1 = { a: 100, b: 200, c: { c1: 100 } }
|
13
|
+
# h2 = { b: 250, c: { c1: 200 } }
|
14
|
+
# h1.deep_merge(h2) { |key, this_val, other_val| this_val + other_val }
|
15
|
+
# # => { a: 100, b: 450, c: { c1: 300 } }
|
16
|
+
def deep_merge(other_hash, options = {}, &block)
|
17
|
+
dup.deep_merge!(other_hash, options, &block)
|
18
|
+
end
|
19
|
+
|
20
|
+
# Same as +deep_merge+, but modifies +self+.
|
21
|
+
def deep_merge!(other_hash, options = {}, &block)
|
22
|
+
other_hash.each_pair do |current_key, other_value|
|
23
|
+
this_value = self[current_key]
|
24
|
+
|
25
|
+
self[current_key] = if this_value.is_a?(Hash) && other_value.is_a?(Hash)
|
26
|
+
this_value.deep_merge(other_value, options, &block)
|
27
|
+
elsif options[:union_arrays] && (this_value.is_a?(Array) || other_value.is_a?(Array))
|
28
|
+
this_values = this_value.is_a?(Array) ? this_value : [this_value]
|
29
|
+
other_values = other_value.is_a?(Array) ? other_value : [other_value]
|
30
|
+
|
31
|
+
this_values | other_values
|
32
|
+
else
|
33
|
+
if block_given? && key?(current_key)
|
34
|
+
block.call(current_key, this_value, other_value)
|
35
|
+
else
|
36
|
+
other_value
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
self
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,94 @@
|
|
1
|
+
class String
|
2
|
+
def camelize
|
3
|
+
self.split('_').collect(&:capitalize).join
|
4
|
+
end
|
5
|
+
|
6
|
+
def underscore
|
7
|
+
self.gsub(/::/, '/').
|
8
|
+
gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
|
9
|
+
gsub(/([a-z\d])([A-Z])/,'\1_\2').
|
10
|
+
tr("-", "_").
|
11
|
+
downcase
|
12
|
+
end
|
13
|
+
|
14
|
+
def constantize
|
15
|
+
camel_cased_word = self
|
16
|
+
|
17
|
+
names = camel_cased_word.split('::')
|
18
|
+
|
19
|
+
# Trigger a built-in NameError exception including the ill-formed constant in the message.
|
20
|
+
Object.const_get(camel_cased_word) if names.empty?
|
21
|
+
|
22
|
+
# Remove the first blank element in case of '::ClassName' notation.
|
23
|
+
names.shift if names.size > 1 && names.first.empty?
|
24
|
+
|
25
|
+
names.inject(Object) do |constant, name|
|
26
|
+
if constant == Object
|
27
|
+
constant.const_get(name)
|
28
|
+
else
|
29
|
+
candidate = constant.const_get(name)
|
30
|
+
next candidate if constant.const_defined?(name, false)
|
31
|
+
next candidate unless Object.const_defined?(name)
|
32
|
+
|
33
|
+
# Go down the ancestors to check if it is owned directly. The check
|
34
|
+
# stops when we reach Object or the end of ancestors tree.
|
35
|
+
constant = constant.ancestors.inject do |const, ancestor|
|
36
|
+
break const if ancestor == Object
|
37
|
+
break ancestor if ancestor.const_defined?(name, false)
|
38
|
+
const
|
39
|
+
end
|
40
|
+
|
41
|
+
# owner is in Object, so raise
|
42
|
+
constant.const_get(name, false)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def deconstantize
|
48
|
+
self.to_s[0, self.rindex("::") || 0]
|
49
|
+
end
|
50
|
+
|
51
|
+
def demodulize
|
52
|
+
if (i = self.rindex("::"))
|
53
|
+
self[(i + 2)..-1]
|
54
|
+
else
|
55
|
+
self
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def squish
|
60
|
+
dup.squish!
|
61
|
+
end
|
62
|
+
|
63
|
+
def squish!
|
64
|
+
gsub!(/\A[[:space:]]+/, '')
|
65
|
+
gsub!(/[[:space:]]+\z/, '')
|
66
|
+
gsub!(/[[:space:]]+/, ' ')
|
67
|
+
self
|
68
|
+
end
|
69
|
+
|
70
|
+
def trim(str=nil)
|
71
|
+
return self.ltrim(str).rtrim(str)
|
72
|
+
end
|
73
|
+
|
74
|
+
def ltrim(str=nil)
|
75
|
+
if (!str)
|
76
|
+
return self.lstrip
|
77
|
+
else
|
78
|
+
escape = Regexp.escape(str)
|
79
|
+
end
|
80
|
+
|
81
|
+
return self.gsub(/^#{escape}+/, "")
|
82
|
+
end
|
83
|
+
|
84
|
+
def rtrim(str=nil)
|
85
|
+
if (!str)
|
86
|
+
return self.rstrip
|
87
|
+
else
|
88
|
+
escape = Regexp.escape(str)
|
89
|
+
end
|
90
|
+
|
91
|
+
return self.gsub(/#{escape}+$/, "")
|
92
|
+
end
|
93
|
+
|
94
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Charyf
|
2
|
+
class StringInquirer < String
|
3
|
+
private
|
4
|
+
|
5
|
+
def respond_to_missing?(method_name, include_private = false)
|
6
|
+
(method_name[-1] == "?") || super
|
7
|
+
end
|
8
|
+
|
9
|
+
def method_missing(method_name, *arguments)
|
10
|
+
if method_name[-1] == "?"
|
11
|
+
self == method_name[0..-2]
|
12
|
+
else
|
13
|
+
super
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
require_relative 'support/all'
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require_relative 'parser/parser'
|
2
|
+
require_relative 'parser/en_parser'
|
3
|
+
|
4
|
+
require_relative 'storage/provider'
|
5
|
+
|
6
|
+
require_relative 'application'
|
7
|
+
require_relative 'charyf'
|
8
|
+
require_relative 'error_handler'
|
9
|
+
require_relative 'initializable'
|
10
|
+
require_relative 'logger'
|
11
|
+
require_relative 'machine'
|
12
|
+
require_relative 'strategy'
|
13
|
+
require_relative 'utils'
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Charyf
|
2
|
+
class AppEngine < Extension
|
3
|
+
class Extensions
|
4
|
+
include Enumerable
|
5
|
+
attr_reader :_all
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
@_all ||= ::Charyf::Extension.subclasses.map(&:instance) +
|
9
|
+
::Charyf::AppEngine.subclasses.map(&:instance)
|
10
|
+
end
|
11
|
+
|
12
|
+
def each(*args, &block)
|
13
|
+
_all.each(*args, &block)
|
14
|
+
end
|
15
|
+
|
16
|
+
def -(others)
|
17
|
+
_all - others
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'extension'
|
4
|
+
require_relative 'app_engine/extensions'
|
5
|
+
|
6
|
+
module Charyf
|
7
|
+
class AppEngine < Extension
|
8
|
+
|
9
|
+
# Load Charyf generators and invoke the registered hooks.
|
10
|
+
# Check <tt>Charyf::Extension.generators</tt> for more info.
|
11
|
+
def load_generators(app = self)
|
12
|
+
require_relative 'generators'
|
13
|
+
Charyf::Generators.configure!(app.config.generators)
|
14
|
+
|
15
|
+
require_relative 'generators/app/app_generator'
|
16
|
+
require_relative 'generators/skill/skill_generator'
|
17
|
+
require_relative 'generators/intents/intents_generator'
|
18
|
+
|
19
|
+
run_generators_blocks(app)
|
20
|
+
self
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'pathname'
|
4
|
+
|
5
|
+
module Charyf
|
6
|
+
module AppLoader # :nodoc:
|
7
|
+
extend self
|
8
|
+
|
9
|
+
RUBY = Gem.ruby
|
10
|
+
EXECUTABLES = %w(bin/charyf charyf/bin/charyf)
|
11
|
+
|
12
|
+
def exec_app
|
13
|
+
original_cwd = Dir.pwd
|
14
|
+
|
15
|
+
loop do
|
16
|
+
if exe = find_executable
|
17
|
+
contents = File.read(exe)
|
18
|
+
|
19
|
+
if contents =~ /(APP|ENGINE)_PATH/
|
20
|
+
exec RUBY, exe, *ARGV
|
21
|
+
break # non reachable, hack to be able to stub exec in the test suite
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
# If we exhaust the search there is no executable, this could be a
|
26
|
+
# call to generate a new application, so restore the original cwd.
|
27
|
+
Dir.chdir(original_cwd) && return if Pathname.new(Dir.pwd).root?
|
28
|
+
|
29
|
+
# Otherwise keep moving upwards in search of an executable.
|
30
|
+
Dir.chdir("..")
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def find_executable
|
35
|
+
EXECUTABLES.find { |exe| File.file?(exe) }
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,176 @@
|
|
1
|
+
require_relative '../app_engine'
|
2
|
+
require_relative '../initializable'
|
3
|
+
require_relative '../utils'
|
4
|
+
require 'i18n'
|
5
|
+
|
6
|
+
module Charyf
|
7
|
+
class Application < AppEngine
|
8
|
+
# noinspection RubyResolve
|
9
|
+
module Bootstrap
|
10
|
+
|
11
|
+
class SkillLoadError < StandardError
|
12
|
+
def initialize(e, skill_name, skill_path)
|
13
|
+
super(e)
|
14
|
+
|
15
|
+
@_name = skill_name
|
16
|
+
@_path = skill_path.dirname
|
17
|
+
end
|
18
|
+
|
19
|
+
def message
|
20
|
+
_message + super
|
21
|
+
end
|
22
|
+
|
23
|
+
def _message
|
24
|
+
<<-EOS
|
25
|
+
|
26
|
+
Unable to load skill #{@_name}
|
27
|
+
Expected to find: '#{@_name}.rb'
|
28
|
+
Located at: '#{@_path}'
|
29
|
+
|
30
|
+
EOS
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
include Charyf::Initializable
|
35
|
+
|
36
|
+
class InitializationError < StandardError; end
|
37
|
+
|
38
|
+
#
|
39
|
+
# Load app environment configuration files
|
40
|
+
# Default application configuration is when a command is triggered
|
41
|
+
# Nothing loaded unless environment file exists
|
42
|
+
#
|
43
|
+
initializer :load_environment, group: :all do
|
44
|
+
Charyf.logger.info "Charyf starting in #{Charyf.env} mode."
|
45
|
+
|
46
|
+
env_file = self.config.root.join('config', 'environments', "#{Charyf.env}.rb")
|
47
|
+
|
48
|
+
if FileTest.exists?(env_file)
|
49
|
+
require env_file
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
initializer :set_load_paths, group: :all do
|
54
|
+
libdir = File.expand_path(self.config.root.join('lib'))
|
55
|
+
$LOAD_PATH.unshift(libdir) unless $LOAD_PATH.include?(libdir)
|
56
|
+
end
|
57
|
+
|
58
|
+
#
|
59
|
+
# Loads I18N
|
60
|
+
#
|
61
|
+
initializer :load_i18n, group: :all do
|
62
|
+
I18n.load_path << Dir[Charyf._gem_source.join('locale', '**', '*.yml').to_s]
|
63
|
+
end
|
64
|
+
|
65
|
+
#
|
66
|
+
# Validates that all required strategies are fulfilled and the application can load
|
67
|
+
#
|
68
|
+
initializer :validate_strategies, group: :all do
|
69
|
+
Charyf.application.session_processor
|
70
|
+
Charyf.application.intent_processors
|
71
|
+
Charyf.application.dispatcher
|
72
|
+
end
|
73
|
+
|
74
|
+
#
|
75
|
+
# Load APP default files
|
76
|
+
#
|
77
|
+
initializer :load_defaults, group: :all do
|
78
|
+
require self.config.root.join('app', 'skill_controller.rb')
|
79
|
+
|
80
|
+
end
|
81
|
+
|
82
|
+
#
|
83
|
+
# Find all skills located in [YourApp]/app/skills/
|
84
|
+
#
|
85
|
+
initializer :load_skill_dir, group: :all do
|
86
|
+
# TODO revisit this
|
87
|
+
condition = lambda do |path|
|
88
|
+
in_root_dir = path.dirname.basename.to_s == 'skills'
|
89
|
+
contain_skill = Dir[path.dirname.join('**', '**')].any? { |p| p.include?('/controllers') } &&
|
90
|
+
Dir[path.dirname.join('**', '**')].any? { |p| p.include?('/intents') }
|
91
|
+
return in_root_dir || contain_skill
|
92
|
+
end
|
93
|
+
|
94
|
+
# Require skill level files
|
95
|
+
Charyf::Utils.require_recursive self.config.root.join('app', 'skills'),
|
96
|
+
condition: condition
|
97
|
+
|
98
|
+
# Require controllers
|
99
|
+
Charyf::Skill.list.each do |skill_klass|
|
100
|
+
# Load initializers
|
101
|
+
root = skill_klass.skill_root
|
102
|
+
|
103
|
+
Dir[root.join('controllers', '**', '*.rb')].each do |controller|
|
104
|
+
require controller
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
#
|
110
|
+
# Load all intents
|
111
|
+
#
|
112
|
+
initializer :load_skill_intents, groups: :all do
|
113
|
+
# Require Skill intents
|
114
|
+
Charyf::Skill.list.each do |skill_klass|
|
115
|
+
Dir[skill_klass.routing_source_dir.join('**', '*.rb')].each do |file|
|
116
|
+
require file
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
Charyf::Skill.list.each do |skill_klass|
|
121
|
+
skill_name = skill_klass.skill_name
|
122
|
+
|
123
|
+
Charyf.application.intent_processors.each do |processor|
|
124
|
+
# Public routing
|
125
|
+
skill_klass._public_routing(processor.strategy_name).each do |block|
|
126
|
+
processor.get_global.load skill_name, block
|
127
|
+
end
|
128
|
+
|
129
|
+
# Private routing
|
130
|
+
skill_klass._private_routing(processor.strategy_name).each do |block|
|
131
|
+
processor.get_for(skill_name).load skill_name, block
|
132
|
+
end
|
133
|
+
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
#
|
139
|
+
# Load all user skill files
|
140
|
+
# - controllers
|
141
|
+
#
|
142
|
+
initializer :load_skill_controllers, group: :all do
|
143
|
+
|
144
|
+
Charyf::Skill.list.each do |skill_klass|
|
145
|
+
|
146
|
+
# Load controllers
|
147
|
+
root = skill_klass.skill_root
|
148
|
+
|
149
|
+
Dir[root.join('controllers', '**', '*.rb')].each do |controller|
|
150
|
+
require controller
|
151
|
+
end
|
152
|
+
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
#
|
157
|
+
# Load user initializer files
|
158
|
+
#
|
159
|
+
initializer :run_initializers, group: :all do
|
160
|
+
Dir[self.config.root.join('config', 'initializers', '**', '**.rb')].each do |initializer|
|
161
|
+
require initializer
|
162
|
+
end
|
163
|
+
|
164
|
+
Charyf::Skill.list.each do |skill_klass|
|
165
|
+
# Load initializers
|
166
|
+
root = skill_klass.skill_root
|
167
|
+
|
168
|
+
Dir[root.join('initializers', '**', '*.rb')].each do |initializer|
|
169
|
+
require initializer
|
170
|
+
end
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
end
|
175
|
+
end
|
176
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require_relative '../app_engine'
|
2
|
+
require_relative '../extension/configuration'
|
3
|
+
|
4
|
+
module Charyf
|
5
|
+
class Application < AppEngine
|
6
|
+
class Configuration < Extension::Configuration
|
7
|
+
|
8
|
+
attr_reader :root
|
9
|
+
|
10
|
+
attr_accessor :console
|
11
|
+
|
12
|
+
attr_accessor :session_processor, :storage_provider, :dispatcher
|
13
|
+
attr_accessor :enabled_intent_processors
|
14
|
+
|
15
|
+
def initialize(root)
|
16
|
+
|
17
|
+
@root = root
|
18
|
+
|
19
|
+
end
|
20
|
+
|
21
|
+
def i18n
|
22
|
+
I18n
|
23
|
+
end
|
24
|
+
|
25
|
+
def error_handlers
|
26
|
+
Charyf::ErrorHandlers
|
27
|
+
end
|
28
|
+
|
29
|
+
sig [], ['Symbol', 'NilClass'],
|
30
|
+
def dispatcher
|
31
|
+
(@dispatcher || 'default').to_sym
|
32
|
+
end
|
33
|
+
|
34
|
+
sig [], ['Symbol'],
|
35
|
+
def session_processor
|
36
|
+
(@session_processor || 'default').to_sym
|
37
|
+
end
|
38
|
+
|
39
|
+
sig [], [Array],
|
40
|
+
def enabled_intent_processors
|
41
|
+
(@enabled_intent_processors || []).map(&:to_sym)
|
42
|
+
end
|
43
|
+
|
44
|
+
sig [], ['Symbol', 'NilClass'],
|
45
|
+
def storage_provider
|
46
|
+
@storage_provider ? @storage_provider.to_sym : nil
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|