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
@@ -2,9 +2,9 @@ class ErrorsController < ApplicationController
2
2
 
3
3
  def index
4
4
  authorize! :read, Action
5
- @actions = Action.reorder(finished_at: :desc).where.not(error_id: nil).preload(:error).limit(50)
6
- @actions = @actions.where(Action.arel_table[:finished_at].lt(params[:before])) if params[:before]
7
- render partial: "errors/actions" if request.xhr?
5
+ @actions = Action.where.not(error_id: nil).preload(:error).limit(50)
6
+ @actions = @actions.where(Action.arel_table[:created_at].lt(params[:before])) if params[:before]
7
+ render partial: "actions/actions" if request.xhr?
8
8
  end
9
9
 
10
10
  end
@@ -0,0 +1,23 @@
1
+ class ProjectFollowsController < ApplicationController
2
+ attr_reader :project
3
+ before_action :find_project
4
+
5
+
6
+ def create
7
+ current_user.follow! project
8
+ redirect_to :back, notice: "You are now following #{project.name}"
9
+ end
10
+
11
+ def destroy
12
+ current_user.unfollow! project
13
+ redirect_to :back, notice: "You are no longer following #{project.name}"
14
+ end
15
+
16
+
17
+ private
18
+
19
+ def find_project
20
+ @project = Project.find_by_slug!(params[:project_id])
21
+ end
22
+
23
+ end
@@ -4,7 +4,7 @@ class ProjectOptionsController < ApplicationController
4
4
 
5
5
 
6
6
  def update
7
- project.props.merge! params[:options]
7
+ project.props.merge! params[:options].to_unsafe_hash # <-- TODO: should props be declared and then permitted?
8
8
  project.save!
9
9
  head :ok
10
10
  end
@@ -3,7 +3,7 @@ class UserOptionsController < ApplicationController
3
3
 
4
4
 
5
5
  def update
6
- current_user.props.merge! params[:options]
6
+ current_user.props.merge! params[:options].to_unsafe_hash # <-- TODO: should props be declared and then permitted?
7
7
  current_user.save!
8
8
  head :ok
9
9
  end
@@ -45,4 +45,16 @@ module ActionsHelper
45
45
  output
46
46
  end
47
47
 
48
+ def format_action_state(action)
49
+ if !action.started?
50
+ '&mdash;'.html_safe
51
+ elsif action.in_progress?
52
+ '<i class="fa fa-spinner fa-pulse"></i>'.html_safe
53
+ elsif action.succeeded?
54
+ '<i class="fa fa-check success"></i>'.html_safe
55
+ else
56
+ '<i class="fa fa-times failure"></i>'.html_safe
57
+ end
58
+ end
59
+
48
60
  end
@@ -86,16 +86,6 @@ module ApplicationHelper
86
86
  end
87
87
  end
88
88
 
89
- def format_action_state(job)
90
- if job.in_progress?
91
- '<i class="fa fa-spinner fa-pulse"></i>'.html_safe
92
- elsif job.succeeded?
93
- '<i class="fa fa-check success"></i>'.html_safe
94
- else
95
- '<i class="fa fa-times failure"></i>'.html_safe
96
- end
97
- end
98
-
99
89
  MINUTE = 60
100
90
  HOUR = MINUTE * 60
101
91
  DAY = HOUR * 24
@@ -0,0 +1,20 @@
1
+ module LayoutHelper
2
+
3
+ def layout_show_navigation?
4
+ return true unless instance_variable_defined?(:@_layout_show_navigation)
5
+ @_layout_show_navigation
6
+ end
7
+
8
+ def layout_container_fluid?
9
+ return true unless instance_variable_defined?(:@_layout_container_fluid)
10
+ @_layout_container_fluid
11
+ end
12
+
13
+
14
+
15
+ def render_layout_extensions(layout, type)
16
+ partials = Houston.layout.extensions_by_layout[layout].public_send(type)
17
+ partials.map { |block| instance_eval(&block) }.inject(&:+)
18
+ end
19
+
20
+ end
@@ -1,21 +1,13 @@
1
1
  module MarkdownHelper
2
2
  include EmojiHelper
3
3
 
4
- def markdown
5
- @markdown ||= Redcarpet::Markdown.new(Redcarpet::Render::HTML,
6
- autolink: true, # parse and identify links
7
- lax_spacing: true, # don't require extra line breaks
8
- space_after_headers: false, # don't require there to be a space between # and a header
9
- no_intra_emphasis: true) # don't italicize bar in foo_bar_baz
10
- end
11
-
12
4
  def mdown(text)
13
5
  return "" if text.blank?
14
- emojify markdown.render(text).html_safe
6
+ emojify Kramdown::Document.new(text).to_html.html_safe
15
7
  end
16
8
 
17
9
  def slackdown(text)
18
- Slackdown.new(text).convert
10
+ Slackdown.convert(text)
19
11
  end
20
12
 
21
13
  end
@@ -1,10 +1,10 @@
1
1
  module NavigationHelper
2
2
 
3
3
  def render_navigation(key)
