houston-core 0.8.4 → 0.9.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +1 -0
- data/Gemfile.lock +72 -78
- data/app/assets/javascripts/houston/app/models/role.coffee +4 -0
- data/app/assets/javascripts/houston/app/views/nested_resources.coffee +44 -0
- data/app/assets/javascripts/houston/app/views/team_roles_view.coffee +10 -0
- data/app/assets/javascripts/houston/application.js +3 -1
- data/app/assets/javascripts/houston/core/ajax_helpers.coffee +26 -0
- data/app/assets/javascripts/houston/core/app.coffee +0 -45
- data/app/assets/javascripts/houston/core/errors.coffee +1 -12
- data/app/assets/javascripts/houston/core/handlebars_helpers.coffee +8 -70
- data/app/assets/javascripts/houston/core/jquery_extensions.coffee +0 -138
- data/app/assets/javascripts/houston/core/timeline_helpers.coffee +44 -0
- data/app/assets/javascripts/houston/core/uploader_helpers.coffee +99 -0
- data/app/assets/javascripts/houston/vendor.js +26 -9
- data/app/assets/stylesheets/houston/application/actions.scss +22 -0
- data/app/assets/stylesheets/houston/application/navigation.scss +2 -2
- data/app/assets/stylesheets/houston/application/{freight_train.css.scss → nested_resources.scss} +1 -0
- data/app/assets/stylesheets/houston/core/alerts.scss +0 -4
- data/app/assets/stylesheets/houston/core/timeline.scss +204 -0
- data/app/assets/templates/houston/teams/roles/index.hbs +1 -0
- data/app/assets/templates/houston/teams/roles/show.hbs +19 -0
- data/app/channels/events_channel.rb +1 -1
- data/app/concerns/houston/props.rb +3 -2
- data/app/controllers/actions_controller.rb +8 -3
- data/app/controllers/application_controller.rb +9 -12
- data/app/controllers/authorizations_controller.rb +41 -14
- data/app/controllers/errors_controller.rb +3 -3
- data/app/controllers/project_follows_controller.rb +23 -0
- data/app/controllers/project_options_controller.rb +1 -1
- data/app/controllers/user_options_controller.rb +1 -1
- data/app/helpers/actions_helper.rb +12 -0
- data/app/helpers/application_helper.rb +0 -10
- data/app/helpers/layout_helper.rb +20 -0
- data/app/helpers/markdown_helper.rb +2 -10
- data/app/helpers/navigation_helper.rb +5 -5
- data/app/helpers/project_helper.rb +6 -0
- data/app/helpers/url_helper.rb +4 -4
- data/app/helpers/view_extensions_helper.rb +20 -0
- data/app/models/action.rb +61 -44
- data/app/models/authorization.rb +55 -10
- data/app/models/follow.rb +6 -0
- data/app/models/persistent_trigger.rb +11 -1
- data/app/models/project.rb +5 -27
- data/app/models/user.rb +15 -59
- data/app/presenters/project_presenter.rb +2 -2
- data/app/views/actions/_actions.html.erb +8 -5
- data/app/views/actions/index.html.erb +1 -1
- data/app/views/actions/running.html.erb +9 -15
- data/app/views/actions/show.html.erb +6 -3
- data/app/views/actions/unqueued.html.erb +41 -0
- data/app/views/authorizations/_form.html.erb +28 -16
- data/app/views/authorizations/index.html.erb +9 -4
- data/app/views/{oauth/providers/edit.html.erb → authorizations/oauth2_callback.html.erb} +3 -2
- data/app/views/devise/sessions/new.html.erb +0 -8
- data/app/views/errors/index.html.erb +9 -5
- data/app/views/layouts/_navigation.html.erb +9 -0
- data/app/views/layouts/application.html.erb +11 -6
- data/app/views/layouts/dashboard.html.erb +9 -0
- data/app/views/projects/_form.html.erb +7 -18
- data/app/views/projects/_header.html.erb +2 -6
- data/app/views/projects/index.html.erb +4 -4
- data/app/views/teams/_form.html.erb +7 -17
- data/app/views/teams/index.html.erb +1 -1
- data/app/views/users/_form.html.erb +1 -38
- data/config/application.rb +8 -5
- data/config/initializers/devise.rb +0 -14
- data/config/initializers/secret_token.rb +8 -13
- data/config/routes.rb +12 -28
- data/db/migrate/20130706141443_drop_deprecated_project_roles.rb +5 -1
- data/db/migrate/20170118005958_remove_antecedents_from_versions_of_tickets.rb +1 -1
- data/db/migrate/20170130011016_drop_users_environments_subscribed_to.rb +9 -0
- data/db/migrate/20170205004452_drop_settings.rb +12 -0
- data/db/migrate/20170206002030_drop_extension_hstore.rb +9 -0
- data/db/migrate/20170206002732_drop_legacy_columns_from_users.rb +10 -0
- data/db/migrate/20170209022159_rename_projects_color_to_color_name.rb +5 -0
- data/db/migrate/20170213001453_change_providers_from_models_to_extensions.rb +27 -0
- data/db/migrate/20170215012012_add_props_to_authorizations.rb +5 -0
- data/db/migrate/20170216041034_add_user_to_persistent_triggers.rb +5 -0
- data/db/migrate/20170226201504_create_follows.rb +20 -0
- data/db/migrate/20170301014051_drop_name_from_authorizations.rb +9 -0
- data/db/migrate/20170307032041_add_created_at_to_actions.rb +11 -0
- data/db/migrate/20170307035755_allow_actions_started_at_to_be_null.rb +5 -0
- data/db/migrate/20170310024505_replace_authorizations_provider_name_with_type.rb +12 -0
- data/db/migrate/20170329030329_drop_consumer_tokens.rb +9 -0
- data/db/structure.sql +187 -212
- data/houston-core.gemspec +10 -13
- data/lib/houston/boot.rb +1 -4
- data/lib/houston/boot/actions.rb +24 -21
- data/lib/houston/boot/configuration.rb +46 -113
- data/lib/houston/boot/extensions.rb +54 -341
- data/lib/houston/boot/extensions/deprecated.rb +194 -0
- data/lib/houston/boot/extensions/dsl.rb +99 -0
- data/lib/houston/boot/extensions/events.rb +81 -0
- data/lib/houston/boot/extensions/features.rb +42 -0
- data/lib/houston/boot/extensions/layout.rb +70 -0
- data/lib/houston/boot/extensions/navigation.rb +42 -0
- data/lib/houston/boot/extensions/oauth.rb +62 -0
- data/lib/houston/boot/extensions/serializers.rb +29 -0
- data/lib/houston/boot/extensions/view.rb +34 -0
- data/lib/houston/boot/observer.rb +10 -5
- data/{app/models/oauth → lib/houston/boot}/provider.rb +7 -5
- data/lib/houston/boot/running_as.rb +0 -5
- data/lib/houston/boot/serializer.rb +12 -6
- data/lib/houston/boot/{active_record_serializer.rb → serializers/active_record_serializer.rb} +0 -2
- data/lib/houston/boot/{readonly_hash_serializer.rb → serializers/readonly_hash_serializer.rb} +0 -2
- data/lib/houston/boot/timer.rb +10 -0
- data/lib/houston/boot/triggers.rb +27 -8
- data/lib/houston/version.rb +1 -1
- data/templates/new-instance/.gitignore +0 -4
- data/templates/new-instance/config/main.rb +8 -10
- data/templates/new-module/test/dummy/houston.rb +1 -0
- data/test/acceptance/layout_test.rb +58 -0
- data/test/acceptance/updating_props_test.rb +72 -0
- data/test/support/config.rb +1 -0
- data/test/unit/extensions/events_extension_test.rb +33 -0
- data/test/unit/extensions/layout_extension_test.rb +74 -0
- data/test/unit/extensions/navigation_extension_test.rb +62 -0
- data/test/unit/extensions/oauth_extension_test.rb +91 -0
- data/test/unit/extensions/project_features_extension_test.rb +79 -0
- data/test/unit/extensions/serializers_extension_test.rb +47 -0
- data/test/unit/extensions/view_extension_test.rb +98 -0
- data/test/unit/models/actions_test.rb +11 -5
- data/test/unit/models/configuration_test.rb +0 -8
- data/test/unit/models/observer_test.rb +16 -0
- data/test/unit/models/persistent_trigger_test.rb +29 -2
- data/test/unit/models/serializer_test.rb +6 -0
- data/test/unit/models/timer_test.rb +88 -0
- metadata +87 -168
- data/app/assets/font/octicons.eot +0 -0
- data/app/assets/font/octicons.svg +0 -198
- data/app/assets/font/octicons.ttf +0 -0
- data/app/assets/font/octicons.woff +0 -0
- data/app/assets/font/roboto-black-webfont.eot +0 -0
- data/app/assets/font/roboto-black-webfont.svg +0 -675
- data/app/assets/font/roboto-black-webfont.ttf +0 -0
- data/app/assets/font/roboto-black-webfont.woff +0 -0
- data/app/assets/font/roboto-blackitalic-webfont.eot +0 -0
- data/app/assets/font/roboto-blackitalic-webfont.svg +0 -677
- data/app/assets/font/roboto-blackitalic-webfont.ttf +0 -0
- data/app/assets/font/roboto-blackitalic-webfont.woff +0 -0
- data/app/assets/font/roboto-bold-webfont.eot +0 -0
- data/app/assets/font/roboto-bold-webfont.svg +0 -675
- data/app/assets/font/roboto-bold-webfont.ttf +0 -0
- data/app/assets/font/roboto-bold-webfont.woff +0 -0
- data/app/assets/font/roboto-bolditalic-webfont.eot +0 -0
- data/app/assets/font/roboto-bolditalic-webfont.svg +0 -677
- data/app/assets/font/roboto-bolditalic-webfont.ttf +0 -0
- data/app/assets/font/roboto-bolditalic-webfont.woff +0 -0
- data/app/assets/font/roboto-italic-webfont.eot +0 -0
- data/app/assets/font/roboto-italic-webfont.svg +0 -668
- data/app/assets/font/roboto-italic-webfont.ttf +0 -0
- data/app/assets/font/roboto-italic-webfont.woff +0 -0
- data/app/assets/font/roboto-light-webfont.eot +0 -0
- data/app/assets/font/roboto-light-webfont.svg +0 -666
- data/app/assets/font/roboto-light-webfont.ttf +0 -0
- data/app/assets/font/roboto-light-webfont.woff +0 -0
- data/app/assets/font/roboto-lightitalic-webfont.eot +0 -0
- data/app/assets/font/roboto-lightitalic-webfont.svg +0 -668
- data/app/assets/font/roboto-lightitalic-webfont.ttf +0 -0
- data/app/assets/font/roboto-lightitalic-webfont.woff +0 -0
- data/app/assets/font/roboto-medium-webfont.eot +0 -0
- data/app/assets/font/roboto-medium-webfont.svg +0 -675
- data/app/assets/font/roboto-medium-webfont.ttf +0 -0
- data/app/assets/font/roboto-medium-webfont.woff +0 -0
- data/app/assets/font/roboto-mediumitalic-webfont.eot +0 -0
- data/app/assets/font/roboto-mediumitalic-webfont.svg +0 -677
- data/app/assets/font/roboto-mediumitalic-webfont.ttf +0 -0
- data/app/assets/font/roboto-mediumitalic-webfont.woff +0 -0
- data/app/assets/font/roboto-regular-webfont.eot +0 -0
- data/app/assets/font/roboto-regular-webfont.svg +0 -666
- data/app/assets/font/roboto-regular-webfont.ttf +0 -0
- data/app/assets/font/roboto-regular-webfont.woff +0 -0
- data/app/assets/font/roboto-thin-webfont.eot +0 -0
- data/app/assets/font/roboto-thin-webfont.svg +0 -666
- data/app/assets/font/roboto-thin-webfont.ttf +0 -0
- data/app/assets/font/roboto-thin-webfont.woff +0 -0
- data/app/assets/font/roboto-thinitalic-webfont.eot +0 -0
- data/app/assets/font/roboto-thinitalic-webfont.svg +0 -668
- data/app/assets/font/roboto-thinitalic-webfont.ttf +0 -0
- data/app/assets/font/roboto-thinitalic-webfont.woff +0 -0
- data/app/assets/images/bug-fixed-128.png +0 -0
- data/app/assets/images/bug-fixed-32.png +0 -0
- data/app/assets/images/bug-fixed-48.png +0 -0
- data/app/assets/images/bug-new-128.png +0 -0
- data/app/assets/images/bug-new-32.png +0 -0
- data/app/assets/images/bug-new-48.png +0 -0
- data/app/assets/images/bug-open-32.png +0 -0
- data/app/assets/images/bug-zero-128.png +0 -0
- data/app/assets/images/bug-zero-48.png +0 -0
- data/app/assets/images/drag-grip.png +0 -0
- data/app/assets/javascripts/houston/core/burndown_chart.coffee +0 -111
- data/app/assets/javascripts/houston/core/stacked_area_graph.coffee +0 -113
- data/app/assets/javascripts/houston/core/stacked_bar_graph.coffee +0 -108
- data/app/assets/stylesheets/houston/application/project_tiles.scss +0 -26
- data/app/assets/stylesheets/houston/application/tips.scss +0 -5
- data/app/assets/stylesheets/houston/core/octicons-icons.scss +0 -221
- data/app/assets/stylesheets/houston/core/octicons.scss.erb +0 -9
- data/app/assets/stylesheets/houston/core/roboto.scss.erb +0 -131
- data/app/concerns/historical_weekly_stats.rb +0 -15
- data/app/concerns/nosync.rb +0 -21
- data/app/controllers/oauth/providers_controller.rb +0 -45
- data/app/controllers/project_roles_controller.rb +0 -22
- data/app/controllers/settings_controller.rb +0 -14
- data/app/controllers/tester_bar_controller.rb +0 -12
- data/app/controllers/user_credentials_controller.rb +0 -24
- data/app/models/role.rb +0 -33
- data/app/models/setting.rb +0 -10
- data/app/models/settings.rb +0 -38
- data/app/models/slackdown.rb +0 -23
- data/app/models/user_credentials.rb +0 -27
- data/app/views/errors/_actions.html.erb +0 -17
- data/app/views/layouts/_tester_bar.html.erb +0 -6
- data/app/views/layouts/minimal.html.erb +0 -50
- data/app/views/layouts/naked.html.erb +0 -47
- data/app/views/layouts/naked_dashboard.html.erb +0 -50
- data/app/views/oauth/providers/_form.html.erb +0 -54
- data/app/views/oauth/providers/index.html.erb +0 -41
- data/app/views/oauth/providers/new.html.erb +0 -7
- data/config/initializers/add_navigation_renderers.rb +0 -5
- data/config/initializers/vestal_versions.rb +0 -9
- data/db/migrate/20130519163615_create_user_credentials.rb +0 -18
- data/lib/houston/boot/events.rb +0 -10
- data/lib/tasks/keypair.rake +0 -17
- data/vendor/assets/javascripts/jquery.pjax.js +0 -817
@@ -0,0 +1,42 @@
|
|
1
|
+
require "concurrent/array"
|
2
|
+
require "delegate"
|
3
|
+
require "houston/boot/extensions/dsl"
|
4
|
+
|
5
|
+
module Houston
|
6
|
+
module Extensions
|
7
|
+
class Navigation
|
8
|
+
attr_reader :links
|
9
|
+
|
10
|
+
def initialize
|
11
|
+
@links = Concurrent::Array.new
|
12
|
+
end
|
13
|
+
|
14
|
+
def add_link(content, &path_block)
|
15
|
+
if content.is_a?(Symbol)
|
16
|
+
slug = content
|
17
|
+
content = slug.to_s.titleize
|
18
|
+
else
|
19
|
+
slug = content.underscore.to_sym
|
20
|
+
end
|
21
|
+
Chain(AbilityBlock, AcceptsName, Link.new(slug, content).tap do |link|
|
22
|
+
link.instance_variable_set :@path_block, path_block
|
23
|
+
@links.push link
|
24
|
+
end)
|
25
|
+
end
|
26
|
+
alias :add :add_link
|
27
|
+
alias :<< :add_link
|
28
|
+
|
29
|
+
def slugs
|
30
|
+
links.map(&:slug)
|
31
|
+
end
|
32
|
+
|
33
|
+
def [](slug)
|
34
|
+
links.find { |link| link.slug == slug }
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
Link = Struct.new(:slug, :name) do
|
39
|
+
include Permitted, LinkTo
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
require "concurrent/array"
|
2
|
+
|
3
|
+
module Houston
|
4
|
+
module Extensions
|
5
|
+
class Oauth
|
6
|
+
class ProviderNotFound < ArgumentError; end
|
7
|
+
|
8
|
+
def initialize
|
9
|
+
reset!
|
10
|
+
end
|
11
|
+
|
12
|
+
def reset!
|
13
|
+
@providers = Concurrent::Hash.new
|
14
|
+
end
|
15
|
+
|
16
|
+
def providers
|
17
|
+
@providers.keys
|
18
|
+
end
|
19
|
+
|
20
|
+
def add_provider(name, &block)
|
21
|
+
provider = Houston::Provider.new(name.to_sym)
|
22
|
+
ProviderDsl.new(provider).instance_eval(&block)
|
23
|
+
|
24
|
+
raise ArgumentError, "Provider must define a site" if provider.site.blank?
|
25
|
+
raise ArgumentError, "Provider must define a authorize_path" if provider.authorize_path.blank?
|
26
|
+
raise ArgumentError, "Provider must define a token_path" if provider.token_path.blank?
|
27
|
+
|
28
|
+
@providers[provider.name] = provider
|
29
|
+
end
|
30
|
+
|
31
|
+
def get_provider(name)
|
32
|
+
name = name.to_sym
|
33
|
+
@providers.fetch(name)
|
34
|
+
rescue KeyError
|
35
|
+
puts "registered providers: #{providers.inspect}"
|
36
|
+
raise ProviderNotFound, "An Oauth Provider named #{name.inspect} has not been registered"
|
37
|
+
end
|
38
|
+
|
39
|
+
|
40
|
+
class ProviderDsl
|
41
|
+
attr_reader :provider
|
42
|
+
|
43
|
+
def initialize(provider)
|
44
|
+
@provider = provider
|
45
|
+
end
|
46
|
+
|
47
|
+
def site(value)
|
48
|
+
provider.site = value
|
49
|
+
end
|
50
|
+
|
51
|
+
def authorize_path(value)
|
52
|
+
provider.authorize_path = value
|
53
|
+
end
|
54
|
+
|
55
|
+
def token_path(value)
|
56
|
+
provider.token_path = value
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require "concurrent/array"
|
2
|
+
|
3
|
+
module Houston
|
4
|
+
module Extensions
|
5
|
+
class Serializers
|
6
|
+
include Enumerable
|
7
|
+
|
8
|
+
def initialize
|
9
|
+
@serializers = Concurrent::Array.new
|
10
|
+
end
|
11
|
+
|
12
|
+
def each(&block)
|
13
|
+
@serializers.each(&block)
|
14
|
+
end
|
15
|
+
|
16
|
+
def add(serializer)
|
17
|
+
serializer = serializer.new if serializer.is_a?(Class)
|
18
|
+
|
19
|
+
[:applies_to?, :pack].each do |method|
|
20
|
+
next if serializer.respond_to?(method)
|
21
|
+
raise ArgumentError, "`serializer` must respond to `#{method}`"
|
22
|
+
end
|
23
|
+
|
24
|
+
@serializers.push serializer
|
25
|
+
end
|
26
|
+
alias :<< :add
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require "concurrent/hash"
|
2
|
+
require "houston/boot/extensions/dsl"
|
3
|
+
|
4
|
+
module Houston
|
5
|
+
module Extensions
|
6
|
+
class Views
|
7
|
+
def initialize
|
8
|
+
@views = Concurrent::Hash.new do |hash, key|
|
9
|
+
hash[key] = Houston::Extensions::View.new
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def [](view)
|
14
|
+
@views[view]
|
15
|
+
end
|
16
|
+
|
17
|
+
def reset!
|
18
|
+
@views.values.each(&:reset!)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
|
23
|
+
class View
|
24
|
+
def has(*constants)
|
25
|
+
constants.each do |constant|
|
26
|
+
extend Houston::Extensions.const_get(:"Has#{constant}")
|
27
|
+
end
|
28
|
+
self
|
29
|
+
end
|
30
|
+
|
31
|
+
def reset!; end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -23,7 +23,12 @@ module Houston
|
|
23
23
|
nil
|
24
24
|
end
|
25
25
|
|
26
|
-
def off(callback)
|
26
|
+
def off(callback, &block)
|
27
|
+
if block_given?
|
28
|
+
event = callback
|
29
|
+
callback = observers_of(event).detect { |callback| callback.block == block }
|
30
|
+
return nil unless callback
|
31
|
+
end
|
27
32
|
observers_of(callback.event).delete callback
|
28
33
|
nil
|
29
34
|
end
|
@@ -67,12 +72,12 @@ module Houston
|
|
67
72
|
|
68
73
|
def assert_registered!(event_name)
|
69
74
|
return if event_name == :*
|
70
|
-
return if Houston.
|
75
|
+
return if Houston.events.registered?(event_name)
|
71
76
|
raise UnregisteredEventError, "#{event_name.inspect} is not a registered event"
|
72
77
|
end
|
73
78
|
|
74
79
|
def assert_registered_params!(event_name, params)
|
75
|
-
event = Houston.
|
80
|
+
event = Houston.events[event_name]
|
76
81
|
|
77
82
|
missing_params = event.params - params.keys.map(&:to_s)
|
78
83
|
unregistered_params = params.keys.map(&:to_s) - event.params
|
@@ -91,7 +96,7 @@ module Houston
|
|
91
96
|
|
92
97
|
|
93
98
|
class Callback
|
94
|
-
attr_reader :observer, :event
|
99
|
+
attr_reader :observer, :event, :block
|
95
100
|
|
96
101
|
def initialize(observer, event, options, block)
|
97
102
|
@observer = observer
|
@@ -113,7 +118,7 @@ module Houston
|
|
113
118
|
def call(*args)
|
114
119
|
Houston.async(invoke_async?) do
|
115
120
|
begin
|
116
|
-
|
121
|
+
block.call(*args)
|
117
122
|
|
118
123
|
rescue Exception # rescues StandardError by default; but we want to rescue and report all errors
|
119
124
|
raise if raise_exceptions?
|
@@ -1,8 +1,10 @@
|
|
1
|
-
module
|
2
|
-
class Provider
|
3
|
-
|
1
|
+
module Houston
|
2
|
+
class Provider
|
3
|
+
attr_accessor :name, :site, :authorize_path, :token_path, :client_id, :client_secret
|
4
4
|
|
5
|
-
|
5
|
+
def initialize(name)
|
6
|
+
@name = name
|
7
|
+
end
|
6
8
|
|
7
9
|
def authorize_url(params={})
|
8
10
|
client.auth_code.authorize_url params.merge(redirect_uri: oauth2_callback_url)
|
@@ -28,7 +30,7 @@ module Oauth
|
|
28
30
|
end
|
29
31
|
|
30
32
|
def oauth2_callback_url
|
31
|
-
"
|
33
|
+
"#{Houston.root_url}/oauth2/callback"
|
32
34
|
end
|
33
35
|
|
34
36
|
end
|
@@ -8,11 +8,6 @@ module Houston
|
|
8
8
|
RUBY
|
9
9
|
end
|
10
10
|
|
11
|
-
def self.server?
|
12
|
-
Houston.deprecation_notice "Houston.server? is deprecated; use Houston.running_as_web_server?"
|
13
|
-
running_as_web_server?
|
14
|
-
end
|
15
|
-
|
16
11
|
def self.running_as
|
17
12
|
@__process_type ||= discover_process_type
|
18
13
|
end
|
@@ -7,6 +7,10 @@ module Houston
|
|
7
7
|
class Serializer
|
8
8
|
class UnserializableError < ArgumentError; end
|
9
9
|
|
10
|
+
def initialize(serializers=Houston.serializers)
|
11
|
+
@serializers = serializers
|
12
|
+
end
|
13
|
+
|
10
14
|
def load(string)
|
11
15
|
begin
|
12
16
|
object = Oj.load(string, nilnil: true, auto_define: false)
|
@@ -25,15 +29,15 @@ module Houston
|
|
25
29
|
end
|
26
30
|
|
27
31
|
private
|
32
|
+
attr_reader :serializers
|
28
33
|
|
29
34
|
def unpack(object)
|
30
35
|
if object.is_a?(Array)
|
31
36
|
object.map { |item| unpack(item) }
|
32
37
|
elsif object.is_a?(Hash)
|
33
38
|
object = object.each_with_object({}) { |(key, value), new_object| new_object[key] = unpack(value) }
|
34
|
-
|
35
|
-
|
36
|
-
end
|
39
|
+
serializer = object["^S"]
|
40
|
+
object = serializer.constantize.new.unpack(object) if serializer
|
37
41
|
object
|
38
42
|
else
|
39
43
|
object
|
@@ -55,13 +59,15 @@ module Houston
|
|
55
59
|
pack object.to_h
|
56
60
|
when ActiveSupport::TimeWithZone
|
57
61
|
object.to_datetime
|
62
|
+
when ActiveRecord::ConnectionAdapters::PostgreSQL::OID::Array::Data
|
63
|
+
pack object.values
|
58
64
|
when *SERIALIZABLE_TYPES
|
59
65
|
object
|
60
66
|
else
|
61
|
-
|
67
|
+
serializers.each do |serializer|
|
62
68
|
next unless serializer.applies_to?(object)
|
63
69
|
packed_object = serializer.pack(object)
|
64
|
-
packed_object
|
70
|
+
packed_object["^S"] = serializer.class.name if serializer.respond_to?(:unpack)
|
65
71
|
return pack(packed_object)
|
66
72
|
end
|
67
73
|
|
@@ -77,8 +83,8 @@ module Houston
|
|
77
83
|
Date,
|
78
84
|
DateTime,
|
79
85
|
FalseClass,
|
80
|
-
Fixnum,
|
81
86
|
Float,
|
87
|
+
Integer,
|
82
88
|
NilClass,
|
83
89
|
String,
|
84
90
|
Symbol,
|
data/lib/houston/boot/timer.rb
CHANGED
@@ -48,6 +48,16 @@ module Houston
|
|
48
48
|
$scheduler.public_send method_name, argument, &block
|
49
49
|
end
|
50
50
|
|
51
|
+
def stop(interval, block)
|
52
|
+
return queued_timers.delete [:every, interval, block] unless $scheduler
|
53
|
+
|
54
|
+
# Look up the job by its handler
|
55
|
+
# Note: this doesn't check `interval`. Conceivably, two jobs could be
|
56
|
+
# set up at different intervals that both invoke the same block.
|
57
|
+
job = $scheduler.jobs.detect { |job| job.handler == block }
|
58
|
+
job.unschedule
|
59
|
+
end
|
60
|
+
|
51
61
|
private
|
52
62
|
|
53
63
|
attr_reader :queued_timers
|
@@ -23,8 +23,8 @@ module Houston
|
|
23
23
|
push build(:on, event, action, params)
|
24
24
|
end
|
25
25
|
|
26
|
-
def build(method_name, value, action, params)
|
27
|
-
Trigger.new(self, method_name, value, action, params)
|
26
|
+
def build(method_name, value, action, params, persistent_trigger_id: nil)
|
27
|
+
Trigger.new(self, method_name, value, action, params, persistent_trigger_id)
|
28
28
|
end
|
29
29
|
|
30
30
|
def push(trigger)
|
@@ -34,27 +34,46 @@ module Houston
|
|
34
34
|
trigger
|
35
35
|
end
|
36
36
|
|
37
|
+
def delete(trigger)
|
38
|
+
i = find_index(trigger)
|
39
|
+
return unless i
|
40
|
+
trigger = self[i]
|
41
|
+
trigger.unregister!
|
42
|
+
delete_at i
|
43
|
+
end
|
44
|
+
|
37
45
|
end
|
38
46
|
|
39
47
|
|
40
|
-
class Trigger < Struct.new(:method_name, :value, :action, :params)
|
48
|
+
class Trigger < Struct.new(:method_name, :value, :action, :params, :persistent_trigger_id)
|
41
49
|
|
42
50
|
def initialize(triggers, *args)
|
43
51
|
@triggers = triggers
|
52
|
+
@callback = method(:call).to_proc
|
44
53
|
super *args
|
45
54
|
end
|
46
55
|
|
47
56
|
def register!
|
48
57
|
case method_name
|
49
|
-
when :every then config.timer.every(value, &
|
50
|
-
when :on then config.observer.on(value, &
|
58
|
+
when :every then config.timer.every(value, &callback)
|
59
|
+
when :on then config.observer.on(value, &callback)
|
60
|
+
else raise NotImplementedError, "Unrecognized method name: #{method_name.inspect}"
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def unregister!
|
65
|
+
case method_name
|
66
|
+
when :every then config.timer.stop(value, callback)
|
67
|
+
when :on then config.observer.off(value, &callback)
|
51
68
|
else raise NotImplementedError, "Unrecognized method name: #{method_name.inspect}"
|
52
69
|
end
|
53
70
|
end
|
54
71
|
|
55
72
|
def call(params={})
|
56
|
-
|
57
|
-
config.actions.run action, self.params.merge(params.to_h),
|
73
|
+
Rails.logger.info "\e[34m[#{to_s} => #{action}]\e[0m"
|
74
|
+
config.actions.run action, self.params.merge(params.to_h),
|
75
|
+
trigger: to_s,
|
76
|
+
async: triggers.async
|
58
77
|
end
|
59
78
|
|
60
79
|
def to_s
|
@@ -62,7 +81,7 @@ module Houston
|
|
62
81
|
end
|
63
82
|
|
64
83
|
private
|
65
|
-
attr_reader :triggers
|
84
|
+
attr_reader :triggers, :callback
|
66
85
|
|
67
86
|
def config
|
68
87
|
triggers.config
|
data/lib/houston/version.rb
CHANGED
@@ -22,22 +22,20 @@ Houston.config do
|
|
22
22
|
# This is the host where Houston will be running
|
23
23
|
host "houston.my-company.com"
|
24
24
|
|
25
|
+
# Your secret key is used for verifying the integrity of signed cookies.
|
26
|
+
# If you change this key, all old signed cookies will become invalid!
|
27
|
+
#
|
28
|
+
# Make sure the secret is at least 30 characters and all random,
|
29
|
+
# no regular words or you'll be exposed to dictionary attacks.
|
30
|
+
# You can use `rake secret` to generate a secure secret key.
|
31
|
+
secret_key_base ENV["HOUSTON_SECRET_KEY_BASE"]
|
32
|
+
|
25
33
|
# This is the email address for emails send from Houston
|
26
34
|
mailer_sender "houston@my-company.com"
|
27
35
|
|
28
36
|
# Range for password length. Default is 8..128.
|
29
37
|
# password_length 8..128
|
30
38
|
|
31
|
-
# This is the passphrase you used when generating config/keypair.pem
|
32
|
-
# Houston will use the keypair to encrypt and decrypt sensitive data
|
33
|
-
# To generate a new keypair.pem, execute these commands:
|
34
|
-
#
|
35
|
-
# openssl genrsa -des3 -out config/private.pem 2048
|
36
|
-
# openssl rsa -in config/private.pem -out config/public.pem -outform PEM -pubout
|
37
|
-
# cat config/private.pem config/public.pem >> config/keypair.pem
|
38
|
-
#
|
39
|
-
passphrase ENV["HOUSTON_PASSPHRASE"]
|
40
|
-
|
41
39
|
# Enter your Google Analytics Tracking ID to add Google's
|
42
40
|
# Universal Analytics script to every page.
|
43
41
|
google_analytics do
|