controll 0.2.0 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +253 -93
- data/Rakefile +1 -1
- data/VERSION +1 -1
- data/controll.gemspec +121 -84
- data/lib/controll/assistant/param_assistant.rb +23 -0
- data/lib/controll/assistant/session_assistant.rb +23 -0
- data/lib/controll/assistant.rb +9 -7
- data/lib/controll/commander.rb +16 -3
- data/lib/controll/enabler/macros.rb +75 -0
- data/lib/controll/enabler/maps.rb +15 -0
- data/lib/controll/enabler/notify.rb +43 -0
- data/lib/controll/enabler/path_handler.rb +49 -0
- data/lib/controll/enabler/path_resolver.rb +47 -0
- data/lib/controll/enabler.rb +49 -0
- data/lib/controll/engine.rb +9 -0
- data/lib/controll/errors.rb +4 -1
- data/lib/controll/event/helper.rb +20 -0
- data/lib/controll/{helper/event_matcher.rb → event/matcher.rb} +3 -3
- data/lib/controll/event.rb +60 -0
- data/lib/controll/events.rb +48 -0
- data/lib/controll/executor/base.rb +3 -7
- data/lib/controll/executor/controlled.rb +36 -0
- data/lib/controll/executor/delegator.rb +6 -0
- data/lib/controll/executor.rb +8 -1
- data/lib/controll/flow/action/base.rb +30 -0
- data/lib/controll/flow/action/fallback.rb +25 -0
- data/lib/controll/flow/action/path_action.rb +24 -0
- data/lib/controll/flow/action.rb +7 -0
- data/lib/controll/flow/action_mapper/base.rb +13 -0
- data/lib/controll/flow/action_mapper/complex.rb +52 -0
- data/lib/controll/flow/action_mapper/simple.rb +54 -0
- data/lib/controll/flow/action_mapper.rb +7 -0
- data/lib/controll/flow/errors.rb +16 -0
- data/lib/controll/flow/event_mapper/path_finder.rb +36 -0
- data/lib/controll/flow/event_mapper/util.rb +43 -0
- data/lib/controll/flow/event_mapper.rb +6 -0
- data/lib/controll/flow/master/executor.rb +57 -0
- data/lib/controll/flow/master/macros.rb +66 -0
- data/lib/controll/flow/master.rb +70 -0
- data/lib/controll/flow.rb +15 -0
- data/lib/controll/focused/enabler.rb +31 -0
- data/lib/controll/helper.rb +0 -94
- data/lib/controll/macros.rb +12 -0
- data/lib/controll/notify/base.rb +22 -43
- data/lib/controll/notify/flash.rb +3 -3
- data/lib/controll/notify/macros.rb +57 -0
- data/lib/controll/notify/message/handler.rb +36 -0
- data/lib/controll/notify/message/resolver.rb +28 -0
- data/lib/controll/notify/message/translator.rb +45 -0
- data/lib/controll/notify/message.rb +25 -0
- data/lib/controll/notify/typed.rb +13 -22
- data/lib/controll/notify.rb +11 -4
- data/lib/controll.rb +8 -2
- data/lib/generators/controll/assistant_generator.rb +27 -0
- data/lib/generators/controll/executor_generator.rb +23 -0
- data/lib/generators/controll/flow_handler_generator.rb +21 -0
- data/lib/generators/controll/notifier_generator.rb +21 -0
- data/lib/generators/controll/setup_generator.rb +37 -0
- data/lib/generators/controll/templates/assistant.tt +10 -0
- data/lib/generators/controll/templates/commander.tt +15 -0
- data/lib/generators/controll/templates/executor.tt +14 -0
- data/lib/generators/controll/templates/flow_handler.tt +26 -0
- data/lib/generators/controll/templates/notifier.tt +31 -0
- data/spec/acceptance/app_test.rb +1 -1
- data/spec/controll/assistant/param_assistant_spec.rb +31 -0
- data/spec/controll/assistant/session_assistant_spec.rb +31 -0
- data/spec/controll/assistant_spec.rb +26 -0
- data/spec/controll/command_spec.rb +4 -4
- data/spec/controll/enabler/macros_spec.rb +76 -0
- data/spec/controll/enabler/maps_spec.rb +31 -0
- data/spec/controll/{helper → enabler}/notify_spec.rb +7 -17
- data/spec/controll/enabler/path_handler_spec.rb +24 -0
- data/spec/controll/enabler/path_resolver_spec.rb +87 -0
- data/spec/controll/enabler_spec.rb +30 -0
- data/spec/controll/event/helper_spec.rb +33 -0
- data/spec/controll/{helper/event_matcher_spec.rb → event/matcher_spec.rb} +4 -3
- data/spec/controll/event_spec.rb +66 -0
- data/spec/controll/events_spec.rb +23 -0
- data/spec/controll/executor/controlled_spec.rb +36 -0
- data/spec/controll/executor/{notificator_spec.rb → delegator_spec.rb} +4 -4
- data/spec/controll/flow/action_mapper/complex_spec.rb +102 -0
- data/spec/controll/flow/action_mapper/fallback_spec.rb +34 -0
- data/spec/controll/{flow_handler/render_spec.rb → flow/action_mapper/simple_spec.rb} +25 -22
- data/spec/controll/{flow_handler/redirect/action_spec.rb → flow/event_mapper/path_finder_spec.rb} +10 -10
- data/spec/controll/{flow_handler/redirect/mapper_spec.rb → flow/event_mapper/util_spec.rb} +9 -9
- data/spec/controll/flow/master/executor_spec.rb +56 -0
- data/spec/{app/app/models/.gitkeep → controll/flow/master/macros_spec.rb} +0 -0
- data/spec/controll/flow/master_spec.rb +157 -0
- data/spec/controll/notify/base_spec.rb +6 -12
- data/spec/controll/notify/message/handler_spec.rb +27 -0
- data/spec/controll/notify/message/resolver_spec.rb +53 -0
- data/spec/controll/notify/message/translator_spec.rb +46 -0
- data/spec/controll/notify/message_spec.rb +4 -0
- data/spec/controll/notify/{message_handler.rb → services_notifier.rb} +3 -5
- data/spec/controll/notify/typed_spec.rb +2 -2
- data/spec/{app → controll_app}/.gitignore +0 -0
- data/spec/{app → controll_app}/Gemfile +0 -0
- data/spec/{app → controll_app}/Gemfile.lock +0 -0
- data/spec/{app → controll_app}/README.rdoc +0 -0
- data/spec/{app → controll_app}/Rakefile +0 -0
- data/spec/controll_app/app/controll/commanders/services_commander.rb +5 -0
- data/spec/controll_app/app/controll/executors/services_executor.rb +4 -0
- data/spec/controll_app/app/controll/flows/create_services.rb +9 -0
- data/spec/controll_app/app/controll/notifiers/services_notifier.rb +9 -0
- data/spec/{app → controll_app}/app/controllers/application_controller.rb +0 -1
- data/spec/controll_app/app/controllers/services_controller.rb +8 -0
- data/spec/{app/lib/assets → controll_app/app/models}/.gitkeep +0 -0
- data/spec/{app → controll_app}/app/models/post.rb +0 -0
- data/spec/{app → controll_app}/app/views/layouts/application.html.erb +0 -0
- data/spec/{app → controll_app}/app/views/posts/_form.html.erb +0 -0
- data/spec/{app → controll_app}/app/views/posts/edit.html.erb +0 -0
- data/spec/{app → controll_app}/app/views/posts/index.html.erb +0 -0
- data/spec/{app → controll_app}/app/views/posts/new.html.erb +0 -0
- data/spec/{app → controll_app}/app/views/posts/show.html.erb +0 -0
- data/spec/{app → controll_app}/config/application.rb +1 -1
- data/spec/{app → controll_app}/config/boot.rb +0 -0
- data/spec/{app → controll_app}/config/environment.rb +0 -0
- data/spec/{app → controll_app}/config/environments/development.rb +0 -0
- data/spec/{app → controll_app}/config/environments/test.rb +0 -0
- data/spec/{app → controll_app}/config/initializers/backtrace_silencers.rb +0 -0
- data/spec/{app → controll_app}/config/initializers/inflections.rb +0 -0
- data/spec/{app → controll_app}/config/initializers/mime_types.rb +0 -0
- data/spec/{app → controll_app}/config/initializers/secret_token.rb +0 -0
- data/spec/{app → controll_app}/config/initializers/session_store.rb +0 -0
- data/spec/{app → controll_app}/config/locales/en.yml +0 -0
- data/spec/controll_app/config/routes.rb +5 -0
- data/spec/{app → controll_app}/config.ru +0 -0
- data/spec/{app → controll_app}/db/seeds.rb +0 -0
- data/spec/{app/lib/tasks → controll_app/log}/.gitkeep +0 -0
- data/spec/{app → controll_app}/public/404.html +0 -0
- data/spec/{app → controll_app}/public/422.html +0 -0
- data/spec/{app → controll_app}/public/500.html +0 -0
- data/spec/{app → controll_app}/public/favicon.ico +0 -0
- data/spec/{app → controll_app}/public/index.html +0 -0
- data/spec/{app → controll_app}/public/javascripts/application.js +0 -0
- data/spec/{app → controll_app}/public/robots.txt +0 -0
- data/spec/{app → controll_app}/public/stylesheets/application.css +0 -0
- metadata +122 -85
- data/lib/controll/executor/notificator.rb +0 -12
- data/lib/controll/flow_handler/base.rb +0 -19
- data/lib/controll/flow_handler/control.rb +0 -85
- data/lib/controll/flow_handler/errors.rb +0 -5
- data/lib/controll/flow_handler/event_helper.rb +0 -18
- data/lib/controll/flow_handler/redirect/action.rb +0 -45
- data/lib/controll/flow_handler/redirect/mapper.rb +0 -41
- data/lib/controll/flow_handler/redirect.rb +0 -51
- data/lib/controll/flow_handler/render.rb +0 -51
- data/lib/controll/flow_handler.rb +0 -11
- data/lib/controll/helper/notify.rb +0 -74
- data/lib/controll/helper/path_resolver.rb +0 -45
- data/spec/app/app/controllers/posts_controller.rb +0 -52
- data/spec/app/config/routes.rb +0 -62
- data/spec/app/log/.gitkeep +0 -0
- data/spec/app/script/rails +0 -6
- data/spec/app/spec/controllers/posts_controller_spec.rb +0 -59
- data/spec/app/spec/isolated_spec_helper.rb +0 -6
- data/spec/app/spec/spec_helper.rb +0 -5
- data/spec/app/spec/unit/controllers/posts_controller_isolated_spec.rb +0 -63
- data/spec/app/spec/unit/controllers/posts_controller_spec.rb +0 -59
- data/spec/app/test/functional/.gitkeep +0 -0
- data/spec/app/test/functional/posts_controller_test.rb +0 -67
- data/spec/app/test/isolated_test_helper.rb +0 -7
- data/spec/app/test/test_helper.rb +0 -6
- data/spec/app/test/unit/.gitkeep +0 -0
- data/spec/app/test/unit/controllers/posts_controller_isolated_test.rb +0 -71
- data/spec/app/test/unit/controllers/posts_controller_test.rb +0 -67
- data/spec/app/vendor/assets/javascripts/.gitkeep +0 -0
- data/spec/app/vendor/assets/stylesheets/.gitkeep +0 -0
- data/spec/app/vendor/plugins/.gitkeep +0 -0
- data/spec/controll/asssistant_spec.rb +0 -5
- data/spec/controll/flow_handler/control_spec.rb +0 -159
- data/spec/controll/flow_handler/redirect_spec.rb +0 -93
- data/spec/controll/helper/path_resolver_spec.rb +0 -49
- data/spec/controll/helper_spec.rb +0 -108
@@ -0,0 +1,70 @@
|
|
1
|
+
module Controll::Flow
|
2
|
+
class Master
|
3
|
+
autoload :Macros, 'controll/flow/master/macros'
|
4
|
+
autoload :Executor, 'controll/flow/master/executor'
|
5
|
+
|
6
|
+
include Macros
|
7
|
+
|
8
|
+
attr_reader :controller, :action, :options
|
9
|
+
|
10
|
+
def initialize controller, options = {}
|
11
|
+
@controller = controller
|
12
|
+
@options = options
|
13
|
+
end
|
14
|
+
|
15
|
+
# Uses Executor to execute each registered ActionHandler, such ad Renderer and Redirecter
|
16
|
+
# The first ActionHandler matching the event returns an appropriate Action
|
17
|
+
# In case no ActionHandler matches, the Fallback action is returned
|
18
|
+
def execute
|
19
|
+
@action = executor.execute || fallback
|
20
|
+
@action.set_errors errors
|
21
|
+
@action
|
22
|
+
end
|
23
|
+
|
24
|
+
def executor
|
25
|
+
@executor ||= Executor.new controller, executor_options
|
26
|
+
end
|
27
|
+
|
28
|
+
def executor_options
|
29
|
+
{event: event, action_handlers: action_handlers}
|
30
|
+
end
|
31
|
+
|
32
|
+
delegate :errors, to: :executor
|
33
|
+
|
34
|
+
class << self
|
35
|
+
def action_handlers
|
36
|
+
@action_handlers ||= []
|
37
|
+
end
|
38
|
+
|
39
|
+
def add_action_handler name
|
40
|
+
@action_handlers ||= []
|
41
|
+
@action_handlers << name.to_s.underscore.to_sym
|
42
|
+
end
|
43
|
+
|
44
|
+
def valid_handler? handler_type
|
45
|
+
raise ArgumentError, "Must be a String or Symbol, was: #{handler_type}" if handler_type.blank?
|
46
|
+
valid_handlers.include? handler_type.to_sym
|
47
|
+
end
|
48
|
+
|
49
|
+
def valid_handlers
|
50
|
+
[:renderer, :redirecter]
|
51
|
+
end
|
52
|
+
|
53
|
+
def mapper_types
|
54
|
+
[:simple, :complex]
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
protected
|
59
|
+
|
60
|
+
delegate :command!, to: :controller
|
61
|
+
|
62
|
+
def action_handlers
|
63
|
+
self.class.action_handlers
|
64
|
+
end
|
65
|
+
|
66
|
+
def event
|
67
|
+
raise Controll::Flow::EventNotImplementedError, 'You must define an #event method that returns an event (or Symbol). You can use an Executor for this.'
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'controll/flow/errors'
|
2
|
+
|
3
|
+
module Controll
|
4
|
+
module Flow
|
5
|
+
autoload :Master, 'controll/flow/master'
|
6
|
+
autoload :Action, 'controll/flow/action'
|
7
|
+
autoload :EventMapper, 'controll/flow/event_mapper'
|
8
|
+
autoload :ActionMapper, 'controll/flow/action_mapper'
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
module Flows
|
13
|
+
Master = Controll::Flow::Master
|
14
|
+
Flow = Controll::Flow::Master
|
15
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Controll
|
2
|
+
module Focused
|
3
|
+
module Enabler
|
4
|
+
include Controll::Enabler
|
5
|
+
|
6
|
+
def execute
|
7
|
+
action.perform
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.assistant_methods *names
|
11
|
+
delegate names, to: :assistant
|
12
|
+
end
|
13
|
+
|
14
|
+
protected
|
15
|
+
|
16
|
+
# the action resulting from executing the flow.
|
17
|
+
# Should be an instance of either:
|
18
|
+
# - Fallback
|
19
|
+
# - Redirecter
|
20
|
+
# - Renderer
|
21
|
+
def action
|
22
|
+
@action ||= flow.execute
|
23
|
+
end
|
24
|
+
|
25
|
+
# @flowhandler ||= Controll::Flow::Master.new self
|
26
|
+
def flow
|
27
|
+
raise NotImplementedError, '#flow must return the Controll::Flow::Master instance to be used'
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
data/lib/controll/helper.rb
CHANGED
@@ -1,101 +1,7 @@
|
|
1
1
|
module Controll
|
2
2
|
module Helper
|
3
|
-
autoload :Notify, 'controll/helper/notify'
|
4
3
|
autoload :HashAccess, 'controll/helper/hash_access'
|
5
4
|
autoload :Params, 'controll/helper/params'
|
6
5
|
autoload :Session, 'controll/helper/session'
|
7
|
-
autoload :PathResolver, 'controll/helper/path_resolver'
|
8
|
-
autoload :EventMatcher, 'controll/helper/event_matcher'
|
9
|
-
|
10
|
-
include Controll::Helper::Notify
|
11
|
-
include Controll::Helper::Params
|
12
|
-
|
13
|
-
extend ActiveSupport::Concern
|
14
|
-
|
15
|
-
delegate :command, :command!, :use_command, to: :commander
|
16
|
-
|
17
|
-
module ClassMethods
|
18
|
-
# TODO: refactor - all use exactly the same pattern - can be generated!
|
19
|
-
def commander name, options = {}
|
20
|
-
define_method :commander do
|
21
|
-
unless instance_variable_get("@commander")
|
22
|
-
clazz = "#{name.to_s.camelize}Commander".constantize
|
23
|
-
instance_variable_set "@commander", clazz.new(self, options)
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
def message_handler name, options = {}
|
29
|
-
define_method :message_handler do
|
30
|
-
unless instance_variable_get("@message_handler")
|
31
|
-
clazz = "#{name.to_s.camelize}MessageHandler".constantize
|
32
|
-
instance_variable_set "@message_handler", clazz.new(self, options)
|
33
|
-
end
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
def assistant name, options = {}
|
38
|
-
define_method :assistant do
|
39
|
-
unless instance_variable_get("@assistant")
|
40
|
-
clazz = "#{name.to_s.camelize}Assistant".constantize
|
41
|
-
instance_variable_set "@assistant", clazz.new(self, options)
|
42
|
-
end
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
def flow_handler name, options = {}
|
47
|
-
define_method :flow_handler do
|
48
|
-
unless instance_variable_get("@flow_handler")
|
49
|
-
clazz = "#{name.to_s.camelize}FlowHandler".constantize
|
50
|
-
instance_variable_set "@flow_handler", clazz.new(self, options)
|
51
|
-
end
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
55
|
-
def delegate_assistant name, options = {}
|
56
|
-
define_method :assistant do
|
57
|
-
unless instance_variable_get("@assistant")
|
58
|
-
clazz = "#{name.to_s.camelize}DelegateAssistant".constantize
|
59
|
-
instance_variable_set "@assistant", clazz.new(self, options)
|
60
|
-
end
|
61
|
-
end
|
62
|
-
end
|
63
|
-
|
64
|
-
def redirect_map map = {}
|
65
|
-
@redirect_map ||= map
|
66
|
-
end
|
67
|
-
|
68
|
-
def render_map map = {}
|
69
|
-
@render_map ||= map
|
70
|
-
end
|
71
|
-
end
|
72
|
-
|
73
|
-
def do_redirect *args
|
74
|
-
options = args.extract_options!
|
75
|
-
path = path_resolver.extract_path(:redirect_map, *args)
|
76
|
-
process_notifications
|
77
|
-
redirect_to path, *args
|
78
|
-
end
|
79
|
-
|
80
|
-
def do_render *args
|
81
|
-
options = args.extract_options!
|
82
|
-
path = path_resolver.extract_path :render_paths, *args
|
83
|
-
process_notifications
|
84
|
-
render path, *args
|
85
|
-
end
|
86
|
-
|
87
|
-
protected
|
88
|
-
|
89
|
-
def redirect_map
|
90
|
-
self.class.redirect_map
|
91
|
-
end
|
92
|
-
|
93
|
-
def render_paths
|
94
|
-
self.class.render_map
|
95
|
-
end
|
96
|
-
|
97
|
-
def path_resolver
|
98
|
-
@path_resolver ||= PathResolver.new self
|
99
|
-
end
|
100
6
|
end
|
101
7
|
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
module Controll
|
2
|
+
module Macros
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
module ClassMethods
|
6
|
+
def enable_controll
|
7
|
+
clazz = self.ancestors.include?(::Imperator::Command) ? Controll::Focused::Enabler : Controll::Enabler
|
8
|
+
self.send :include, clazz
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
data/lib/controll/notify/base.rb
CHANGED
@@ -1,14 +1,16 @@
|
|
1
|
-
require 'liquid'
|
2
1
|
require 'controll/notify/flash'
|
3
2
|
|
4
3
|
module Controll
|
5
4
|
module Notify
|
6
5
|
class Base < Flash
|
7
|
-
|
6
|
+
Message = Controll::Notify::Message
|
7
|
+
|
8
|
+
attr_reader :name
|
8
9
|
|
9
10
|
def notify name, options = {}
|
10
|
-
@options.merge! options
|
11
|
-
|
11
|
+
@options.merge! options
|
12
|
+
@name = name
|
13
|
+
signal message_resolver.resolve
|
12
14
|
end
|
13
15
|
|
14
16
|
def self.inherited(base)
|
@@ -16,7 +18,9 @@ module Controll
|
|
16
18
|
end
|
17
19
|
|
18
20
|
module ClassMethods
|
19
|
-
|
21
|
+
def signal_type
|
22
|
+
@signal_type ||= self.name.demodulize.sub(/Handler$/, '').underscore.to_sym
|
23
|
+
end
|
20
24
|
|
21
25
|
def type name
|
22
26
|
@signal_type = name
|
@@ -25,51 +29,26 @@ module Controll
|
|
25
29
|
|
26
30
|
protected
|
27
31
|
|
28
|
-
def
|
29
|
-
|
30
|
-
|
31
|
-
msg = send(name) if respond_to? name
|
32
|
-
msg ||= messages[name.to_sym] if respond_to? :messages
|
33
|
-
msg ||= name.to_sym
|
34
|
-
|
35
|
-
# if name is not mapped to a message, it could well be, that the
|
36
|
-
# event should not generate a nofification message
|
37
|
-
return nil if !msg
|
38
|
-
|
39
|
-
# try various approaches!
|
40
|
-
case msg
|
41
|
-
when Symbol
|
42
|
-
translate msg, opts
|
43
|
-
when String
|
44
|
-
msg.strip!
|
45
|
-
return replace_args(msg, opts) if msg =~ /{{.*}}/
|
46
|
-
msg
|
47
|
-
else
|
48
|
-
msg_error!
|
49
|
-
end
|
50
|
-
rescue
|
32
|
+
def message_resolver
|
33
|
+
@message_resolver ||= Message::Resolver.new self, message
|
51
34
|
end
|
52
35
|
|
53
|
-
def
|
54
|
-
|
55
|
-
end
|
36
|
+
def message
|
37
|
+
@message ||= Message.new text, options
|
38
|
+
end
|
56
39
|
|
57
|
-
def
|
58
|
-
|
40
|
+
def text
|
41
|
+
@text ||= resolve_text(name) || key
|
59
42
|
end
|
60
43
|
|
61
|
-
def
|
62
|
-
|
63
|
-
Liquid::Template.parse(msg).render(opts)
|
44
|
+
def key
|
45
|
+
@key ||= name.to_sym
|
64
46
|
end
|
65
47
|
|
66
|
-
def
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
ns = [middle, type].join('.').sub /^./, ''
|
71
|
-
[ns,msg].join('.')
|
72
|
-
end
|
48
|
+
def resolve_text name
|
49
|
+
return send(name) if respond_to? name
|
50
|
+
messages[name.to_sym] if respond_to? :messages
|
51
|
+
end
|
73
52
|
end
|
74
53
|
end
|
75
54
|
end
|
@@ -20,11 +20,11 @@ module Controll
|
|
20
20
|
attr_writer :types
|
21
21
|
|
22
22
|
def types
|
23
|
-
@types ||=
|
23
|
+
@types ||= Controll::Event.valid_types
|
24
24
|
end
|
25
25
|
|
26
26
|
def add_types *types
|
27
|
-
@types += types.
|
27
|
+
@types += types if types.all? {|type| type.kind_of? Symbol}
|
28
28
|
end
|
29
29
|
alias_method :add_type, :add_types
|
30
30
|
end
|
@@ -41,7 +41,7 @@ module Controll
|
|
41
41
|
end
|
42
42
|
|
43
43
|
def types
|
44
|
-
self.class.types
|
44
|
+
self.class.types.map(&:to_sym)
|
45
45
|
end
|
46
46
|
|
47
47
|
def signal_type
|
@@ -0,0 +1,57 @@
|
|
1
|
+
module Controll::Notify
|
2
|
+
module Macros
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
module ClassMethods
|
6
|
+
def handler type, options = {}, &block
|
7
|
+
unless valid_type? type
|
8
|
+
raise ArgumentError, "Notification type must be any of: #{types}, was: #{type}"
|
9
|
+
end
|
10
|
+
|
11
|
+
clazz_name = "#{parent}::#{type.to_s.camelize}Handler"
|
12
|
+
parent = options[:parent] || Controll::Notify::Base
|
13
|
+
|
14
|
+
clazz = parent ? Class.new(parent) : Class.new
|
15
|
+
Object.const_set clazz_name, clazz
|
16
|
+
context = self.kind_of?(Class) ? self : self.class
|
17
|
+
clazz = context.const_get(clazz_name)
|
18
|
+
|
19
|
+
if block_given?
|
20
|
+
clazz.instance_eval &block
|
21
|
+
end
|
22
|
+
clazz
|
23
|
+
end
|
24
|
+
|
25
|
+
def messages hash = nil, &block
|
26
|
+
unless block_given? || !hash.blank?
|
27
|
+
raise ArgumentError, "Must be called with non-empty Hash or block"
|
28
|
+
end
|
29
|
+
|
30
|
+
define_method :messages do
|
31
|
+
block_given? ? instance_eval(&block) : hash
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def message event_name, text = nil, &block
|
36
|
+
unless event_name.kind_of?(Symbol) || event_name.kind_of?(String)
|
37
|
+
raise ArgumentError, "First argument must be an event name, was: #{event_name}"
|
38
|
+
end
|
39
|
+
|
40
|
+
unless block_given? || !text.blank?
|
41
|
+
raise ArgumentError, "Must be called with non-empty String or block"
|
42
|
+
end
|
43
|
+
|
44
|
+
define_method event_name do
|
45
|
+
block_given? ? instance_eval(&block) : hash
|
46
|
+
end
|
47
|
+
end
|
48
|
+
alias_method :msg, :message
|
49
|
+
|
50
|
+
protected
|
51
|
+
|
52
|
+
def valid_type? type
|
53
|
+
types.include? type.to_sym
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'liquid'
|
2
|
+
|
3
|
+
module Controll::Notify
|
4
|
+
class Message
|
5
|
+
class Handler
|
6
|
+
attr_reader :message
|
7
|
+
|
8
|
+
def initialize message
|
9
|
+
@message = message
|
10
|
+
end
|
11
|
+
|
12
|
+
def handle
|
13
|
+
return args? ? replace_args : message.text
|
14
|
+
rescue StandardError
|
15
|
+
nil
|
16
|
+
end
|
17
|
+
|
18
|
+
protected
|
19
|
+
|
20
|
+
delegate :text, to: :message
|
21
|
+
|
22
|
+
def options
|
23
|
+
@options ||= message.options.stringify_keys
|
24
|
+
end
|
25
|
+
|
26
|
+
def args?
|
27
|
+
text =~ /{{.*}}/
|
28
|
+
end
|
29
|
+
|
30
|
+
def replace_args
|
31
|
+
# Parses and compiles the template
|
32
|
+
Liquid::Template.parse(text).render(options)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Controll::Notify
|
2
|
+
class Message
|
3
|
+
class Resolver
|
4
|
+
Message = Controll::Notify::Message
|
5
|
+
|
6
|
+
attr_reader :caller, :message
|
7
|
+
|
8
|
+
def initialize caller, message
|
9
|
+
@caller = caller
|
10
|
+
@message = message
|
11
|
+
end
|
12
|
+
|
13
|
+
def resolve
|
14
|
+
message.translate? ? translator.translate : message_handler.handle
|
15
|
+
end
|
16
|
+
|
17
|
+
protected
|
18
|
+
|
19
|
+
def message_handler
|
20
|
+
Message::Handler.new message
|
21
|
+
end
|
22
|
+
|
23
|
+
def translator
|
24
|
+
Message::Translator.new caller, message
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module Controll
|
2
|
+
module Notify
|
3
|
+
class Message
|
4
|
+
class Translator
|
5
|
+
attr_reader :caller, :key, :options
|
6
|
+
|
7
|
+
def initialize caller, message
|
8
|
+
@caller = caller
|
9
|
+
@key = message.text
|
10
|
+
@options = message.options.symbolize_keys
|
11
|
+
end
|
12
|
+
|
13
|
+
def translate
|
14
|
+
I18n.t i18n_key, options
|
15
|
+
end
|
16
|
+
|
17
|
+
protected
|
18
|
+
|
19
|
+
def i18n_key
|
20
|
+
[namespace_key, key].join('.')
|
21
|
+
end
|
22
|
+
|
23
|
+
def namespace_key
|
24
|
+
[namespace, type].join('.').sub /^\\./, ''
|
25
|
+
end
|
26
|
+
|
27
|
+
def parts
|
28
|
+
@parts ||= caller.class.name.split('::')
|
29
|
+
end
|
30
|
+
|
31
|
+
def namespace
|
32
|
+
(parts.first == 'Notifiers' ? parts[1..-2] : parts[0..-2]).join('.').underscore
|
33
|
+
end
|
34
|
+
|
35
|
+
def type
|
36
|
+
parts.last.sub(/#{clazz_postfix}$/, '').underscore
|
37
|
+
end
|
38
|
+
|
39
|
+
def clazz_postfix
|
40
|
+
'Handler'
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Controll::Notify
|
2
|
+
class Message
|
3
|
+
autoload :Translator, 'controll/notify/message/translator'
|
4
|
+
autoload :Handler, 'controll/notify/message/handler'
|
5
|
+
autoload :Resolver, 'controll/notify/message/resolver'
|
6
|
+
|
7
|
+
attr_reader :text, :options
|
8
|
+
|
9
|
+
def initialize text, options = {}
|
10
|
+
raise ArgumentError, "Message text must be a String or Symbol" unless valid_text? text
|
11
|
+
@text = text
|
12
|
+
@options = options
|
13
|
+
end
|
14
|
+
|
15
|
+
def translate?
|
16
|
+
text.kind_of? Symbol
|
17
|
+
end
|
18
|
+
|
19
|
+
protected
|
20
|
+
|
21
|
+
def valid_text? text
|
22
|
+
text.kind_of?(String) || text.kind_of?(Symbol)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -3,36 +3,27 @@ require 'controll/notify/flash'
|
|
3
3
|
module Controll
|
4
4
|
module Notify
|
5
5
|
class Typed < Flash
|
6
|
-
class
|
6
|
+
class MissingNotifyHandlerClass < StandardError; end
|
7
7
|
|
8
|
-
|
9
|
-
raise MissingNotifyClass, "#{msg_class(:notice)} class missing" unless msg_class(:notice)
|
10
|
-
@notice ||= msg_class(:notice).new flash #, options
|
11
|
-
end
|
12
|
-
|
13
|
-
def error
|
14
|
-
raise MissingNotifyClass, "#{msg_class(:warning)} class missing" unless msg_class(:error)
|
15
|
-
@error ||= msg_class(:error).new flash #, options
|
16
|
-
end
|
17
|
-
|
18
|
-
def success
|
19
|
-
raise MissingNotifyClass, "#{msg_class(:success)} class missing" unless msg_class(:success)
|
20
|
-
@success ||= msg_class(:success).new flash #, options
|
21
|
-
end
|
8
|
+
include Controll::Notify::Macros
|
22
9
|
|
23
|
-
|
24
|
-
|
25
|
-
|
10
|
+
types.each do |type|
|
11
|
+
define_method type do
|
12
|
+
clazz = handler_class(type)
|
13
|
+
raise MissingNotifyHandlerClass, "#{clazz} class missing" unless clazz
|
14
|
+
var = "@#{type}"
|
15
|
+
instance_variable_get(var) || instance_variable_set(var, clazz.new(flash))
|
16
|
+
end
|
26
17
|
end
|
27
18
|
|
28
19
|
protected
|
29
20
|
|
30
|
-
def
|
31
|
-
|
21
|
+
def handler_class name
|
22
|
+
handler_classes[name] ||= "#{self.class}::#{name.to_s.camelize}Handler".constantize
|
32
23
|
end
|
33
24
|
|
34
|
-
def
|
35
|
-
@
|
25
|
+
def handler_classes
|
26
|
+
@handler_classes ||= {}
|
36
27
|
end
|
37
28
|
end
|
38
29
|
end
|
data/lib/controll/notify.rb
CHANGED
@@ -1,7 +1,14 @@
|
|
1
1
|
module Controll
|
2
2
|
module Notify
|
3
|
-
autoload :Base,
|
4
|
-
autoload :Flash,
|
5
|
-
autoload :Typed,
|
3
|
+
autoload :Base, 'controll/notify/base'
|
4
|
+
autoload :Flash, 'controll/notify/flash'
|
5
|
+
autoload :Typed, 'controll/notify/typed'
|
6
|
+
autoload :Macros, 'controll/notify/macros'
|
7
|
+
autoload :Message, 'controll/notify/message'
|
6
8
|
end
|
7
|
-
end
|
9
|
+
end
|
10
|
+
|
11
|
+
module Notifiers
|
12
|
+
Typed = Controll::Notify::Typed
|
13
|
+
Notifier = Controll::Notify::Typed
|
14
|
+
end
|
data/lib/controll.rb
CHANGED
@@ -4,11 +4,17 @@ end
|
|
4
4
|
require 'hashie'
|
5
5
|
require 'imperator-ext'
|
6
6
|
require 'controll/errors'
|
7
|
+
require 'controll/event'
|
8
|
+
require 'controll/events'
|
9
|
+
require 'controll/assistant'
|
7
10
|
require 'controll/executor'
|
8
11
|
require 'controll/notify'
|
9
|
-
require 'controll/
|
12
|
+
require 'controll/flow'
|
10
13
|
require 'controll/helper'
|
14
|
+
require 'controll/enabler'
|
11
15
|
require 'controll/command'
|
12
16
|
require 'controll/commander'
|
13
|
-
require 'controll/
|
17
|
+
require 'controll/macros'
|
18
|
+
|
19
|
+
require 'controll/engine' if defined?(::Rails::Engine)
|
14
20
|
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Controll
|
2
|
+
module Generators
|
3
|
+
class AssistantGenerator < ::Rails::Generators::NamedBase
|
4
|
+
desc 'Generates an Assitant'
|
5
|
+
|
6
|
+
class_option :delegate, type: :boolean, default: false
|
7
|
+
|
8
|
+
def main_flow
|
9
|
+
template "assistant.tt", "app/controll/assistants/#{file_name}.rb"
|
10
|
+
end
|
11
|
+
|
12
|
+
protected
|
13
|
+
|
14
|
+
def delegate?
|
15
|
+
options[:delegate]
|
16
|
+
end
|
17
|
+
|
18
|
+
def parent_class
|
19
|
+
name.include?('::') ? "::Controll::#{parent_class_name}" : parent_class_name
|
20
|
+
end
|
21
|
+
|
22
|
+
def parent_class_name
|
23
|
+
delegate? 'DelegateAssistant' : 'Assistant'
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Controll
|
2
|
+
module Generators
|
3
|
+
class ExecutorGenerator < ::Rails::Generators::NamedBase
|
4
|
+
desc 'Generates an Executor'
|
5
|
+
|
6
|
+
class_option :type, default: 'base', desc: 'The type of executor'
|
7
|
+
|
8
|
+
def main_flow
|
9
|
+
template 'executor.tt', "app/controll/executors/#{file_name}.rb"
|
10
|
+
end
|
11
|
+
|
12
|
+
protected
|
13
|
+
|
14
|
+
def parent_class
|
15
|
+
name.include?('::') ? "::Controll::Executor::#{parent_class_name}" : parent_class_name
|
16
|
+
end
|
17
|
+
|
18
|
+
def parent_class_name
|
19
|
+
(options[:type] || 'base').camelize
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|