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.
Files changed (225) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +1 -0
  3. data/Gemfile.lock +72 -78
  4. data/app/assets/javascripts/houston/app/models/role.coffee +4 -0
  5. data/app/assets/javascripts/houston/app/views/nested_resources.coffee +44 -0
  6. data/app/assets/javascripts/houston/app/views/team_roles_view.coffee +10 -0
  7. data/app/assets/javascripts/houston/application.js +3 -1
  8. data/app/assets/javascripts/houston/core/ajax_helpers.coffee +26 -0
  9. data/app/assets/javascripts/houston/core/app.coffee +0 -45
  10. data/app/assets/javascripts/houston/core/errors.coffee +1 -12
  11. data/app/assets/javascripts/houston/core/handlebars_helpers.coffee +8 -70
  12. data/app/assets/javascripts/houston/core/jquery_extensions.coffee +0 -138
  13. data/app/assets/javascripts/houston/core/timeline_helpers.coffee +44 -0
  14. data/app/assets/javascripts/houston/core/uploader_helpers.coffee +99 -0
  15. data/app/assets/javascripts/houston/vendor.js +26 -9
  16. data/app/assets/stylesheets/houston/application/actions.scss +22 -0
  17. data/app/assets/stylesheets/houston/application/navigation.scss +2 -2
  18. data/app/assets/stylesheets/houston/application/{freight_train.css.scss → nested_resources.scss} +1 -0
  19. data/app/assets/stylesheets/houston/core/alerts.scss +0 -4
  20. data/app/assets/stylesheets/houston/core/timeline.scss +204 -0
  21. data/app/assets/templates/houston/teams/roles/index.hbs +1 -0
  22. data/app/assets/templates/houston/teams/roles/show.hbs +19 -0
  23. data/app/channels/events_channel.rb +1 -1
  24. data/app/concerns/houston/props.rb +3 -2
  25. data/app/controllers/actions_controller.rb +8 -3
  26. data/app/controllers/application_controller.rb +9 -12
  27. data/app/controllers/authorizations_controller.rb +41 -14
  28. data/app/controllers/errors_controller.rb +3 -3
  29. data/app/controllers/project_follows_controller.rb +23 -0
  30. data/app/controllers/project_options_controller.rb +1 -1
  31. data/app/controllers/user_options_controller.rb +1 -1
  32. data/app/helpers/actions_helper.rb +12 -0
  33. data/app/helpers/application_helper.rb +0 -10
  34. data/app/helpers/layout_helper.rb +20 -0
  35. data/app/helpers/markdown_helper.rb +2 -10
  36. data/app/helpers/navigation_helper.rb +5 -5
  37. data/app/helpers/project_helper.rb +6 -0
  38. data/app/helpers/url_helper.rb +4 -4
  39. data/app/helpers/view_extensions_helper.rb +20 -0
  40. data/app/models/action.rb +61 -44
  41. data/app/models/authorization.rb +55 -10
  42. data/app/models/follow.rb +6 -0
  43. data/app/models/persistent_trigger.rb +11 -1
  44. data/app/models/project.rb +5 -27
  45. data/app/models/user.rb +15 -59
  46. data/app/presenters/project_presenter.rb +2 -2
  47. data/app/views/actions/_actions.html.erb +8 -5
  48. data/app/views/actions/index.html.erb +1 -1
  49. data/app/views/actions/running.html.erb +9 -15
  50. data/app/views/actions/show.html.erb +6 -3
  51. data/app/views/actions/unqueued.html.erb +41 -0
  52. data/app/views/authorizations/_form.html.erb +28 -16
  53. data/app/views/authorizations/index.html.erb +9 -4
  54. data/app/views/{oauth/providers/edit.html.erb → authorizations/oauth2_callback.html.erb} +3 -2
  55. data/app/views/devise/sessions/new.html.erb +0 -8
  56. data/app/views/errors/index.html.erb +9 -5
  57. data/app/views/layouts/_navigation.html.erb +9 -0
  58. data/app/views/layouts/application.html.erb +11 -6
  59. data/app/views/layouts/dashboard.html.erb +9 -0
  60. data/app/views/projects/_form.html.erb +7 -18
  61. data/app/views/projects/_header.html.erb +2 -6
  62. data/app/views/projects/index.html.erb +4 -4
  63. data/app/views/teams/_form.html.erb +7 -17
  64. data/app/views/teams/index.html.erb +1 -1
  65. data/app/views/users/_form.html.erb +1 -38
  66. data/config/application.rb +8 -5
  67. data/config/initializers/devise.rb +0 -14
  68. data/config/initializers/secret_token.rb +8 -13
  69. data/config/routes.rb +12 -28
  70. data/db/migrate/20130706141443_drop_deprecated_project_roles.rb +5 -1
  71. data/db/migrate/20170118005958_remove_antecedents_from_versions_of_tickets.rb +1 -1
  72. data/db/migrate/20170130011016_drop_users_environments_subscribed_to.rb +9 -0
  73. data/db/migrate/20170205004452_drop_settings.rb +12 -0
  74. data/db/migrate/20170206002030_drop_extension_hstore.rb +9 -0
  75. data/db/migrate/20170206002732_drop_legacy_columns_from_users.rb +10 -0
  76. data/db/migrate/20170209022159_rename_projects_color_to_color_name.rb +5 -0
  77. data/db/migrate/20170213001453_change_providers_from_models_to_extensions.rb +27 -0
  78. data/db/migrate/20170215012012_add_props_to_authorizations.rb +5 -0
  79. data/db/migrate/20170216041034_add_user_to_persistent_triggers.rb +5 -0
  80. data/db/migrate/20170226201504_create_follows.rb +20 -0
  81. data/db/migrate/20170301014051_drop_name_from_authorizations.rb +9 -0
  82. data/db/migrate/20170307032041_add_created_at_to_actions.rb +11 -0
  83. data/db/migrate/20170307035755_allow_actions_started_at_to_be_null.rb +5 -0
  84. data/db/migrate/20170310024505_replace_authorizations_provider_name_with_type.rb +12 -0
  85. data/db/migrate/20170329030329_drop_consumer_tokens.rb +9 -0
  86. data/db/structure.sql +187 -212
  87. data/houston-core.gemspec +10 -13
  88. data/lib/houston/boot.rb +1 -4
  89. data/lib/houston/boot/actions.rb +24 -21
  90. data/lib/houston/boot/configuration.rb +46 -113
  91. data/lib/houston/boot/extensions.rb +54 -341
  92. data/lib/houston/boot/extensions/deprecated.rb +194 -0
  93. data/lib/houston/boot/extensions/dsl.rb +99 -0
  94. data/lib/houston/boot/extensions/events.rb +81 -0
  95. data/lib/houston/boot/extensions/features.rb +42 -0
  96. data/lib/houston/boot/extensions/layout.rb +70 -0
  97. data/lib/houston/boot/extensions/navigation.rb +42 -0
  98. data/lib/houston/boot/extensions/oauth.rb +62 -0
  99. data/lib/houston/boot/extensions/serializers.rb +29 -0
  100. data/lib/houston/boot/extensions/view.rb +34 -0
  101. data/lib/houston/boot/observer.rb +10 -5
  102. data/{app/models/oauth → lib/houston/boot}/provider.rb +7 -5
  103. data/lib/houston/boot/running_as.rb +0 -5
  104. data/lib/houston/boot/serializer.rb +12 -6
  105. data/lib/houston/boot/{active_record_serializer.rb → serializers/active_record_serializer.rb} +0 -2
  106. data/lib/houston/boot/{readonly_hash_serializer.rb → serializers/readonly_hash_serializer.rb} +0 -2
  107. data/lib/houston/boot/timer.rb +10 -0
  108. data/lib/houston/boot/triggers.rb +27 -8
  109. data/lib/houston/version.rb +1 -1
  110. data/templates/new-instance/.gitignore +0 -4
  111. data/templates/new-instance/config/main.rb +8 -10
  112. data/templates/new-module/test/dummy/houston.rb +1 -0
  113. data/test/acceptance/layout_test.rb +58 -0
  114. data/test/acceptance/updating_props_test.rb +72 -0
  115. data/test/support/config.rb +1 -0
  116. data/test/unit/extensions/events_extension_test.rb +33 -0
  117. data/test/unit/extensions/layout_extension_test.rb +74 -0
  118. data/test/unit/extensions/navigation_extension_test.rb +62 -0
  119. data/test/unit/extensions/oauth_extension_test.rb +91 -0
  120. data/test/unit/extensions/project_features_extension_test.rb +79 -0
  121. data/test/unit/extensions/serializers_extension_test.rb +47 -0
  122. data/test/unit/extensions/view_extension_test.rb +98 -0
  123. data/test/unit/models/actions_test.rb +11 -5
  124. data/test/unit/models/configuration_test.rb +0 -8
  125. data/test/unit/models/observer_test.rb +16 -0
  126. data/test/unit/models/persistent_trigger_test.rb +29 -2
  127. data/test/unit/models/serializer_test.rb +6 -0
  128. data/test/unit/models/timer_test.rb +88 -0
  129. metadata +87 -168
  130. data/app/assets/font/octicons.eot +0 -0
  131. data/app/assets/font/octicons.svg +0 -198
  132. data/app/assets/font/octicons.ttf +0 -0
  133. data/app/assets/font/octicons.woff +0 -0
  134. data/app/assets/font/roboto-black-webfont.eot +0 -0
  135. data/app/assets/font/roboto-black-webfont.svg +0 -675
  136. data/app/assets/font/roboto-black-webfont.ttf +0 -0
  137. data/app/assets/font/roboto-black-webfont.woff +0 -0
  138. data/app/assets/font/roboto-blackitalic-webfont.eot +0 -0
  139. data/app/assets/font/roboto-blackitalic-webfont.svg +0 -677
  140. data/app/assets/font/roboto-blackitalic-webfont.ttf +0 -0
  141. data/app/assets/font/roboto-blackitalic-webfont.woff +0 -0
  142. data/app/assets/font/roboto-bold-webfont.eot +0 -0
  143. data/app/assets/font/roboto-bold-webfont.svg +0 -675
  144. data/app/assets/font/roboto-bold-webfont.ttf +0 -0
  145. data/app/assets/font/roboto-bold-webfont.woff +0 -0
  146. data/app/assets/font/roboto-bolditalic-webfont.eot +0 -0
  147. data/app/assets/font/roboto-bolditalic-webfont.svg +0 -677
  148. data/app/assets/font/roboto-bolditalic-webfont.ttf +0 -0
  149. data/app/assets/font/roboto-bolditalic-webfont.woff +0 -0
  150. data/app/assets/font/roboto-italic-webfont.eot +0 -0
  151. data/app/assets/font/roboto-italic-webfont.svg +0 -668
  152. data/app/assets/font/roboto-italic-webfont.ttf +0 -0
  153. data/app/assets/font/roboto-italic-webfont.woff +0 -0
  154. data/app/assets/font/roboto-light-webfont.eot +0 -0
  155. data/app/assets/font/roboto-light-webfont.svg +0 -666
  156. data/app/assets/font/roboto-light-webfont.ttf +0 -0
  157. data/app/assets/font/roboto-light-webfont.woff +0 -0
  158. data/app/assets/font/roboto-lightitalic-webfont.eot +0 -0
  159. data/app/assets/font/roboto-lightitalic-webfont.svg +0 -668
  160. data/app/assets/font/roboto-lightitalic-webfont.ttf +0 -0
  161. data/app/assets/font/roboto-lightitalic-webfont.woff +0 -0
  162. data/app/assets/font/roboto-medium-webfont.eot +0 -0
  163. data/app/assets/font/roboto-medium-webfont.svg +0 -675
  164. data/app/assets/font/roboto-medium-webfont.ttf +0 -0
  165. data/app/assets/font/roboto-medium-webfont.woff +0 -0
  166. data/app/assets/font/roboto-mediumitalic-webfont.eot +0 -0
  167. data/app/assets/font/roboto-mediumitalic-webfont.svg +0 -677
  168. data/app/assets/font/roboto-mediumitalic-webfont.ttf +0 -0
  169. data/app/assets/font/roboto-mediumitalic-webfont.woff +0 -0
  170. data/app/assets/font/roboto-regular-webfont.eot +0 -0
  171. data/app/assets/font/roboto-regular-webfont.svg +0 -666
  172. data/app/assets/font/roboto-regular-webfont.ttf +0 -0
  173. data/app/assets/font/roboto-regular-webfont.woff +0 -0
  174. data/app/assets/font/roboto-thin-webfont.eot +0 -0
  175. data/app/assets/font/roboto-thin-webfont.svg +0 -666
  176. data/app/assets/font/roboto-thin-webfont.ttf +0 -0
  177. data/app/assets/font/roboto-thin-webfont.woff +0 -0
  178. data/app/assets/font/roboto-thinitalic-webfont.eot +0 -0
  179. data/app/assets/font/roboto-thinitalic-webfont.svg +0 -668
  180. data/app/assets/font/roboto-thinitalic-webfont.ttf +0 -0
  181. data/app/assets/font/roboto-thinitalic-webfont.woff +0 -0
  182. data/app/assets/images/bug-fixed-128.png +0 -0
  183. data/app/assets/images/bug-fixed-32.png +0 -0
  184. data/app/assets/images/bug-fixed-48.png +0 -0
  185. data/app/assets/images/bug-new-128.png +0 -0
  186. data/app/assets/images/bug-new-32.png +0 -0
  187. data/app/assets/images/bug-new-48.png +0 -0
  188. data/app/assets/images/bug-open-32.png +0 -0
  189. data/app/assets/images/bug-zero-128.png +0 -0
  190. data/app/assets/images/bug-zero-48.png +0 -0
  191. data/app/assets/images/drag-grip.png +0 -0
  192. data/app/assets/javascripts/houston/core/burndown_chart.coffee +0 -111
  193. data/app/assets/javascripts/houston/core/stacked_area_graph.coffee +0 -113
  194. data/app/assets/javascripts/houston/core/stacked_bar_graph.coffee +0 -108
  195. data/app/assets/stylesheets/houston/application/project_tiles.scss +0 -26
  196. data/app/assets/stylesheets/houston/application/tips.scss +0 -5
  197. data/app/assets/stylesheets/houston/core/octicons-icons.scss +0 -221
  198. data/app/assets/stylesheets/houston/core/octicons.scss.erb +0 -9
  199. data/app/assets/stylesheets/houston/core/roboto.scss.erb +0 -131
  200. data/app/concerns/historical_weekly_stats.rb +0 -15
  201. data/app/concerns/nosync.rb +0 -21
  202. data/app/controllers/oauth/providers_controller.rb +0 -45
  203. data/app/controllers/project_roles_controller.rb +0 -22
  204. data/app/controllers/settings_controller.rb +0 -14
  205. data/app/controllers/tester_bar_controller.rb +0 -12
  206. data/app/controllers/user_credentials_controller.rb +0 -24
  207. data/app/models/role.rb +0 -33
  208. data/app/models/setting.rb +0 -10
  209. data/app/models/settings.rb +0 -38
  210. data/app/models/slackdown.rb +0 -23
  211. data/app/models/user_credentials.rb +0 -27
  212. data/app/views/errors/_actions.html.erb +0 -17
  213. data/app/views/layouts/_tester_bar.html.erb +0 -6
  214. data/app/views/layouts/minimal.html.erb +0 -50
  215. data/app/views/layouts/naked.html.erb +0 -47
  216. data/app/views/layouts/naked_dashboard.html.erb +0 -50
  217. data/app/views/oauth/providers/_form.html.erb +0 -54
  218. data/app/views/oauth/providers/index.html.erb +0 -41
  219. data/app/views/oauth/providers/new.html.erb +0 -7
  220. data/config/initializers/add_navigation_renderers.rb +0 -5
  221. data/config/initializers/vestal_versions.rb +0 -9
  222. data/db/migrate/20130519163615_create_user_credentials.rb +0 -18
  223. data/lib/houston/boot/events.rb +0 -10
  224. data/lib/tasks/keypair.rake +0 -17
  225. 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.registered_event?(event_name)
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.get_registered_event(event_name)
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
- @block.call(*args)
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 Oauth
2
- class Provider < ActiveRecord::Base
3
- self.table_name = "oauth_providers"
1
+ module Houston
2
+ class Provider
3
+ attr_accessor :name, :site, :authorize_path, :token_path, :client_id, :client_secret
4
4
 
