softwear 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (38) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/Rakefile +37 -0
  4. data/app/assets/javascripts/softwear/application.js +13 -0
  5. data/app/assets/javascripts/softwear/error_utils.js.coffee +82 -0
  6. data/app/assets/javascripts/softwear/modals.js.coffee +171 -0
  7. data/app/assets/stylesheets/softwear/application.css +33 -0
  8. data/app/controllers/softwear/application_controller.rb +4 -0
  9. data/app/controllers/softwear/error_reports_controller.rb +37 -0
  10. data/app/helpers/softwear/application_helper.rb +4 -0
  11. data/app/helpers/softwear/emails_helper.rb +9 -0
  12. data/app/mailers/error_report_mailer.rb +53 -0
  13. data/app/views/error_report_mailer/send_report.html.erb +30 -0
  14. data/app/views/layouts/softwear/application.html.erb +14 -0
  15. data/app/views/softwear/errors/_error.html.erb +35 -0
  16. data/app/views/softwear/errors/internal_server_error.html.erb +6 -0
  17. data/app/views/softwear/errors/internal_server_error.js.erb +10 -0
  18. data/bin/rails +12 -0
  19. data/config/routes.rb +3 -0
  20. data/lib/softwear/auth/belongs_to_user.rb +43 -0
  21. data/lib/softwear/auth/controller.rb +43 -0
  22. data/lib/softwear/auth/helper.rb +35 -0
  23. data/lib/softwear/auth/model.rb +16 -0
  24. data/lib/softwear/auth/spec.rb +62 -0
  25. data/lib/softwear/auth/standard_model.rb +498 -0
  26. data/lib/softwear/auth/stubbed_model.rb +130 -0
  27. data/lib/softwear/auth/token_authentication.rb +72 -0
  28. data/lib/softwear/engine.rb +5 -0
  29. data/lib/softwear/error_catcher.rb +65 -0
  30. data/lib/softwear/library/api_controller.rb +169 -0
  31. data/lib/softwear/library/capistrano.rb +94 -0
  32. data/lib/softwear/library/controller_authentication.rb +145 -0
  33. data/lib/softwear/library/enqueue.rb +87 -0
  34. data/lib/softwear/library/spec.rb +127 -0
  35. data/lib/softwear/library/tcp_server.rb +107 -0
  36. data/lib/softwear/version.rb +3 -0
  37. data/lib/softwear.rb +107 -0
  38. metadata +172 -0