4
- renderer = Houston.get_navigation_renderer(key)
5
- return unless renderer.permitted?(current_ability)
4
+ link = Houston.navigation[key]
5
+ return unless link.permitted?(current_ability)
6
6
 
7
- render_nav_link renderer.name, renderer.path
7
+ render_nav_link link.name, link.path
8
8
  rescue KeyError
9
9
  Rails.logger.error "\e[31;1mThere is no navigation renderer named #{key.inspect}\e[0m"
10
10
  nil
@@ -18,10 +18,10 @@ module NavigationHelper
18
18
  end
19
19
 
20
20
  def render_nav_for_feature(feature)
21
- feature = Houston.get_project_feature feature
21
+ feature = Houston.project_features[feature]
22
22
  return unless feature.permitted?(current_ability, current_project)
23
23
 
24
- render_nav_link feature.name, feature.project_path(current_project)
24
+ render_nav_link feature.name, feature.path(current_project)
25
25
  rescue KeyError
26
26
  Rails.logger.error "\e[31;1mThere is no project feature named #{feature.inspect}\e[0m"
27
27
  nil
@@ -5,4 +5,10 @@ module ProjectHelper
5
5
  "<b class=\"label #{project.color}\">#{h project.slug.gsub("_", " ")}</b>".html_safe
6
6
  end
7
7
 
8
+ def project_banner(project, &block)
9
+ content_for :title do
10
+ content_tag :h1, class: "project-banner #{project.color} space-below", "data-project-slug" => project.slug, "data-project-color" => project.color, &block
11
+ end
12
+ end
13
+
8
14
  end
@@ -1,13 +1,13 @@
1
1
  module UrlHelper
2
2
 
3
3
  def feature_path(project, feature)
4
- feature = Houston.get_project_feature feature
5
- feature.project_path project
4
+ feature = Houston.project_features[feature]
5
+ feature.path project
6
6
  end
7
7
 
8
8
  def link_to_project_feature(project, feature)
9
- feature = Houston.get_project_feature feature
10
- link_to feature.name, feature.project_path(project)
9
+ feature = Houston.project_features[feature]
10
+ link_to feature.name, feature.path(project)
11
11
  end
12
12
 
13
13
  end
@@ -0,0 +1,20 @@
1
+ module ViewExtensionsHelper
2
+
3
+ def render_props_fields(form, view_name)
4
+ form.fields_for :props, form.object.props do |f|
5
+ Houston.view[view_name].fields.map do |field|
6
+ <<~HTML
7
+ <hr />
8
+
9
+ <div class="control-group">
10
+ <label class="control-label" for="#{field.id}">#{field.label}</label>
11
+ <div class="controls">
12
+ #{field.render(self, f)}
13
+ </div>
14
+ </div>
15
+ HTML
16
+ end.join.html_safe
17
+ end
18
+ end
19
+
20
+ end
data/app/models/action.rb CHANGED
@@ -1,13 +1,12 @@
1
1
  class Action < ActiveRecord::Base
2
2
 
3
- validates :name, :started_at, presence: true
3
+ validates :name, presence: true
4
4
  belongs_to :error
5
5
 
6
- default_scope -> { order(started_at: :desc) }
6
+ default_scope -> { order(created_at: :desc) }
7
7
 
8
8
  serialize :params, Houston::ParamsSerializer.new
9
9
 