5
- validates :name, :site, :authorize_path, :token_path, :client_id, :client_secret, presence: true
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
- "http://#{Houston.host}/oauth2/callback"
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
- if serializer = object["^S"]
35
- object = serializer.constantize.new.unpack(object)
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
- Houston.serializers.each do |serializer|
67
+ serializers.each do |serializer|
62
68
  next unless serializer.applies_to?(object)
63
69
  packed_object = serializer.pack(object)
64
- packed_object.merge!("^S" => serializer.class.name) if serializer.respond_to?(:unpack)
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,
@@ -21,5 +21,3 @@ module Houston
21
21
 
22
22
  end
23
23
  end
24
-
25
- Houston.add_serializer Houston::ActiveRecordSerializer.new
@@ -11,5 +11,3 @@ module Houston
11
11
 
12
12
  end
13
13
  end
14
-
15
- Houston.add_serializer Houston::ReadonlyHashSerializer.new
@@ -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, &method(:call))
50
- when :on then config.observer.on(value, &method(:call))
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
- options = { trigger: to_s, async: triggers.async }
57
- config.actions.run action, self.params.merge(params.to_h), options
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
@@ -1,3 +1,3 @@
1
1
  module Houston
2
- VERSION = "0.8.4"
2
+ VERSION = "0.9.0.rc1"
3
3
  end
@@ -7,10 +7,6 @@
7
7
  # Ignore bundler config.
8
8
  /.bundle
9
9
 
10
- # Ignore sensitive passwords and things.
11
- config/keypair.pem
12
-
13
10
  # Ignore all logfiles and tempfiles.
14
11
  /log/*.log
15
12
  /tmp
16
-
@@ -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