@@ -0,0 +1,87 @@
1
+ require 'sidekiq'
2
+
3
+ module Softwear
4
+ module Library
5
+ module Enqueue
6
+ extend ActiveSupport::Concern
7
+
8
+ class Worker
9
+ include ::Sidekiq::Worker
10
+
11
+ def perform(model_name, id, method, *args)
12
+ model_name.constantize.find(id).send(method, *args)
13
+ end
14
+ end
15
+
16
+ module ClassMethods
17
+ def enqueue(*method_names)
18
+ if method_names.last.is_a?(Hash)
19
+ options = method_names.pop
20
+ else
21
+ options = {}
22
+ end
23
+ raise "enqueue what?" if method_names.empty?
24
+
25
+ # We will extend the class mod and include the instance mod.
26
+ # This allows us to override the generated enqueue methods and
27
+ # call `super`.
28
+ #
29
+ enqueue_class_mod = Module.new
30
+ enqueue_instance_mod = Module.new
31
+
32
+ method_names.each do |method_name|
33
+ enqueue_class_mod.module_eval <<-RUBY, __FILE__, __LINE__ + 1
34
+ def #{method_name}(id, *args)
35
+ find(id).#{method_name}(*args)
36
+ end
37
+ RUBY
38
+
39
+ if Rails.env.production?
40
+ enqueue_class_mod.module_eval <<-RUBY, __FILE__, __LINE__ + 1
41
+ def enqueue_#{method_name}(id, *args)
42
+ ::Sidekiq::Client.push(
43
+ 'class' => ::Softwear::Lib::Enqueue::Worker,
44
+ 'args' => [name, id, #{method_name.inspect}] + args,
45
+ 'queue' => #{options[:queue].inspect}
46
+ )
47
+ end
48
+ RUBY
49
+
50
+ enqueue_instance_mod.module_eval <<-RUBY, __FILE__, __LINE__ + 1
51
+ def enqueue_#{method_name}(*args)
52
+ self.class.enqueue_#{method_name}(id, *args)
53
+ end
54
+ RUBY
55
+ else
56
+ enqueue_class_mod.module_eval <<-RUBY, __FILE__, __LINE__ + 1
57
+ def enqueue_#{method_name}(id, *args)
58
+ self.#{method_name}(id, *args)
59
+ end
60
+ RUBY
61
+
62
+ enqueue_instance_mod.module_eval <<-RUBY, __FILE__, __LINE__ + 1
63
+ def enqueue_#{method_name}(*args)
64
+ self.#{method_name}(*args)
65
+ end
66
+ RUBY
67
+ end
68
+ end
69
+
70
+ send :extend, enqueue_class_mod
71
+ send :include, enqueue_instance_mod
72
+
73
+ r = method_names.map { |m| "enqueue_#{m}".to_sym }
74
+ r.size == 1 ? r.first : r
75
+ end
76
+ end
77
+
78
+ included do
79
+ extend ClassMethods
80
+
81
+ def enqueue(method_name, *args)
82
+ send("enqueue_#{method_name}", *args)
83
+ end
84
+ end
85
+ end
86
+ end
87
+ end
@@ -0,0 +1,127 @@
1
+ require 'active_support/concern'
2
+
3
+ module Softwear::Library
4
+ module Spec
5
+ extend ActiveSupport::Concern
6
+
7
+ module CapybaraHelpers
8
+ def wait_for_ajax
9
+ begin
10
+ Timeout.timeout(Capybara.default_wait_time) do
11
+ wait_for_jquery
12
+ loop until finished_all_ajax_requests?
13
+ end
14
+ rescue
15
+ sleep 0.1
16
+ end
17
+ end
18
+
19
+ def finished_all_ajax_requests?
20
+ page.evaluate_script('jQuery.active').zero?
21
+ end
22
+
23
+ def wait_for_redirect
24
+ original_url = current_path
25
+ until current_path != original_url
26
+ sleep(0.1)
27
+ end
28
+ end
29
+
30
+ def wait_for_jquery
31
+ until page.evaluate_script('jQuery.active') == 0
32
+ sleep(0.1)
33
+ end
34
+ end
35
+
36
+ def accept_alert
37
+ page.evaluate_script('window.confirm = function() { return true; }')
38
+ yield
39
+ end
40
+
41
+ def dismiss_alert
42
+ page.evaluate_script('window.confirm = function() { return false; }')
43
+ yield
44
+ # Restore existing default
45
+ page.evaluate_script('window.confirm = function() { return true; }')
46
+ end
47
+
48
+ def eventually_fill_in(field, options={})
49
+ page.should have_css('#' + field)
50
+ fill_in field, options
51
+ end
52
+
53
+ def within_row(num, &block)
54
+ if RSpec.current_example.metadata[:js]
55
+ within("table.index tbody tr:nth-child(#{num})", &block)
56
+ else
57
+ within(:xpath, all('table.index tbody tr')[num-1].path, &block)
58
+ end
59
+ end
60
+
61
+ def column_text(num)
62
+ if RSpec.current_example.metadata[:js]
63
+ find("td:nth-child(#{num})").text
64
+ else
65
+ all('td')[num-1].text
66
+ end
67
+ end
68
+
69
+ def find_label_by_text(text, options = {})
70
+ label = find_label(text)
71
+
72
+ if !options[:try] && label.nil?
73
+ raise "Could not find label by text #{text}"
74
+ end
75
+
76
+ label
77
+ end
78
+
79
+ def find_label(text)
80
+ first(:xpath, "//label[text()[contains(.,'#{text}')]]")
81
+ end
82
+
83
+ end
84
+
85
+ module Select2
86
+ def select2(text, options)
87
+ label = find_label_by_text(options[:from], try: true)
88
+ if label
89
+ selector = "select[name='#{label['for']}']+span,select[id='#{label['for']}']+span"
90
+ else
91
+ selector = "#{options[:from]}+span"
92
+ end
93
+
94
+ if options[:last]
95
+ all(selector).last.click
96
+ else
97
+ find(selector).click
98
+ end
99
+
100
+ old_scopes = page.instance_variable_get(:@scopes)
101
+ page.instance_variable_set(:@scopes, [nil])
102
+
103
+ find('input.select2-search__field').set(text)
104
+ sleep options[:wait_before_click] if options[:wait_before_click]
105
+ result = first('li.select2-results__option')
106
+ if result.nil? || result.text == "No results found"
107
+ raise %(No results matching "#{text}" found during select2)
108
+ else
109
+ result.click
110
+ end
111
+
112
+ ensure
113
+ page.instance_variable_set(:@scopes, old_scopes) if old_scopes
114
+ end
115
+ end
116
+
117
+ included do
118
+ include Warden::Test::Helpers
119
+ Warden.test_mode!
120
+
121
+ RSpec.configure do |config|
122
+ config.include CapybaraHelpers, type: :feature
123
+ end
124
+ end
125
+
126
+ end
127
+ end
@@ -0,0 +1,107 @@
1
+ def split(string, limit = nil)
2
+ string.split(/\s+/, limit)
3
+ end
4
+
5
+ def report_error(client, whole_command, error)
6
+ $stderr.puts "=== ERROR WHILE PROCESSING THE COMMAND \"#{whole_command}\" ===\n"\
7
+ "#{error.class.name}: #{error.message}\n#{error.backtrace.join("\n")}"
8
+ client.puts "sorry"
9
+ end
10
+
11
+ def dev_log(*a)
12
+ $stdout.puts(*a) if Rails.env.development?
13
+ end
14
+
15
+ def log(*a)
16
+ $stdout.puts(*a) unless Rails.env.test?
17
+ end
18
+
19
+ # TODO for production, we want to use the SSL server instead of straight up TCP.
20
+
21
+ # ==== Send Format: =======
22
+ # One line strings: "#{command} #{arg1} #{arg2} #{etc}"
23
+ # The last argument, depending on the command, may contain spaces (but usually does not need to)
24
+ # =========================
25
+ # === Receive Format: =====
26
+ # Usually one string, like "yes", or "no".
27
+ # Returns "denied" if an unauthorized command was attempted.
28
+ # Returns "invalid" if an invalid command was attempted.
29
+ # Returns "sorry" if an error was raised while processing the command.
30
+ # Can be a json argument, often following "yes ".
31
+ # =========================
32
+ def address_of(socket)
33
+ _family, port, name, host = socket.addr
34
+ if host == name
35
+ "#{host}:#{port}"
36
+ else
37
+ "#{name}(#{host}):#{port}"
38
+ end
39
+ end
40
+
41
+ def start_server!(*args)
42
+ log "Connecting...!"
43
+
44
+ if args.size > 1
45
+ port = args.first
46
+ else
47
+ port = ENV['port'] || ENV['PORT'] || 2900
48
+ end
49
+
50
+ server = TCPServer.new port
51
+ log "Ready! Using \"#{ActiveRecord::Base.connection.current_database}\" database"
52
+
53
+ client_count = 0
54
+ commands = args.last
55
+
56
+ loop do
57
+ Thread.start(server.accept) do |client|
58
+ client_count += 1
59
+ dev_log "New client! ##{client_count} #{address_of client}"
60
+
61
+ if Rails.env.development?
62
+ response_logger = Module.new do
63
+ def puts(s)
64
+ $stdout.puts "==> #{s}"
65
+ super
66
+ end
67
+ end
68
+ client.singleton_class.send :include, response_logger
69
+ end
70
+
71
+ while line_in = client.gets.chomp
72
+ log "Processing \"#{line_in}\"" if Rails.env.test?
73
+
74
+ command, rest_of_command = split(line_in, 2)
75
+
76
+ before = Time.now
77
+ begin
78
+ command = commands[command.downcase.to_sym]
79
+
80
+ if command.nil?
81
+ log "SOMEONE attempted invalid command: \"#{line_in}\""
82
+ else
83
+ dev_log "<== #{line_in}"
84
+ ActiveRecord::Base.connection_pool.with_connection do
85
+ command.call(client, rest_of_command)
86
+ end
87
+ end
88
+
89
+ rescue StandardError => e
90
+ report_error(client, line_in, e)
91
+ rescue Exception => e
92
+ report_error(client, line_in, e)
93
+ break
94
+ end
95
+ after = Time.now
96
+
97
+ ms = (after - before) * 1000
98
+ dev_log %((#{'%.2f' % ms}ms) from #{address_of(client)})
99
+ dev_log ""
100
+ end
101
+
102
+ client_count -= 1
103
+ client.close rescue nil
104
+ dev_log "Client disconnected. #{address_of client}"
105
+ end
106
+ end
107
+ end
@@ -0,0 +1,3 @@
1
+ module Softwear
2
+ VERSION = "2.0.0"
3
+ end
data/lib/softwear.rb ADDED
@@ -0,0 +1,107 @@
1
+ require 'softwear/engine'
2
+ require 'softwear/version'
3
+ require 'softwear/error_catcher'
4
+
5
+ require "softwear/library/spec"
6
+ require "softwear/library/api_controller"
7
+ begin
8
+ require "softwear/library/enqueue"
9
+ rescue LoadError
10
+ end
11
+
12
+ require "softwear/library/controller_authentication"
13
+ require "softwear/auth/helper"
14
+ require "softwear/auth/model"
15
+ require "softwear/auth/belongs_to_user"
16
+ require "softwear/auth/spec"
17
+ require "softwear/auth/token_authentication"
18
+
19
+ module Softwear
20
+ GEMFILE_OPENER = "# === BEGIN SOFTWEAR LIB GEMS === #"
21
+ GEMFILE_CLOSER = "# === END SOFTWEAR LIB GEMS === #"
22
+
23
+ COMMON_GEMS = %(
24
+ gem 'rails', '~> 4.2.3'
25
+
26
+ gem 'mysql2'
27
+ gem 'sass-rails'
28
+ gem 'uglifier', '>= 1.3.0'
29
+ gem 'coffee-rails', '~> 4.0.0'
30
+ gem 'bootstrap-sass', '~> 3.2.0'
31
+ gem 'activeresource'
32
+ gem 'jquery-rails'
33
+ gem 'jquery-ui-rails'
34
+ gem 'hirb'
35
+ gem 'momentjs-rails', '~> 2.9.0'
36
+ gem 'bootstrap3-datetimepicker-rails', '4.7.14'
37
+ gem 'js-routes'
38
+ gem 'inherited_resources'
39
+ gem 'devise'
40
+ gem 'figaro'
41
+ gem 'paranoia', '~> 2.0'
42
+ gem 'paperclip'
43
+ gem 'kaminari'
44
+ gem 'whenever'
45
+ gem 'dumpsync', git: 'git://github.com/AnnArborTees/dumpsync.git'
46
+ gem 'bootstrap_form'
47
+ gem 'acts_as_warnable', git: 'git://github.com/AnnArborTees/acts_as_warnable.git'
48
+
49
+ group :development do
50
+ gem 'capistrano', '~> 3.2.0'
51
+ gem 'capistrano-rails'
52
+ gem 'capistrano-rvm', github: 'AnnArborTees/rvm'
53
+ gem 'capistrano-bundler', github: 'AnnArborTees/bundler'
54
+ gem 'better_errors', '>= 0.3.2'
55
+ gem 'binding_of_caller'
56
+ end
57
+
58
+ group :development, :test do
59
+ gem 'byebug', platforms: :mri
60
+ gem 'rubinius-debugger', platforms: :rbx
61
+ end
62
+
63
+ group :test do
64
+ gem "rspec-rails", "~> 3.2.0"
65
+ gem 'factory_girl_rails', '>= 4.2.0', require: true
66
+ gem 'capybara', '~> 2.4'
67
+ gem 'capybara-webkit'
68
+ gem 'webmock', require: false
69
+ gem 'rspec-mocks'
70
+ gem 'rspec-retry'
71
+ gem 'email_spec'
72
+ gem 'selenium-webdriver'
73
+ gem 'shoulda-matchers'
74
+ end
75
+ )
76
+
77
+ def self.fix_sort_argument_error_on_rubinius
78
+ # Rubinius calls Enumerator#sort! within Enumerator#sort_by,
79
+ # # and Mail::PartsList calls sort_by within sort!... See the
80
+ # problem?
81
+
82
+ if RUBY_ENGINE == 'rbx'
83
+ require 'mail'
84
+
85
+ Mail::PartsList.class_eval do
86
+ def map!(&block)
87
+ Mail::PartsList.new(collect(&block))
88
+ end
89
+
90
+ def sort!(order = nil)
91
+ return super() if order.nil?
92
+
93
+ i = 0
94
+ sorted = self.sort_by do |a|
95
+ [get_order_value(a, order), i += 1]
96
+ end
97
+ self.clear
98
+ sorted.each(&self.method(:<<))
99
+ end
100
+ end
101
+ end
102
+ end
103
+
104
+ def self.fix_state_machine_around_validation
105
+ StateMachine::Integrations::ActiveModel.instance_eval { public :around_validation }
106
+ end
107
+ end
metadata ADDED
@@ -0,0 +1,172 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: softwear
3
+ version: !ruby/object:Gem::Version
4
+ version: 2.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Nigel Baillie
8
+ - Stefan Gale
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2016-11-23 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rails
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - "~>"
19
+ - !ruby/object:Gem::Version
20
+ version: '4.2'
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: 4.2.7.1
24
+ type: :runtime
25
+ prerelease: false
26
+ version_requirements: !ruby/object:Gem::Requirement
27
+ requirements:
28
+ - - "~>"
29
+ - !ruby/object:Gem::Version
30
+ version: '4.2'
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 4.2.7.1
34
+ - !ruby/object:Gem::Dependency
35
+ name: activesupport
36
+ requirement: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 4.2.5
41
+ type: :runtime
42
+ prerelease: false
43
+ version_requirements: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: 4.2.5
48
+ - !ruby/object:Gem::Dependency
49
+ name: sqlite3
50
+ requirement: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ type: :development
56
+ prerelease: false
57
+ version_requirements: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ - !ruby/object:Gem::Dependency
63
+ name: bundler
64
+ requirement: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '1.7'
69
+ type: :development
70
+ prerelease: false
71
+ version_requirements: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '1.7'
76
+ - !ruby/object:Gem::Dependency
77
+ name: rake
78
+ requirement: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '10.0'
83
+ type: :development
84
+ prerelease: false
85
+ version_requirements: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '10.0'
90
+ - !ruby/object:Gem::Dependency
91
+ name: rspec
92
+ requirement: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: 3.2.0
97
+ type: :development
98
+ prerelease: false
99
+ version_requirements: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: 3.2.0
104
+ description: Re-worked softwear-lib gem.
105
+ email:
106
+ - nigel@annarbortees.com
107
+ - stefan@annarbortees.com
108
+ executables: []
109
+ extensions: []
110
+ extra_rdoc_files: []
111
+ files:
112
+ - MIT-LICENSE
113
+ - Rakefile
114
+ - app/assets/javascripts/softwear/application.js
115
+ - app/assets/javascripts/softwear/error_utils.js.coffee
116
+ - app/assets/javascripts/softwear/modals.js.coffee
117
+ - app/assets/stylesheets/softwear/application.css
118
+ - app/controllers/softwear/application_controller.rb
119
+ - app/controllers/softwear/error_reports_controller.rb
120
+ - app/helpers/softwear/application_helper.rb
121
+ - app/helpers/softwear/emails_helper.rb
122
+ - app/mailers/error_report_mailer.rb
123
+ - app/views/error_report_mailer/send_report.html.erb
124
+ - app/views/layouts/softwear/application.html.erb
125
+ - app/views/softwear/errors/_error.html.erb
126
+ - app/views/softwear/errors/internal_server_error.html.erb
127
+ - app/views/softwear/errors/internal_server_error.js.erb
128
+ - bin/rails
129
+ - config/routes.rb
130
+ - lib/softwear.rb
131
+ - lib/softwear/auth/belongs_to_user.rb
132
+ - lib/softwear/auth/controller.rb
133
+ - lib/softwear/auth/helper.rb
134
+ - lib/softwear/auth/model.rb
135
+ - lib/softwear/auth/spec.rb
136
+ - lib/softwear/auth/standard_model.rb
137
+ - lib/softwear/auth/stubbed_model.rb
138
+ - lib/softwear/auth/token_authentication.rb
139
+ - lib/softwear/engine.rb
140
+ - lib/softwear/error_catcher.rb
141
+ - lib/softwear/library/api_controller.rb
142
+ - lib/softwear/library/capistrano.rb
143
+ - lib/softwear/library/controller_authentication.rb
144
+ - lib/softwear/library/enqueue.rb
145
+ - lib/softwear/library/spec.rb
146
+ - lib/softwear/library/tcp_server.rb
147
+ - lib/softwear/version.rb
148
+ homepage: http://annarbortees.com/
149
+ licenses:
150
+ - MIT
151
+ metadata: {}
152
+ post_install_message:
153
+ rdoc_options: []
154
+ require_paths:
155
+ - softwear
156
+ required_ruby_version: !ruby/object:Gem::Requirement
157
+ requirements:
158
+ - - ">="
159
+ - !ruby/object:Gem::Version
160
+ version: '0'
161
+ required_rubygems_version: !ruby/object:Gem::Requirement
162
+ requirements:
163
+ - - ">="
164
+ - !ruby/object:Gem::Version
165
+ version: '0'
166
+ requirements: []
167
+ rubyforge_project:
168
+ rubygems_version: 2.4.8
169
+ signing_key:
170
+ specification_version: 4
171
+ summary: Common gems and logic for all softwear apps.
172
+ test_files: []