10
-
11
10
  @ignored_exceptions = [
12
11
  SocketError,
13
12
  Errno::ECONNREFUSED,
@@ -31,52 +30,66 @@ class Action < ActiveRecord::Base
31
30
  where arel_table[:started_at].lteq time
32
31
  end
33
32
 
34
- def record(action_name, params, trigger)
35
- action = create!(name: action_name, started_at: Time.now, trigger: trigger, params: params)
36
- begin
37
- exception = nil
38
-
39
- Houston.reconnect do
40
- yield
41
- end
42
-
43
- rescue *ignored_exceptions
44
-
45
- # Note that the action failed, but do not report _these_ exceptions
46
- exception = $!
47
-
48
- rescue Exception # rescues StandardError by default; but we want to rescue and report all errors
49
-
50
- # Report all other exceptions
51
- exception = $!
52
- Houston.report_exception($!, parameters: {
53
- action_id: action.id,
54
- action_name: action_name,
55
- trigger: trigger,
56
- params: params
57
- })
58
-
59
- ensure
60
- begin
61
- Houston.reconnect do
62
- action.finish! exception
63
- end
64
- rescue Exception # rescues StandardError by default; but we want to rescue and report all errors
65
- Houston.report_exception($!, parameters: {
66
- action_id: action.id,
67
- action_name: action_name,
68
- trigger: trigger,
69
- params: params
70
- })
71
- end
72
- end
33
+ def running
34
+ where.not(started_at: nil).where(finished_at: nil)
35
+ end
36
+
37
+ def unqueued
38
+ where(started_at: nil)
39
+ end
40
+
41
+ def run!(action_name, params, trigger)
42
+ action = create!(name: action_name, trigger: trigger, params: params)
43
+ action.run!
73
44
  end
74
45
  end
75
46
 
76
47
 
77
48
 
49
+ def run!
50
+ exception = nil
51
+
52
+ Houston.reconnect do
53
+ touch :started_at
54
+ Houston.actions.fetch(name).execute(params)
55
+ end
56
+
57
+ rescue *::Action.ignored_exceptions
58
+
59
+ # Note that the action failed, but do not report _these_ exceptions
60
+ exception = $!
61
+
62
+ rescue Exception # rescues StandardError by default; but we want to rescue and report all errors
63
+
64
+ # Report all other exceptions
65
+ exception = $!
66
+ Houston.report_exception($!, parameters: {
67
+ action_id: id,
68
+ action_name: name,
69
+ trigger: trigger,
70
+ params: params
71
+ })
72
+
73
+ ensure
74
+ begin
75
+ Houston.reconnect do
76
+ finish! exception
77
+ end
78
+ rescue Exception # rescues StandardError by default; but we want to rescue and report all errors
79
+ Houston.report_exception($!, parameters: {
80
+ action_id: id,
81
+ action_name: name,
82
+ trigger: trigger,
83
+ params: params
84
+ })
85
+ end
86
+ end
87
+
78
88
  def retry!
79
- Houston.actions.run name, params
89
+ update_attributes! started_at: Time.now, finished_at: nil, succeeded: nil, exception: nil
90
+ Houston.async do
91
+ run!
92
+ end
80
93
  end
81
94
 
82
95
  def exception=(exception)
@@ -92,12 +105,16 @@ class Action < ActiveRecord::Base
92
105
  finished_at - started_at
93
106
  end
94
107
 
108
+ def started?
109
+ started_at.present?
110
+ end
111
+
95
112
  def finished?
96
113
  finished_at.present?
97
114
  end
98
115
 
99
116
  def in_progress?
100
- finished_at.nil?
117
+ started_at.present? && finished_at.nil?
101
118
  end
102
119
 
103
120
  end
@@ -1,21 +1,56 @@
1
1
  class Authorization < ActiveRecord::Base
2
+ include Houston::Props
2
3
 
3
- belongs_to :provider, class_name: "Oauth::Provider"
4
+ belongs_to :user
4
5
 
5
- validates :name, :provider_id, presence: true
6
+ validates :user_id, presence: true
6
7
 
7
- def self.[](name)
8
- find_by(name: name)
8
+ after_destroy do
9
+ next unless granted?
10
+ Houston.observer.fire "authorization:revoke", authorization: self
9
11
  end
10
12
 
11
- def self.set_access_token!(params)
12
- Authorization.find(params.fetch(:state)).tap do |authorization|
13
- authorization.get_access_token! params.fetch(:code)
13
+
14
+
15
+ class << self
16
+ def for(user)
17
+ where(user_id: user.id)
18
+ end
19
+
20
+ def granted
21
+ where.not(access_token: nil)
22
+ end
23
+
24
+ def with_scope(*scopes)
25
+ where("regexp_split_to_array(scope, '[,\\s]+') @> ARRAY[?]", scopes)
26
+ end
27
+ alias :with_scopes :with_scope
28
+
29
+
30
+
31
+ def providers
32
+ Houston.config.oauth_providers.map(&:classify)
33
+ end
34
+
35
+ def provider
36
+ @provider ||= Houston.oauth.get_provider(name.underscore)
14
37
  end
38
+
39
+ def set_access_token!(params)
40
+ Authorization.find(params.fetch(:state)).tap do |authorization|
41
+ authorization.get_access_token! params.fetch(:code)
42
+ end
43
+ end
44
+ end
45
+
46
+
47
+
48
+ def provider
49
+ self.class.provider
15
50
  end
16
51
 
17
52
  def granted?
18
- expires_in.present?
53
+ access_token.present?
19
54
  end
20
55
 
21
56
  def authorize_url(params={})
@@ -36,19 +71,29 @@ class Authorization < ActiveRecord::Base
36
71
  end
37
72
 
38
73
  def expired?
39
- return false unless granted?
74
+ return false if expires_in.nil?
40
75
  Time.now >= expires_at
41
76
  end
42
77
 
78
+ def url
79
+ "#{Houston.root_url}/auth/#{id}"
80
+ end
81
+
43
82
  private
44
83
 
45
84
  def merge!(new_token)
46
85
  self.access_token = new_token.token
47
86
  self.expires_in = new_token.expires_in
48
- self.expires_at = expires_in.seconds.from_now
87
+ self.expires_at = expires_in.seconds.from_now if expires_in
49
88
  self.refresh_token = new_token.refresh_token if new_token.respond_to?(:refresh_token)
50
89
  self.secret = new_token.secret if new_token.respond_to?(:secret)
51
90
  save!
91
+
92
+ Houston.observer.fire "authorization:grant", authorization: self
52
93
  end
53
94
 
54
95
  end
96
+
97
+ Houston.config.oauth_providers.each do |provider|
98
+ require_dependency provider
99
+ end